diff options
411 files changed, 12803 insertions, 3316 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 18afc03b460..2dfeda9985d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -264,8 +264,8 @@ Check packing of Python tools: sandbox test.py: parallel: matrix: - - HOST: "fast arm64" - - HOST: "fast amd64" + - HOST: "arm64" + - HOST: "amd64" tags: - ${HOST} variables: @@ -276,8 +276,8 @@ sandbox test.py: sandbox with clang test.py: parallel: matrix: - - HOST: "fast arm64" - - HOST: "fast amd64" + - HOST: "arm64" + - HOST: "amd64" tags: - ${HOST} variables: @@ -288,8 +288,8 @@ sandbox with clang test.py: sandbox64 test.py: parallel: matrix: - - HOST: "fast arm64" - - HOST: "fast amd64" + - HOST: "arm64" + - HOST: "amd64" tags: - ${HOST} variables: @@ -299,8 +299,8 @@ sandbox64 test.py: sandbox64 with clang test.py: parallel: matrix: - - HOST: "fast arm64" - - HOST: "fast amd64" + - HOST: "arm64" + - HOST: "amd64" tags: - ${HOST} variables: @@ -311,8 +311,8 @@ sandbox64 with clang test.py: sandbox64_lwip test.py: parallel: matrix: - - HOST: "fast arm64" - - HOST: "fast amd64" + - HOST: "arm64" + - HOST: "amd64" tags: - ${HOST} variables: @@ -39,6 +39,7 @@ Casey Connolly <casey.connolly@linaro.org> <caleb.connolly@linaro.org> Christian Kohn <chris.kohn@amd.com> <christian.kohn@xilinx.com> Christopher Obbard <christopher.obbard@linaro.org> <chris.obbard@collabora.com> Dirk Behme <dirk.behme@googlemail.com> +<duje@dujemihanovic.xyz> <duje.mihanovic@skole.hr> Durga Challa <durga.challa@amd.com> <vnsl.durga.challa@xilinx.com> Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@microchip.com> Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@collabora.com> @@ -309,7 +309,7 @@ config SYS_MALLOC_F_LEN config SYS_MALLOC_LEN hex "Define memory for Dynamic allocation" default 0x4000000 if SANDBOX - default 0x2000000 if ARCH_ROCKCHIP || ARCH_OMAP2PLUS || ARCH_MESON + default 0x2000000 if ARCH_ROCKCHIP || ARCH_OMAP2PLUS || ARCH_MESON || ARCH_K3 default 0x200000 if ARCH_BMIPS || X86 default 0x4020000 if SUNXI_MINIMUM_DRAM_MB >= 256 default 0x220000 if SUNXI_MINIMUM_DRAM_MB >= 64 diff --git a/MAINTAINERS b/MAINTAINERS index 92119667618..d5264c8f5df 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -391,7 +391,7 @@ F: drivers/pci/pci-aardvark.c F: drivers/pci/pci_mvebu.c ARM MARVELL PXA1908 -M: Duje Mihanović <duje.mihanovic@skole.hr> +M: Duje Mihanović <duje@dujemihanovic.xyz> S: Maintained T: git git://git.dujemihanovic.xyz/u-boot.git F: arch/arm/dts/pxa1908* @@ -1073,6 +1073,7 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-dfu.git F: cmd/dfu.c F: cmd/usb_*.c F: common/dfu.c +F: common/spl/spl_dfu.c F: common/update.c F: doc/api/dfu.rst F: doc/usage/dfu.rst @@ -1409,6 +1410,7 @@ F: net/ NETWORK (LWIP) M: Jerome Forissier <jerome.forissier@linaro.org> S: Maintained +F: cmd/lwip/ F: cmd/net-lwip.c F: configs/qemu_arm64_lwip_defconfig F: drivers/net/sandbox-lwip.c @@ -1574,6 +1576,7 @@ M: Yao Zi <ziyao@disroot.org> S: Maintained F: arch/riscv/cpu/th1520/ F: drivers/clk/thead/clk-th1520-ap.c +F: drivers/pinctrl/pinctrl-th1520.c F: drivers/ram/thead/th1520_ddr.c RNG @@ -3,7 +3,7 @@ VERSION = 2025 PATCHLEVEL = 07 SUBLEVEL = -EXTRAVERSION = -rc4 +EXTRAVERSION = NAME = # *DOCUMENTATION* @@ -12,6 +12,10 @@ NAME = # Comments in this file are targeted only to the developer, do not # expect to learn how to build the kernel reading this file. +# That's our default target when none is given on the command line +PHONY := _all +_all: + # Determine target architecture for the sandbox include include/host_arch.h ifeq ("", "$(CROSS_COMPILE)") @@ -41,7 +45,7 @@ undefine MK_ARCH # Most importantly: sub-Makefiles should only ever modify files in # their own directory. If in some directory we have a dependency on # a file in another dir (which doesn't happen often, but it's often -# unavoidable when linking the built-in.o targets which finally +# unavoidable when linking the built-in.a targets which finally # turn into vmlinux), we will call a sub make in that other dir, and # after that we are sure that everything which is in that other dir # is now up to date. @@ -109,7 +113,6 @@ endif # If the user is running make -s (silent mode), suppress echoing of # commands - ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4 ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),) quiet=silent_ @@ -137,8 +140,8 @@ export quiet Q KBUILD_VERBOSE # The O= assignment takes precedence over the KBUILD_OUTPUT environment # variable. -# KBUILD_SRC is set on invocation of make in OBJ directory -# KBUILD_SRC is not intended to be used by the regular user (for now) +# KBUILD_SRC is not intended to be used by the regular user (for now), +# it is set on invocation of make with KBUILD_OUTPUT or O= specified. # OK, Make called in directory where kernel src resides # Do we want to locate output files in a separate directory? @@ -146,19 +149,15 @@ ifeq ("$(origin O)", "command line") KBUILD_OUTPUT := $(O) endif -# That's our default target when none is given on the command line -PHONY := _all -_all: - -# Cancel implicit rules on top Makefile -$(CURDIR)/Makefile Makefile: ; +ifneq ($(words $(subst :, ,$(CURDIR))), 1) + $(error main directory cannot contain spaces nor colons) +endif ifneq ($(KBUILD_OUTPUT),) -# Invoke a second make in the output directory, passing relevant variables # check that the output directory actually exists saved-output := $(KBUILD_OUTPUT) KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \ - && /bin/pwd) + && pwd) $(if $(KBUILD_OUTPUT),, \ $(error failed to create output directory "$(saved-output)")) @@ -169,6 +168,7 @@ $(if $(KBUILD_OUTPUT),, \ # 'sub-make' below. MAKEFLAGS += --include-dir=$(CURDIR) +need-sub-make := 1 else # Do not print "Entering directory ..." at all for in-tree build. @@ -176,19 +176,34 @@ MAKEFLAGS += --no-print-directory endif # ifneq ($(KBUILD_OUTPUT),) +ifneq ($(filter 3.%,$(MAKE_VERSION)),) +# 'MAKEFLAGS += -rR' does not immediately become effective for GNU Make 3.x +# We need to invoke sub-make to avoid implicit rules in the top Makefile. +need-sub-make := 1 +# Cancel implicit rules for this Makefile. +$(lastword $(MAKEFILE_LIST)): ; +endif + export sub_make_done := 1 + +ifeq ($(need-sub-make),1) + PHONY += $(MAKECMDGOALS) sub-make $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make @: -sub-make: FORCE +# Invoke a second make in the output directory, passing relevant variables +sub-make: $(Q)$(MAKE) \ $(if $(KBUILD_OUTPUT),-C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR)) \ -f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS)) -else # sub_make_done +endif # need-sub-make +endif # sub_make_done + # We process the rest of the Makefile if this is the final invocation of make +ifeq ($(need-sub-make),) # Do not print "Entering directory ...", # but we want to display it when entering to the output directory @@ -202,8 +217,8 @@ MAKEFLAGS += --no-print-directory # Use 'make C=2' to enable checking of *all* source files, regardless # of whether they are re-compiled or not. # -# See the file "doc/sparse.txt" for more details, including -# where to get the "sparse" utility. +# See the file "Documentation/dev-tools/sparse.rst" for more details, +# including where to get the "sparse" utility. ifeq ("$(origin C)", "command line") KBUILD_CHECKSRC = $(C) @@ -216,6 +231,10 @@ endif # Old syntax make ... SUBDIRS=$PWD is still supported # Setting the environment variable KBUILD_EXTMOD take precedence ifdef SUBDIRS + $(warning ================= WARNING ================) + $(warning 'SUBDIRS' will be removed after Linux 5.3) + $(warning Please use 'M=' or 'KBUILD_EXTMOD' instead) + $(warning ==========================================) KBUILD_EXTMOD ?= $(SUBDIRS) endif @@ -223,18 +242,6 @@ ifeq ("$(origin M)", "command line") KBUILD_EXTMOD := $(M) endif -# If building an external module we do not care about the all: rule -# but instead _all depend on modules -PHONY += all -ifeq ($(KBUILD_EXTMOD),) -_all: all -else -_all: modules -PHONY += prepare -prepare: - $(cmd_crmodverdir) -endif - ifeq ($(KBUILD_SRC),) # building in the source tree srctree := . @@ -246,132 +253,177 @@ else srctree := $(KBUILD_SRC) endif endif + +export KBUILD_CHECKSRC KBUILD_EXTMOD KBUILD_SRC + objtree := . src := $(srctree) obj := $(objtree) -VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD)) +VPATH := $(srctree) export srctree objtree VPATH -# Make sure CDPATH settings don't interfere -unexport CDPATH +# To make sure we do not include .config for any of the *config targets +# catch them early, and hand them over to scripts/kconfig/Makefile +# It is allowed to specify more targets when calling make, including +# mixing *config targets and build targets. +# For example 'make oldconfig all'. +# Detect when mixed targets is specified, and make a second invocation +# of make so .config is not included in this case either (for *config). -######################################################################### +version_h := include/generated/version_autogenerated.h +timestamp_h := include/generated/timestamp_autogenerated.h +defaultenv_h := include/generated/defaultenv_autogenerated.h +dt_h := include/generated/dt.h +env_h := include/generated/environment.h -HOSTARCH := $(shell uname -m | \ - sed -e s/i.86/x86/ \ - -e s/sun4u/sparc64/ \ - -e s/arm.*/arm/ \ - -e s/sa110/arm/ \ - -e s/ppc64/powerpc/ \ - -e s/ppc/powerpc/ \ - -e s/macppc/powerpc/\ - -e s/sh.*/sh/) +clean-targets := %clean mrproper cleandocs +no-dot-config-targets := $(clean-targets) \ + clobber distclean \ + help %docs check% coccicheck \ + ubootversion backup tests check pcheck qcheck tcheck \ + pylint pylint_err _pip pip pip_test pip_release +no-sync-config-targets := $(no-dot-config-targets) install %install \ + kernelrelease -HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ - sed -e 's/\(cygwin\).*/cygwin/') +config-targets := 0 +mixed-targets := 0 +dot-config := 1 +may-sync-config := 1 -export HOSTARCH HOSTOS +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) + dot-config := 0 + endif +endif -######################################################################### +ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),) + may-sync-config := 0 + endif +endif -# set default to nothing for native builds -ifeq ($(HOSTARCH),$(ARCH)) -CROSS_COMPILE ?= +ifneq ($(KBUILD_EXTMOD),) + may-sync-config := 0 endif -KCONFIG_CONFIG ?= .config -export KCONFIG_CONFIG +ifeq ($(KBUILD_EXTMOD),) + ifneq ($(filter config %config,$(MAKECMDGOALS)),) + config-targets := 1 + ifneq ($(words $(MAKECMDGOALS)),1) + mixed-targets := 1 + endif + endif +endif -# SHELL used by kbuild -CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ - else if [ -x /bin/bash ]; then echo /bin/bash; \ - else echo sh; fi ; fi) +# For "make -j clean all", "make -j mrproper defconfig all", etc. +ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),) + ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),) + mixed-targets := 1 + endif +endif -HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null) -HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null) -HOST_LFS_LIBS := $(shell getconf LFS_LIBS 2>/dev/null) +# install and modules_install need also be processed one by one +ifneq ($(filter install,$(MAKECMDGOALS)),) + ifneq ($(filter modules_install,$(MAKECMDGOALS)),) + mixed-targets := 1 + endif +endif -HOSTCC = cc -HOSTCXX = c++ -KBUILD_HOSTCFLAGS := -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer \ - $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) -KBUILD_HOSTCXXFLAGS := -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) -KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) -KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) +ifeq ($(mixed-targets),1) +# =========================================================================== +# We're called with mixed targets (*config and build targets). +# Handle them one by one. -# With the move to GCC 6, we have implicitly upgraded our language -# standard to GNU11 (see https://gcc.gnu.org/gcc-5/porting_to.html). -# Some Linux distributions (including RHEL7, SLES13, Debian 8) still -# have older compilers as their default, so we make it explicit for -# these that our host tools are GNU11 (i.e. C11 w/ GNU extensions). -CSTD_FLAG := -std=gnu11 -KBUILD_HOSTCFLAGS += $(CSTD_FLAG) +PHONY += $(MAKECMDGOALS) __build_one_by_one -ifeq ($(HOSTOS),cygwin) -KBUILD_HOSTCFLAGS += -ansi -endif +$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one + @: -# Mac OS X / Darwin's C preprocessor is Apple specific. It -# generates numerous errors and warnings. We want to bypass it -# and use GNU C's cpp. To do this we pass the -traditional-cpp -# option to the compiler. Note that the -traditional-cpp flag -# DOES NOT have the same semantics as GNU C's flag, all it does -# is invoke the GNU preprocessor in stock ANSI/ISO C fashion. -# -# Apple's linker is similar, thanks to the new 2 stage linking -# multiple symbol definitions are treated as errors, hence the -# -multiply_defined suppress option to turn off this error. -# -ifeq ($(HOSTOS),darwin) -# get major and minor product version (e.g. '10' and '6' for Snow Leopard) -DARWIN_MAJOR_VERSION := $(shell sw_vers -productVersion | cut -f 1 -d '.') -DARWIN_MINOR_VERSION := $(shell sw_vers -productVersion | cut -f 2 -d '.') +__build_one_by_one: + $(Q)set -e; \ + for i in $(MAKECMDGOALS); do \ + $(MAKE) -f $(srctree)/Makefile $$i; \ + done -os_x_before = $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \ - $(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;) +else -os_x_after = $(shell if [ $(DARWIN_MAJOR_VERSION) -ge $(1) -a \ - $(DARWIN_MINOR_VERSION) -ge $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;) +include scripts/Kbuild.include -# Snow Leopards build environment has no longer restrictions as described above -HOSTCC = $(call os_x_before, 10, 5, "cc", "gcc") -KBUILD_HOSTCFLAGS += $(call os_x_before, 10, 4, "-traditional-cpp") -KBUILD_HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress") +# Read UBOOTRELEASE from include/config/uboot.release (if it exists) +UBOOTRELEASE = $(shell cat include/config/uboot.release 2> /dev/null) +UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) +export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION -# macOS Mojave (10.14.X) -# Undefined symbols for architecture x86_64: "_PyArg_ParseTuple" -KBUILD_HOSTLDFLAGS += $(call os_x_after, 10, 14, "-lpython -dynamclib", "") -endif +# Modified for U-Boot +-include scripts/subarch.include -# Decide whether to build built-in, modular, or both. -# Normally, just do built-in. +# Cross compiling and selecting different set of gcc/bin-utils +# --------------------------------------------------------------------------- +# +# When performing cross compilation for other architectures ARCH shall be set +# to the target architecture. (See arch/* for the possibilities). +# ARCH can be set during invocation of make: +# make ARCH=ia64 +# Another way is to have ARCH set in the environment. +# The default ARCH is the host where make is executed. -KBUILD_MODULES := -KBUILD_BUILTIN := 1 +# CROSS_COMPILE specify the prefix used for all executables used +# during compilation. Only gcc and related bin-utils executables +# are prefixed with $(CROSS_COMPILE). +# CROSS_COMPILE can be set on the command line +# make CROSS_COMPILE=ia64-linux- +# Alternatively CROSS_COMPILE can be set in the environment. +# Default value for CROSS_COMPILE is not to prefix executables +# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile +ARCH ?= $(SUBARCH) -# If we have only "make modules", don't compile built-in objects. -# When we're building modules with modversions, we need to consider -# the built-in objects during the descend as well, in order to -# make sure the checksums are up to date before we record them. +# Architecture as present in compile.h +UTS_MACHINE := $(ARCH) +SRCARCH := $(ARCH) -ifeq ($(MAKECMDGOALS),modules) - KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) +# Additional ARCH settings for x86 +ifeq ($(ARCH),i386) + SRCARCH := x86 +endif +ifeq ($(ARCH),x86_64) + SRCARCH := x86 endif -# If we have "make <whatever> modules", compile modules -# in addition to whatever we do anyway. -# Just "make" or "make all" shall build modules as well +# Additional ARCH settings for sparc +ifeq ($(ARCH),sparc32) + SRCARCH := sparc +endif +ifeq ($(ARCH),sparc64) + SRCARCH := sparc +endif -# U-Boot does not need modules -#ifneq ($(filter all _all modules,$(MAKECMDGOALS)),) -# KBUILD_MODULES := 1 -#endif +# Additional ARCH settings for sh +ifeq ($(ARCH),sh64) + SRCARCH := sh +endif -#ifeq ($(MAKECMDGOALS),) -# KBUILD_MODULES := 1 -#endif +KCONFIG_CONFIG ?= .config +export KCONFIG_CONFIG + +# SHELL used by kbuild +CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi ; fi) + +HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null) +HOST_LFS_LDFLAGS := $(shell getconf LFS_LDFLAGS 2>/dev/null) +HOST_LFS_LIBS := $(shell getconf LFS_LIBS 2>/dev/null) + +HOSTCC = gcc +HOSTCXX = g++ +KBUILD_HOSTCFLAGS := -Wall -Wstrict-prototypes -O2 \ + -fomit-frame-pointer -std=gnu11 $(HOST_LFS_CFLAGS) \ + $(HOSTCFLAGS) #-Wmissing-prototypes Enable it and fix warnings +KBUILD_HOSTCXXFLAGS := -O2 $(HOST_LFS_CFLAGS) $(HOSTCXXFLAGS) +KBUILD_HOSTLDFLAGS := $(HOST_LFS_LDFLAGS) $(HOSTLDFLAGS) +KBUILD_HOSTLDLIBS := $(HOST_LFS_LIBS) $(HOSTLDLIBS) # Check ths size of a binary: # Args: @@ -393,19 +445,9 @@ export size_check export KBUILD_MODULES KBUILD_BUILTIN export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD -# We need some generic definitions (do not try to remake the file). -scripts/Kbuild.include: ; -include scripts/Kbuild.include - # Make variables (CC, etc...) - AS = $(CROSS_COMPILE)as -# Always use GNU ld -ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),) -LD = $(CROSS_COMPILE)ld.bfd -else LD = $(CROSS_COMPILE)ld -endif CC = $(CROSS_COMPILE)gcc CPP = $(CC) -E AR = $(CROSS_COMPILE)ar @@ -418,10 +460,12 @@ READELF = $(CROSS_COMPILE)readelf LEX = flex YACC = bison AWK = awk +INSTALLKERNEL := installkernel +DEPMOD = /sbin/depmod PERL = perl -PYTHON ?= python +PYTHON = python PYTHON2 = python2 -PYTHON3 ?= python3 +PYTHON3 = python3 # The devicetree compiler and pylibfdt are automatically built unless DTC is # provided. If DTC is provided, it is assumed the pylibfdt is available too. @@ -432,51 +476,79 @@ DTC_MIN_VERSION := 010406 CHECK = sparse CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ - -Wbitwise -Wno-return-void -Wno-unknown-attribute \ - -D__CHECK_ENDIAN__ $(CF) - -KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__ - -KBUILD_CFLAGS := -Wall -Werror=strict-prototypes -Wno-trigraphs \ - -Wno-format-security \ - -fno-builtin -ffreestanding $(CSTD_FLAG) \ - -fno-PIE \ - -Werror=implicit-function-declaration -Werror=implicit-int -KBUILD_CFLAGS += -fshort-wchar -fno-strict-aliasing -KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE -KBUILD_LDFLAGS := + -Wbitwise -Wno-return-void -Wno-unknown-attribute -D__CHECK_ENDIAN__ $(CF) +NOSTDINC_FLAGS := +CFLAGS_MODULE = +AFLAGS_MODULE = +LDFLAGS_MODULE = +CFLAGS_KERNEL = +AFLAGS_KERNEL = +LDFLAGS_vmlinux = + +# Use USERINCLUDE when you must reference the UAPI directories only. +USERINCLUDE := \ + -I$(srctree)/arch/$(SRCARCH)/include/uapi \ + -I$(objtree)/arch/$(SRCARCH)/include/generated/uapi \ + -I$(srctree)/include/uapi \ + -I$(objtree)/include/generated/uapi \ + -include $(srctree)/include/linux/kconfig.h -ifeq ($(cc-name),clang) -ifneq ($(CROSS_COMPILE),) -CLANG_TARGET := --target=$(notdir $(CROSS_COMPILE:%-=%)) -LDPPFLAGS += $(CLANG_TARGET) -GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) -CLANG_PREFIX := --prefix=$(GCC_TOOLCHAIN_DIR) -GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) -endif -ifneq ($(GCC_TOOLCHAIN),) -CLANG_GCC_TC := --gcc-toolchain=$(GCC_TOOLCHAIN) -endif -KBUILD_CFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) $(CLANG_PREFIX) -KBUILD_AFLAGS += $(CLANG_TARGET) $(CLANG_GCC_TC) $(CLANG_PREFIX) -KBUILD_CFLAGS += $(call cc-option, -no-integrated-as) -KBUILD_AFLAGS += $(call cc-option, -no-integrated-as) -endif - -# Read UBOOTRELEASE from include/config/uboot.release (if it exists) -UBOOTRELEASE = $(shell cat include/config/uboot.release 2> /dev/null) -UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) +# Use UBOOTINCLUDE when you must reference the include/ directory. +# Needed to be compatible with the O= option +UBOOTINCLUDE := \ + -Iinclude \ + $(if $(KBUILD_SRC), -I$(srctree)/include) \ + $(if $(CONFIG_$(XPL_)MBEDTLS_LIB), \ + "-DMBEDTLS_CONFIG_FILE=\"mbedtls_def_config.h\"" \ + -I$(srctree)/lib/mbedtls \ + -I$(srctree)/lib/mbedtls/port \ + -I$(srctree)/lib/mbedtls/external/mbedtls \ + -I$(srctree)/lib/mbedtls/external/mbedtls/include) \ + $(if $(CONFIG_$(PHASE_)SYS_THUMB_BUILD), \ + $(if $(CONFIG_HAS_THUMB2), \ + $(if $(CONFIG_CPU_V7M), \ + -I$(srctree)/arch/arm/thumb1/include), \ + -I$(srctree)/arch/arm/thumb1/include)) \ + -I$(srctree)/arch/$(ARCH)/include \ + -include $(srctree)/include/linux/kconfig.h \ + -I$(srctree)/dts/upstream/include \ + $(if $(CONFIG_NET_LWIP), -I$(srctree)/lib/lwip/lwip/src/include \ + -I$(srctree)/lib/lwip/u-boot) -export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION -export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR -export CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC -export CPP AR NM LDR STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS -export MAKE LEX YACC AWK PERL PYTHON PYTHON2 PYTHON3 -export HOSTCXX KBUILD_HOSTCXXFLAGS CHECK CHECKFLAGS DTC DTC_FLAGS -export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS -export KBUILD_CFLAGS KBUILD_AFLAGS +KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE +KBUILD_CFLAGS := -Wall -Werror=strict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ + -Werror=implicit-function-declaration -Werror=implicit-int \ + -Wno-format-security -std=gnu11 #-Wundef Enable it and fix warnings +UBOOT_CFLAGS := -ffreestanding -fno-builtin +KBUILD_CFLAGS += $(UBOOT_CFLAGS) +KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__ +KBUILD_AFLAGS_KERNEL := +KBUILD_CFLAGS_KERNEL := +KBUILD_AFLAGS_MODULE := -DMODULE +KBUILD_CFLAGS_MODULE := -DMODULE +KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds +KBUILD_LDFLAGS := +GCC_PLUGINS_CFLAGS := + +export ARCH SRCARCH CONFIG_SHELL HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE AS LD CC +export CPP AR NM STRIP OBJCOPY OBJDUMP KBUILD_HOSTLDFLAGS KBUILD_HOSTLDLIBS +export MAKE LEX YACC AWK INSTALLKERNEL PERL PYTHON PYTHON2 PYTHON3 UTS_MACHINE +export HOSTCXX KBUILD_HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS + +export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS KBUILD_LDFLAGS +export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE +export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN +export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE +export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE +export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL +export KBUILD_ARFLAGS + +export LDR +export CPU BOARD VENDOR SOC CPUDIR BOARDDIR +export UBOOTINCLUDE export CC_VERSION_TEXT := $(shell $(CC) --version | head -n 1) # When compiling out-of-tree modules, put MODVERDIR in the module @@ -504,15 +576,12 @@ endif # =========================================================================== # Rules shared between *config targets and build targets -# Basic helpers built in scripts/ +# Basic helpers built in scripts/basic/ PHONY += scripts_basic scripts_basic: $(Q)$(MAKE) $(build)=scripts/basic $(Q)rm -f .tmp_quiet_recordmcount -# To avoid any implicit rule to kick in, define an empty command. -scripts/basic/%: scripts_basic ; - PHONY += outputmakefile # outputmakefile generates a Makefile in the output directory, if using a # separate output directory. This allows convenient use of make in the @@ -524,71 +593,51 @@ ifneq ($(KBUILD_SRC),) $(Q)ln -fsn $(srctree) source $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile $(srctree) $(Q)test -e .gitignore || \ - { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore + { echo "# this is build directory, ignore it"; echo "*"; } > .gitignore endif -# To make sure we do not include .config for any of the *config targets -# catch them early, and hand them over to scripts/kconfig/Makefile -# It is allowed to specify more targets when calling make, including -# mixing *config targets and build targets. -# For example 'make oldconfig all'. -# Detect when mixed targets is specified, and make a second invocation -# of make so .config is not included in this case either (for *config). - -version_h := include/generated/version_autogenerated.h -timestamp_h := include/generated/timestamp_autogenerated.h -defaultenv_h := include/generated/defaultenv_autogenerated.h -dt_h := include/generated/dt.h -env_h := include/generated/environment.h - -no-dot-config-targets := clean clobber mrproper distclean \ - help %docs check% coccicheck \ - ubootversion backup tests check pcheck qcheck tcheck \ - pylint pylint_err _pip pip pip_test pip_release - -config-targets := 0 -mixed-targets := 0 -dot-config := 1 - -ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) - ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) - dot-config := 0 - endif +ifneq ($(shell $(CC) --version 2>&1 | head -n 1 | grep clang),) +ifneq ($(CROSS_COMPILE),) +CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%)) +GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)elfedit)) +CLANG_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR) +GCC_TOOLCHAIN := $(realpath $(GCC_TOOLCHAIN_DIR)/..) endif - -ifeq ($(KBUILD_EXTMOD),) - ifneq ($(filter config %config,$(MAKECMDGOALS)),) - config-targets := 1 - ifneq ($(words $(MAKECMDGOALS)),1) - mixed-targets := 1 - endif - endif +ifneq ($(GCC_TOOLCHAIN),) +CLANG_FLAGS += --gcc-toolchain=$(GCC_TOOLCHAIN) +endif +CLANG_FLAGS += -no-integrated-as +KBUILD_CFLAGS += $(CLANG_FLAGS) +KBUILD_AFLAGS += $(CLANG_FLAGS) +export CLANG_FLAGS endif -ifeq ($(mixed-targets),1) -# =========================================================================== -# We're called with mixed targets (*config and build targets). -# Handle them one by one. - -PHONY += $(MAKECMDGOALS) __build_one_by_one +RETPOLINE_CFLAGS_GCC := -mindirect-branch=thunk-extern -mindirect-branch-register +RETPOLINE_VDSO_CFLAGS_GCC := -mindirect-branch=thunk-inline -mindirect-branch-register +RETPOLINE_CFLAGS_CLANG := -mretpoline-external-thunk +RETPOLINE_VDSO_CFLAGS_CLANG := -mretpoline +RETPOLINE_CFLAGS := $(call cc-option,$(RETPOLINE_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_CFLAGS_CLANG))) +RETPOLINE_VDSO_CFLAGS := $(call cc-option,$(RETPOLINE_VDSO_CFLAGS_GCC),$(call cc-option,$(RETPOLINE_VDSO_CFLAGS_CLANG))) +export RETPOLINE_CFLAGS +export RETPOLINE_VDSO_CFLAGS -$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one - @: - -__build_one_by_one: - $(Q)set -e; \ - for i in $(MAKECMDGOALS); do \ - $(MAKE) -f $(srctree)/Makefile $$i; \ - done +# The expansion should be delayed until arch/$(SRCARCH)/Makefile is included. +# Some architectures define CROSS_COMPILE in arch/$(SRCARCH)/Makefile. +# CC_VERSION_TEXT is referenced from Kconfig (so it needs export), +# and from include/config/auto.conf.cmd to detect the compiler upgrade. +CC_VERSION_TEXT = $(shell $(CC) --version | head -n 1) -else ifeq ($(config-targets),1) # =========================================================================== # *config targets only - make sure prerequisites are updated, and descend # in scripts/kconfig to make the *config target -KBUILD_DEFCONFIG := sandbox_defconfig -export KBUILD_DEFCONFIG KBUILD_KCONFIG +# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed. +# KBUILD_DEFCONFIG may point out an alternative default configuration +# used for 'make defconfig' +# Modified for U-Boot +-include arch/$(SRCARCH)/Makefile +export KBUILD_DEFCONFIG KBUILD_KCONFIG CC_VERSION_TEXT config: scripts_basic outputmakefile FORCE $(Q)$(MAKE) $(build)=scripts/kconfig $@ @@ -601,29 +650,104 @@ else # Build targets only - this includes vmlinux, arch specific targets, clean # targets and others. In general all targets except *config targets. -# Additional helpers built in scripts/ -# Carefully list dependencies so we do not try to build scripts twice -# in parallel -PHONY += scripts -scripts: scripts_basic scripts_dtc include/config/auto.conf - $(Q)$(MAKE) $(build)=$(@) +# If building an external module we do not care about the all: rule +# but instead _all depend on modules +PHONY += all +ifeq ($(KBUILD_EXTMOD),) +_all: all +else +_all: modules +endif + +# Decide whether to build built-in, modular, or both. +# Normally, just do built-in. + +KBUILD_MODULES := +KBUILD_BUILTIN := 1 + +# If we have only "make modules", don't compile built-in objects. +# When we're building modules with modversions, we need to consider +# the built-in objects during the descend as well, in order to +# make sure the checksums are up to date before we record them. + +ifeq ($(MAKECMDGOALS),modules) + KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) +endif + +# If we have "make <whatever> modules", compile modules +# in addition to whatever we do anyway. +# Just "make" or "make all" shall build modules as well + +ifneq ($(filter all _all modules,$(MAKECMDGOALS)),) + KBUILD_MODULES := 1 +endif + +ifeq ($(MAKECMDGOALS),) + KBUILD_MODULES := 1 +endif + +export KBUILD_MODULES KBUILD_BUILTIN + +ifeq ($(KBUILD_EXTMOD),) +# Objects we will link into vmlinux / subdirs we need to visit +init-y := init/ +drivers-y := drivers/ sound/ +net-y := net/ +libs-y := lib/ +core-y := usr/ +virt-y := virt/ +endif # KBUILD_EXTMOD ifeq ($(dot-config),1) -# Read in config +# Modified for U-Boot -include include/config/auto.conf +endif + +# The all: target is the default when no target is given on the +# command line. +# This allow a user to issue only 'make' to build a kernel including modules +# Defaults to vmlinux, but the arch makefile usually adds further targets +all: u-boot + +CFLAGS_GCOV := -fprofile-arcs -ftest-coverage \ + $(call cc-option,-fno-tree-loop-im) \ + $(call cc-disable-warning,maybe-uninitialized,) +export CFLAGS_GCOV + +# The arch Makefiles can override CC_FLAGS_FTRACE. We may also append it later. +ifdef CONFIG_FUNCTION_TRACER + CC_FLAGS_FTRACE := -pg +endif + +# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default +# values of the respective KBUILD_* variables +ARCH_CPPFLAGS := +ARCH_AFLAGS := +ARCH_CFLAGS := +# Modified for U-Boot +-include arch/$(SRCARCH)/Makefile -# Read in dependencies to all Kconfig* files, make sure to run -# oldconfig if changes are detected. +ifeq ($(dot-config),1) +ifeq ($(may-sync-config),1) +# Read in dependencies to all Kconfig* files, make sure to run syncconfig if +# changes are detected. This should be included after arch/$(SRCARCH)/Makefile +# because some architectures define CROSS_COMPILE there. -include include/config/auto.conf.cmd -# To avoid any implicit rule to kick in, define an empty command -$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; +$(KCONFIG_CONFIG): + @echo >&2 '***' + @echo >&2 '*** Configuration file "$@" not found!' + @echo >&2 '***' + @echo >&2 '*** Please run some configurator (e.g. "make oldconfig" or' + @echo >&2 '*** "make menuconfig" or "make xconfig").' + @echo >&2 '***' + @/bin/false # If .config is newer than include/config/auto.conf, someone tinkered # with it and forgot to run make oldconfig. # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files -include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd +include/config/%.conf: $(KCONFIG_CONFIG) #include/config/auto.conf.cmd $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig @# If the following part fails, include/config/auto.conf should be @# deleted so "make silentoldconfig" will be re-run on the next build. @@ -698,10 +822,30 @@ ifndef LDSCRIPT endif else -# Dummy target needed, because used as prerequisite -include/config/auto.conf: ; +# External modules and some install targets need include/generated/autoconf.h +# and include/config/auto.conf but do not care if they are up-to-date. +# Use auto.conf to trigger the test +PHONY += include/config/auto.conf + +include/config/auto.conf: + $(Q)test -e include/generated/autoconf.h -a -e $@ || ( \ + echo >&2; \ + echo >&2 " ERROR: Kernel configuration is invalid."; \ + echo >&2 " include/generated/autoconf.h or $@ are missing.";\ + echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ + echo >&2 ; \ + /bin/false) + +endif # may-sync-config endif # $(dot-config) +KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,) +KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,) +KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation) +KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow) +KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context) +KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) + ifdef CONFIG_CC_OPTIMIZE_FOR_DEBUG KBUILD_HOSTCFLAGS := -Wall -Wstrict-prototypes -Og -g -fomit-frame-pointer \ $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) @@ -721,19 +865,19 @@ endif ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += -Os +else +KBUILD_CFLAGS += -O2 endif -ifdef CONFIG_CC_OPTIMIZE_FOR_SPEED -KBUILD_CFLAGS += -O2 +ifdef CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED +KBUILD_CFLAGS += -Wno-maybe-uninitialized endif -ifdef CONFIG_CC_OPTIMIZE_FOR_DEBUG -KBUILD_CFLAGS += -Og -# Avoid false positives -Wmaybe-uninitialized -# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78394 -KBUILD_CFLAGS += -Wno-maybe-uninitialized -endif +# Tell gcc to never replace conditional load with a non-conditional one +KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) +include scripts/Makefile.kcov +include scripts/Makefile.gcc-plugins LTO_CFLAGS := LTO_FINAL_LDFLAGS := export LTO_CFLAGS LTO_FINAL_LDFLAGS @@ -768,12 +912,6 @@ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector) endif KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks) -# disable pointer signed / unsigned warnings in gcc 4.0 -KBUILD_CFLAGS += -Wno-pointer-sign - -# disable stringop warnings in gcc 8+ -KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) - KBUILD_CFLAGS += $(call cc-disable-warning, zero-length-bounds) KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) KBUILD_CFLAGS += $(call cc-disable-warning, stringop-overflow) @@ -813,6 +951,11 @@ KBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare) KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,) KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior) KBUILD_CFLAGS += $(call cc-disable-warning, deprecated-non-prototype) +else + +# These warnings generated too much noise in a regular build. +# Use make W=1 to enable them (see scripts/Makefile.extrawarn) +KBUILD_CFLAGS += -Wno-unused-but-set-variable endif # These warnings generated too much noise in a regular build. @@ -864,6 +1007,7 @@ cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \ $(NOSTDINC_FLAGS) c_flags := $(KBUILD_CFLAGS) $(cpp_flags) + ######################################################################### # U-Boot objects....order is important (i.e. start must be first) @@ -912,7 +1056,15 @@ u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples u-boot-alldirs := $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-)))) -libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) +libs-y := $(patsubst %/, %/built-in.a, $(libs-y)) +# Not needed in U-Boot +#init-y := $(patsubst %/, %/built-in.a, $(init-y)) +#core-y := $(patsubst %/, %/built-in.a, $(core-y)) +drivers-y := $(patsubst %/, %/built-in.a, $(drivers-y)) +#net-y := $(patsubst %/, %/built-in.a, $(net-y)) +libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) +libs-y2 := $(patsubst %/, %/built-in.a, $(filter-out %.a, $(libs-y))) +#virt-y := $(patsubst %/, %/built-in.a, $(virt-y)) u-boot-init := $(head-y) u-boot-main := $(libs-y) @@ -1031,6 +1183,37 @@ INPUTS-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin endif endif +ifdef CONFIG_FUNCTION_TRACER +ifdef CONFIG_FTRACE_MCOUNT_RECORD + # gcc 5 supports generating the mcount tables directly + ifeq ($(call cc-option-yn,-mrecord-mcount),y) + CC_FLAGS_FTRACE += -mrecord-mcount + export CC_USING_RECORD_MCOUNT := 1 + endif + ifdef CONFIG_HAVE_NOP_MCOUNT + ifeq ($(call cc-option-yn, -mnop-mcount),y) + CC_FLAGS_FTRACE += -mnop-mcount + CC_FLAGS_USING += -DCC_USING_NOP_MCOUNT + endif + endif +endif +ifdef CONFIG_HAVE_FENTRY + ifeq ($(call cc-option-yn, -mfentry),y) + CC_FLAGS_FTRACE += -mfentry + CC_FLAGS_USING += -DCC_USING_FENTRY + endif +endif +export CC_FLAGS_FTRACE +KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING) +KBUILD_AFLAGS += $(CC_FLAGS_USING) +ifdef CONFIG_DYNAMIC_FTRACE + ifdef CONFIG_HAVE_C_RECORDMCOUNT + BUILD_C_RECORDMCOUNT := y + export BUILD_C_RECORDMCOUNT + endif +endif +endif + # Add optional build target if defined in board/cpu/soc headers ifneq ($(CONFIG_BUILD_TARGET),) INPUTS-y += $(CONFIG_BUILD_TARGET:"%"=%) @@ -1076,6 +1259,15 @@ quiet_cmd_objcopy = OBJCOPY $@ cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \ $(OBJCOPYFLAGS_$(@F)) $< $@ +# disable pointer signed / unsigned warnings in gcc 4.0 +KBUILD_CFLAGS += -Wno-pointer-sign + +# disable stringop warnings in gcc 8+ +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) + +# disable invalid "can't wrap" optimizations for signed / pointers +KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) + # Provide a version which does not do this, for use by EFI and hex/srec quiet_cmd_zobjcopy = OBJCOPY $@ cmd_zobjcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ @@ -1216,7 +1408,7 @@ FINAL_DTB_CONTAINER = fit-dtb.blob endif fit-dtb.blob.gz: fit-dtb.blob - @gzip -kf9 $< > $@ + @gzip -nkf9 $< > $@ fit-dtb.blob.lzo: fit-dtb.blob @lzop -f9 $< > $@ @@ -1392,17 +1584,17 @@ ifneq ($(EXT_DTB),) ext_dtb_list := $(basename $(notdir $(EXT_DTB))) default_dt := $(firstword $(ext_dtb_list)) of_list := "$(ext_dtb_list)" -of_list_dirs := $(dir $(EXT_DTB)) +of_list_dirs := $(dir $(EXT_DTB)) $(dt_dir) else of_list := $(CONFIG_OF_LIST) -ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),) -of_list_dirs := $(dt_dir) arch/$(ARCH)/dts -else of_list_dirs := $(dt_dir) -endif default_dt := $(if $(DEVICE_TREE),$(DEVICE_TREE),$(CONFIG_DEFAULT_DEVICE_TREE)) endif +ifneq ($(CONFIG_OF_UPSTREAM_INCLUDE_LOCAL_FALLBACK_DTBOS),) +of_list_dirs += arch/$(ARCH)/dts +endif + binman_dtb := $(shell echo $(CONFIG_BINMAN_DTB)) ifeq ($(strip $(binman_dtb)),) ifeq ($(CONFIG_OF_EMBED),y) @@ -1927,7 +2119,7 @@ $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ; PHONY += $(u-boot-dirs) $(u-boot-dirs): prepare - $(Q)$(MAKE) $(build)=$@ + $(Q)$(MAKE) $(build)=$@ need-builtin=1 tools: prepare # The "tools" are needed early @@ -1946,7 +2138,12 @@ endef # Store (new) UBOOTRELEASE string in include/config/uboot.release include/config/uboot.release: include/config/auto.conf FORCE $(call filechk,uboot.release) - +# Additional helpers built in scripts/ +# Carefully list dependencies so we do not try to build scripts twice +# in parallel +PHONY += scripts +scripts: scripts_basic scripts_dtc + $(Q)$(MAKE) $(build)=$(@) # Things we need to do before we recursively start building the kernel # or the modules are listed in "prepare". @@ -1954,7 +2151,6 @@ include/config/uboot.release: include/config/auto.conf FORCE # archprepare is used in arch Makefiles and when processed asm symlink, # version.h and scripts_basic is processed / created. -# Listed in dependency order PHONY += prepare archprepare prepare1 prepare3 # prepare3 is used to check if we are building in a separate output directory, @@ -1982,14 +2178,35 @@ prepare1: $(defaultenv_h) envtools: $(defaultenv_h) endif - archprepare: prepare1 scripts -prepare0: archprepare FORCE +prepare0: archprepare $(Q)$(MAKE) $(build)=. # All the preparing.. -prepare: prepare0 +prepare: prepare0 prepare-objtool + +# Support for using generic headers in asm-generic +asm-generic := -f $(srctree)/scripts/Makefile.asm-generic obj + +PHONY += asm-generic uapi-asm-generic +asm-generic: uapi-asm-generic + $(Q)$(MAKE) $(asm-generic)=arch/$(SRCARCH)/include/generated/asm \ + generic=include/asm-generic +uapi-asm-generic: + $(Q)$(MAKE) $(asm-generic)=arch/$(SRCARCH)/include/generated/uapi/asm \ + generic=include/uapi/asm-generic + +PHONY += prepare-objtool +prepare-objtool: $(objtool_target) +ifeq ($(SKIP_STACK_VALIDATION),1) +ifdef CONFIG_UNWINDER_ORC + @echo "error: Cannot generate ORC metadata for CONFIG_UNWINDER_ORC=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2 + @false +else + @echo "warning: Cannot use CONFIG_STACK_VALIDATION=y, please install libelf-dev, libelf-devel or elfutils-libelf-devel" >&2 +endif +endif # Generate some files # --------------------------------------------------------------------------- @@ -2072,13 +2289,20 @@ ifneq ($(dtstree),) %.dtb: prepare3 scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ -PHONY += dtbs dtbs_install -dtbs: prepare3 scripts_dtc +PHONY += dtbs dtbs_install dt_binding_check +dtbs dtbs_check: prepare3 scripts_dtc $(Q)$(MAKE) $(build)=$(dtstree) +dtbs_check: export CHECK_DTBS=1 +dtbs_check: dt_binding_check + dtbs_install: $(Q)$(MAKE) $(dtbinst)=$(dtstree) +ifdef CONFIG_OF_EARLY_FLATTREE +all: dtbs +endif + endif # Check dtc and pylibfdt, if DTC is provided, else build them @@ -2180,8 +2404,6 @@ SYSTEM_MAP = \ System.map: u-boot @$(call SYSTEM_MAP,$<) > $@ -######################################################################### - # ARM relocations should all be R_ARM_RELATIVE (32-bit) or # R_AARCH64_RELATIVE (64-bit). checkarmreloc: u-boot @@ -2255,9 +2477,7 @@ MRPROPER_FILES += .config .config.old include/autoconf.mk* include/config.h \ # clean: rm-dirs := $(CLEAN_DIRS) clean: rm-files := $(CLEAN_FILES) - clean-dirs := $(foreach f,$(u-boot-alldirs),$(if $(wildcard $(srctree)/$f/Makefile),$f)) - clean-dirs := $(addprefix _clean_, $(clean-dirs)) PHONY += $(clean-dirs) clean archclean @@ -2465,11 +2685,25 @@ checkstack: $(OBJDUMP) -d u-boot $$(find . -name u-boot-spl) | \ $(PERL) $(src)/scripts/checkstack.pl $(ARCH) +ubootversion: + @echo $(UBOOTVERSION) + ubootrelease: @$(filechk_uboot.release) -ubootversion: - @echo $(UBOOTVERSION) +# Clear a bunch of variables before executing the submake + +ifeq ($(quiet),silent_) +tools_silent=s +endif + +tools/: FORCE + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/ + +tools/%: FORCE + $(Q)mkdir -p $(objtree)/tools + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(tools_silent) $(filter --j% -j,$(MAKEFLAGS))" O=$(abspath $(objtree)) subdir=tools -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- @@ -2481,41 +2715,32 @@ ubootversion: # target-dir => where to store outputfile # build-dir => directory in kernel source tree to use -ifeq ($(KBUILD_EXTMOD),) - build-dir = $(patsubst %/,%,$(dir $@)) - target-dir = $(dir $@) -else - zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@))) - build-dir = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash)) - target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@)) -endif - -%.s: %.c prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.i: %.c prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.o: %.c prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.lst: %.c prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.s: %.S prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.o: %.S prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -%.symtypes: %.c prepare FORCE - $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) +build-target = $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD)/)$@ +build-dir = $(patsubst %/,%,$(dir $(build-target))) + +%.i: prepare FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) +%.ll: prepare FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) +%.lst: prepare FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) +%.o: prepare FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) +%.s: prepare FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) +%.symtypes: prepare FORCE + $(Q)$(MAKE) $(build)=$(build-dir) $(build-target) +%.ko: %.o + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost # Modules -/: prepare FORCE - $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ - $(build)=$(build-dir) +PHONY += / +/: ./ + +# Make sure the latest headers are built for Documentation +Documentation/ samples/: headers_install %/: prepare FORCE - $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ - $(build)=$(build-dir) -%.ko: prepare FORCE - $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ - $(build)=$(build-dir) $(@:.ko=.o) - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost + $(Q)$(MAKE) KBUILD_MODULES=1 $(build)=$(build-dir) quiet_cmd_genenv = GENENV $@ cmd_genenv = \ @@ -2544,15 +2769,24 @@ quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs))) quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files))) cmd_rmfiles = rm -f $(rm-files) +# Run depmod only if we have System.map and depmod is executable +quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) + cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \ + $(KERNELRELEASE) + +# Create temporary dir for module support files +# clean it up only when building all modules +cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \ + $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*) + # read saved command lines for existing targets existing-targets := $(wildcard $(sort $(targets))) -cmd_files := $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) -$(cmd_files): ; # Do not try to update included dependency files --include $(cmd_files) -endif #ifeq ($(config-targets),1) -endif #ifeq ($(mixed-targets),1) -endif # sub_make_done +-include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) + +endif # ifeq ($(config-targets),1) +endif # ifeq ($(mixed-targets),1) +endif # need-sub-make PHONY += FORCE FORCE: diff --git a/arch/Kconfig b/arch/Kconfig index 597b40ffd60..7e05e0c2263 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -220,6 +220,7 @@ config SANDBOX imply BITREVERSE select BLOBLIST imply LTO + imply CMD_BOOTEFI_SELFTEST imply CMD_DM imply CMD_EXCEPTION imply CMD_GETTIME diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index da67f20675a..9ed55e6cfac 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -108,6 +108,18 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE The value subtracted from CONFIG_TEXT_BASE to calculate the TEXT_OFFSET value written to the Linux kernel image header. +config KVM_VIRT_INS + bool "Emit virtualizable instructions" + help + Instructions in the ARM ISA that have multiple output registers, + can't be used if the instruction leads to an exception to the hypervisor. + These instructions cannot be emulated by KVM because they do not produce + syndrome information data that KVM can use to infer the destination + register, the faulting address, whether it was a load or store, + if it's a 32 or 64 bit general-purpose register amongst other things. + Use this to produce virtualizable instructions if you plan to run U-Boot + with KVM. + config NVIC bool @@ -821,6 +833,7 @@ config ARCH_K3 select FIT select REGEX select FIT_SIGNATURE if ARM64 + select LTO imply TI_SECURE_DEVICE config ARCH_OMAP2PLUS @@ -1126,6 +1139,7 @@ config ARCH_SNAPDRAGON select LINUX_KERNEL_IMAGE_HEADER if !ENABLE_ARM_SOC_BOOT0_HOOK select SYSRESET select SYSRESET_PSCI + select ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR imply OF_UPSTREAM imply CMD_DM imply DM_USB_GADGET diff --git a/arch/arm/cpu/armv8/fel_utils.S b/arch/arm/cpu/armv8/fel_utils.S index 044a7c16cc5..6a7ec9a7ec1 100644 --- a/arch/arm/cpu/armv8/fel_utils.S +++ b/arch/arm/cpu/armv8/fel_utils.S @@ -41,7 +41,7 @@ ENTRY(return_to_fel) str w2, [x1] ldr w0, =0xfa50392f // CPU hotplug magic -#ifdef CONFIG_MACH_SUN50I_H616 +#if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) ldr w2, =(SUNXI_R_CPUCFG_BASE + 0x1c0) str w0, [x2], #0x4 #elif CONFIG_MACH_SUN50I_H6 diff --git a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi index f67fe166d31..845fe205925 100644 --- a/arch/arm/dts/imx8ulp-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8ulp-evk-u-boot.dtsi @@ -28,7 +28,6 @@ &iomuxc1 { bootph-pre-ram; - fsl,mux_mask = <0xf00>; }; &pinctrl_lpuart5 { diff --git a/arch/arm/dts/imxrt1020.dtsi b/arch/arm/dts/imxrt1020.dtsi index 13511ebb18e..336aeedb2ce 100644 --- a/arch/arm/dts/imxrt1020.dtsi +++ b/arch/arm/dts/imxrt1020.dtsi @@ -64,7 +64,6 @@ iomuxc: iomuxc@401f8000 { compatible = "fsl,imxrt-iomuxc"; reg = <0x401f8000 0x4000>; - fsl,mux_mask = <0x7>; }; anatop: anatop@400d8000 { diff --git a/arch/arm/dts/imxrt1170.dtsi b/arch/arm/dts/imxrt1170.dtsi index 08665eaf06a..7566402353a 100644 --- a/arch/arm/dts/imxrt1170.dtsi +++ b/arch/arm/dts/imxrt1170.dtsi @@ -77,7 +77,6 @@ iomuxc: iomuxc@400e8000 { compatible = "fsl,imxrt-iomuxc"; reg = <0x400e8000 0x4000>; - fsl,mux_mask = <0x7>; }; anatop: anatop@40c84000 { diff --git a/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi b/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi new file mode 100644 index 00000000000..9e4af4d9f72 --- /dev/null +++ b/arch/arm/dts/ipq5424-rdp466-u-boot.dtsi @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * IPQ5424 RDP466 board device tree source + * + * Copyright (c) 2025 The Linux Foundation. All rights reserved. + */ + +/ { + /* Will be removed when SMEM parsing is updated */ + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x20000000>; + }; + +}; + + &sdhc { + sdhci-caps-mask = <0x0 0x04000000>; + sdhci-caps = <0x0 0x04000000>; /* SDHCI_CAN_VDD_180 */ + mmc-ddr-1_8v; + mmc-hs200-1_8v; + max-frequency = <192000000>; + bus-width = <4>; + pinctrl-0 = <&sdc_default_state>; + pinctrl-names = "default"; + non-removable; + + /* + * This reset is needed to clear out the settings done by + * previous boot loader. Without this the SDHCI_RESET_ALL + * reset done sdhci_init() times out. + */ + resets = <&gcc GCC_SDCC_BCR>; + + status = "okay"; + }; + diff --git a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi index 32d8804a395..6deebdadf09 100644 --- a/arch/arm/dts/k3-am625-phycore-som-binman.dtsi +++ b/arch/arm/dts/k3-am625-phycore-som-binman.dtsi @@ -400,11 +400,105 @@ }; &binman { + tifsstub-hs { + filename = "tifsstub.bin_hs"; + ti-secure-rom { + content = <&tifsstub_hs_cert>; + core = "secure"; + load = <0x40000>; + sw-rev = <CONFIG_K3_X509_SWRV>; + keyfile = "custMpk.pem"; + countersign; + tifsstub; + }; + tifsstub_hs_cert: tifsstub-hs-cert.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin"; + type = "blob-ext"; + optional; + }; + tifsstub_hs_enc: tifsstub-hs-enc.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin"; + type = "blob-ext"; + optional; + }; + }; + + tifsstub-fs { + filename = "tifsstub.bin_fs"; + tifsstub_fs_cert: tifsstub-fs-cert.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin"; + type = "blob-ext"; + optional; + }; + tifsstub_fs_enc: tifsstub-fs-enc.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin"; + type = "blob-ext"; + optional; + }; + + }; + + tifsstub-gp { + filename = "tifsstub.bin_gp"; + ti-secure-rom { + content = <&tifsstub_gp>; + core = "secure"; + load = <0x60000>; + sw-rev = <CONFIG_K3_X509_SWRV>; + keyfile = "ti-degenerate-key.pem"; + tifsstub; + }; + tifsstub_gp: tifsstub-gp.bin { + filename = "ti-sysfw/ti-fs-stub-firmware-am62x-gp.bin"; + type = "blob-ext"; + optional; + }; + }; + ti-spl_unsigned { insert-template = <&ti_spl_unsigned_template>; fit { images { + tifsstub-hs { + description = "TIFSSTUB"; + type = "firmware"; + arch = "arm32"; + compression = "none"; + os = "tifsstub-hs"; + load = <0x9dc00000>; + entry = <0x9dc00000>; + blob-ext { + filename = "tifsstub.bin_hs"; + }; + }; + + tifsstub-fs { + description = "TIFSSTUB"; + type = "firmware"; + arch = "arm32"; + compression = "none"; + os = "tifsstub-fs"; + load = <0x9dc00000>; + entry = <0x9dc00000>; + blob-ext { + filename = "tifsstub.bin_fs"; + }; + }; + + tifsstub-gp { + description = "TIFSSTUB"; + type = "firmware"; + arch = "arm32"; + compression = "none"; + os = "tifsstub-gp"; + load = <0x9dc00000>; + entry = <0x9dc00000>; + blob-ext { + filename = "tifsstub.bin_gp"; + }; + }; + dm { ti-dm { filename = "ti-dm/am62xx/ipc_echo_testb_mcu1_0_release_strip.xer5f"; diff --git a/arch/arm/dts/qcs615-ride-u-boot.dtsi b/arch/arm/dts/qcs615-ride-u-boot.dtsi new file mode 100644 index 00000000000..68fffc70fcb --- /dev/null +++ b/arch/arm/dts/qcs615-ride-u-boot.dtsi @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/ { + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x7a00000>, + <0x0 0x89600000 0x0 0x30100000>, + <0x0 0xc0000000 0x0 0xc0000000>, + <0x1 0x80000000 0x1 0x00000000>; + }; +}; diff --git a/arch/arm/dts/qcs8300-ride-u-boot.dtsi b/arch/arm/dts/qcs8300-ride-u-boot.dtsi new file mode 100644 index 00000000000..8c353ace71e --- /dev/null +++ b/arch/arm/dts/qcs8300-ride-u-boot.dtsi @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/ { + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x11a80000>, + <0x0 0xc0000000 0x0 0x10000000>, + <0x0 0xd3100000 0x0 0x26b00000>, + <0xe 0x80000000 0x1 0x00000000>, + <0xa 0x80000000 0x1 0x80000000>, + <0x0 0xb0800000 0x0 0x0f200000>, + <0x0 0xd0100000 0x0 0x01800000>, + <0x0 0x91b00000 0x0 0x1e500000>; + }; +}; + diff --git a/arch/arm/dts/versal-mini-emmc0.dts b/arch/arm/dts/versal-mini-emmc0.dts index 179060c56ee..9044ef1889b 100644 --- a/arch/arm/dts/versal-mini-emmc0.dts +++ b/arch/arm/dts/versal-mini-emmc0.dts @@ -28,28 +28,20 @@ bootph-all; }; - amba: axi { - bootph-all; - compatible = "simple-bus"; - #address-cells = <0x2>; - #size-cells = <0x2>; - ranges; - - sdhci0: sdhci@f1040000 { - compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a"; - status = "okay"; - non-removable; - disable-wp; - no-sd; - no-sdio; - cap-mmc-hw-reset; - bus-width = <8>; - reg = <0x0 0xf1040000 0x0 0x10000>; - clock-names = "clk_xin", "clk_ahb"; - clocks = <&clk200 &clk200>; - no-1-8-v; - xlnx,mio-bank = <0>; - }; + sdhci0: sdhci@f1040000 { + compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a"; + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + reg = <0x0 0xf1040000 0x0 0x10000>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&clk200 &clk200>; + no-1-8-v; + xlnx,mio-bank = <0>; }; aliases { diff --git a/arch/arm/dts/versal-mini-emmc1.dts b/arch/arm/dts/versal-mini-emmc1.dts index ffcc3334529..47f3b74c065 100644 --- a/arch/arm/dts/versal-mini-emmc1.dts +++ b/arch/arm/dts/versal-mini-emmc1.dts @@ -28,28 +28,20 @@ bootph-all; }; - amba: axi { - bootph-all; - compatible = "simple-bus"; - #address-cells = <0x2>; - #size-cells = <0x2>; - ranges; - - sdhci1: sdhci@f1050000 { - compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a"; - status = "okay"; - non-removable; - disable-wp; - no-sd; - no-sdio; - cap-mmc-hw-reset; - bus-width = <8>; - reg = <0x0 0xf1050000 0x0 0x10000>; - clock-names = "clk_xin", "clk_ahb"; - clocks = <&clk200 &clk200>; - no-1-8-v; - xlnx,mio-bank = <0>; - }; + sdhci1: sdhci@f1050000 { + compatible = "xlnx,versal-8.9a", "arasan,sdhci-8.9a"; + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + reg = <0x0 0xf1050000 0x0 0x10000>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&clk200 &clk200>; + no-1-8-v; + xlnx,mio-bank = <0>; }; aliases { diff --git a/arch/arm/dts/versal-mini-ospi.dtsi b/arch/arm/dts/versal-mini-ospi.dtsi index 9ca0cf3c027..eec2a08e7c7 100644 --- a/arch/arm/dts/versal-mini-ospi.dtsi +++ b/arch/arm/dts/versal-mini-ospi.dtsi @@ -28,37 +28,29 @@ bootph-all; }; - amba: axi { - bootph-all; - compatible = "simple-bus"; - #address-cells = <0x2>; - #size-cells = <0x2>; - ranges; - - ospi: spi@f1010000 { - compatible = "cdns,qspi-nor"; - status = "okay"; - reg = <0 0xf1010000 0 0x10000 0 0xc0000000 0 0x20000000>; - clock-names = "ref_clk", "pclk"; - clocks = <&clk125 &clk125>; - bus-num = <2>; - num-cs = <1>; - cdns,fifo-depth = <256>; - cdns,fifo-width = <4>; - cdns,is-dma = <1>; - cdns,trigger-address = <0xc0000000>; - #address-cells = <1>; - #size-cells = <0>; + ospi: spi@f1010000 { + compatible = "cdns,qspi-nor"; + status = "okay"; + reg = <0 0xf1010000 0 0x10000 0 0xc0000000 0 0x20000000>; + clock-names = "ref_clk", "pclk"; + clocks = <&clk125 &clk125>; + bus-num = <2>; + num-cs = <1>; + cdns,fifo-depth = <256>; + cdns,fifo-width = <4>; + cdns,is-dma = <1>; + cdns,trigger-address = <0xc0000000>; + #address-cells = <1>; + #size-cells = <0>; - flash0: flash@0 { - compatible = "n25q512a", "micron,m25p80", - "jedec,spi-nor"; - reg = <0x0>; - spi-tx-bus-width = <8>; - spi-rx-bus-width = <8>; - spi-max-frequency = <20000000>; - no-wp; - }; + flash0: flash@0 { + compatible = "n25q512a", "micron,m25p80", + "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; }; }; diff --git a/arch/arm/dts/versal-mini-qspi.dtsi b/arch/arm/dts/versal-mini-qspi.dtsi index 57427e099f9..ec4eef74020 100644 --- a/arch/arm/dts/versal-mini-qspi.dtsi +++ b/arch/arm/dts/versal-mini-qspi.dtsi @@ -28,31 +28,23 @@ bootph-all; }; - amba: axi { - bootph-all; - compatible = "simple-bus"; - #address-cells = <0x2>; - #size-cells = <0x2>; - ranges; - - qspi: spi@f1030000 { - compatible = "xlnx,versal-qspi-1.0"; - status = "okay"; - clock-names = "ref_clk", "pclk"; - num-cs = <0x1>; - reg = <0x0 0xf1030000 0x0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clk150 &clk150>; + qspi: spi@f1030000 { + compatible = "xlnx,versal-qspi-1.0"; + status = "okay"; + clock-names = "ref_clk", "pclk"; + num-cs = <0x1>; + reg = <0x0 0xf1030000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk150 &clk150>; - flash0: flash@0 { - compatible = "n25q512a", "micron,m25p80", - "jedec,spi-nor"; - reg = <0x0>; - spi-tx-bus-width = <4>; - spi-rx-bus-width = <4>; - spi-max-frequency = <20000000>; - }; + flash0: flash@0 { + compatible = "n25q512a", "micron,m25p80", + "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <20000000>; }; }; diff --git a/arch/arm/dts/versal-net-mini-emmc.dts b/arch/arm/dts/versal-net-mini-emmc.dts index 20e4e299404..567ceeb36a0 100644 --- a/arch/arm/dts/versal-net-mini-emmc.dts +++ b/arch/arm/dts/versal-net-mini-emmc.dts @@ -2,7 +2,7 @@ /* * dts file for Xilinx Versal NET Mini eMMC Configuration * - * (C) Copyright 2023, Advanced Micro Devices, Inc. + * (C) Copyright 2023-2025, Advanced Micro Devices, Inc. * * Michal Simek <michal.simek@amd.com> * Ashok Reddy Soma <ashok.reddy.soma@amd.com> @@ -42,26 +42,18 @@ bootph-all; }; - amba: axi { - bootph-all; - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - sdhci1: mmc@f1050000 { - compatible = "xlnx,versal-net-emmc"; - status = "okay"; - non-removable; - disable-wp; - no-sd; - no-sdio; - cap-mmc-hw-reset; - bus-width = <8>; - reg = <0 0xf1050000 0 0x10000>; - clock-names = "clk_xin", "clk_ahb"; - clocks = <&clk200>, <&clk200>; - xlnx,mio-bank = <0>; - }; + sdhci1: mmc@f1050000 { + compatible = "xlnx,versal-net-emmc"; + status = "okay"; + non-removable; + disable-wp; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + reg = <0 0xf1050000 0 0x10000>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&clk200>, <&clk200>; + xlnx,mio-bank = <0>; }; }; diff --git a/arch/arm/dts/versal-net-mini-ospi.dtsi b/arch/arm/dts/versal-net-mini-ospi.dtsi index a9bf7cc4248..1c94b352dc9 100644 --- a/arch/arm/dts/versal-net-mini-ospi.dtsi +++ b/arch/arm/dts/versal-net-mini-ospi.dtsi @@ -2,7 +2,7 @@ /* * dts file for Xilinx Versal NET Mini OSPI Configuration * - * (C) Copyright 2023, Advanced Micro Devices, Inc. + * (C) Copyright 2023-2025, Advanced Micro Devices, Inc. * * Michal Simek <michal.simek@amd.com> * Ashok Reddy Soma <ashok.reddy.soma@amd.com> @@ -42,38 +42,30 @@ bootph-all; }; - amba: axi { - bootph-all; - compatible = "simple-bus"; - #address-cells = <0x2>; - #size-cells = <0x2>; - ranges; - - ospi: spi@f1010000 { - compatible = "cdns,qspi-nor"; - status = "okay"; - reg = <0 0xf1010000 0 0x10000>, <0 0xc0000000 0 0x20000000>; - clock-names = "ref_clk", "pclk"; - clocks = <&clk125>, <&clk125>; - bus-num = <2>; - num-cs = <1>; - cdns,fifo-depth = <256>; - cdns,fifo-width = <4>; - cdns,is-dma = <1>; - cdns,is-stig-pgm = <1>; - cdns,trigger-address = <0xc0000000>; - #address-cells = <1>; - #size-cells = <0>; + ospi: spi@f1010000 { + compatible = "cdns,qspi-nor"; + status = "okay"; + reg = <0 0xf1010000 0 0x10000>, <0 0xc0000000 0 0x20000000>; + clock-names = "ref_clk", "pclk"; + clocks = <&clk125>, <&clk125>; + bus-num = <2>; + num-cs = <1>; + cdns,fifo-depth = <256>; + cdns,fifo-width = <4>; + cdns,is-dma = <1>; + cdns,is-stig-pgm = <1>; + cdns,trigger-address = <0xc0000000>; + #address-cells = <1>; + #size-cells = <0>; - flash0: flash@0 { - compatible = "mt35xu02g", "micron,m25p80", - "jedec,spi-nor"; - reg = <0>; - spi-tx-bus-width = <8>; - spi-rx-bus-width = <8>; - spi-max-frequency = <20000000>; - no-wp; - }; + flash0: flash@0 { + compatible = "mt35xu02g", "micron,m25p80", + "jedec,spi-nor"; + reg = <0>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <20000000>; + no-wp; }; }; }; diff --git a/arch/arm/dts/versal-net-mini-qspi.dtsi b/arch/arm/dts/versal-net-mini-qspi.dtsi index e29a3f36d6e..97cc39c73e0 100644 --- a/arch/arm/dts/versal-net-mini-qspi.dtsi +++ b/arch/arm/dts/versal-net-mini-qspi.dtsi @@ -2,7 +2,7 @@ /* * dts file for Xilinx Versal NET Mini QSPI Configuration * - * (C) Copyright 2023, Advanced Micro Devices, Inc. + * (C) Copyright 2023-2025, Advanced Micro Devices, Inc. * * Michal Simek <michal.simek@amd.com> * Ashok Reddy Soma <ashok.reddy.soma@amd.com> @@ -42,31 +42,23 @@ bootph-all; }; - amba: axi { - bootph-all; - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - qspi: spi@f1030000 { - compatible = "xlnx,versal-qspi-1.0"; - status = "okay"; - clock-names = "ref_clk", "pclk"; - num-cs = <1>; - reg = <0 0xf1030000 0 0x1000>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clk150>, <&clk150>; + qspi: spi@f1030000 { + compatible = "xlnx,versal-qspi-1.0"; + status = "okay"; + clock-names = "ref_clk", "pclk"; + num-cs = <1>; + reg = <0 0xf1030000 0 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk150>, <&clk150>; - flash0: flash@0 { - compatible = "n25q512a", "micron,m25p80", - "jedec,spi-nor"; - reg = <0>; - spi-tx-bus-width = <4>; - spi-rx-bus-width = <4>; - spi-max-frequency = <20000000>; - }; + flash0: flash@0 { + compatible = "n25q512a", "micron,m25p80", + "jedec,spi-nor"; + reg = <0>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-max-frequency = <20000000>; }; }; }; diff --git a/arch/arm/dts/versal-net-mini.dts b/arch/arm/dts/versal-net-mini.dts index f98f95a5c2f..0f0a82e3aa3 100644 --- a/arch/arm/dts/versal-net-mini.dts +++ b/arch/arm/dts/versal-net-mini.dts @@ -3,7 +3,7 @@ * dts file for Xilinx Versal NET * * Copyright (C) 2021 - 2022, Xilinx, Inc. - * Copyright (C) 2022, Advanced Micro Devices, Inc. + * Copyright (C) 2022-2025, Advanced Micro Devices, Inc. * * Michal Simek <michal.simek@amd.com> */ @@ -45,22 +45,14 @@ bootph-all; }; - amba: axi { - compatible = "simple-bus"; + serial0: serial@f1920000 { bootph-all; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - serial0: serial@f1920000 { - bootph-all; - compatible = "arm,pl011", "arm,primecell"; - reg = <0 0xf1920000 0 0x1000>; - reg-io-width = <4>; - clock-names = "uartclk", "apb_pclk"; - clocks = <&clk1>, <&clk1>; - clock = <1000000>; - skip-init; - }; + compatible = "arm,pl011", "arm,primecell"; + reg = <0 0xf1920000 0 0x1000>; + reg-io-width = <4>; + clock-names = "uartclk", "apb_pclk"; + clocks = <&clk1>, <&clk1>; + clock = <1000000>; + skip-init; }; }; diff --git a/arch/arm/dts/vf610-pcm052.dtsi b/arch/arm/dts/vf610-pcm052.dtsi index ccdc0f57e2b..2b82b7313dd 100644 --- a/arch/arm/dts/vf610-pcm052.dtsi +++ b/arch/arm/dts/vf610-pcm052.dtsi @@ -244,7 +244,7 @@ qflash0: spi_flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <108000000>; reg = <0>; }; @@ -252,7 +252,7 @@ qflash1: spi_flash@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "spi-flash"; + compatible = "jedec,spi-nor"; spi-max-frequency = <66000000>; reg = <1>; }; diff --git a/arch/arm/dts/zynqmp-clk-ccf.dtsi b/arch/arm/dts/zynqmp-clk-ccf.dtsi index 385fed8a852..52e122fc7c9 100644 --- a/arch/arm/dts/zynqmp-clk-ccf.dtsi +++ b/arch/arm/dts/zynqmp-clk-ccf.dtsi @@ -8,7 +8,7 @@ * Michal Simek <michal.simek@amd.com> */ -#include <dt-bindings/clock/xlnx-zynqmp-clk.h> +#include "xlnx-zynqmp-clk.h" / { pss_ref_clk: pss-ref-clk { bootph-all; diff --git a/arch/arm/dts/zynqmp-mini-emmc0.dts b/arch/arm/dts/zynqmp-mini-emmc0.dts index ad4b3c5f8b1..05f61d6bb35 100644 --- a/arch/arm/dts/zynqmp-mini-emmc0.dts +++ b/arch/arm/dts/zynqmp-mini-emmc0.dts @@ -41,25 +41,18 @@ clock-frequency = <200000000>; }; - amba: axi { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - sdhci0: mmc@ff160000 { - bootph-all; - compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; - status = "disabled"; - non-removable; - no-sd; - no-sdio; - cap-mmc-hw-reset; - bus-width = <8>; - reg = <0x0 0xff160000 0x0 0x1000>; - clock-names = "clk_xin", "clk_ahb"; - clocks = <&clk_xin &clk_xin>; - }; + sdhci0: mmc@ff160000 { + bootph-all; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; + status = "disabled"; + non-removable; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + reg = <0x0 0xff160000 0x0 0x1000>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&clk_xin &clk_xin>; }; }; diff --git a/arch/arm/dts/zynqmp-mini-emmc1.dts b/arch/arm/dts/zynqmp-mini-emmc1.dts index fd421b4fe7e..7857106260e 100644 --- a/arch/arm/dts/zynqmp-mini-emmc1.dts +++ b/arch/arm/dts/zynqmp-mini-emmc1.dts @@ -41,25 +41,18 @@ clock-frequency = <200000000>; }; - amba: axi { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - - sdhci1: mmc@ff170000 { - bootph-all; - compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; - status = "disabled"; - non-removable; - no-sd; - no-sdio; - cap-mmc-hw-reset; - bus-width = <8>; - reg = <0x0 0xff170000 0x0 0x1000>; - clock-names = "clk_xin", "clk_ahb"; - clocks = <&clk_xin &clk_xin>; - }; + sdhci1: mmc@ff170000 { + bootph-all; + compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; + status = "disabled"; + non-removable; + no-sd; + no-sdio; + cap-mmc-hw-reset; + bus-width = <8>; + reg = <0x0 0xff170000 0x0 0x1000>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&clk_xin &clk_xin>; }; }; diff --git a/arch/arm/dts/zynqmp-mini-nand.dts b/arch/arm/dts/zynqmp-mini-nand.dts index 5e2135158cd..1ece3999791 100644 --- a/arch/arm/dts/zynqmp-mini-nand.dts +++ b/arch/arm/dts/zynqmp-mini-nand.dts @@ -35,27 +35,20 @@ bootph-all; }; - amba: axi { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - ranges; - - nand0: nand@ff100000 { - compatible = "arasan,nfc-v3p10"; - status = "okay"; - reg = <0x0 0xff100000 0x1000>; - clock-names = "clk_sys", "clk_flash"; - #address-cells = <1>; - #size-cells = <0>; - arasan,has-mdma; - num-cs = <2>; - nand@0 { - reg = <0>; - #address-cells = <2>; - #size-cells = <1>; - nand-ecc-mode = "hw"; - }; + nand0: nand@ff100000 { + compatible = "arasan,nfc-v3p10"; + status = "okay"; + reg = <0x0 0xff100000 0x1000>; + clock-names = "clk_sys", "clk_flash"; + #address-cells = <1>; + #size-cells = <0>; + arasan,has-mdma; + num-cs = <2>; + nand@0 { + reg = <0>; + #address-cells = <2>; + #size-cells = <1>; + nand-ecc-mode = "hw"; }; }; }; diff --git a/arch/arm/dts/zynqmp-mini-qspi.dts b/arch/arm/dts/zynqmp-mini-qspi.dts index 917603dec61..ddcc39b4e94 100644 --- a/arch/arm/dts/zynqmp-mini-qspi.dts +++ b/arch/arm/dts/zynqmp-mini-qspi.dts @@ -42,22 +42,15 @@ clock-frequency = <125000000>; }; - amba: axi { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - ranges; - - qspi: spi@ff0f0000 { - compatible = "xlnx,zynqmp-qspi-1.0"; - status = "disabled"; - clock-names = "ref_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; - num-cs = <1>; - reg = <0x0 0xff0f0000 0x1000 0x0 0xc0000000 0x8000000>; - #address-cells = <1>; - #size-cells = <0>; - }; + qspi: spi@ff0f0000 { + compatible = "xlnx,zynqmp-qspi-1.0"; + status = "disabled"; + clock-names = "ref_clk", "pclk"; + clocks = <&misc_clk &misc_clk>; + num-cs = <1>; + reg = <0x0 0xff0f0000 0x1000 0x0 0xc0000000 0x8000000>; + #address-cells = <1>; + #size-cells = <0>; }; }; diff --git a/arch/arm/include/asm/arch-imxrt/gpio.h b/arch/arm/include/asm/arch-imxrt/gpio.h index da31a7438aa..be130e00652 100644 --- a/arch/arm/include/asm/arch-imxrt/gpio.h +++ b/arch/arm/include/asm/arch-imxrt/gpio.h @@ -7,13 +7,6 @@ #ifndef __ASM_ARCH_GPIO_H__ #define __ASM_ARCH_GPIO_H__ -#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__)) -/* GPIO registers */ -struct gpio_regs { - u32 gpio_dr; /* data */ - u32 gpio_dir; /* direction */ - u32 gpio_psr; /* pad satus */ -}; -#endif +#include <asm/mach-imx/gpio.h> #endif /* __ASM_ARCH_GPIO_H__ */ diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h index ccacc99d018..575dff68804 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h @@ -90,6 +90,13 @@ #define CCM_PLL6_DEFAULT 0xe8216300 #define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 #define CCM_APB1_DEFAULT 0x03000102 + +#elif CONFIG_MACH_SUN50I_A133 /* A133 */ + +#define CCM_PLL6_DEFAULT 0xb8003100 +#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 +#define CCM_AHB3_DEFAULT 0x03000002 +#define CCM_APB1_DEFAULT 0x03000102 #endif /* apb2 bit field */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h index 8a3f465545a..2a9b086991c 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h @@ -29,6 +29,10 @@ #define SUNXI_DRAM_COM_BASE 0x047FA000 #define SUNXI_DRAM_CTL0_BASE 0x047FB000 #define SUNXI_DRAM_PHY0_BASE 0x04800000 +#elif CONFIG_MACH_SUN50I_A133 +#define SUNXI_DRAM_COM_BASE 0x04810000 +#define SUNXI_DRAM_CTL0_BASE 0x04820000 +#define SUNXI_DRAM_PHY0_BASE 0x04830000 #endif #define SUNXI_TWI0_BASE 0x05002000 diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index 9d21b492418..0708ae3ee3b 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -31,6 +31,8 @@ #include <asm/arch/dram_sun50i_h6.h> #elif defined(CONFIG_MACH_SUN50I_H616) #include <asm/arch/dram_sun50i_h616.h> +#elif defined(CONFIG_DRAM_SUN50I_A133) +#include <asm/arch/dram_sun50i_a133.h> #elif defined(CONFIG_MACH_SUNIV) #include <asm/arch/dram_suniv.h> #else diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h b/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h new file mode 100644 index 00000000000..a5fc6ad3656 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_a133.h @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A133 dram controller register and constant defines + * + * (C) Copyright 2024 MasterR3C0RD <masterr3c0rd@epochal.quest> + */ + +#ifndef _SUNXI_DRAM_SUN50I_A133_H +#define _SUNXI_DRAM_SUN50I_A133_H + +#include <linux/bitops.h> + +enum sunxi_dram_type { + SUNXI_DRAM_TYPE_DDR3 = 3, + SUNXI_DRAM_TYPE_DDR4, + SUNXI_DRAM_TYPE_LPDDR3 = 7, + SUNXI_DRAM_TYPE_LPDDR4 +}; + +static inline int ns_to_t(int nanoseconds) +{ + const unsigned int ctrl_freq = CONFIG_DRAM_CLK / 2; + + return DIV_ROUND_UP(ctrl_freq * nanoseconds, 1000); +} + +/* MBUS part is largely the same as in H6, except for one special register */ +#define MCTL_COM_UNK_008 0x008 +/* NOTE: This register has the same importance as mctl_ctl->clken in H616 */ +#define MCTL_COM_MAER0 0x020 + +/* + * Controller registers seems to be the same or at least very similar + * to those in H6. + */ +struct sunxi_mctl_ctl_reg { + u32 mstr; /* 0x000 */ + u32 statr; /* 0x004 unused */ + u32 mstr1; /* 0x008 unused */ + u32 clken; /* 0x00c */ + u32 mrctrl0; /* 0x010 unused */ + u32 mrctrl1; /* 0x014 unused */ + u32 mrstatr; /* 0x018 unused */ + u32 mrctrl2; /* 0x01c unused */ + u32 derateen; /* 0x020 unused */ + u32 derateint; /* 0x024 unused */ + u8 reserved_0x028[8]; /* 0x028 */ + u32 pwrctl; /* 0x030 unused */ + u32 pwrtmg; /* 0x034 unused */ + u32 hwlpctl; /* 0x038 unused */ + u8 reserved_0x03c[20]; /* 0x03c */ + u32 rfshctl0; /* 0x050 unused */ + u32 rfshctl1; /* 0x054 unused */ + u8 reserved_0x058[8]; /* 0x05c */ + u32 rfshctl3; /* 0x060 */ + u32 rfshtmg; /* 0x064 */ + u8 reserved_0x068[104]; /* 0x068 */ + u32 init[8]; /* 0x0d0 */ + u32 dimmctl; /* 0x0f0 unused */ + u32 rankctl; /* 0x0f4 */ + u8 reserved_0x0f8[8]; /* 0x0f8 */ + u32 dramtmg[17]; /* 0x100 */ + u8 reserved_0x144[60]; /* 0x144 */ + u32 zqctl[3]; /* 0x180 */ + u32 zqstat; /* 0x18c unused */ + u32 dfitmg0; /* 0x190 */ + u32 dfitmg1; /* 0x194 */ + u32 dfilpcfg[2]; /* 0x198 unused */ + u32 dfiupd[3]; /* 0x1a0 */ + u32 reserved_0x1ac; /* 0x1ac */ + u32 dfimisc; /* 0x1b0 */ + u32 dfitmg2; /* 0x1b4 unused */ + u32 dfitmg3; /* 0x1b8 unused */ + u32 dfistat; /* 0x1bc */ + u32 dbictl; /* 0x1c0 */ + u8 reserved_0x1c4[60]; /* 0x1c4 */ + u32 addrmap[12]; /* 0x200 */ + u8 reserved_0x230[16]; /* 0x230 */ + u32 odtcfg; /* 0x240 */ + u32 odtmap; /* 0x244 */ + u8 reserved_0x248[8]; /* 0x248 */ + u32 sched[2]; /* 0x250 */ + u8 reserved_0x258[180]; /* 0x258 */ + u32 dbgcmd; /* 0x30c unused */ + u32 dbgstat; /* 0x310 unused */ + u8 reserved_0x314[12]; /* 0x314 */ + u32 swctl; /* 0x320 */ + u32 swstat; /* 0x324 */ + u8 reserved_0x328[7768]; /* 0x328 */ + u32 unk_0x2180; /* 0x2180 */ + u8 reserved_0x2184[188]; /* 0x2184 */ + u32 unk_0x2240; /* 0x2240 */ + u8 reserved_0x2244[3900]; /* 0x2244 */ + u32 unk_0x3180; /* 0x3180 */ + u8 reserved_0x3184[188]; /* 0x3184 */ + u32 unk_0x3240; /* 0x3240 */ + u8 reserved_0x3244[3900]; /* 0x3244 */ + u32 unk_0x4180; /* 0x4180 */ + u8 reserved_0x4184[188]; /* 0x4184 */ + u32 unk_0x4240; /* 0x4240 */ +}; + +check_member(sunxi_mctl_ctl_reg, swstat, 0x324); +check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240); + +#define MSTR_DEVICETYPE_DDR3 BIT(0) +#define MSTR_DEVICETYPE_LPDDR2 BIT(2) +#define MSTR_DEVICETYPE_LPDDR3 BIT(3) +#define MSTR_DEVICETYPE_DDR4 BIT(4) +#define MSTR_DEVICETYPE_LPDDR4 BIT(5) +#define MSTR_DEVICETYPE_MASK GENMASK(5, 0) +#define MSTR_GEARDOWNMODE BIT(0) /* Same as MSTR_DEVICETYPE_DDR3, only used for DDR4 */ +#define MSTR_2TMODE BIT(10) +#define MSTR_BUSWIDTH_FULL (0 << 12) +#define MSTR_BUSWIDTH_HALF (1 << 12) +#define MSTR_ACTIVE_RANKS(x) (((x == 1) ? 3 : 1) << 24) +#define MSTR_BURST_LENGTH(x) (((x) >> 1) << 16) +#define MSTR_DEVICECONFIG_X32 (3 << 30) + +#define TPR10_CA_BIT_DELAY BIT(16) +#define TPR10_DX_BIT_DELAY0 BIT(17) +#define TPR10_DX_BIT_DELAY1 BIT(18) +#define TPR10_WRITE_LEVELING BIT(20) +#define TPR10_READ_CALIBRATION BIT(21) +#define TPR10_READ_TRAINING BIT(22) +#define TPR10_WRITE_TRAINING BIT(23) + +/* MRCTRL constants */ +#define MRCTRL0_MR_RANKS_ALL (3 << 4) +#define MRCTRL0_MR_ADDR(x) (x << 12) +#define MRCTRL0_MR_WR BIT(31) + +#define MRCTRL1_MR_ADDR(x) (x << 8) +#define MRCTRL1_MR_DATA(x) (x) + +/* ADDRMAP constants */ +#define ADDRMAP_DISABLED_3F_B(b) (0x3f + b) +#define ADDRMAP_DISABLED_1F_B(b) (0x1f + b) +#define ADDRMAP_DISABLED_0F_B(b) (0x0f + b) + +#define _ADDRMAP_VALUE(a,x,b) (((a) - b) << (x * 8)) + +/* + * Bx = internal base + * The selected HIF address bit for each address bit is determined + * by adding the internal base to the value of each field + * */ + +#define ADDRMAP0_CS0_B6(v) _ADDRMAP_VALUE(v, 0, 6) + +#define ADDRMAP1_BANK0_B2(v) _ADDRMAP_VALUE(v, 0, 2) +#define ADDRMAP1_BANK1_B3(v) _ADDRMAP_VALUE(v, 1, 3) +#define ADDRMAP1_BANK2_B4(v) _ADDRMAP_VALUE(v, 2, 4) + +#define ADDRMAP2_COL2_B2(v) _ADDRMAP_VALUE(v, 0, 2) +#define ADDRMAP2_COL3_B3(v) _ADDRMAP_VALUE(v, 1, 3) +#define ADDRMAP2_COL4_B4(v) _ADDRMAP_VALUE(v, 2, 4) +#define ADDRMAP2_COL5_B5(v) _ADDRMAP_VALUE(v, 3, 5) + +#define ADDRMAP3_COL6_B6(v) _ADDRMAP_VALUE(v, 0, 6) +#define ADDRMAP3_COL7_B7(v) _ADDRMAP_VALUE(v, 1, 7) +#define ADDRMAP3_COL8_B8(v) _ADDRMAP_VALUE(v, 2, 8) +#define ADDRMAP3_COL9_B9(v) _ADDRMAP_VALUE(v, 3, 9) + +#define ADDRMAP4_COL10_B10(v) _ADDRMAP_VALUE(v, 0, 10) +#define ADDRMAP4_COL11_B11(v) _ADDRMAP_VALUE(v, 1, 11) + +#define ADDRMAP5_ROW0_B6(v) _ADDRMAP_VALUE(v, 0, 6) +#define ADDRMAP5_ROW1_B7(v) _ADDRMAP_VALUE(v, 1, 7) +#define ADDRMAP5_ROW2_10_B8(v) _ADDRMAP_VALUE(v, 2, 8) +#define ADDRMAP5_ROW11_B17(v) _ADDRMAP_VALUE(v, 3, 17) + +#define ADDRMAP6_ROW12_B18(v) _ADDRMAP_VALUE(v, 0, 18) +#define ADDRMAP6_ROW13_B19(v) _ADDRMAP_VALUE(v, 1, 19) +#define ADDRMAP6_ROW14_B20(v) _ADDRMAP_VALUE(v, 2, 20) +#define ADDRMAP6_ROW15_B21(v) _ADDRMAP_VALUE(v, 3, 21) + +#define ADDRMAP7_ROW16_B22(v) _ADDRMAP_VALUE(v, 0, 22) +#define ADDRMAP7_ROW17_B23(v) _ADDRMAP_VALUE(v, 1, 23) + +#define ADDRMAP8_BG0_B2(v) _ADDRMAP_VALUE(v, 0, 2) +#define ADDRMAP8_BG1_B3(v) _ADDRMAP_VALUE(v, 1, 3) + +/* These are only used if ADDRMAP5_ROW_BITS_2_10 = ADDRMAP_DISABLED_0F */ +#define ADDRMAP9_ROW2_B8(v) _ADDRMAP_VALUE(v, 0, 8) +#define ADDRMAP9_ROW3_B9(v) _ADDRMAP_VALUE(v, 1, 9) +#define ADDRMAP9_ROW4_B10(v) _ADDRMAP_VALUE(v, 2, 10) +#define ADDRMAP9_ROW5_B11(v) _ADDRMAP_VALUE(v, 3, 11) + +#define ADDRMAP10_ROW6_B12(v) _ADDRMAP_VALUE(v, 0, 12) +#define ADDRMAP10_ROW7_B13(v) _ADDRMAP_VALUE(v, 1, 13) +#define ADDRMAP10_ROW8_B14(v) _ADDRMAP_VALUE(v, 2, 14) +#define ADDRMAP10_ROW9_B15(v) _ADDRMAP_VALUE(v, 3, 15) + +#define ADDRMAP11_ROW10_B16(v) _ADDRMAP_VALUE(v, 0, 16) + +struct dram_para { + uint32_t clk; + enum sunxi_dram_type type; + uint32_t dx_odt; + uint32_t dx_dri; + uint32_t ca_dri; + uint32_t para0; + uint32_t mr11; + uint32_t mr12; + uint32_t mr13; + uint32_t mr14; + uint32_t tpr1; + uint32_t tpr2; + uint32_t tpr3; + uint32_t tpr6; + uint32_t tpr10; + uint32_t tpr11; + uint32_t tpr12; + uint32_t tpr13; + uint32_t tpr14; +}; + +void mctl_set_timing_params(const struct dram_para *para); + +struct dram_config { + u8 cols; /* Column bits */ + u8 rows; /* Row bits */ + u8 ranks; /* Rank bits (different from H616!) */ + u8 banks; /* Bank bits */ + u8 bankgrps; /* Bank group bits */ + u8 bus_full_width; /* 1 = x32, 0 = x16 */ +}; + +#endif /* _SUNXI_DRAM_SUN50I_A133_H */ diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 89b1015bc4d..85ec0e6937e 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -20,23 +20,108 @@ static inline void sync(void) { } -/* Generic virtual read/write. */ -#define __arch_getb(a) (*(volatile unsigned char *)(a)) -#define __arch_getw(a) (*(volatile unsigned short *)(a)) -#define __arch_getl(a) (*(volatile unsigned int *)(a)) -#define __arch_getq(a) (*(volatile unsigned long long *)(a)) +#ifdef CONFIG_ARM64 +#define __W "w" +#else +#define __W +#endif + +#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD) +#define __R "l" +#define __RM "=l" +#else +#define __R "r" +#define __RM "=r" +#endif -#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) -#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) -#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) -#define __arch_putq(v,a) (*(volatile unsigned long long *)(a) = (v)) +#ifdef CONFIG_KVM_VIRT_INS +/* + * The __raw_writeX/__raw_readX below should be converted to static inline + * functions. However doing so produces a lot of compilation warnings when + * called with a raw address. Convert these once the callers have been fixed. + */ +#define __raw_writeb(val, addr) \ + do { \ + asm volatile("strb %" __W "0, [%1]" \ + : \ + : __R ((u8)(val)), __R (addr)); \ + } while (0) + +#define __raw_readb(addr) \ + ({ \ + u32 __val; \ + asm volatile("ldrb %" __W "0, [%1]" \ + : __RM (__val) \ + : __R (addr)); \ + __val; \ + }) + +#define __raw_writew(val, addr) \ + do { \ + asm volatile("strh %" __W "0, [%1]" \ + : \ + : __R ((u16)(val)), __R (addr)); \ + } while (0) + +#define __raw_readw(addr) \ + ({ \ + u32 __val; \ + asm volatile("ldrh %" __W "0, [%1]" \ + : __RM (__val) \ + : __R (addr)); \ + __val; \ + }) + +#define __raw_writel(val, addr) \ + do { \ + asm volatile("str %" __W "0, [%1]" \ + : \ + : __R ((u32)(val)), __R (addr)); \ + } while (0) + +#define __raw_readl(addr) \ + ({ \ + u32 __val; \ + asm volatile("ldr %" __W "0, [%1]" \ + : __RM (__val) \ + : __R (addr)); \ + __val; \ + }) + +#define __raw_writeq(val, addr) \ + do { \ + asm volatile("str %0, [%1]" \ + : \ + : __R ((u64)(val)), __R (addr)); \ + } while (0) + +#define __raw_readq(addr) \ + ({ \ + u64 __val; \ + asm volatile("ldr %0, [%1]" \ + : __RM (__val) \ + : __R (addr)); \ + __val; \ + }) +#else +/* Generic virtual read/write. */ +#define __raw_readb(a) (*(volatile unsigned char *)(a)) +#define __raw_readw(a) (*(volatile unsigned short *)(a)) +#define __raw_readl(a) (*(volatile unsigned int *)(a)) +#define __raw_readq(a) (*(volatile unsigned long long *)(a)) + +#define __raw_writeb(v, a) (*(volatile unsigned char *)(a) = (v)) +#define __raw_writew(v, a) (*(volatile unsigned short *)(a) = (v)) +#define __raw_writel(v, a) (*(volatile unsigned int *)(a) = (v)) +#define __raw_writeq(v, a) (*(volatile unsigned long long *)(a) = (v)) +#endif static inline void __raw_writesb(unsigned long addr, const void *data, int bytelen) { uint8_t *buf = (uint8_t *)data; while(bytelen--) - __arch_putb(*buf++, addr); + __raw_writeb(*buf++, addr); } static inline void __raw_writesw(unsigned long addr, const void *data, @@ -44,7 +129,7 @@ static inline void __raw_writesw(unsigned long addr, const void *data, { uint16_t *buf = (uint16_t *)data; while(wordlen--) - __arch_putw(*buf++, addr); + __raw_writew(*buf++, addr); } static inline void __raw_writesl(unsigned long addr, const void *data, @@ -52,40 +137,30 @@ static inline void __raw_writesl(unsigned long addr, const void *data, { uint32_t *buf = (uint32_t *)data; while(longlen--) - __arch_putl(*buf++, addr); + __raw_writel(*buf++, addr); } static inline void __raw_readsb(unsigned long addr, void *data, int bytelen) { uint8_t *buf = (uint8_t *)data; while(bytelen--) - *buf++ = __arch_getb(addr); + *buf++ = __raw_readb(addr); } static inline void __raw_readsw(unsigned long addr, void *data, int wordlen) { uint16_t *buf = (uint16_t *)data; while(wordlen--) - *buf++ = __arch_getw(addr); + *buf++ = __raw_readw(addr); } static inline void __raw_readsl(unsigned long addr, void *data, int longlen) { uint32_t *buf = (uint32_t *)data; while(longlen--) - *buf++ = __arch_getl(addr); + *buf++ = __raw_readl(addr); } -#define __raw_writeb(v,a) __arch_putb(v,a) -#define __raw_writew(v,a) __arch_putw(v,a) -#define __raw_writel(v,a) __arch_putl(v,a) -#define __raw_writeq(v,a) __arch_putq(v,a) - -#define __raw_readb(a) __arch_getb(a) -#define __raw_readw(a) __arch_getw(a) -#define __raw_readl(a) __arch_getl(a) -#define __raw_readq(a) __arch_getq(a) - /* * TODO: The kernel offers some more advanced versions of barriers, it might * have some advantages to use them instead of the simple one here. @@ -98,15 +173,15 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen) #define smp_processor_id() 0 -#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; }) -#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; }) -#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; }) -#define writeq(v,c) ({ u64 __v = v; __iowmb(); __arch_putq(__v,c); __v; }) +#define writeb(v, c) ({ u8 __v = v; __iowmb(); writeb_relaxed(__v, c); __v; }) +#define writew(v, c) ({ u16 __v = v; __iowmb(); writew_relaxed(__v, c); __v; }) +#define writel(v, c) ({ u32 __v = v; __iowmb(); writel_relaxed(__v, c); __v; }) +#define writeq(v, c) ({ u64 __v = v; __iowmb(); writeq_relaxed(__v, c); __v; }) -#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; }) -#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; }) -#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; }) -#define readq(c) ({ u64 __v = __arch_getq(c); __iormb(); __v; }) +#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) +#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) +#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) +#define readq(c) ({ u64 __v = readq_relaxed(c); __iormb(); __v; }) /* * Relaxed I/O memory access primitives. These follow the Device memory @@ -121,13 +196,10 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen) #define readq_relaxed(c) ({ u64 __r = le64_to_cpu((__force __le64) \ __raw_readq(c)); __r; }) -#define writeb_relaxed(v, c) ((void)__raw_writeb((v), (c))) -#define writew_relaxed(v, c) ((void)__raw_writew((__force u16) \ - cpu_to_le16(v), (c))) -#define writel_relaxed(v, c) ((void)__raw_writel((__force u32) \ - cpu_to_le32(v), (c))) -#define writeq_relaxed(v, c) ((void)__raw_writeq((__force u64) \ - cpu_to_le64(v), (c))) +#define writeb_relaxed(v, c) __raw_writeb((v), (c)) +#define writew_relaxed(v, c) __raw_writew((__force u16)cpu_to_le16(v), (c)) +#define writel_relaxed(v, c) __raw_writel((__force u32)cpu_to_le32(v), (c)) +#define writeq_relaxed(v, c) __raw_writeq((__force u64)cpu_to_le64(v), (c)) /* * The compiler seems to be incapable of optimising constants diff --git a/arch/arm/mach-airoha/an7581/init.c b/arch/arm/mach-airoha/an7581/init.c index cefe9c6db9e..d149e0ee3c8 100644 --- a/arch/arm/mach-airoha/an7581/init.c +++ b/arch/arm/mach-airoha/an7581/init.c @@ -2,6 +2,7 @@ #include <fdtdec.h> #include <init.h> +#include <sysreset.h> #include <asm/armv8/mmu.h> #include <asm/system.h> @@ -21,7 +22,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -void reset_cpu(ulong addr) +void reset_cpu(void) { psci_system_reset(); } diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 2604c5a710e..4cd8979bdc2 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -773,22 +773,31 @@ u64 get_page_table_size(void) #define KERNEL_COMP_SIZE SZ_128M +#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) + int board_late_init(void) { u32 status = 0; + phys_addr_t addr; /* somewhat based on the Linux Kernel boot requirements: * align by 2M and maximal FDT size 2M */ - status |= env_set_hex("loadaddr", lmb_alloc(SZ_1G, SZ_2M)); - status |= env_set_hex("fdt_addr_r", lmb_alloc(SZ_2M, SZ_2M)); - status |= env_set_hex("kernel_addr_r", lmb_alloc(SZ_128M, SZ_2M)); - status |= env_set_hex("ramdisk_addr_r", lmb_alloc(SZ_1G, SZ_2M)); - status |= env_set_hex("kernel_comp_addr_r", - lmb_alloc(KERNEL_COMP_SIZE, SZ_2M)); - status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE); - status |= env_set_hex("scriptaddr", lmb_alloc(SZ_4M, SZ_2M)); - status |= env_set_hex("pxefile_addr_r", lmb_alloc(SZ_4M, SZ_2M)); + status |= !lmb_alloc(SZ_1G, &addr) ? env_set_hex("loadaddr", addr) : 1; + status |= !lmb_alloc(SZ_2M, &addr) ? + env_set_hex("fdt_addr_r", addr) : 1; + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("kernel_addr_r", addr) : 1; + status |= !lmb_alloc(SZ_1G, &addr) ? + env_set_hex("ramdisk_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_size", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("scriptaddr", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("pxefile_addr_r", addr) : 1; if (status) log_warning("late_init: Failed to set run time variables\n"); diff --git a/arch/arm/mach-k3/am62ax/am62a7_init.c b/arch/arm/mach-k3/am62ax/am62a7_init.c index ac4d30052f3..00173e6836b 100644 --- a/arch/arm/mach-k3/am62ax/am62a7_init.c +++ b/arch/arm/mach-k3/am62ax/am62a7_init.c @@ -57,7 +57,6 @@ static void ctrl_mmr_unlock(void) mmr_unlock(CTRL_MMR0_BASE, 1); mmr_unlock(CTRL_MMR0_BASE, 2); mmr_unlock(CTRL_MMR0_BASE, 4); - mmr_unlock(CTRL_MMR0_BASE, 5); mmr_unlock(CTRL_MMR0_BASE, 6); /* Unlock all MCU_CTRL_MMR0 module registers */ diff --git a/arch/arm/mach-k3/j722s/j722s_init.c b/arch/arm/mach-k3/j722s/j722s_init.c index d8123f282ee..1180c75f551 100644 --- a/arch/arm/mach-k3/j722s/j722s_init.c +++ b/arch/arm/mach-k3/j722s/j722s_init.c @@ -166,6 +166,8 @@ static void k3_mem_init(void) if (ret) panic("DRAM init failed: %d\n", ret); } + + spl_enable_cache(); } static __maybe_unused void enable_mcu_esm_reset(void) diff --git a/arch/arm/mach-mediatek/tzcfg.c b/arch/arm/mach-mediatek/tzcfg.c index 71982ba4d20..c8fe8ac0e9b 100644 --- a/arch/arm/mach-mediatek/tzcfg.c +++ b/arch/arm/mach-mediatek/tzcfg.c @@ -173,6 +173,7 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) int arch_misc_init(void) { + phys_addr_t addr; struct arm_smccc_res res; /* @@ -180,11 +181,14 @@ int arch_misc_init(void) * there's no need to check the result */ arm_smccc_smc(MTK_SIP_GET_BL31_REGION, 0, 0, 0, 0, 0, 0, 0, &res); - lmb_reserve(res.a1, res.a2, LMB_NOMAP); + addr = (phys_addr_t)res.a1; + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, res.a2, LMB_NOMAP); arm_smccc_smc(MTK_SIP_GET_BL32_REGION, 0, 0, 0, 0, 0, 0, 0, &res); + addr = (phys_addr_t)res.a1; if (!res.a0 && res.a1 && res.a2) - lmb_reserve(res.a1, res.a2, LMB_NOMAP); + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, res.a2, + LMB_NOMAP); #if IS_ENABLED(CONFIG_CMD_PSTORE) char cmd[64]; diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c index 99597076d2c..43d151708e4 100644 --- a/arch/arm/mach-rockchip/rk3399/rk3399.c +++ b/arch/arm/mach-rockchip/rk3399/rk3399.c @@ -16,6 +16,7 @@ #include <asm/arch-rockchip/gpio.h> #include <asm/arch-rockchip/grf_rk3399.h> #include <asm/arch-rockchip/hardware.h> +#include <asm/gpio.h> #include <linux/bitops.h> #include <linux/printk.h> #include <power/regulator.h> diff --git a/arch/arm/mach-snapdragon/board.c b/arch/arm/mach-snapdragon/board.c index 5547d6d054f..ec51ebbbe7f 100644 --- a/arch/arm/mach-snapdragon/board.c +++ b/arch/arm/mach-snapdragon/board.c @@ -37,6 +37,8 @@ DECLARE_GLOBAL_DATA_PTR; +enum qcom_boot_source qcom_boot_source __section(".data") = 0; + static struct mm_region rbx_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { { 0 } }; struct mm_region *mem_map = rbx_mem_map; @@ -238,6 +240,12 @@ int board_fdt_blob_setup(void **fdtp) if (ret < 0) panic("No valid memory ranges found!\n"); + /* If we have an external FDT, it can only have come from the Android bootloader. */ + if (external_valid) + qcom_boot_source = QCOM_BOOT_SOURCE_ANDROID; + else + qcom_boot_source = QCOM_BOOT_SOURCE_XBL; + debug("ram_base = %#011lx, ram_size = %#011llx\n", gd->ram_base, gd->ram_size); @@ -481,6 +489,23 @@ static void configure_env(void) qcom_set_serialno(); } +void qcom_show_boot_source(void) +{ + const char *name = "UNKNOWN"; + + switch (qcom_boot_source) { + case QCOM_BOOT_SOURCE_ANDROID: + name = "ABL"; + break; + case QCOM_BOOT_SOURCE_XBL: + name = "XBL"; + break; + } + + log_info("U-Boot loaded from %s\n", name); + env_set("boot_source", name); +} + void __weak qcom_late_init(void) { } @@ -492,38 +517,56 @@ void __weak qcom_late_init(void) #define FASTBOOT_BUF_SIZE 0 #endif -#define addr_alloc(size) lmb_alloc(size, SZ_2M) +#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) /* Stolen from arch/arm/mach-apple/board.c */ int board_late_init(void) { - u32 status = 0; + u32 status = 0, fdt_status = 0; phys_addr_t addr; struct fdt_header *fdt_blob = (struct fdt_header *)gd->fdt_blob; /* We need to be fairly conservative here as we support boards with just 1G of TOTAL RAM */ - addr = addr_alloc(SZ_128M); + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("loadaddr", addr) : 1; status |= env_set_hex("kernel_addr_r", addr); - status |= env_set_hex("loadaddr", addr); - status |= env_set_hex("ramdisk_addr_r", addr_alloc(SZ_128M)); - status |= env_set_hex("kernel_comp_addr_r", addr_alloc(KERNEL_COMP_SIZE)); - status |= env_set_hex("kernel_comp_size", KERNEL_COMP_SIZE); - if (IS_ENABLED(CONFIG_FASTBOOT)) - status |= env_set_hex("fastboot_addr_r", addr_alloc(FASTBOOT_BUF_SIZE)); - status |= env_set_hex("scriptaddr", addr_alloc(SZ_4M)); - status |= env_set_hex("pxefile_addr_r", addr_alloc(SZ_4M)); - addr = addr_alloc(SZ_2M); - status |= env_set_hex("fdt_addr_r", addr); - - if (status) + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("ramdisk_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_addr_r", addr) : 1; + status |= !lmb_alloc(KERNEL_COMP_SIZE, &addr) ? + env_set_hex("kernel_comp_size", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("scriptaddr", addr) : 1; + status |= !lmb_alloc(SZ_4M, &addr) ? + env_set_hex("pxefile_addr_r", addr) : 1; + + if (IS_ENABLED(CONFIG_FASTBOOT)) { + status |= !lmb_alloc(FASTBOOT_BUF_SIZE, &addr) ? + env_set_hex("fastboot_addr_r", addr) : 1; + /* override loadaddr for memory rich soc */ + status |= !lmb_alloc(SZ_128M, &addr) ? + env_set_hex("loadaddr", addr) : 1; + } + + fdt_status |= !lmb_alloc(SZ_2M, &addr) ? + env_set_hex("fdt_addr_r", addr) : 1; + + if (status || fdt_status) log_warning("%s: Failed to set run time variables\n", __func__); /* By default copy U-Boots FDT, it will be used as a fallback */ - memcpy((void *)addr, (void *)gd->fdt_blob, fdt32_to_cpu(fdt_blob->totalsize)); + if (fdt_status) + log_warning("%s: Failed to reserve memory for copying FDT\n", + __func__); + else + memcpy((void *)addr, (void *)gd->fdt_blob, + fdt32_to_cpu(fdt_blob->totalsize)); configure_env(); qcom_late_init(); + qcom_show_boot_source(); /* Configure the dfu_string for capsule updates */ qcom_configure_capsule_updates(); diff --git a/arch/arm/mach-snapdragon/capsule_update.c b/arch/arm/mach-snapdragon/capsule_update.c index bf75a9a1b24..4dced4961b6 100644 --- a/arch/arm/mach-snapdragon/capsule_update.c +++ b/arch/arm/mach-snapdragon/capsule_update.c @@ -20,22 +20,19 @@ #include "qcom-priv.h" /* - * NOTE: for now this implementation only supports the rb3gen2. Supporting other - * boards that boot in different ways (e.g. chainloaded from ABL) will require - * additional complexity to properly create the dfu string and fw_images array. - */ - -/* - * To handle different variants like chainloaded U-Boot here we'll need to - * build the fw_images array dynamically at runtime. It looks like - * mach-rockchip is a good example for how to do this. - * Detecting which image types a board uses is TBD, hence for now we only - * support the one new board that runs U-Boot as its primary bootloader. + * To handle different variants like chainloaded U-Boot here we need to + * build the fw_images array dynamically at runtime. These are the possible + * implementations: + * + * - Devices with U-Boot on the uefi_a/b partition + * - Devices with U-Boot on the boot (a/b) partition + * - Devices with U-Boot on the xbl (a/b) partition + * + * Which partition actually has U-Boot on it is determined based on the + * qcom_boot_source variable and additional logic in find_target_partition(). */ struct efi_fw_image fw_images[] = { { - /* U-Boot flashed to the uefi_X partition (e.g. rb3gen2) */ - .fw_name = u"UBOOT_UEFI_PARTITION", .image_index = 1, }, }; @@ -47,6 +44,12 @@ struct efi_capsule_update_info update_info = { .images = fw_images, }; +enum target_part_type { + TARGET_PART_UEFI = 1, + TARGET_PART_XBL, + TARGET_PART_BOOT, +}; + /* LSB first */ struct part_slot_status { u16: 2; @@ -57,35 +60,202 @@ struct part_slot_status { u16 tries_remaining : 4; }; -static int find_boot_partition(const char *partname, struct blk_desc *blk_dev, char *name) +enum ab_slot { + SLOT_NONE, + SLOT_A, + SLOT_B, +}; + +static enum ab_slot get_part_slot(const char *partname) +{ + int len = strlen(partname); + + if (partname[len - 2] != '_') + return SLOT_NONE; + if (partname[len - 1] == 'a') + return SLOT_A; + if (partname[len - 1] == 'b') + return SLOT_B; + + return SLOT_NONE; +} + +/* + * Determine which partition U-Boot is flashed to based on the boot source (ABL/XBL), + * the slot status, and prioritizing the uefi partition over xbl if found. + */ +static int find_target_partition(int *devnum, enum uclass_id *uclass, + enum target_part_type *target_part_type) { int ret; - int partnum; + int partnum, uefi_partnum = -1, xbl_partnum = -1; struct disk_partition info; struct part_slot_status *slot_status; + struct udevice *dev = NULL; + struct blk_desc *desc = NULL, *xbl_desc = NULL; + uchar ptn_name[32] = { 0 }; + bool have_ufs = false; + + /* + * Check to see if we have UFS storage, if so U-Boot MUST be on it and we can skip + * all non-UFS block devices + */ + uclass_foreach_dev_probe(UCLASS_UFS, dev) { + have_ufs = true; + break; + } - for (partnum = 1;; partnum++) { - ret = part_get_info(blk_dev, partnum, &info); - if (ret) - return ret; + uclass_foreach_dev_probe(UCLASS_BLK, dev) { + if (device_get_uclass_id(dev) != UCLASS_BLK) + continue; - slot_status = (struct part_slot_status *)&info.type_flags; - log_io("%16s: Active: %1d, Successful: %1d, Unbootable: %1d, Tries left: %1d\n", - info.name, slot_status->active, - slot_status->successful, slot_status->unbootable, - slot_status->tries_remaining); + /* If we have a UFS then don't look at any other block devices */ + if (have_ufs) { + if (device_get_uclass_id(dev->parent->parent) != UCLASS_UFS) + continue; /* - * FIXME: eventually we'll want to find the active/inactive variant of the partition - * but on the rb3gen2 these values might all be 0 + * If we don't have UFS, then U-Boot must be on the eMMC which is always the first + * MMC device. */ - if (!strncmp(info.name, partname, strlen(partname))) { - log_debug("Found active %s partition: '%s'!\n", partname, info.name); - strlcpy(name, info.name, sizeof(info.name)); - return partnum; + } else if (dev->parent->seq_ > 0) { + continue; } + + desc = dev_get_uclass_plat(dev); + if (!desc || desc->part_type == PART_TYPE_UNKNOWN) + continue; + for (partnum = 1;; partnum++) { + ret = part_get_info(desc, partnum, &info); + if (ret) + break; + + slot_status = (struct part_slot_status *)&info.type_flags; + + /* + * Qualcomm Linux devices have a "uefi" partition, it's A/B but the + * flags might not be set so we assume the A partition unless the B + * partition is active. + */ + if (!strncmp(info.name, "uefi", strlen("uefi"))) { + /* + * If U-Boot was chainloaded somehow we can't be flashed to + * the uefi partition + */ + if (qcom_boot_source != QCOM_BOOT_SOURCE_XBL) + continue; + + *target_part_type = TARGET_PART_UEFI; + /* + * Found an active UEFI partition, this is where U-Boot is + * flashed. + */ + if (slot_status->active) + goto found; + + /* Prefer A slot if it's not marked active */ + if (get_part_slot(info.name) == SLOT_A) { + /* + * If we found the A slot after the B slot (both + * inactive) then we assume U-Boot is on the A slot. + */ + if (uefi_partnum >= 0) + goto found; + + /* Didn't find the B slot yet */ + uefi_partnum = partnum; + strlcpy(ptn_name, info.name, 32); + } else { + /* + * Found inactive B slot after inactive A slot, return + * the A slot + */ + if (uefi_partnum >= 0) { + partnum = uefi_partnum; + goto found; + } + + /* + * Didn't find the A slot yet. Record that we found the + * B slot + */ + uefi_partnum = partnum; + strlcpy(ptn_name, info.name, 32); + } + /* xbl and aboot are effectively the same */ + } else if ((!strncmp(info.name, "xbl", strlen("xbl")) && + strlen(info.name) == 5) || + !strncmp(info.name, "aboot", strlen("aboot"))) { + /* + * If U-Boot was booted via ABL, we can't be flashed to the + * XBL partition + */ + if (qcom_boot_source != QCOM_BOOT_SOURCE_XBL) + continue; + + /* + * ignore xbl partition if we have uefi partitions, U-Boot will + * always be on the UEFI partition in this case. + */ + if (*target_part_type == TARGET_PART_UEFI) + continue; + + /* Either non-A/B or find the active XBL partition */ + if (slot_status->active || !get_part_slot(info.name)) { + /* + * No quick return since we might find a uefi partition + * later + */ + xbl_partnum = partnum; + *target_part_type = TARGET_PART_XBL; + xbl_desc = desc; + strlcpy(ptn_name, info.name, 32); + } + + /* + * No fast return since we might also have a uefi partition which + * will take priority. + */ + } else if (!strncmp(info.name, "boot", strlen("boot"))) { + /* We can only be flashed to boot if we were chainloaded */ + if (qcom_boot_source != QCOM_BOOT_SOURCE_ANDROID) + continue; + + /* + * Either non-A/B or find the active partition. We can return + * immediately here since we've narrowed it down to a single option + */ + if (slot_status->active || !get_part_slot(info.name)) { + *target_part_type = TARGET_PART_BOOT; + goto found; + } + } + } + } + + /* + * Now we've exhausted all options, if we didn't find a uefi partition + * then we are indeed flashed to the xbl partition. + */ + if (*target_part_type == TARGET_PART_XBL) { + partnum = xbl_partnum; + desc = xbl_desc; + goto found; } + /* Found no candidate partitions */ return -1; + +found: + if (desc) { + *devnum = desc->devnum; + *uclass = desc->uclass_id; + } + + /* info won't match for XBL hence the copy. */ + log_info("Capsule update target: %s (disk %d:%d)\n", + *target_part_type == TARGET_PART_BOOT ? info.name : ptn_name, + *devnum, partnum); + return partnum; } /** @@ -101,12 +271,10 @@ static int find_boot_partition(const char *partname, struct blk_desc *blk_dev, c */ void qcom_configure_capsule_updates(void) { - struct blk_desc *desc; int ret = 0, partnum = -1, devnum; static char dfu_string[32] = { 0 }; - char name[32]; /* GPT partition name */ - char *partname = "uefi_a"; - struct udevice *dev = NULL; + enum target_part_type target_part_type = 0; + enum uclass_id dev_uclass; if (IS_ENABLED(CONFIG_SCSI)) { /* Scan for SCSI devices */ @@ -117,26 +285,30 @@ void qcom_configure_capsule_updates(void) } } - uclass_foreach_dev_probe(UCLASS_BLK, dev) { - if (device_get_uclass_id(dev) != UCLASS_BLK) - continue; - - desc = dev_get_uclass_plat(dev); - if (!desc || desc->part_type == PART_TYPE_UNKNOWN) - continue; - devnum = desc->devnum; - partnum = find_boot_partition(partname, desc, - name); - if (partnum >= 0) - break; - } - + partnum = find_target_partition(&devnum, &dev_uclass, &target_part_type); if (partnum < 0) { log_err("Failed to find boot partition\n"); return; } - switch (desc->uclass_id) { + /* + * Set the fw_name based on the partition type. This causes the GUID to be different + * so we will never accidentally flash a U-Boot image intended for XBL to the boot + * partition. + */ + switch (target_part_type) { + case TARGET_PART_UEFI: + fw_images[0].fw_name = u"UBOOT_UEFI_PARTITION"; + break; + case TARGET_PART_XBL: + fw_images[0].fw_name = u"UBOOT_XBL_PARTITION"; + break; + case TARGET_PART_BOOT: + fw_images[0].fw_name = u"UBOOT_BOOT_PARTITION"; + break; + } + + switch (dev_uclass) { case UCLASS_SCSI: snprintf(dfu_string, 32, "scsi %d=u-boot.bin part %d", devnum, partnum); break; @@ -144,10 +316,10 @@ void qcom_configure_capsule_updates(void) snprintf(dfu_string, 32, "mmc 0=u-boot.bin part %d %d", devnum, partnum); break; default: - debug("Unsupported storage uclass: %d\n", desc->uclass_id); + debug("Unsupported storage uclass: %d\n", dev_uclass); return; } - log_debug("boot partition is %s, DFU string: '%s'\n", name, dfu_string); + log_debug("DFU string: '%s'\n", dfu_string); update_info.dfu_string = dfu_string; } diff --git a/arch/arm/mach-snapdragon/of_fixup.c b/arch/arm/mach-snapdragon/of_fixup.c index b398c6b7b9f..328c7812f30 100644 --- a/arch/arm/mach-snapdragon/of_fixup.c +++ b/arch/arm/mach-snapdragon/of_fixup.c @@ -99,19 +99,6 @@ static int fixup_qcom_dwc3(struct device_node *root, struct device_node *glue_np return ret; } - /* - * The RB1/2 boards only have a single USB controller and it's muxed between the type-C port - * and a USB hub. Since we can't do OTG in U-Boot properly we prefer to put it into host mode. - */ - if (of_device_is_compatible(root, "qcom,qrb4210-rb2", NULL, NULL) || - of_device_is_compatible(root, "qcom,qrb2210-rb1", NULL, NULL)) { - ret = of_write_prop(dwc3, "dr_mode", sizeof("host"), "host"); - if (ret) { - log_err("Failed to set 'dr_mode' property: %d\n", ret); - return ret; - } - } - return 0; } diff --git a/arch/arm/mach-snapdragon/qcom-priv.h b/arch/arm/mach-snapdragon/qcom-priv.h index 4f398e2ba37..b8bf574e8bb 100644 --- a/arch/arm/mach-snapdragon/qcom-priv.h +++ b/arch/arm/mach-snapdragon/qcom-priv.h @@ -3,6 +3,20 @@ #ifndef __QCOM_PRIV_H__ #define __QCOM_PRIV_H__ +/** + * enum qcom_boot_source - Track where we got loaded from. + * Used for capsule update logic. + * + * @QCOM_BOOT_SOURCE_ANDROID: chainloaded (typically from ABL) + * @QCOM_BOOT_SOURCE_XBL: flashed to the XBL or UEFI partition + */ +enum qcom_boot_source { + QCOM_BOOT_SOURCE_ANDROID = 1, + QCOM_BOOT_SOURCE_XBL, +}; + +extern enum qcom_boot_source qcom_boot_source; + #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT) void qcom_configure_capsule_updates(void); #else diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 17179593913..0a7c029b15a 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -51,7 +51,13 @@ config DRAM_SUN50I_H616 Select this dram controller driver for some sun50i platforms, like H616. -if DRAM_SUN50I_H616 +config DRAM_SUN50I_A133 + bool + help + Select this dram controller driver for some sun50i platforms, + like A133. + +if DRAM_SUN50I_H616 || DRAM_SUN50I_A133 config DRAM_SUNXI_DX_ODT hex "DRAM DX ODT parameter" help @@ -73,18 +79,64 @@ config DRAM_SUNXI_ODT_EN help ODT EN value from vendor DRAM settings. +config DRAM_SUNXI_PARA0 + hex "DRAM PARA0 parameter" + depends on DRAM_SUN50I_A133 + help + PARA0 value from vendor DRAM settings. + +config DRAM_SUNXI_MR11 + hex "DRAM MR11 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR11 value from vendor DRAM settings. + +config DRAM_SUNXI_MR12 + hex "DRAM MR12 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR12 value from vendor DRAM settings. + +config DRAM_SUNXI_MR13 + hex "DRAM MR13 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR13 value from vendor DRAM settings. + +config DRAM_SUNXI_MR14 + hex "DRAM MR14 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + MR14 value from vendor DRAM settings. + config DRAM_SUNXI_TPR0 hex "DRAM TPR0 parameter" default 0x0 help TPR0 value from vendor DRAM settings. +config DRAM_SUNXI_TPR1 + hex "DRAM TPR1 parameter" + default 0x0 + help + TPR1 value from vendor DRAM settings. + config DRAM_SUNXI_TPR2 hex "DRAM TPR2 parameter" default 0x0 help TPR2 value from vendor DRAM settings. +config DRAM_SUNXI_TPR3 + hex "DRAM TPR3 parameter" + default 0x0 + help + TPR3 value from vendor DRAM settings. + config DRAM_SUNXI_TPR6 hex "DRAM TPR6 parameter" default 0x3300c080 @@ -109,6 +161,20 @@ config DRAM_SUNXI_TPR12 help TPR12 value from vendor DRAM settings. +config DRAM_SUNXI_TPR13 + hex "DRAM TPR13 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + TPR13 value from vendor DRAM settings. + +config DRAM_SUNXI_TPR14 + hex "DRAM TPR14 parameter" + depends on DRAM_SUN50I_A133 + default 0x0 + help + TPR14 value from vendor DRAM settings. + choice prompt "DRAM PHY pin mapping selection" default DRAM_SUNXI_PHY_ADDR_MAP_0 @@ -116,7 +182,8 @@ choice config DRAM_SUNXI_PHY_ADDR_MAP_0 bool "DRAM PHY address map 0" help - This pin mapping selection should be used by the H313, H616, H618. + This pin mapping selection should be used by the H313, H616, H618, + and A133, R818 SoCs. config DRAM_SUNXI_PHY_ADDR_MAP_1 bool "DRAM PHY address map 1" @@ -153,6 +220,7 @@ config SUNXI_SRAM_ADDRESS config SUNXI_RVBAR_ADDRESS hex depends on ARM64 + default 0x08100040 if MACH_SUN50I_A133 default 0x09010040 if SUN50I_GEN_H6 default 0x017000a0 ---help--- @@ -179,8 +247,8 @@ config SUNXI_RVBAR_ALTERNATIVE config SUNXI_BL31_BASE hex default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5 - default 0x00104000 if MACH_SUN50I_H6 default 0x40000000 if MACH_SUN50I_H616 + default 0x00104000 if SUN50I_GEN_H6 default 0x0 help Address where BL31 (TF-A) is loaded, or zero if BL31 is not used. @@ -262,7 +330,7 @@ config MACH_SUNXI_H3_H5 # TODO: try out A80's 8GiB DRAM space config SUNXI_DRAM_MAX_SIZE hex - default 0x100000000 if MACH_SUN50I_H616 + default 0x100000000 if MACH_SUN50I_H616 || MACH_SUN50I_A133 default 0xC0000000 if MACH_SUN50I || MACH_SUN50I_H5 || MACH_SUN50I_H6 default 0x80000000 @@ -459,6 +527,10 @@ config MACH_SUN50I_H616 config MACH_SUN50I_A133 bool "sun50i (Allwinner A133)" + select ARM64 + select DRAM_SUN50I_A133 + select SUN50I_GEN_H6 + imply OF_UPSTREAM endchoice @@ -497,7 +569,7 @@ config ARM_BOOT_HOOK_RMR This allows both the SPL and the U-Boot proper to be entered in either mode and switch to AArch64 if needed. -if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 +if SUNXI_DRAM_DW || DRAM_SUN50I_H6 || DRAM_SUN50I_H616 || DRAM_SUN50I_A133 config SUNXI_DRAM_DDR3 bool @@ -510,6 +582,9 @@ config SUNXI_DRAM_LPDDR3 config SUNXI_DRAM_LPDDR4 bool +config SUNXI_DRAM_DDR4 + bool + choice prompt "DRAM Type and Timing" default SUNXI_DRAM_DDR3_1333 if !MACH_SUN8I_V3S @@ -518,6 +593,7 @@ choice config SUNXI_DRAM_DDR3_1333 bool "DDR3 1333" select SUNXI_DRAM_DDR3 + depends on !DRAM_SUN50I_A133 ---help--- This option is the original only supported memory type, which suits many H3/H5/A64 boards available now. @@ -525,6 +601,7 @@ config SUNXI_DRAM_DDR3_1333 config SUNXI_DRAM_LPDDR3_STOCK bool "LPDDR3 with Allwinner stock configuration" select SUNXI_DRAM_LPDDR3 + depends on !DRAM_SUN50I_A133 ---help--- This option is the LPDDR3 timing used by the stock boot0 by Allwinner. @@ -548,7 +625,7 @@ config SUNXI_DRAM_H6_DDR3_1333 config SUNXI_DRAM_H616_LPDDR3 bool "LPDDR3 DRAM chips on the H616 DRAM controller" select SUNXI_DRAM_LPDDR3 - depends on DRAM_SUN50I_H616 + depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133 help This option is the LPDDR3 timing used by the stock boot0 by Allwinner. @@ -556,7 +633,7 @@ config SUNXI_DRAM_H616_LPDDR3 config SUNXI_DRAM_H616_LPDDR4 bool "LPDDR4 DRAM chips on the H616 DRAM controller" select SUNXI_DRAM_LPDDR4 - depends on DRAM_SUN50I_H616 + depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133 help This option is the LPDDR4 timing used by the stock boot0 by Allwinner. @@ -564,11 +641,27 @@ config SUNXI_DRAM_H616_LPDDR4 config SUNXI_DRAM_H616_DDR3_1333 bool "DDR3-1333 boot0 timings on the H616 DRAM controller" select SUNXI_DRAM_DDR3 - depends on DRAM_SUN50I_H616 + depends on DRAM_SUN50I_H616 || DRAM_SUN50I_A133 help This option is the DDR3 timing used by the boot0 on H616 TV boxes which use a DDR3-1333 timing. +config SUNXI_DRAM_A133_DDR4 + bool "DDR4 boot0 timings on the A133 DRAM controller" + select SUNXI_DRAM_DDR4 + depends on DRAM_SUN50I_A133 + help + This option is the DDR4 timing used by the boot0 on A133 devices + which use a DDR4 timing. + +config SUNXI_DRAM_A133_LPDDR4 + bool "LPDDR4 boot0 timings on the A133 DRAM controller" + select SUNXI_DRAM_LPDDR4 + depends on DRAM_SUN50I_A133 + help + This option is the LPDDR4 timing used by the boot0 on A133 devices + which use an LPDDR4 timing. + config SUNXI_DRAM_DDR2_V3S bool "DDR2 found in V3s chip" select SUNXI_DRAM_DDR2 @@ -596,7 +689,7 @@ config DRAM_CLK MACH_SUN8I_V3S default 672 if MACH_SUN50I default 744 if MACH_SUN50I_H6 - default 720 if MACH_SUN50I_H616 + default 720 if MACH_SUN50I_H616 || MACH_SUN50I_A133 ---help--- Set the dram clock speed, valid range 240 - 480 (prior to sun9i), must be a multiple of 24. For the sun9i (A80), the tested values @@ -613,7 +706,7 @@ endif config DRAM_ZQ int "sunxi dram zq value" - depends on !MACH_SUN50I_H616 + depends on !MACH_SUN50I_H616 && !MACH_SUN50I_A133 default 123 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || \ MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_A83T default 127 if MACH_SUN7I @@ -733,6 +826,7 @@ config SYS_CONFIG_NAME default "sun50i" if MACH_SUN50I default "sun50i" if MACH_SUN50I_H6 default "sun50i" if MACH_SUN50I_H616 + default "sun50i" if MACH_SUN50I_A133 config SYS_BOARD default "sunxi" diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index a33cd5b0f07..8eff20b77bf 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -45,4 +45,6 @@ obj-$(CONFIG_DRAM_SUN50I_H6) += dram_sun50i_h6.o dram_dw_helpers.o obj-$(CONFIG_DRAM_SUN50I_H6) += dram_timings/ obj-$(CONFIG_DRAM_SUN50I_H616) += dram_sun50i_h616.o dram_dw_helpers.o obj-$(CONFIG_DRAM_SUN50I_H616) += dram_timings/ +obj-$(CONFIG_DRAM_SUN50I_A133) += dram_sun50i_a133.o +obj-$(CONFIG_DRAM_SUN50I_A133) += dram_timings/ endif diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index b1bf51f40c5..08d55b3a0e3 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -137,6 +137,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_H616_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_H616_GPH_UART0); sunxi_gpio_set_pull(SUNXI_GPH(1), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN50I_A133) + sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN50I_H616_GPH_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN50I_H616_GPH_UART0); + sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A83T) sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0); diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index 4c522f60810..3f375a51965 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -87,7 +87,8 @@ void clock_set_pll1(unsigned int clk) /* clk = 24*n/p, p is ignored if clock is >288MHz */ val = CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2; val |= CCM_PLL1_CTRL_N(clk / 24000000); - if (IS_ENABLED(CONFIG_MACH_SUN50I_H616)) + if (IS_ENABLED(CONFIG_MACH_SUN50I_H616) || + IS_ENABLED(CONFIG_MACH_SUN50I_A133)) val |= CCM_PLL1_OUT_EN; if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) val |= CCM_PLL1_OUT_EN | CCM_PLL1_LDO_EN; diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c index 310dca06e57..3f4735d4717 100644 --- a/arch/arm/mach-sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -104,6 +104,8 @@ int print_cpuinfo(void) puts("CPU: Allwinner H6 (SUN50I)\n"); #elif defined CONFIG_MACH_SUN50I_H616 puts("CPU: Allwinner H616 (SUN50I)\n"); +#elif defined CONFIG_MACH_SUN50I_A133 + puts("CPU: Allwinner A133 (SUN50I)\n"); #else #warning Please update cpu_info.c with correct CPU information puts("CPU: SUNXI Family\n"); diff --git a/arch/arm/mach-sunxi/dram_sun50i_a133.c b/arch/arm/mach-sunxi/dram_sun50i_a133.c new file mode 100644 index 00000000000..a0fca3738f4 --- /dev/null +++ b/arch/arm/mach-sunxi/dram_sun50i_a133.c @@ -0,0 +1,1204 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * sun50i A133 platform dram controller driver + * + * Controller and PHY appear to be quite similar to that of the H616; + * however certain offsets, timings, and other details are different enough that + * the original code does not work as expected. Some device flags and + * calibrations are not yet implemented, and configuration aside from DDR4 + * have not been tested. + * + * (C) Copyright 2024 MasterR3C0RD <masterr3c0rd@epochal.quest> + * + * Uses code from H616 driver, which is + * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net> + * + */ + +//#define DEBUG + +#include <asm/arch/clock.h> +#include <asm/arch/cpu.h> +#include <asm/arch/dram.h> +#include <asm/arch/prcm.h> +#include <asm/io.h> +#include <init.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <log.h> + +#ifdef CONFIG_DRAM_SUNXI_PHY_ADDR_MAP_1 +static const u8 phy_init[] = { +#ifdef CONFIG_SUNXI_DRAM_DDR3 + 0x0c, 0x08, 0x19, 0x18, 0x10, 0x06, 0x0a, 0x03, 0x0e, + 0x00, 0x0b, 0x05, 0x09, 0x1a, 0x04, 0x13, 0x16, 0x11, + 0x01, 0x15, 0x0d, 0x07, 0x12, 0x17, 0x14, 0x02, 0x0f +#elif CONFIG_SUNXI_DRAM_DDR4 + 0x19, 0x1a, 0x04, 0x12, 0x09, 0x06, 0x08, 0x0a, 0x16, + 0x17, 0x18, 0x0f, 0x0c, 0x13, 0x02, 0x05, 0x01, 0x11, + 0x0e, 0x00, 0x0b, 0x07, 0x03, 0x14, 0x15, 0x0d, 0x10 +#elif CONFIG_SUNXI_DRAM_LPDDR3 + 0x08, 0x03, 0x02, 0x00, 0x18, 0x19, 0x09, 0x01, 0x06, + 0x17, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x05, 0x07, 0x1a +#elif CONFIG_SUNXI_DRAM_LPDDR4 + 0x01, 0x05, 0x02, 0x00, 0x19, 0x03, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x04, 0x1a +#endif +}; +#else +static const u8 phy_init[] = { +#ifdef CONFIG_SUNXI_DRAM_DDR3 + 0x03, 0x19, 0x18, 0x02, 0x10, 0x15, 0x16, 0x07, 0x06, + 0x0e, 0x05, 0x08, 0x0d, 0x04, 0x17, 0x1a, 0x13, 0x11, + 0x12, 0x14, 0x00, 0x01, 0x0c, 0x0a, 0x09, 0x0b, 0x0f +#elif CONFIG_SUNXI_DRAM_DDR4 + 0x13, 0x17, 0x0e, 0x01, 0x06, 0x12, 0x14, 0x07, 0x09, + 0x02, 0x0f, 0x00, 0x0d, 0x05, 0x16, 0x0c, 0x0a, 0x11, + 0x04, 0x03, 0x18, 0x15, 0x08, 0x10, 0x0b, 0x19, 0x1a +#elif CONFIG_SUNXI_DRAM_LPDDR3 + 0x05, 0x06, 0x17, 0x02, 0x19, 0x18, 0x04, 0x07, 0x03, + 0x01, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x08, 0x09, 0x00, 0x1a +#elif CONFIG_SUNXI_DRAM_LPDDR4 + 0x01, 0x03, 0x02, 0x19, 0x17, 0x00, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x04, 0x18, 0x05, 0x1a +#endif +}; +#endif + +static void mctl_clk_init(u32 clk) +{ + void * const ccm = (void *)SUNXI_CCM_BASE; + + /* Place all DRAM blocks into reset */ + clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE); + clrbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET); + clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); + clrbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT)); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, CCM_PLL5_CTRL_EN); + clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET); + udelay(5); + + /* Set up PLL5 clock, used for DRAM */ + clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0xff03, + CCM_PLL5_CTRL_N((clk * 2) / 24) | CCM_PLL5_CTRL_EN); + setbits_le32(ccm + CCU_H6_PLL5_CFG, BIT(24)); + clrsetbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3, + CCM_PLL5_LOCK_EN | CCM_PLL5_CTRL_EN | BIT(30)); + clrbits_le32(ccm + CCU_H6_PLL5_CFG, 0x3 | BIT(30)); + mctl_await_completion(ccm + CCU_H6_PLL5_CFG, + CCM_PLL5_LOCK, CCM_PLL5_LOCK); + + /* Enable DRAM clock and gate*/ + clrbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, BIT(24) | BIT(25)); + clrsetbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, 0x1f, BIT(1) | BIT(0)); + setbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_CLK_UPDATE); + setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(RESET_SHIFT)); + setbits_le32(ccm + CCU_H6_DRAM_GATE_RESET, BIT(GATE_SHIFT)); + + /* Re-enable MBUS and reset the DRAM module */ + setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_RESET); + setbits_le32(ccm + CCU_H6_MBUS_CFG, MBUS_ENABLE); + setbits_le32(ccm + CCU_H6_DRAM_CLK_CFG, DRAM_MOD_RESET); + udelay(5); +} + +static void mctl_set_odtmap(const struct dram_para *para, + const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + u32 val, temp1, temp2; + + /* Set ODT/rank mappings*/ + if (config->bus_full_width) + writel_relaxed(0x0201, &mctl_ctl->odtmap); + else + writel_relaxed(0x0303, &mctl_ctl->odtmap); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = 0x06000400; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + /* TODO: What's the purpose of these values? */ + temp1 = para->clk * 7 / 2000; + if (para->clk < 400) + temp2 = 0x3; + else + temp2 = 0x4; + + val = 0x400 | (temp2 - temp1) << 16 | temp1 << 24; + break; + case SUNXI_DRAM_TYPE_DDR4: + /* MR4: CS to CMD / ADDR Latency and write preamble */ + val = 0x400 | (0x000 << 10 & 0x70000) | + (((0x0000 >> 12) & 1) + 6) << 24; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + val = 0x4000400; + break; + } + + writel_relaxed(val, &mctl_ctl->odtcfg); + /* Documented as ODTCFG_SHADOW */ + writel_relaxed(val, &mctl_ctl->unk_0x2240); + /* Offset's interesting; additional undocumented shadows? */ + writel_relaxed(val, &mctl_ctl->unk_0x3240); + writel_relaxed(val, &mctl_ctl->unk_0x4240); +} + +/* + * This function produces address mapping parameters, used internally by the + * controller to map address lines to HIF addresses. HIF addresses are word + * addresses, not byte addresses; + * In other words, DDR address 0x400 maps to HIF address 0x100. + * + * This implementation sets up a reasonable mapping where HIF address + * ordering (LSB->MSB) is as such: + * - Bank Groups + * - Columns + * - Banks + * - Rows + * - Ranks + * + * TODO: Handle 1.5GB + 3GB configurations. Info about these is stored in + * upper bits of TPR13 after autoscan in boot0, and then some extra logic + * happens in the address mapping + */ +#define INITIAL_HIF_OFFSET 3 + +static void mctl_set_addrmap(const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + u8 bankgrp_bits = config->bankgrps; + u8 col_bits = config->cols; + u8 bank_bits = config->banks; + u8 row_bits = config->rows; + u8 rank_bits = config->ranks; + + unsigned int i, hif_offset, hif_bits[6]; + + /* + * When the bus is half width, we need to adjust address mapping, + * as COL[0] will be reallocated as part of the byte address, + * offsetting the column address mapping values by 1 + */ + if (!config->bus_full_width) + col_bits--; + + /* Match boot0's DRAM requirements */ + if (bankgrp_bits > 2) + panic("invalid dram configuration (bankgrps_bits = %d)", + bankgrp_bits); + if (col_bits < 8 || col_bits > 12) + panic("invalid dram configuration (col_bits = %d)", col_bits); + + if (bank_bits < 2 || bank_bits > 3) + panic("invalid dram configuration (bank_bits = %d)", bank_bits); + + if (row_bits < 14 || row_bits > 18) + panic("invalid dram configuration (row_bits = %d)", row_bits); + + if (rank_bits > 1) + panic("invalid dram configuration (rank_bits = %d)", rank_bits); + + /* + * Col[0:1] + HIF[0:1] (hardwired), Col[2] = HIF[2] (required) + * Thus, we start allocating from HIF[3] onwards + */ + hif_offset = INITIAL_HIF_OFFSET; + + /* BG[bankgrp_bits:0] = HIF[3 + bankgrp_bits:3]*/ + switch (bankgrp_bits) { + case 0: + writel_relaxed(ADDRMAP8_BG0_B2(ADDRMAP_DISABLED_1F_B(2)) | + ADDRMAP8_BG1_B3(ADDRMAP_DISABLED_1F_B(3)), + &mctl_ctl->addrmap[8]); + break; + case 1: + writel_relaxed(ADDRMAP8_BG0_B2(hif_offset) | + ADDRMAP8_BG1_B3(ADDRMAP_DISABLED_1F_B(3)), + &mctl_ctl->addrmap[8]); + break; + case 2: + writel_relaxed(ADDRMAP8_BG0_B2(hif_offset) | + ADDRMAP8_BG1_B3(hif_offset + 1), + &mctl_ctl->addrmap[8]); + break; + default: + panic("invalid dram configuration (bankgrp_bits = %d)", + bankgrp_bits); + } + + hif_offset += bankgrp_bits; + + /* Col[2] = HIF[2], Col[5:3] = HIF[offset + 2:offset] */ + writel_relaxed(ADDRMAP2_COL2_B2(2) | ADDRMAP2_COL3_B3(hif_offset) | + ADDRMAP2_COL4_B4(hif_offset + 1) | + ADDRMAP2_COL5_B5(hif_offset + 2), + &mctl_ctl->addrmap[2]); + + /* Col[col_bits:6] = HIF[col_bits + offset - 3:offset - 3] */ + for (i = 6; i < 12; i++) { + if (i < col_bits) + hif_bits[i - 6] = hif_offset + (i - INITIAL_HIF_OFFSET); + else + hif_bits[i - 6] = ADDRMAP_DISABLED_1F_B(i); + } + + writel_relaxed(ADDRMAP3_COL6_B6(hif_bits[0]) | + ADDRMAP3_COL7_B7(hif_bits[1]) | + ADDRMAP3_COL8_B8(hif_bits[2]) | + ADDRMAP3_COL9_B9(hif_bits[3]), + &mctl_ctl->addrmap[3]); + + writel_relaxed(ADDRMAP4_COL10_B10(hif_bits[4]) | + ADDRMAP4_COL11_B11(hif_bits[5]), + &mctl_ctl->addrmap[4]); + + hif_offset = bankgrp_bits + col_bits; + + /* Bank[bank_bits:0] = HIF[bank_bits + offset:offset] */ + if (bank_bits == 3) + writel_relaxed(ADDRMAP1_BANK0_B2(hif_offset) | + ADDRMAP1_BANK1_B3(hif_offset + 1) | + ADDRMAP1_BANK2_B4(hif_offset + 2), + &mctl_ctl->addrmap[1]); + else + writel_relaxed(ADDRMAP1_BANK0_B2(hif_offset) | + ADDRMAP1_BANK1_B3(hif_offset + 1) | + ADDRMAP1_BANK2_B4(ADDRMAP_DISABLED_1F_B(4)), + &mctl_ctl->addrmap[1]); + + hif_offset += bank_bits; + + /* Row[11:0] = HIF[11 + offset:offset] */ + writel_relaxed(ADDRMAP5_ROW0_B6(hif_offset) | + ADDRMAP5_ROW1_B7(hif_offset + 1) | + ADDRMAP5_ROW2_10_B8(hif_offset + 2) | + ADDRMAP5_ROW11_B17(hif_offset + 11), + &mctl_ctl->addrmap[5]); + + /* + * There's some complexity here because of a special case + * in boot0 code that appears to work around a hardware bug. + * For (col_bits, row_bits, rank_bits) = (10, 16, 1), we have to + * place CS[0] in the position we would normally place ROW[14], + * and shift ROW[14] and ROW[15] over by one. Using the bit following + * ROW[15], as would be standard here, seems to cause nonsensical + * aliasing patterns. + * + * Aside from this case, mapping is simple: + * Row[row_bits:12] = HIF[offset + row_bits:offset + 12] + */ + for (i = 12; i < 18; i++) { + if (i >= row_bits) + hif_bits[i - 12] = ADDRMAP_DISABLED_0F_B(6 + i); + else if (rank_bits != 1 || col_bits != 10 || row_bits != 16 || + i < 14) + hif_bits[i - 12] = hif_offset + i; + else + hif_bits[i - 12] = hif_offset + i + 1; + } + + writel_relaxed(ADDRMAP6_ROW12_B18(hif_bits[0]) | + ADDRMAP6_ROW13_B19(hif_bits[1]) | + ADDRMAP6_ROW14_B20(hif_bits[2]) | + ADDRMAP6_ROW15_B21(hif_bits[3]), + &mctl_ctl->addrmap[6]); + + writel_relaxed(ADDRMAP7_ROW16_B22(hif_bits[4]) | + ADDRMAP7_ROW17_B23(hif_bits[5]), + &mctl_ctl->addrmap[7]); + + hif_offset += row_bits; + + /* + * Ranks + * Most cases: CS[0] = HIF[offset] + * Special case (see above): CS[0] = HIF[offset - 2] + */ + if (rank_bits == 0) + writel_relaxed(ADDRMAP0_CS0_B6(ADDRMAP_DISABLED_1F_B(6)), + &mctl_ctl->addrmap[0]); + else if (col_bits == 10 && row_bits == 16) + writel_relaxed(ADDRMAP0_CS0_B6(hif_offset - 2), + &mctl_ctl->addrmap[0]); + else + writel_relaxed(ADDRMAP0_CS0_B6(hif_offset), + &mctl_ctl->addrmap[0]); +} + +static void mctl_com_init(const struct dram_para *para, + const struct dram_config *config) +{ + void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + /* Might control power/reset of DDR-related blocks */ + clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(25) | BIT(9)); + + /* Unlock mctl_ctl registers */ + setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(15)); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + setbits_le32(0x03102ea8, BIT(0)); + + clrsetbits_le32(&mctl_ctl->sched[0], 0xff << 8, 0x30 << 8); + if (!(para->tpr13 & BIT(28))) + clrsetbits_le32(&mctl_ctl->sched[0], 0xf, BIT(0)); + + writel_relaxed(0, &mctl_ctl->hwlpctl); + + /* Master settings */ + u32 mstr_value = MSTR_DEVICECONFIG_X32 | + MSTR_ACTIVE_RANKS(config->ranks); + + if (config->bus_full_width) + mstr_value |= MSTR_BUSWIDTH_FULL; + else + mstr_value |= MSTR_BUSWIDTH_HALF; + + /* + * Geardown and 2T mode are always enabled here, but is controlled by a flag in boot0; + * it has not been a problem so far, but may be suspect if a particular board isn't booting. + */ + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + mstr_value |= MSTR_DEVICETYPE_DDR3 | MSTR_BURST_LENGTH(8) | + MSTR_2TMODE; + break; + case SUNXI_DRAM_TYPE_DDR4: + mstr_value |= MSTR_DEVICETYPE_DDR4 | MSTR_BURST_LENGTH(8) | + MSTR_GEARDOWNMODE | MSTR_2TMODE; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + mstr_value |= MSTR_DEVICETYPE_LPDDR3 | MSTR_BURST_LENGTH(8); + break; + case SUNXI_DRAM_TYPE_LPDDR4: + mstr_value |= MSTR_DEVICETYPE_LPDDR4 | MSTR_BURST_LENGTH(16); + break; + } + + writel_relaxed(mstr_value, &mctl_ctl->mstr); + + mctl_set_odtmap(para, config); + mctl_set_addrmap(config); + mctl_set_timing_params(para); + + dsb(); + writel(0, &mctl_ctl->pwrctl); + + /* Disable automatic controller updates + automatic controller update requests */ + setbits_le32(&mctl_ctl->dfiupd[0], BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->zqctl[0], BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x2180, BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x3180, BIT(31) | BIT(30)); + setbits_le32(&mctl_ctl->unk_0x4180, BIT(31) | BIT(30)); + + /* + * Data bus inversion + * Controlled by a flag in boot0, enabled by default here. + */ + if (para->type == SUNXI_DRAM_TYPE_DDR4 || + para->type == SUNXI_DRAM_TYPE_LPDDR4) + setbits_le32(&mctl_ctl->dbictl, BIT(2)); +} + +static void mctl_drive_odt_config(const struct dram_para *para) +{ + u32 val; + u64 base; + u32 i; + + /* DX drive */ + for (i = 0; i < 4; i++) { + base = SUNXI_DRAM_PHY0_BASE + 0x388 + 0x40 * i; + val = (para->dx_dri >> (i * 8)) & 0x1f; + + writel_relaxed(val, base); + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) { + if (para->tpr3 & 0x1f1f1f1f) + val = (para->tpr3 >> (i * 8)) & 0x1f; + else + val = 4; + } + writel_relaxed(val, base + 4); + } + + /* CA drive */ + for (i = 0; i < 2; i++) { + base = SUNXI_DRAM_PHY0_BASE + 0x340 + 0x8 * i; + val = (para->ca_dri >> (i * 8)) & 0x1f; + + writel_relaxed(val, base); + writel_relaxed(val, base + 4); + } + + /* DX ODT */ + for (i = 0; i < 4; i++) { + base = SUNXI_DRAM_PHY0_BASE + 0x380 + 0x40 * i; + val = (para->dx_odt >> (i * 8)) & 0x1f; + + if (para->type == SUNXI_DRAM_TYPE_DDR4 || + para->type == SUNXI_DRAM_TYPE_LPDDR3) + writel_relaxed(0, base); + else + writel_relaxed(val, base); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + writel_relaxed(0, base + 4); + else + writel_relaxed(val, base + 4); + } + dsb(); +} + +static void mctl_phy_ca_bit_delay_compensation(const struct dram_para *para) +{ + u32 val, i; + u32 *ptr; + + if (para->tpr10 & BIT(31)) { + val = para->tpr2; + } else { + val = ((para->tpr10 << 1) & 0x1e) | + ((para->tpr10 << 5) & 0x1e00) | + ((para->tpr10 << 9) & 0x1e0000) | + ((para->tpr10 << 13) & 0x1e000000); + + if (para->tpr10 >> 29 != 0) + val <<= 1; + } + + ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x780); + for (i = 0; i < 32; i++) + writel_relaxed((val >> 8) & 0x3f, &ptr[i]); + + writel_relaxed(val & 0x3f, SUNXI_DRAM_PHY0_BASE + 0x7dc); + writel_relaxed(val & 0x3f, SUNXI_DRAM_PHY0_BASE + 0x7e0); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x7b8); + writel_relaxed((val >> 24) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x784); + break; + case SUNXI_DRAM_TYPE_DDR4: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x784); + break; + case SUNXI_DRAM_TYPE_LPDDR3: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x788); + writel_relaxed((val >> 24) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x790); + break; + case SUNXI_DRAM_TYPE_LPDDR4: + writel_relaxed((val >> 16) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x790); + writel_relaxed((val >> 24) & 0x3f, + SUNXI_DRAM_PHY0_BASE + 0x78c); + break; + } + + dsb(); +} + +static void mctl_phy_init(const struct dram_para *para, + const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + void *const prcm = (void *)SUNXI_PRCM_BASE; + void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + + u32 val, val2, i; + u32 *ptr; + + /* Disable auto refresh. */ + setbits_le32(&mctl_ctl->rfshctl3, BIT(0)); + + /* Set "phy_dbi_mode" to mark the DFI as implementing DBI functionality */ + writel_relaxed(0, &mctl_ctl->pwrctl); + clrbits_le32(&mctl_ctl->dfimisc, 1); + writel_relaxed(0x20, &mctl_ctl->pwrctl); + + /* PHY cold reset */ + clrsetbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24), BIT(9)); + udelay(1); + setbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(24)); + + /* Not sure what this gates the power of. */ + clrbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, BIT(4)); + + if (para->type == SUNXI_DRAM_TYPE_LPDDR4) + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, BIT(7)); + + /* Note: Similar enumeration of values is used during read training */ + if (config->bus_full_width) + val = 0xf; + else + val = 0x3; + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x3c, 0xf, val); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = 13; + val2 = 9; + break; + case SUNXI_DRAM_TYPE_DDR4: + val = 13; + val2 = 10; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + val = 14; + val2 = 8; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + if (para->tpr13 & BIT(28)) + val = 22; + else + val = 20; + + val2 = 10; + break; + } + + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x14); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x35c); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x368); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x374); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x18); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x360); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x36c); + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x378); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x1c); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x364); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x370); + writel_relaxed(val2, SUNXI_DRAM_PHY0_BASE + 0x37c); + + /* Set up SDQ swizzle */ + ptr = (u32 *)(SUNXI_DRAM_PHY0_BASE + 0xc0); + for (i = 0; i < ARRAY_SIZE(phy_init); i++) + writel_relaxed(phy_init[i], &ptr[i]); + + /* Set VREF */ + val = 0; + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = para->tpr6 & 0xff; + if (val == 0) + val = 0x80; + break; + case SUNXI_DRAM_TYPE_DDR4: + val = (para->tpr6 >> 8) & 0xff; + if (val == 0) + val = 0x80; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + val = (para->tpr6 >> 16) & 0xff; + if (val == 0) + val = 0x80; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + val = (para->tpr6 >> 24) & 0xff; + if (val == 0) + val = 0x33; + break; + } + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3dc); + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x45c); + + mctl_drive_odt_config(para); + + if (para->tpr10 & TPR10_CA_BIT_DELAY) + mctl_phy_ca_bit_delay_compensation(para); + + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + val = 2; + break; + case SUNXI_DRAM_TYPE_LPDDR3: + val = 3; + break; + case SUNXI_DRAM_TYPE_DDR4: + val = 4; + break; + case SUNXI_DRAM_TYPE_LPDDR4: + val = 5; + break; + } + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, 0x7, val | 8); + + if (para->clk <= 672) + writel_relaxed(0xf, SUNXI_DRAM_PHY0_BASE + 0x20); + + if (para->clk > 500) { + val = 0; + val2 = 0; + } else { + val = 0x80; + val2 = 0x20; + } + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x144, 0x80, val); + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, 0xe0, val2); + + dsb(); + clrbits_le32(mctl_com + MCTL_COM_UNK_008, BIT(9)); + udelay(1); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x14c, BIT(3)); + + mctl_await_completion((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x180), BIT(2), + BIT(2)); + + /* + * This delay is controlled by a tpr13 flag in boot0; doesn't hurt + * to always do it though. + */ + udelay(1000); + writel(0x37, SUNXI_DRAM_PHY0_BASE + 0x58); + + setbits_le32(prcm + CCU_PRCM_SYS_PWROFF_GATING, BIT(4)); +} + +/* Helpers for updating mode registers */ +static inline void mctl_mr_write(u32 mrctrl0, u32 mrctrl1) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + writel(mrctrl1, &mctl_ctl->mrctrl1); + writel(mrctrl0 | MRCTRL0_MR_WR | MRCTRL0_MR_RANKS_ALL, + &mctl_ctl->mrctrl0); + mctl_await_completion(&mctl_ctl->mrctrl0, MRCTRL0_MR_WR, 0); +} + +static inline void mctl_mr_write_lpddr4(u8 addr, u8 value) +{ + mctl_mr_write(0, MRCTRL1_MR_ADDR(addr) | MRCTRL1_MR_DATA(value)); +} + +static inline void mctl_mr_write_lpddr3(u8 addr, u8 value) +{ + /* Bit [7:6] are set by boot0, but undocumented */ + mctl_mr_write(BIT(6) | BIT(7), + MRCTRL1_MR_ADDR(addr) | MRCTRL1_MR_DATA(value)); +} + +static void mctl_dfi_init(const struct dram_para *para) +{ + void *const mctl_com = (void *)SUNXI_DRAM_COM_BASE; + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + /* Unlock DFI registers? */ + setbits_le32(mctl_com + MCTL_COM_MAER0, BIT(8)); + + /* Enable dfi_init_complete signal and trigger PHY init start request */ + writel_relaxed(0, &mctl_ctl->swctl); + setbits_le32(&mctl_ctl->dfimisc, BIT(0)); + setbits_le32(&mctl_ctl->dfimisc, BIT(5)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + + /* Stop sending init request and wait for DFI initialization to complete. */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->dfimisc, BIT(5)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + mctl_await_completion(&mctl_ctl->dfistat, BIT(0), BIT(0)); + + /* Enter Software Exit from Self Refresh */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->pwrctl, BIT(5)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + mctl_await_completion(&mctl_ctl->statr, 0x3, 1); + + udelay(200); + + /* Disable dfi_init_complete signal */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->dfimisc, BIT(0)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + + /* Write mode registers, fixed in the JEDEC spec */ + switch (para->type) { + case SUNXI_DRAM_TYPE_DDR3: + mctl_mr_write(MRCTRL0_MR_ADDR(0), 0x1c70); /* MR0 */ + /* + * outbuf en, TDQs dis, write leveling dis, out drv 40 Ohms, + * DLL en, Rtt_nom 120 Ohms + */ + mctl_mr_write(MRCTRL0_MR_ADDR(1), 0x40); /* MR1 */ + /* + * full array self-ref, CAS: 8 cyc, SRT w/ norm temp range, + * dynamic ODT off + */ + mctl_mr_write(MRCTRL0_MR_ADDR(2), 0x18); /* MR2 */ + /* predef MPR pattern */ + mctl_mr_write(MRCTRL0_MR_ADDR(3), 0); /* MR3 */ + break; + case SUNXI_DRAM_TYPE_DDR4: + mctl_mr_write(MRCTRL0_MR_ADDR(0), 0x840); + mctl_mr_write(MRCTRL0_MR_ADDR(1), 0x601); + mctl_mr_write(MRCTRL0_MR_ADDR(2), 0x8); + mctl_mr_write(MRCTRL0_MR_ADDR(3), 0); + mctl_mr_write(MRCTRL0_MR_ADDR(4), 0); + mctl_mr_write(MRCTRL0_MR_ADDR(5), 0x400); + + mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 | BIT(7)); + mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 | BIT(7)); + mctl_mr_write(MRCTRL0_MR_ADDR(6), 0x862 & (~BIT(7))); + break; + case SUNXI_DRAM_TYPE_LPDDR3: + mctl_mr_write_lpddr3(1, 0xc3); /* MR1: nWR=8, BL8 */ + mctl_mr_write_lpddr3(2, 0xa); /* MR2: RL=12, WL=6 */ + mctl_mr_write_lpddr3(3, 0x2); /* MR3: 40 0hms PD/PU */ + mctl_mr_write_lpddr3(11, para->mr11); + break; + case SUNXI_DRAM_TYPE_LPDDR4: + mctl_mr_write_lpddr4(0, 0); /* MR0 */ + mctl_mr_write_lpddr4(1, 0x34); /* MR1 */ + mctl_mr_write_lpddr4(2, 0x1b); /* MR2 */ + mctl_mr_write_lpddr4(3, 0x33); /* MR3 */ + mctl_mr_write_lpddr4(4, 0x3); /* MR4 */ + mctl_mr_write_lpddr4(11, para->mr11); + mctl_mr_write_lpddr4(12, para->mr12); + mctl_mr_write_lpddr4(13, para->mr13); + mctl_mr_write_lpddr4(14, para->mr14); + mctl_mr_write_lpddr4(22, para->tpr1); + break; + } + + writel(0, SUNXI_DRAM_PHY0_BASE + 0x54); + + /* Re-enable controller refresh */ + writel(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->rfshctl3, BIT(0)); + writel(1, &mctl_ctl->swctl); +} + +/* Slightly modified from H616 driver */ +static bool mctl_phy_read_calibration(const struct dram_config *config) +{ + bool result = true; + u32 val, tmp; + + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x20); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + + if (config->bus_full_width) + val = 0xf; + else + val = 3; + + while ((readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & val) != val) { + if (readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & 0x20) { + result = false; + break; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30); + + if (config->ranks == 1) { + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30, 0x10); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + + while ((readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & val) != + val) { + if (readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x184) & + 0x20) { + result = false; + break; + } + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 1); + } + + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 8, 0x30); + + val = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x274) & 7; + tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x26c) & 7; + if (val < tmp) + val = tmp; + tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x32c) & 7; + if (val < tmp) + val = tmp; + tmp = readl_relaxed(SUNXI_DRAM_PHY0_BASE + 0x334) & 7; + if (val < tmp) + val = tmp; + clrsetbits_le32(SUNXI_DRAM_PHY0_BASE + 0x38, 0x7, (val + 2) & 7); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 4, 0x20); + + return result; +} + +static inline void mctl_phy_dx_delay1_inner(u32 *base, u32 val1, u32 val2) +{ + u32 *ptr = base; + + for (int i = 0; i < 9; i++) { + writel_relaxed(val1, ptr); + writel_relaxed(val1, ptr + 0x30); + ptr += 2; + } + + writel_relaxed(val2, ptr + 1); + writel_relaxed(val2, ptr + 49); + writel_relaxed(val2, ptr); + writel_relaxed(val2, ptr + 48); +} + +static inline void mctl_phy_dx_delay0_inner(u32 *base1, u32 *base2, u32 val1, + u32 val2) +{ + u32 *ptr = base1; + + for (int i = 0; i < 9; i++) { + writel_relaxed(val1, ptr); + writel_relaxed(val1, ptr + 0x30); + ptr += 2; + } + + writel_relaxed(val2, base2); + writel_relaxed(val2, base2 + 48); + writel_relaxed(val2, ptr); + writel_relaxed(val2, base2 + 44); +} + +/* + * This might be somewhat transferable to H616; whether or not people like + * the design is another question + */ +static void mctl_phy_dx_delay_compensation(const struct dram_para *para) +{ + if (para->tpr10 & TPR10_DX_BIT_DELAY1) { + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1); + setbits_le32(SUNXI_DRAM_PHY0_BASE + 8, BIT(3)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, BIT(4)); + + if (para->type == SUNXI_DRAM_TYPE_DDR4) + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x4, BIT(7)); + + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x484), + para->tpr11 & 0x3f, + para->para0 & 0x3f); + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d8), + (para->tpr11 >> 8) & 0x3f, + (para->para0 >> 8) & 0x3f); + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x604), + (para->tpr11 >> 16) & 0x3f, + (para->para0 >> 16) & 0x3f); + mctl_phy_dx_delay1_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x658), + (para->tpr11 >> 24) & 0x3f, + (para->para0 >> 24) & 0x3f); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, 1); + } + + if (para->tpr10 & TPR10_DX_BIT_DELAY0) { + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x190, BIT(2)); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x480), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528), + para->tpr12 & 0x3f, + para->tpr14 & 0x3f); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x4d4), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x52c), + (para->tpr12 >> 8) & 0x3f, + (para->tpr14 >> 8) & 0x3f); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x600), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6a8), + (para->tpr12 >> 16) & 0x3f, + (para->tpr14 >> 16) & 0x3f); + + mctl_phy_dx_delay0_inner((u32 *)(SUNXI_DRAM_PHY0_BASE + 0x6ac), + (u32 *)(SUNXI_DRAM_PHY0_BASE + 0x528), + (para->tpr12 >> 24) & 0x3f, + (para->tpr14 >> 24) & 0x3f); + + setbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, BIT(7)); + } +} + +static bool mctl_calibrate_phy(const struct dram_para *para, + const struct dram_config *config) +{ + struct sunxi_mctl_ctl_reg *mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + int i; + + /* TODO: Implement write levelling */ + if (para->tpr10 & TPR10_READ_CALIBRATION) { + for (i = 0; i < 5; i++) + if (mctl_phy_read_calibration(config)) + break; + if (i == 5) { + debug("read calibration failed\n"); + return false; + } + } + + /* TODO: Implement read training */ + /* TODO: Implement write training */ + + mctl_phy_dx_delay_compensation(para); + /* TODO: Implement DFS */ + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x60, BIT(0)); + clrbits_le32(SUNXI_DRAM_PHY0_BASE + 0x54, 7); + + /* Q: Does self-refresh get disabled by a calibration? */ + writel_relaxed(0, &mctl_ctl->swctl); + clrbits_le32(&mctl_ctl->rfshctl3, BIT(1)); + writel_relaxed(1, &mctl_ctl->swctl); + mctl_await_completion(&mctl_ctl->swstat, BIT(0), BIT(0)); + + return true; +} + +static bool mctl_core_init(const struct dram_para *para, + const struct dram_config *config) +{ + mctl_clk_init(para->clk); + mctl_com_init(para, config); + mctl_phy_init(para, config); + mctl_dfi_init(para); + + return mctl_calibrate_phy(para, config); +} + +/* Heavily inspired from H616 driver. */ +static void auto_detect_ranks(const struct dram_para *para, + struct dram_config *config) +{ + int i; + + config->cols = 9; + config->rows = 14; + config->banks = 2; + config->bankgrps = 0; + + /* Test ranks */ + for (i = 1; i >= 0; i--) { + config->ranks = i; + config->bus_full_width = true; + debug("Testing ranks = %d, 32-bit bus: ", i); + if (mctl_core_init(para, config)) { + debug("OK\n"); + break; + } + + config->bus_full_width = false; + debug("Testing ranks = %d, 16-bit bus: ", i); + if (mctl_core_init(para, config)) { + debug("OK\n"); + break; + } + } + + if (i < 0) + debug("rank testing failed\n"); +} + +static void mctl_write_pattern(void) +{ + unsigned int i; + u32 *ptr, val; + + ptr = (u32 *)CFG_SYS_SDRAM_BASE; + for (i = 0; i < 16; ptr++, i++) { + if (i & 1) + val = ~(ulong)ptr; + else + val = (ulong)ptr; + writel(val, ptr); + } +} + +static bool mctl_check_pattern(ulong offset) +{ + unsigned int i; + u32 *ptr, val; + + ptr = (u32 *)CFG_SYS_SDRAM_BASE; + for (i = 0; i < 16; ptr++, i++) { + if (i & 1) + val = ~(ulong)ptr; + else + val = (ulong)ptr; + if (val != *(ptr + offset / 4)) + return false; + } + + return true; +} + +static void mctl_auto_detect_dram_size(const struct dram_para *para, + struct dram_config *config) +{ + unsigned int shift; + u32 buffer[16]; + + /* max config for bankgrps on DDR4, minimum for everything else */ + config->cols = 8; + config->banks = 2; + config->rows = 14; + + shift = 1 + config->bus_full_width; + if (para->type == SUNXI_DRAM_TYPE_DDR4) { + config->bankgrps = 2; + mctl_core_init(para, config); + + /* store content so it can be restored later. */ + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + if (mctl_check_pattern(1ULL << (shift + 4))) + config->bankgrps = 1; + + /* restore data */ + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); + } else { + /* No bank groups in (LP)DDR3/LPDDR4 */ + config->bankgrps = 0; + } + + /* reconfigure to make sure all active columns are accessible */ + config->cols = 12; + mctl_core_init(para, config); + + /* store data again as it might be moved */ + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + /* + * Detect column address bits. The last number of columns checked + * is 11, if that doesn't match, is must be 12, no more checks needed. + */ + shift = 1 + config->bus_full_width + config->bankgrps; + for (config->cols = 8; config->cols < 12; config->cols++) { + if (mctl_check_pattern(1ULL << (config->cols + shift))) + break; + } + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); + + /* reconfigure to make sure that all active banks are accessible */ + config->banks = 3; + mctl_core_init(para, config); + + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + /* detect bank bits */ + shift += config->cols; + for (config->banks = 2; config->banks < 3; config->banks++) { + if (mctl_check_pattern(1ULL << (config->banks + shift))) + break; + } + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); + + /* reconfigure to make sure that all active rows are accessible */ + config->rows = 18; + mctl_core_init(para, config); + + memcpy(buffer, (u32 *)CFG_SYS_SDRAM_BASE, sizeof(buffer)); + mctl_write_pattern(); + + /* detect row address bits */ + shift += config->banks; + for (config->rows = 14; config->rows < 18; config->rows++) { + if (mctl_check_pattern(1ULL << (config->rows + shift))) + break; + } + memcpy((u32 *)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer)); +} + +/* Modified from H616 driver to add banks and bank groups */ +static unsigned long calculate_dram_size(const struct dram_config *config) +{ + /* Bootrom only uses x32 or x16 bus widths */ + u8 width = config->bus_full_width ? 4 : 2; + + return (1ULL << (config->cols + config->rows + config->banks + + config->bankgrps)) * + width * (1ULL << config->ranks); +} + +static const struct dram_para para = { + .clk = CONFIG_DRAM_CLK, +#ifdef CONFIG_SUNXI_DRAM_DDR3 + .type = SUNXI_DRAM_TYPE_DDR3, +#elif defined(CONFIG_SUNXI_DRAM_DDR4) + .type = SUNXI_DRAM_TYPE_DDR4, +#elif defined(CONFIG_SUNXI_DRAM_LPDDR3) + .type = SUNXI_DRAM_TYPE_LPDDR3, +#elif defined(CONFIG_SUNXI_DRAM_LPDDR4) + .type = SUNXI_DRAM_TYPE_LPDDR4, +#endif + /* TODO: Populate from config */ + .dx_odt = CONFIG_DRAM_SUNXI_DX_ODT, + .dx_dri = CONFIG_DRAM_SUNXI_DX_DRI, + .ca_dri = CONFIG_DRAM_SUNXI_CA_DRI, + .para0 = CONFIG_DRAM_SUNXI_PARA0, + .mr11 = CONFIG_DRAM_SUNXI_MR11, + .mr12 = CONFIG_DRAM_SUNXI_MR12, + .mr13 = CONFIG_DRAM_SUNXI_MR13, + .mr14 = CONFIG_DRAM_SUNXI_MR14, + .tpr1 = CONFIG_DRAM_SUNXI_TPR1, + .tpr2 = CONFIG_DRAM_SUNXI_TPR2, + .tpr3 = CONFIG_DRAM_SUNXI_TPR3, + .tpr6 = CONFIG_DRAM_SUNXI_TPR6, + .tpr10 = CONFIG_DRAM_SUNXI_TPR10, + .tpr11 = CONFIG_DRAM_SUNXI_TPR11, + .tpr12 = CONFIG_DRAM_SUNXI_TPR12, + .tpr13 = CONFIG_DRAM_SUNXI_TPR13, + .tpr14 = CONFIG_DRAM_SUNXI_TPR14, +}; + +unsigned long sunxi_dram_init(void) +{ + struct dram_config config; + + /* Writing to undocumented SYS_CFG area, according to user manual. */ + setbits_le32(0x03000160, BIT(8)); + clrbits_le32(0x03000168, 0x3f); + + auto_detect_ranks(¶, &config); + mctl_auto_detect_dram_size(¶, &config); + + if (!mctl_core_init(¶, &config)) + return 0; + + debug("cols = 2^%d, rows = 2^%d, banks = %d, bank groups = %d, ranks = %d, width = %d\n", + config.cols, config.rows, 1U << config.banks, + 1U << config.bankgrps, 1U << config.ranks, + 16U << config.bus_full_width); + + return calculate_dram_size(&config); +} diff --git a/arch/arm/mach-sunxi/dram_timings/Makefile b/arch/arm/mach-sunxi/dram_timings/Makefile index 5f203419240..4dc1f29fc08 100644 --- a/arch/arm/mach-sunxi/dram_timings/Makefile +++ b/arch/arm/mach-sunxi/dram_timings/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_SUNXI_DRAM_H6_DDR3_1333) += h6_ddr3_1333.o obj-$(CONFIG_SUNXI_DRAM_H616_DDR3_1333) += h616_ddr3_1333.o obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR3) += h616_lpddr3.o obj-$(CONFIG_SUNXI_DRAM_H616_LPDDR4) += h616_lpddr4_2133.o +obj-$(CONFIG_SUNXI_DRAM_A133_DDR4) += a133_ddr4.o +obj-$(CONFIG_SUNXI_DRAM_A133_LPDDR4) += a133_lpddr4.o diff --git a/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c b/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c new file mode 100644 index 00000000000..dec208e22df --- /dev/null +++ b/arch/arm/mach-sunxi/dram_timings/a133_ddr4.c @@ -0,0 +1,80 @@ +#include <asm/arch/cpu.h> +#include <asm/arch/dram.h> + +void mctl_set_timing_params(const struct dram_para *para) +{ + struct sunxi_mctl_ctl_reg *const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + u8 txsr = 4; + u8 tccd = 3; + u8 rd2wr = 5; + u8 tmrd = 4; + u8 tmrw = 0; + u8 wrlat = 5; + u8 rdlat = 7; + u8 wr2pre = 14; + u8 dfi_tphy_wrlat = 6; + u8 dfi_trddata_en = 10; + + u8 tfaw = ns_to_t(35); + u8 trrd = max(ns_to_t(8), 2); + u8 txp = max(ns_to_t(6), 2); + u8 tmrd_pda = max(ns_to_t(10), 8); + u8 trp = ns_to_t(15); + u8 trc = ns_to_t(49); + u8 wr2rd_s = max(ns_to_t(3), 1) + 7; + u8 tras_min = ns_to_t(34); + u16 trefi_x32 = ns_to_t(7800) / 32; + u16 trfc_min = ns_to_t(350); + u16 txs_x32 = ns_to_t(360) / 32; + u16 tmod = max(ns_to_t(15), 12); + u8 tcke = max(ns_to_t(5), 2); + u8 tcksrx = max(ns_to_t(10), 3); + u8 txs_abort_x32 = ns_to_t(170) / 32; + u8 tras_max = ns_to_t(70200) / 1024; + + u8 rd2pre = (trp < 5 ? 9 - trp : 4); + u8 wr2rd = trrd + 7; + u8 tckesr = tcke + 1; + u8 trcd = trp; + u8 trrd_s = txp; + u8 tcksre = tcksrx; + + writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24, + &mctl_ctl->dramtmg[0]); + writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]); + writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24, + &mctl_ctl->dramtmg[2]); + writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]); + writel(trp | trrd << 8 | tccd << 16 | trcd << 24, + &mctl_ctl->dramtmg[4]); + writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24, + &mctl_ctl->dramtmg[5]); + writel((txp + 2) | 0x20 << 16 | 0x20 << 24, + &mctl_ctl->dramtmg[6]); + writel(txs_x32 | 0x10 << 8 | txs_abort_x32 << 16 | txs_abort_x32 << 24, + &mctl_ctl->dramtmg[8]); + writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]); + writel(0xe0c05, &mctl_ctl->dramtmg[10]); + writel(0x440c021c, &mctl_ctl->dramtmg[11]); + writel(tmrd_pda, &mctl_ctl->dramtmg[12]); + writel(0xa100002, &mctl_ctl->dramtmg[13]); + writel(txsr, &mctl_ctl->dramtmg[14]); + + clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008); + writel(0x1f20000, &mctl_ctl->init[1]); + clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05); + writel(0, &mctl_ctl->dfimisc); + + writel(0x840 << 16 | 0x601, &mctl_ctl->init[3]); /* MR0 / MR1 */ + writel(0x8 << 16 | 0x0, &mctl_ctl->init[4]); /* MR2 / MR3 */ + writel(0x0 << 16 | 0x400, &mctl_ctl->init[6]); /* MR4 / MR5 */ + writel(0x826, &mctl_ctl->init[7]); /* MR6 */ + + clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660); + writel((dfi_tphy_wrlat - 1) | 0x2000000 | (dfi_trddata_en - 1) << 16 | + 0x808000, &mctl_ctl->dfitmg0); + writel(0x100202, &mctl_ctl->dfitmg1); + writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg); +} diff --git a/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c b/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c new file mode 100644 index 00000000000..1e607381023 --- /dev/null +++ b/arch/arm/mach-sunxi/dram_timings/a133_lpddr4.c @@ -0,0 +1,102 @@ +#include <asm/arch/cpu.h> +#include <asm/arch/dram.h> + +void mctl_set_timing_params(const struct dram_para *para) +{ + struct sunxi_mctl_ctl_reg *const mctl_ctl = + (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; + + bool tpr13_flag1 = para->tpr13 & BIT(28); + bool tpr13_flag2 = para->tpr13 & BIT(3); + bool tpr13_flag3 = para->tpr13 & BIT(5); + + u8 tccd = 4; + u8 tfaw = ns_to_t(40); + u8 trrd = max(ns_to_t(10), 2); + u8 trcd = max(ns_to_t(18), 2); + u8 trc = ns_to_t(65); + u8 txp = max(ns_to_t(8), 2); + + u8 trp = ns_to_t(21); + u8 tras_min = ns_to_t(42); + u16 trefi_x32 = ns_to_t(3904) / 32; + u16 trfc_min = ns_to_t(180); + u16 txsr = ns_to_t(190); + + u8 tmrw = max(ns_to_t(14), 5); + u8 tmrd = max(ns_to_t(14), 5); + u8 tmod = 12; + u8 tcke = max(ns_to_t(15), 2); + u8 tcksrx = max(ns_to_t(2), 2); + u8 tcksre = max(ns_to_t(5), 2); + u8 tckesr = max(ns_to_t(15), 2); + u8 tras_max = (trefi_x32 * 9) / 32; + u8 txs_x32 = 4; + u8 txsabort_x32 = 4; + + u8 wrlat = 5; + u8 wr2rd_s = 8; + u8 trrd_s = 2; + u8 tmrd_pda = 8; + + u8 wr2pre = 24; + u8 rd2pre = 4; + u8 wr2rd = 14 + max(ns_to_t(tpr13_flag1 ? 10 : 12), 4); + u8 rd2wr = 17 + ns_to_t(4) - ns_to_t(1); + u8 tphy_wrlat = 5; + + u8 rdlat = 10; + u8 trddata_en = 17; + + if (tpr13_flag1) { + rdlat = 11; + trddata_en = 19; + } + + writel(tras_min | tras_max << 8 | tfaw << 16 | wr2pre << 24, + &mctl_ctl->dramtmg[0]); + writel(trc | rd2pre << 8 | txp << 16, &mctl_ctl->dramtmg[1]); + writel(wr2rd | rd2wr << 8 | rdlat << 16 | wrlat << 24, + &mctl_ctl->dramtmg[2]); + writel(tmod | tmrd << 12 | tmrw << 20, &mctl_ctl->dramtmg[3]); + writel(trp | trrd << 8 | tccd << 16 | trcd << 24, + &mctl_ctl->dramtmg[4]); + writel(tcke | tckesr << 8 | tcksre << 16 | tcksrx << 24, + &mctl_ctl->dramtmg[5]); + writel((txp + 2) | 0x20 << 16 | 0x20 << 24, &mctl_ctl->dramtmg[6]); + writel(txs_x32 | 0x10 << 8 | txsabort_x32 << 16 | txsabort_x32 << 24, + &mctl_ctl->dramtmg[8]); + writel(wr2rd_s | trrd_s << 8 | 0x2 << 16, &mctl_ctl->dramtmg[9]); + writel(0xe0c05, &mctl_ctl->dramtmg[10]); + writel(0x440c021c, &mctl_ctl->dramtmg[11]); + writel(tmrd_pda, &mctl_ctl->dramtmg[12]); + writel(0xa100002, &mctl_ctl->dramtmg[13]); + writel(txsr, &mctl_ctl->dramtmg[14]); + + clrsetbits_le32(&mctl_ctl->init[0], 0xc0000fff, 1008); + + if (tpr13_flag2) + writel(0x420000, &mctl_ctl->init[1]); + else + writel(0x1f20000, &mctl_ctl->init[1]); + + clrsetbits_le32(&mctl_ctl->init[2], 0xff0f, 0xd05); + writel(0, &mctl_ctl->dfimisc); + + writel(0x34 << 16 | 0x1b, &mctl_ctl->init[3]); /* MR1/MR2 */ + writel(0x33 << 16, &mctl_ctl->init[4]); /* MR3 */ + writel(para->mr11 << 16 | para->mr12, &mctl_ctl->init[6]); + writel(para->tpr1 << 16 | para->mr14, &mctl_ctl->init[7]); + + clrsetbits_le32(&mctl_ctl->rankctl, 0xff0, 0x660); + if (!tpr13_flag3) { + tphy_wrlat -= 1; + trddata_en -= 1; + } + + writel(tphy_wrlat | trddata_en << 16 | 0x808000 | 0x2000000, + &mctl_ctl->dfitmg0); + writel(0x100202, &mctl_ctl->dfitmg1); + + writel(trfc_min | trefi_x32 << 16, &mctl_ctl->rfshtmg); +} diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index b288c65e7fd..8ade6f7b9d1 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -155,10 +155,6 @@ config TARGET_M5282EVB bool "Support M5282EVB" select M5282 -config TARGET_ASTRO_MCF5373L - bool "Support astro_mcf5373l" - select M5373 - config TARGET_M53017EVB bool "Support M53017EVB" select M53015 @@ -183,7 +179,6 @@ config TARGET_STMARK2 endchoice source "board/BuS/eb_cpu5282/Kconfig" -source "board/astro/mcf5373l/Kconfig" source "board/cobra5272/Kconfig" source "board/freescale/m5208evbe/Kconfig" source "board/freescale/m5235evb/Kconfig" diff --git a/arch/m68k/dts/Makefile b/arch/m68k/dts/Makefile index 0f06109aa06..c89559be309 100644 --- a/arch/m68k/dts/Makefile +++ b/arch/m68k/dts/Makefile @@ -11,7 +11,6 @@ dtb-$(CONFIG_TARGET_M5253DEMO) += M5253DEMO.dtb dtb-$(CONFIG_TARGET_M5272C3) += M5272C3.dtb dtb-$(CONFIG_TARGET_M5275EVB) += M5275EVB.dtb dtb-$(CONFIG_TARGET_M5282EVB) += M5282EVB.dtb -dtb-$(CONFIG_TARGET_ASTRO_MCF5373L) += astro_mcf5373l.dtb dtb-$(CONFIG_TARGET_M53017EVB) += M53017EVB.dtb dtb-$(CONFIG_TARGET_M5329EVB) += M5329AFEE.dtb M5329BFEE.dtb dtb-$(CONFIG_TARGET_M5373EVB) += M5373EVB.dtb diff --git a/arch/m68k/dts/astro_mcf5373l.dts b/arch/m68k/dts/astro_mcf5373l.dts deleted file mode 100644 index 40f84dd64b6..00000000000 --- a/arch/m68k/dts/astro_mcf5373l.dts +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018 Angelo Dureghello <angelo@sysam.it> - */ - -/dts-v1/; -/include/ "mcf537x.dtsi" - -/ { - model = "Astro mcf5373l"; - compatible = "astro,mcf5373l"; - - chosen { - stdout-path = "serial0:115200n8"; - }; -}; - -&uart0 { - bootph-all; - status = "okay"; -}; - -&i2c0 { - clock-frequency = <80000>; - u-boot,i2c-slave-addr = <0x7f>; - status = "okay"; -}; diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 8918a401fac..bee6758dc9a 100644 --- a/arch/powerpc/cpu/mpc85xx/mp.c +++ b/arch/powerpc/cpu/mpc85xx/mp.c @@ -410,9 +410,9 @@ static void plat_mp_up(unsigned long bootpg, unsigned int pagesize) void cpu_mp_lmb_reserve(void) { - u32 bootpg = determine_mp_bootpg(NULL); + phys_addr_t bootpg = determine_mp_bootpg(NULL); - lmb_reserve(bootpg, 4096, LMB_NONE); + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &bootpg, 4096, LMB_NONE); } void setup_mp(void) diff --git a/arch/powerpc/lib/misc.c b/arch/powerpc/lib/misc.c index 7e303419624..fc10ae50cf8 100644 --- a/arch/powerpc/lib/misc.c +++ b/arch/powerpc/lib/misc.c @@ -36,11 +36,12 @@ int arch_misc_init(void) size = min(size, (ulong)CFG_SYS_LINUX_LOWMEM_MAX_SIZE); if (size < bootm_size) { - ulong base = bootmap_base + size; + phys_addr_t base = bootmap_base + size; printf("WARNING: adjusting available memory from 0x%lx to 0x%llx\n", size, (unsigned long long)bootm_size); - lmb_reserve(base, bootm_size - size, LMB_NONE); + lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &base, + bootm_size - size, LMB_NONE); } #ifdef CONFIG_MP diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk index 9f16dda92a0..eddd6a3b9a2 100644 --- a/arch/riscv/config.mk +++ b/arch/riscv/config.mk @@ -10,19 +10,29 @@ # Rick Chen, Andes Technology Corporation <rick@andestech.com> # -32bit-emul := elf32lriscv -64bit-emul := elf64lriscv +ifdef CONFIG_SYS_BIG_ENDIAN +small-endian := b +large-endian := big +PLATFORM_CPPFLAGS += -mbig-endian +KBUILD_LDFLAGS += -mbig-endian +else +small-endian := l +large-endian := little +endif + +32bit-emul := elf32$(small-endian)riscv +64bit-emul := elf64$(small-endian)riscv ifdef CONFIG_32BIT KBUILD_LDFLAGS += -m $(32bit-emul) EFI_LDS := elf_riscv32_efi.lds -PLATFORM_ELFFLAGS += -B riscv -O elf32-littleriscv +PLATFORM_ELFFLAGS += -B riscv -O elf32-$(large-endian)riscv endif ifdef CONFIG_64BIT KBUILD_LDFLAGS += -m $(64bit-emul) EFI_LDS := elf_riscv64_efi.lds -PLATFORM_ELFFLAGS += -B riscv -O elf64-littleriscv +PLATFORM_ELFFLAGS += -B riscv -O elf64-$(large-endian)riscv endif PLATFORM_CPPFLAGS += -ffixed-x3 -fpic diff --git a/arch/riscv/cpu/th1520/Kconfig b/arch/riscv/cpu/th1520/Kconfig index 4d44191bd22..c73462c04b8 100644 --- a/arch/riscv/cpu/th1520/Kconfig +++ b/arch/riscv/cpu/th1520/Kconfig @@ -11,6 +11,7 @@ config THEAD_TH1520 select BINMAN if SPL select SYS_CACHE_THEAD_CMO select CLK_THEAD + select PINCTRL_TH1520 imply CPU imply CPU_RISCV imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) diff --git a/arch/riscv/cpu/th1520/cpu.c b/arch/riscv/cpu/th1520/cpu.c index b83f1272c67..f60446fd772 100644 --- a/arch/riscv/cpu/th1520/cpu.c +++ b/arch/riscv/cpu/th1520/cpu.c @@ -9,8 +9,35 @@ #include <asm/io.h> #include <cpu_func.h> +#include <linux/bitops.h> -#define TH1520_PMP_BASE (void *)0xffdc020000 +#define TH1520_C910_RST (void __iomem *)(0xffef014000 + 0x004) +#define TH1520_C910_CORE_RST_N(n) BIT((n) + 1) +#define TH1520_SYSCFG_AP_BASE (void __iomem *)(0xffef018000) +#define TH1520_SYSCFG_CORE_START_L(n) (TH1520_SYSCFG_AP_BASE + 0x50 + 8 * (n)) +#define TH1520_SYSCFG_CORE_START_H(n) (TH1520_SYSCFG_AP_BASE + 0x54 + 8 * (n)) +#define TH1520_PMP_BASE (void *)0xffdc020000 + +void th1520_kick_secondary_cores(void) +{ + int i; + + /* + * On coldboot, only HART 0 is brought up by hardware, and resets for + * secondary cores are asserted. Set reset address of secondary cores + * to the entry of SPL, then deassert the resets to bring them up. + */ + for (i = 1; i < 4; i++) { + writel(CONFIG_SPL_TEXT_BASE & 0xffffffff, + TH1520_SYSCFG_CORE_START_L(i)); + writel(CONFIG_SPL_TEXT_BASE >> 32, + TH1520_SYSCFG_CORE_START_H(i)); + } + + setbits_le32(TH1520_C910_RST, TH1520_C910_CORE_RST_N(1) | + TH1520_C910_CORE_RST_N(2) | + TH1520_C910_CORE_RST_N(3)); +} void th1520_invalidate_pmp(void) { diff --git a/arch/riscv/cpu/th1520/spl.c b/arch/riscv/cpu/th1520/spl.c index 362fe895f86..b95470485f6 100644 --- a/arch/riscv/cpu/th1520/spl.c +++ b/arch/riscv/cpu/th1520/spl.c @@ -4,6 +4,7 @@ */ #include <asm/arch/iopmp.h> #include <asm/io.h> +#include <cpu_func.h> #include <dm.h> #include <linux/sizes.h> #include <log.h> @@ -21,6 +22,52 @@ DECLARE_GLOBAL_DATA_PTR; #define TH1520_SUBSYS_RST_VI_N BIT(1) #define TH1520_SUBSYS_RST_DSP_N BIT(0) +#define CSR_MXSTATUS 0x7c0 +#define CSR_MXSTATUS_THEADISAEE BIT(22) +#define CSR_MXSTATUS_MAEE BIT(21) +#define CSR_MXSTATUS_CLINTEE BIT(17) +#define CSR_MXSTATUS_UCME BIT(16) +#define CSR_MXSTATUS_MM BIT(15) +#define CSR_MHCR 0x7c1 +#define CSR_MHCR_WBR BIT(8) +#define CSR_MHCR_BTB BIT(6) +#define CSR_MHCR_BPE BIT(5) +#define CSR_MHCR_RS BIT(4) +#define CSR_MHCR_WB BIT(3) +#define CSR_MHCR_WA BIT(2) +#define CSR_MHCR_DE BIT(1) +#define CSR_MHCR_IE BIT(0) +#define CSR_MCOR 0x7c2 +#define CSR_MCOR_IBP_INV BIT(18) +#define CSR_MCOR_BTB_INV BIT(17) +#define CSR_MCOR_BHT_INV BIT(16) +#define CSR_MCOR_CACHE_INV BIT(4) +#define CSR_MCCR2 0x7c3 +#define CSR_MCCR2_TPRF BIT(31) +#define CSR_MCCR2_IPRF(n) ((n) << 29) +#define CSR_MCCR2_TSETUP BIT(25) +#define CSR_MCCR2_TLNTCY(n) ((n) << 22) +#define CSR_MCCR2_DSETUP BIT(19) +#define CSR_MCCR2_DLNTCY(n) ((n) << 16) +#define CSR_MCCR2_L2EN BIT(3) +#define CSR_MCCR2_RFE BIT(0) +#define CSR_MHINT 0x7c5 +#define CSR_MHINT_FENCERW_BROAD_DIS BIT(22) +#define CSR_MHINT_TLB_BRAOD_DIS BIT(21) +#define CSR_MHINT_NSFE BIT(18) +#define CSR_MHINT_L2_PREF_DIST(n) ((n) << 16) +#define CSR_MHINT_L2PLD BIT(15) +#define CSR_MHINT_DCACHE_PREF_DIST(n) ((n) << 13) +#define CSR_MHINT_LPE BIT(9) +#define CSR_MHINT_ICACHE_PREF BIT(8) +#define CSR_MHINT_AMR BIT(3) +#define CSR_MHINT_DCACHE_PREF BIT(2) +#define CSR_MHINT2 0x7cc +#define CSR_MHINT2_LOCAL_ICG_EN(n) BIT((n) + 14) +#define CSR_MHINT4 0x7ce +#define CSR_MSMPR 0x7f3 +#define CSR_MSMPR_SMPEN BIT(0) + int spl_dram_init(void) { int ret; @@ -77,6 +124,42 @@ void harts_early_init(void) { int i; + /* Invalidate cache and buffer entries */ + csr_write(CSR_MCOR, CSR_MCOR_IBP_INV | CSR_MCOR_BTB_INV | + CSR_MCOR_BHT_INV | CSR_MCOR_CACHE_INV | 0x3); + + /* Enable cache snooping */ + csr_write(CSR_MSMPR, CSR_MSMPR_SMPEN); + + /* + * Configure and enable L2 cache, + * Enable tag/data RAM prefetch, both cost 2 cycles + * Prefetch 3 cache lines of instructions + * Enable read allocation + */ + csr_write(CSR_MCCR2, CSR_MCCR2_TPRF | CSR_MCCR2_IPRF(3) | + CSR_MCCR2_TSETUP | CSR_MCCR2_TLNTCY(1) | + CSR_MCCR2_DSETUP | CSR_MCCR2_DLNTCY(1) | + CSR_MCCR2_L2EN | CSR_MCCR2_RFE); + csr_write(CSR_MXSTATUS, CSR_MXSTATUS_THEADISAEE | CSR_MXSTATUS_MAEE | + CSR_MXSTATUS_CLINTEE | CSR_MXSTATUS_UCME | + CSR_MXSTATUS_MM); + csr_write(CSR_MHINT, CSR_MHINT_FENCERW_BROAD_DIS | + CSR_MHINT_TLB_BRAOD_DIS | + CSR_MHINT_NSFE | + CSR_MHINT_L2_PREF_DIST(2) | + CSR_MHINT_L2PLD | + CSR_MHINT_DCACHE_PREF_DIST(3) | + CSR_MHINT_LPE | + CSR_MHINT_ICACHE_PREF | + CSR_MHINT_AMR | + CSR_MHINT_DCACHE_PREF); + csr_write(CSR_MHCR, CSR_MHCR_WBR | CSR_MHCR_BTB | CSR_MHCR_BPE | + CSR_MHCR_RS | CSR_MHCR_WB | CSR_MHCR_WA | 0x3); + csr_write(CSR_MHINT2, CSR_MHINT2_LOCAL_ICG_EN(8) | + CSR_MHINT2_LOCAL_ICG_EN(3)); + csr_write(CSR_MHINT4, 0x410); + /* * Set IOPMPs to the default attribute, allowing the application * processor to access various peripherals. Subsystem clocks should be diff --git a/arch/riscv/dts/th1520.dtsi b/arch/riscv/dts/th1520.dtsi index 28107a9f354..8306eda5521 100644 --- a/arch/riscv/dts/th1520.dtsi +++ b/arch/riscv/dts/th1520.dtsi @@ -128,6 +128,13 @@ #clock-cells = <0>; }; + aonsys_clk: clock-73728000 { + compatible = "fixed-clock"; + clock-frequency = <73728000>; + clock-output-names = "aonsys_clk"; + #clock-cells = <0>; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&plic>; @@ -151,6 +158,7 @@ clint: timer@ffdc000000 { compatible = "thead,th1520-clint", "thead,c900-clint"; reg = <0xff 0xdc000000 0x0 0x00010000>; + bootph-pre-ram; interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>, <&cpu1_intc 3>, <&cpu1_intc 7>, <&cpu2_intc 3>, <&cpu2_intc 7>, @@ -258,6 +266,13 @@ }; }; + padctrl1_apsys: pinctrl@ffe7f3c000 { + compatible = "thead,th1520-pinctrl"; + reg = <0xff 0xe7f3c000 0x0 0x1000>; + clocks = <&clk CLK_PADCTRL1>; + thead,pad-group = <2>; + }; + gpio0: gpio@ffec005000 { compatible = "snps,dw-apb-gpio"; reg = <0xff 0xec005000 0x0 0x1000>; @@ -298,6 +313,13 @@ }; }; + padctrl0_apsys: pinctrl@ffec007000 { + compatible = "thead,th1520-pinctrl"; + reg = <0xff 0xec007000 0x0 0x1000>; + clocks = <&clk CLK_PADCTRL0>; + thead,pad-group = <3>; + }; + uart2: serial@ffec010000 { compatible = "snps,dw-apb-uart"; reg = <0xff 0xec010000 0x0 0x4000>; @@ -438,6 +460,13 @@ }; }; + padctrl_aosys: pinctrl@fffff4a000 { + compatible = "thead,th1520-pinctrl"; + reg = <0xff 0xfff4a000 0x0 0x2000>; + clocks = <&aonsys_clk>; + thead,pad-group = <1>; + }; + ao_gpio1: gpio@fffff52000 { compatible = "snps,dw-apb-gpio"; reg = <0xff 0xfff52000 0x0 0x1000>; diff --git a/arch/riscv/include/asm/arch-th1520/cpu.h b/arch/riscv/include/asm/arch-th1520/cpu.h index 837f0b8d06b..e164e9ab979 100644 --- a/arch/riscv/include/asm/arch-th1520/cpu.h +++ b/arch/riscv/include/asm/arch-th1520/cpu.h @@ -5,5 +5,6 @@ #ifndef _ASM_TH1520_CPU_H_ #define _ASM_TH1520_CPU_H_ +void th1520_kick_secondary_cores(void); void th1520_invalidate_pmp(void); #endif /* _ASM_TH1520_CPU_H_ */ diff --git a/arch/riscv/include/asm/byteorder.h b/arch/riscv/include/asm/byteorder.h index d26ac5688fa..3140c1f585e 100644 --- a/arch/riscv/include/asm/byteorder.h +++ b/arch/riscv/include/asm/byteorder.h @@ -26,7 +26,7 @@ # define __SWAB_64_THRU_32__ #endif -#ifdef __RISCVEB__ +#if defined(__RISCVEB__) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) #include <linux/byteorder/big_endian.h> #else #include <linux/byteorder/little_endian.h> diff --git a/arch/riscv/lib/aclint_ipi.c b/arch/riscv/lib/aclint_ipi.c index dcd7e5e6b34..1c9a2d70301 100644 --- a/arch/riscv/lib/aclint_ipi.c +++ b/arch/riscv/lib/aclint_ipi.c @@ -29,6 +29,10 @@ int riscv_init_ipi(void) ret = uclass_get_device_by_driver(UCLASS_TIMER, DM_DRIVER_GET(riscv_aclint_timer), &dev); + if (ret == -ENODEV) + ret = uclass_get_device_by_driver(UCLASS_SYSCON, + DM_DRIVER_GET(riscv_aclint_swi), &dev); + if (ret) return ret; @@ -66,6 +70,7 @@ int riscv_get_ipi(int hart, int *pending) static const struct udevice_id riscv_aclint_swi_ids[] = { { .compatible = "riscv,aclint-mswi", .data = RISCV_SYSCON_ACLINT }, + { .compatible = "thead,c900-clint", .data = RISCV_SYSCON_ACLINT }, { } }; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 49236db99c2..6a15c8b0a18 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -480,7 +480,9 @@ int state_init(void) state = &main_state; state->ram_size = CFG_SYS_SDRAM_SIZE; - state->ram_buf = os_malloc(state->ram_size); + state->mmap_addr = os_malloc(state->ram_size + SB_SDRAM_ALIGN); + state->ram_buf = (uint8_t *)ALIGN((uintptr_t)state->mmap_addr, + SB_SDRAM_ALIGN); if (!state->ram_buf) { printf("Out of memory\n"); os_exit(1); @@ -533,7 +535,7 @@ int state_uninit(void) trace_set_enabled(0); os_free(state->state_fdt); - os_free(state->ram_buf); + os_free(state->mmap_addr); memset(state, '\0', sizeof(*state)); return 0; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index dc21a623106..9dea0980bfc 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -75,6 +75,7 @@ struct sandbox_state { char **argv; /* Command line arguments */ const char *jumped_fname; /* Jumped from previous U-Boot */ const char *prog_fname; /* U-Boot executable filename */ + uint8_t *mmap_addr; /* Memory allocated via mmap */ uint8_t *ram_buf; /* Emulated RAM buffer */ unsigned long ram_size; /* Size of RAM buffer */ const char *ram_buf_fname; /* Filename to use for RAM buffer */ diff --git a/board/amd/versal2/board.c b/board/amd/versal2/board.c index 72967e69a84..7d91d288d2e 100644 --- a/board/amd/versal2/board.c +++ b/board/amd/versal2/board.c @@ -365,9 +365,11 @@ int dram_init(void) return 0; } +#if !CONFIG_IS_ENABLED(SYSRESET) void reset_cpu(void) { } +#endif #if defined(CONFIG_ENV_IS_NOWHERE) enum env_location env_get_location(enum env_operation op, int prio) diff --git a/board/astro/mcf5373l/Kconfig b/board/astro/mcf5373l/Kconfig deleted file mode 100644 index a7c04cef83d..00000000000 --- a/board/astro/mcf5373l/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -if TARGET_ASTRO_MCF5373L - -config SYS_CPU - default "mcf532x" - -config SYS_BOARD - default "mcf5373l" - -config SYS_VENDOR - default "astro" - -config SYS_CONFIG_NAME - default "astro_mcf5373l" - -endif diff --git a/board/astro/mcf5373l/MAINTAINERS b/board/astro/mcf5373l/MAINTAINERS deleted file mode 100644 index 6c23da71968..00000000000 --- a/board/astro/mcf5373l/MAINTAINERS +++ /dev/null @@ -1,6 +0,0 @@ -MCF5373L BOARD -M: Wolfgang Wegner <w.wegner@astro-kom.de> -S: Maintained -F: board/astro/mcf5373l/ -F: include/configs/astro_mcf5373l.h -F: configs/astro_mcf5373l_defconfig diff --git a/board/astro/mcf5373l/Makefile b/board/astro/mcf5373l/Makefile deleted file mode 100644 index d3ea0d06a8d..00000000000 --- a/board/astro/mcf5373l/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. - -obj-y = mcf5373l.o fpga.o diff --git a/board/astro/mcf5373l/astro.h b/board/astro/mcf5373l/astro.h deleted file mode 100644 index b55a6f785ce..00000000000 --- a/board/astro/mcf5373l/astro.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __ASTRO_H__ -#define __ASTRO_H__ - -/* in mcf5373l.c */ -int rs_serial_init(int port, int baud); -void astro_put_char(char ch); -int astro_is_char(void); -int astro_get_char(void); - -/* in fpga.c */ -int astro5373l_altera_load(void); -int astro5373l_xilinx_load(void); - -/* data structures used for communication (update.c) */ -typedef struct card_id { - char card_type; - char hardware_version; - char software_version; - char software_subversion; /* " ","a".."z" */ - char fpga_version_altera; - char fpga_version_xilinx; -} card_id_t; - -typedef struct { - unsigned char mode; - unsigned char deviation; - unsigned short freq; -} __attribute__ ((packed)) output_params_t; - -typedef struct { - unsigned short satfreq; - unsigned char satdatallg; - unsigned short symbolrate; - unsigned char viterbirate; - unsigned char symbolrate_l; - output_params_t output_params; - unsigned char reserve; - unsigned char card_error; - unsigned short dummy_ts_id; - unsigned char dummy_pat_ver; - unsigned char dummy_sdt_ver; -} __attribute__ ((packed)) parameters_t; - -#endif /* __ASTRO_H__ */ diff --git a/board/astro/mcf5373l/fpga.c b/board/astro/mcf5373l/fpga.c deleted file mode 100644 index 6e505c630d1..00000000000 --- a/board/astro/mcf5373l/fpga.c +++ /dev/null @@ -1,407 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2006 - * Wolfgang Wegner, ASTRO Strobel Kommunikationssysteme GmbH, - * w.wegner@astro-kom.de - * - * based on the files by - * Heiko Schocher, DENX Software Engineering, hs@denx.de - * and - * Rich Ireland, Enterasys Networks, rireland@enterasys.com. - * Keith Outwater, keith_outwater@mvis.com. - */ - -/* Altera/Xilinx FPGA configuration support for the ASTRO "URMEL" board */ - -#include <console.h> -#include <watchdog.h> -#include <altera.h> -#include <ACEX1K.h> -#include <spartan3.h> -#include <command.h> -#include <asm/immap_5329.h> -#include <asm/io.h> -#include "fpga.h" - -int altera_pre_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - unsigned char tmp_char; - unsigned short tmp_short; - - /* first, set the required pins to GPIO function */ - /* PAR_T0IN -> GPIO */ - tmp_char = readb(&gpiop->par_timer); - tmp_char &= 0xfc; - writeb(tmp_char, &gpiop->par_timer); - /* all QSPI pins -> GPIO */ - writew(0x0000, &gpiop->par_qspi); - /* U0RTS, U0CTS -> GPIO */ - tmp_short = __raw_readw(&gpiop->par_uart); - tmp_short &= 0xfff3; - __raw_writew(tmp_short, &gpiop->par_uart); - /* all PWM pins -> GPIO */ - writeb(0x00, &gpiop->par_pwm); - /* next, set data direction registers */ - writeb(0x01, &gpiop->pddr_timer); - writeb(0x25, &gpiop->pddr_qspi); - writeb(0x0c, &gpiop->pddr_uart); - writeb(0x04, &gpiop->pddr_pwm); - - /* ensure other SPI peripherals are deselected */ - writeb(0x08, &gpiop->ppd_uart); - writeb(0x38, &gpiop->ppd_qspi); - - /* CONFIG = 0 STATUS = 0 -> FPGA in reset state */ - writeb(0xFB, &gpiop->pclrr_uart); - /* enable Altera configuration by clearing QSPI_CS2 and DT0IN */ - writeb(0xFE, &gpiop->pclrr_timer); - writeb(0xDF, &gpiop->pclrr_qspi); - return FPGA_SUCCESS; -} - -/* Set the state of CONFIG Pin */ -int altera_config_fn(int assert_config, int flush, int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - if (assert_config) - writeb(0x04, &gpiop->ppd_uart); - else - writeb(0xFB, &gpiop->pclrr_uart); - return FPGA_SUCCESS; -} - -/* Returns the state of STATUS Pin */ -int altera_status_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - if (readb(&gpiop->ppd_pwm) & 0x08) - return FPGA_FAIL; - return FPGA_SUCCESS; -} - -/* Returns the state of CONF_DONE Pin */ -int altera_done_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - if (readb(&gpiop->ppd_pwm) & 0x20) - return FPGA_FAIL; - return FPGA_SUCCESS; -} - -/* - * writes the complete buffer to the FPGA - * writing the complete buffer in one function is much faster, - * then calling it for every bit - */ -int altera_write_fn(const void *buf, size_t len, int flush, int cookie) -{ - size_t bytecount = 0; - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - unsigned char *data = (unsigned char *)buf; - unsigned char val = 0; - int i; - int len_40 = len / 40; - - while (bytecount < len) { - val = data[bytecount++]; - i = 8; - do { - writeb(0xFB, &gpiop->pclrr_qspi); - if (val & 0x01) - writeb(0x01, &gpiop->ppd_qspi); - else - writeb(0xFE, &gpiop->pclrr_qspi); - writeb(0x04, &gpiop->ppd_qspi); - val >>= 1; - i--; - } while (i > 0); - - if (bytecount % len_40 == 0) { -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - schedule(); -#endif -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc('.'); /* let them know we are alive */ -#endif -#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc()) - return FPGA_FAIL; -#endif - } - } - return FPGA_SUCCESS; -} - -/* called, when programming is aborted */ -int altera_abort_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - writeb(0x20, &gpiop->ppd_qspi); - writeb(0x08, &gpiop->ppd_uart); - return FPGA_SUCCESS; -} - -/* called, when programming was succesful */ -int altera_post_fn(int cookie) -{ - return altera_abort_fn(cookie); -} - -/* - * Note that these are pointers to code that is in Flash. They will be - * relocated at runtime. - * FIXME: relocation not yet working for coldfire, see below! - */ -Altera_CYC2_Passive_Serial_fns altera_fns = { - altera_pre_fn, - altera_config_fn, - altera_status_fn, - altera_done_fn, - altera_write_fn, - altera_abort_fn, - altera_post_fn -}; - -#define FPGA_COUNT 1 -Altera_desc altera_fpga[FPGA_COUNT] = { - {Altera_CYC2, - passive_serial, - 85903, - (void *)&altera_fns, - NULL, - 0} -}; - -/* Initialize the fpga. Return 1 on success, 0 on failure. */ -int astro5373l_altera_load(void) -{ - int i; - - for (i = 0; i < FPGA_COUNT; i++) { - /* - * I did not yet manage to get relocation work properly, - * so set stuff here instead of static initialisation: - */ - altera_fns.pre = altera_pre_fn; - altera_fns.config = altera_config_fn; - altera_fns.status = altera_status_fn; - altera_fns.done = altera_done_fn; - altera_fns.write = altera_write_fn; - altera_fns.abort = altera_abort_fn; - altera_fns.post = altera_post_fn; - altera_fpga[i].iface_fns = (void *)&altera_fns; - fpga_add(fpga_altera, &altera_fpga[i]); - } - return 1; -} - -/* Set the FPGA's PROG_B line to the specified level */ -int xilinx_pgm_config_fn(int assert, int flush, int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - if (assert) - writeb(0xFB, &gpiop->pclrr_uart); - else - writeb(0x04, &gpiop->ppd_uart); - return assert; -} - -/* - * Test the state of the active-low FPGA INIT line. Return 1 on INIT - * asserted (low). - */ -int xilinx_init_config_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - return (readb(&gpiop->ppd_pwm) & 0x08) == 0; -} - -/* Test the state of the active-high FPGA DONE pin */ -int xilinx_done_config_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - return (readb(&gpiop->ppd_pwm) & 0x20) >> 5; -} - -/* Abort an FPGA operation */ -int xilinx_abort_config_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - /* ensure all SPI peripherals and FPGAs are deselected */ - writeb(0x08, &gpiop->ppd_uart); - writeb(0x01, &gpiop->ppd_timer); - writeb(0x38, &gpiop->ppd_qspi); - return FPGA_FAIL; -} - -/* - * FPGA pre-configuration function. Just make sure that - * FPGA reset is asserted to keep the FPGA from starting up after - * configuration. - */ -int xilinx_pre_config_fn(int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - unsigned char tmp_char; - unsigned short tmp_short; - - /* first, set the required pins to GPIO function */ - /* PAR_T0IN -> GPIO */ - tmp_char = readb(&gpiop->par_timer); - tmp_char &= 0xfc; - writeb(tmp_char, &gpiop->par_timer); - /* all QSPI pins -> GPIO */ - writew(0x0000, &gpiop->par_qspi); - /* U0RTS, U0CTS -> GPIO */ - tmp_short = __raw_readw(&gpiop->par_uart); - tmp_short &= 0xfff3; - __raw_writew(tmp_short, &gpiop->par_uart); - /* all PWM pins -> GPIO */ - writeb(0x00, &gpiop->par_pwm); - /* next, set data direction registers */ - writeb(0x01, &gpiop->pddr_timer); - writeb(0x25, &gpiop->pddr_qspi); - writeb(0x0c, &gpiop->pddr_uart); - writeb(0x04, &gpiop->pddr_pwm); - - /* ensure other SPI peripherals are deselected */ - writeb(0x08, &gpiop->ppd_uart); - writeb(0x38, &gpiop->ppd_qspi); - writeb(0x01, &gpiop->ppd_timer); - - /* CONFIG = 0, STATUS = 0 -> FPGA in reset state */ - writeb(0xFB, &gpiop->pclrr_uart); - /* enable Xilinx configuration by clearing QSPI_CS2 and U0CTS */ - writeb(0xF7, &gpiop->pclrr_uart); - writeb(0xDF, &gpiop->pclrr_qspi); - return 0; -} - -/* - * FPGA post configuration function. Should perform a test if FPGA is running. - */ -int xilinx_post_config_fn(int cookie) -{ - int rc = 0; - - /* - * no test yet - */ - return rc; -} - -int xilinx_clk_config_fn(int assert_clk, int flush, int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - if (assert_clk) - writeb(0x04, &gpiop->ppd_qspi); - else - writeb(0xFB, &gpiop->pclrr_qspi); - return assert_clk; -} - -int xilinx_wr_config_fn(int assert_write, int flush, int cookie) -{ - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - - if (assert_write) - writeb(0x01, &gpiop->ppd_qspi); - else - writeb(0xFE, &gpiop->pclrr_qspi); - return assert_write; -} - -int xilinx_fastwr_config_fn(void *buf, size_t len, int flush, int cookie) -{ - size_t bytecount = 0; - gpio_t *gpiop = (gpio_t *)MMAP_GPIO; - unsigned char *data = (unsigned char *)buf; - unsigned char val = 0; - int i; - int len_40 = len / 40; - - for (bytecount = 0; bytecount < len; bytecount++) { - val = *(data++); - for (i = 8; i > 0; i--) { - writeb(0xFB, &gpiop->pclrr_qspi); - if (val & 0x80) - writeb(0x01, &gpiop->ppd_qspi); - else - writeb(0xFE, &gpiop->pclrr_qspi); - writeb(0x04, &gpiop->ppd_qspi); - val <<= 1; - } - if (bytecount % len_40 == 0) { -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - schedule(); -#endif -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc('.'); /* let them know we are alive */ -#endif -#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc()) - return FPGA_FAIL; -#endif - } - } - return FPGA_SUCCESS; -} - -/* - * Note that these are pointers to code that is in Flash. They will be - * relocated at runtime. - * FIXME: relocation not yet working for coldfire, see below! - */ -xilinx_spartan3_slave_serial_fns xilinx_fns = { - xilinx_pre_config_fn, - xilinx_pgm_config_fn, - xilinx_clk_config_fn, - xilinx_init_config_fn, - xilinx_done_config_fn, - xilinx_wr_config_fn, - 0, - xilinx_fastwr_config_fn -}; - -xilinx_desc xilinx_fpga[FPGA_COUNT] = { - {xilinx_spartan3, - slave_serial, - XILINX_XC3S4000_SIZE, - (void *)&xilinx_fns, - 0, - &spartan3_op} -}; - -/* Initialize the fpga. Return 1 on success, 0 on failure. */ -int astro5373l_xilinx_load(void) -{ - int i; - - fpga_init(); - - for (i = 0; i < FPGA_COUNT; i++) { - /* - * I did not yet manage to get relocation work properly, - * so set stuff here instead of static initialisation: - */ - xilinx_fns.pre = xilinx_pre_config_fn; - xilinx_fns.pgm = xilinx_pgm_config_fn; - xilinx_fns.clk = xilinx_clk_config_fn; - xilinx_fns.init = xilinx_init_config_fn; - xilinx_fns.done = xilinx_done_config_fn; - xilinx_fns.wr = xilinx_wr_config_fn; - xilinx_fns.bwr = xilinx_fastwr_config_fn; - xilinx_fpga[i].iface_fns = (void *)&xilinx_fns; - fpga_add(fpga_xilinx, &xilinx_fpga[i]); - } - return 1; -} diff --git a/board/astro/mcf5373l/mcf5373l.c b/board/astro/mcf5373l/mcf5373l.c deleted file mode 100644 index 43fcbc65513..00000000000 --- a/board/astro/mcf5373l/mcf5373l.c +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2000-2003 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * modified by Wolfgang Wegner <w.wegner@astro-kom.de> for ASTRO 5373l - */ - -#include <config.h> -#include <init.h> -#include <serial.h> -#include <time.h> -#include <watchdog.h> -#include <command.h> -#include <asm/global_data.h> -#include <asm/m5329.h> -#include <asm/immap_5329.h> -#include <asm/io.h> -#include <linux/delay.h> - -/* needed for astro bus: */ -#include <asm/uart.h> -#include "astro.h" - -DECLARE_GLOBAL_DATA_PTR; -extern void uart_port_conf(void); - -int checkboard(void) -{ - puts("Board: "); - puts("ASTRO MCF5373L (Urmel) Board\n"); - return 0; -} - -int dram_init(void) -{ -#if !defined(CONFIG_MONITOR_IS_IN_RAM) - sdram_t *sdp = (sdram_t *)(MMAP_SDRAM); - - /* - * GPIO configuration for bus should be set correctly from reset, - * so we do not care! First, set up address space: at this point, - * we should be running from internal SRAM; - * so use CFG_SYS_SDRAM_BASE as the base address for SDRAM, - * and do not care where it is - */ - __raw_writel((CFG_SYS_SDRAM_BASE & 0xFFF00000) | 0x00000018, - &sdp->cs0); - __raw_writel((CFG_SYS_SDRAM_BASE & 0xFFF00000) | 0x00000000, - &sdp->cs1); - /* - * I am not sure from the data sheet, but it seems burst length - * has to be 8 for the 16 bit data bus we use; - * so these values are for BL = 8 - */ - __raw_writel(0x33211530, &sdp->cfg1); - __raw_writel(0x56570000, &sdp->cfg2); - /* send PrechargeALL, REF and IREF remain cleared! */ - __raw_writel(0xE1462C02, &sdp->ctrl); - udelay(1); - /* refresh SDRAM twice */ - __raw_writel(0xE1462C04, &sdp->ctrl); - udelay(1); - __raw_writel(0xE1462C04, &sdp->ctrl); - /* init MR */ - __raw_writel(0x008D0000, &sdp->mode); - /* initialize EMR */ - __raw_writel(0x80010000, &sdp->mode); - /* wait until DLL is locked */ - udelay(1); - /* - * enable automatic refresh, lock mode register, - * clear iref and ipall - */ - __raw_writel(0x71462C00, &sdp->ctrl); - /* Dummy write to start SDRAM */ - writel(0, CFG_SYS_SDRAM_BASE); -#endif - - /* - * for get_ram_size() to work, both CS areas have to be - * configured, i.e. CS1 has to be explicitely disabled, else - * probing for memory will cause the SDRAM bus to hang! - * (Do not rely on the SDCS register(s) being set to 0x00000000 - * during reset as stated in the data sheet.) - */ - gd->ram_size = get_ram_size((long *)CFG_SYS_SDRAM_BASE, - 0x80000000 - CFG_SYS_SDRAM_BASE); - - return 0; -} - -#define UART_BASE MMAP_UART0 -int rs_serial_init(int port, int baud) -{ - uart_t *uart; - u32 counter; - - switch (port) { - case 0: - uart = (uart_t *)(MMAP_UART0); - break; - case 1: - uart = (uart_t *)(MMAP_UART1); - break; - case 2: - uart = (uart_t *)(MMAP_UART2); - break; - default: - uart = (uart_t *)(MMAP_UART0); - } - - uart_port_conf(); - - /* write to SICR: SIM2 = uart mode,dcd does not affect rx */ - writeb(UART_UCR_RESET_RX, &uart->ucr); - writeb(UART_UCR_RESET_TX, &uart->ucr); - writeb(UART_UCR_RESET_ERROR, &uart->ucr); - writeb(UART_UCR_RESET_MR, &uart->ucr); - __asm__ ("nop"); - - writeb(0, &uart->uimr); - - /* write to CSR: RX/TX baud rate from timers */ - writeb(UART_UCSR_RCS_SYS_CLK | UART_UCSR_TCS_SYS_CLK, &uart->ucsr); - - writeb(UART_UMR_BC_8 | UART_UMR_PM_NONE, &uart->umr); - writeb(UART_UMR_SB_STOP_BITS_1, &uart->umr); - - /* Setting up BaudRate */ - counter = (u32) (gd->bus_clk / (baud)); - counter >>= 5; - - /* write to CTUR: divide counter upper byte */ - writeb((u8) ((counter & 0xff00) >> 8), &uart->ubg1); - /* write to CTLR: divide counter lower byte */ - writeb((u8) (counter & 0x00ff), &uart->ubg2); - - writeb(UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED, &uart->ucr); - - return 0; -} - -void astro_put_char(char ch) -{ - uart_t *uart; - unsigned long timer; - - uart = (uart_t *)(MMAP_UART0); - /* - * Wait for last character to go. Timeout of 6ms should - * be enough for our lowest baud rate of 2400. - */ - timer = get_timer(0); - while (get_timer(timer) < 6) { - if (readb(&uart->usr) & UART_USR_TXRDY) - break; - } - writeb(ch, &uart->utb); - - return; -} - -int astro_is_char(void) -{ - uart_t *uart; - - uart = (uart_t *)(MMAP_UART0); - return readb(&uart->usr) & UART_USR_RXRDY; -} - -int astro_get_char(void) -{ - uart_t *uart; - - uart = (uart_t *)(MMAP_UART0); - while (!(readb(&uart->usr) & UART_USR_RXRDY)) ; - return readb(&uart->urb); -} - -int misc_init_r(void) -{ - int retval = 0; - - puts("Configure Xilinx FPGA..."); - retval = astro5373l_xilinx_load(); - if (!retval) { - puts("failed!\n"); - return retval; - } - puts("done\n"); - - puts("Configure Altera FPGA..."); - retval = astro5373l_altera_load(); - if (!retval) { - puts("failed!\n"); - return retval; - } - puts("done\n"); - - return retval; -} diff --git a/board/congatec/common/Makefile b/board/congatec/common/Makefile index f8170d9c653..7f1c8994d27 100644 --- a/board/congatec/common/Makefile +++ b/board/congatec/common/Makefile @@ -16,8 +16,8 @@ endif endif ifdef MINIMAL -# necessary to create built-in.o -obj- := __dummy__.o +# necessary to create built-in.a +obj- := __dummy__.a else obj-y += mmc.o diff --git a/board/cssi/cmpc885/u-boot.lds b/board/cssi/cmpc885/u-boot.lds index 53f616fcfe1..167606357e0 100644 --- a/board/cssi/cmpc885/u-boot.lds +++ b/board/cssi/cmpc885/u-boot.lds @@ -18,8 +18,8 @@ SECTIONS { arch/powerpc/cpu/mpc8xx/start.o (.text) arch/powerpc/cpu/mpc8xx/traps.o (.text*) - arch/powerpc/lib/built-in.o (.text*) - drivers/net/built-in.o (.text*) + arch/powerpc/lib/built-in.a (.text*) + drivers/net/built-in.a (.text*) . = DEFINED(env_offset) ? env_offset : .; env/embedded.o (.text.environment) diff --git a/board/cssi/mcr3000/u-boot.lds b/board/cssi/mcr3000/u-boot.lds index 24b535e724a..66afdebc0f7 100644 --- a/board/cssi/mcr3000/u-boot.lds +++ b/board/cssi/mcr3000/u-boot.lds @@ -18,8 +18,8 @@ SECTIONS { arch/powerpc/cpu/mpc8xx/start.o (.text) arch/powerpc/cpu/mpc8xx/traps.o (.text*) - arch/powerpc/lib/built-in.o (.text*) - drivers/net/built-in.o (.text*) + arch/powerpc/lib/built-in.a (.text*) + drivers/net/built-in.a (.text*) . = DEFINED(env_offset) ? env_offset : .; env/embedded.o (.text.environment) diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index b04e19e9428..ed102ae7bf7 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -14,8 +14,8 @@ endif endif ifdef MINIMAL -# necessary to create built-in.o -obj- := __dummy__.o +# necessary to create built-in.a +obj- := __dummy__.a else # include i2c_common.o once if either VID or FSL_USE_PCA9547_MUX I2C_COMMON= diff --git a/board/freescale/imx8mm_evk/imx8mm_evk.c b/board/freescale/imx8mm_evk/imx8mm_evk.c index d41db8d31d8..ecc20768cb5 100644 --- a/board/freescale/imx8mm_evk/imx8mm_evk.c +++ b/board/freescale/imx8mm_evk/imx8mm_evk.c @@ -3,6 +3,8 @@ * Copyright 2018 NXP */ +#include <config.h> +#include <efi_loader.h> #include <env.h> #include <init.h> #include <miiphy.h> @@ -15,6 +17,26 @@ DECLARE_GLOBAL_DATA_PTR; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +#define IMX_BOOT_IMAGE_GUID \ + EFI_GUID(0xead2005e, 0x7780, 0x400b, 0x93, 0x48, \ + 0xa2, 0x82, 0xeb, 0x85, 0x8b, 0x6b) + +struct efi_fw_image fw_images[] = { + { + .image_type_id = IMX_BOOT_IMAGE_GUID, + .fw_name = u"IMX8MM-EVK-RAW", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0x42 0x2000 mmcpart 1", + .num_images = ARRAY_SIZE(fw_images), + .images = fw_images, +}; +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + #if IS_ENABLED(CONFIG_FEC_MXC) static int setup_fec(void) { diff --git a/board/freescale/imx8mn_evk/imx8mn_evk.c b/board/freescale/imx8mn_evk/imx8mn_evk.c index c62d7a47e21..9d3f29f2253 100644 --- a/board/freescale/imx8mn_evk/imx8mn_evk.c +++ b/board/freescale/imx8mn_evk/imx8mn_evk.c @@ -5,9 +5,31 @@ #include <asm/arch/sys_proto.h> #include <asm/io.h> +#include <config.h> +#include <efi_loader.h> #include <env.h> #include <init.h> +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +#define IMX_BOOT_IMAGE_GUID \ + EFI_GUID(0xcbabf44d, 0x12cc, 0x45dd, 0xb0, 0xc5, \ + 0x29, 0xc5, 0xb7, 0x42, 0x2d, 0x34) + +struct efi_fw_image fw_images[] = { + { + .image_type_id = IMX_BOOT_IMAGE_GUID, + .fw_name = u"IMX8MN-EVK-RAW", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0 0x2000 mmcpart 1", + .num_images = ARRAY_SIZE(fw_images), + .images = fw_images, +}; +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_mmc_get_env_dev(int devno) { return devno; diff --git a/board/freescale/imx8mp_evk/imx8mp_evk.c b/board/freescale/imx8mp_evk/imx8mp_evk.c index 2ff067bc675..2a9ba7df2bb 100644 --- a/board/freescale/imx8mp_evk/imx8mp_evk.c +++ b/board/freescale/imx8mp_evk/imx8mp_evk.c @@ -4,8 +4,31 @@ */ #include <asm/arch/sys_proto.h> +#include <config.h> +#include <efi_loader.h> #include <env.h> +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +#define IMX_BOOT_IMAGE_GUID \ + EFI_GUID(0x928b33bc, 0xe58b, 0x4247, 0x9f, 0x1d, \ + 0x3b, 0xf1, 0xee, 0x1c, 0xda, 0xff) + +struct efi_fw_image fw_images[] = { + { + .image_type_id = IMX_BOOT_IMAGE_GUID, + .fw_name = u"IMX8MP-EVK-RAW", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 2=flash-bin raw 0 0x2000 mmcpart 1", + .num_images = ARRAY_SIZE(fw_images), + .images = fw_images, +}; +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + + int board_init(void) { return 0; diff --git a/board/freescale/imx8mq_evk/imx8mq_evk.c b/board/freescale/imx8mq_evk/imx8mq_evk.c index 18e83d90a08..e90c56c33ff 100644 --- a/board/freescale/imx8mq_evk/imx8mq_evk.c +++ b/board/freescale/imx8mq_evk/imx8mq_evk.c @@ -7,6 +7,7 @@ #include <asm/arch/imx8mq_pins.h> #include <asm/arch/sys_proto.h> #include <asm/mach-imx/iomux-v3.h> +#include <efi_loader.h> #include <env.h> #define UART_PAD_CTRL (PAD_CTL_DSE6 | PAD_CTL_FSEL1) @@ -22,6 +23,26 @@ static iomux_v3_cfg_t const uart_pads[] = { IMX8MQ_PAD_UART1_TXD__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), }; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +#define IMX_BOOT_IMAGE_GUID \ + EFI_GUID(0x296119cf, 0xdd70, 0x43de, 0x8a, 0xc8, \ + 0xa7, 0x05, 0x1f, 0x31, 0x25, 0x77) + +struct efi_fw_image fw_images[] = { + { + .image_type_id = IMX_BOOT_IMAGE_GUID, + .fw_name = u"IMX8MQ-EVK-RAW", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 0=flash-bin raw 0x42 0x2000 mmcpart 1", + .num_images = ARRAY_SIZE(fw_images), + .images = fw_images, +}; +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_early_init_f(void) { struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; diff --git a/board/freescale/imx93_evk/imx93_evk.c b/board/freescale/imx93_evk/imx93_evk.c index c9171df330e..d84d56be5e1 100644 --- a/board/freescale/imx93_evk/imx93_evk.c +++ b/board/freescale/imx93_evk/imx93_evk.c @@ -4,6 +4,7 @@ */ #include <env.h> +#include <efi_loader.h> #include <init.h> #include <miiphy.h> #include <netdev.h> @@ -28,6 +29,26 @@ static iomux_v3_cfg_t const uart_pads[] = { MX93_PAD_UART1_TXD__LPUART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL), }; +#if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) +#define IMX_BOOT_IMAGE_GUID \ + EFI_GUID(0xbc550d86, 0xda26, 0x4b70, 0xac, 0x05, \ + 0x2a, 0x44, 0x8e, 0xda, 0x6f, 0x21) + +struct efi_fw_image fw_images[] = { + { + .image_type_id = IMX_BOOT_IMAGE_GUID, + .fw_name = u"IMX93-11X11-EVK-RAW", + .image_index = 1, + }, +}; + +struct efi_capsule_update_info update_info = { + .dfu_string = "mmc 0=flash-bin raw 0 0x2000 mmcpart 1", + .num_images = ARRAY_SIZE(fw_images), + .images = fw_images, +}; +#endif /* EFI_HAVE_CAPSULE_SUPPORT */ + int board_early_init_f(void) { imx_iomux_v3_setup_multiple_pads(uart_pads, ARRAY_SIZE(uart_pads)); diff --git a/board/lg/star/star.c b/board/lg/star/star.c index dc593754101..0b4a433a5df 100644 --- a/board/lg/star/star.c +++ b/board/lg/star/star.c @@ -9,6 +9,7 @@ #include <fdt_support.h> #include <log.h> #include <spl_gpio.h> +#include <asm/gpio.h> static int star_fix_panel(void *fdt) { diff --git a/board/menlo/mx8menlo/Makefile b/board/menlo/mx8menlo/Makefile index 62939395ba1..c71fa9edfd9 100644 --- a/board/menlo/mx8menlo/Makefile +++ b/board/menlo/mx8menlo/Makefile @@ -16,8 +16,8 @@ endif # Common for all Toradex modules ifeq ($(CONFIG_XPL_BUILD),y) -# Necessary to create built-in.o -obj- := __dummy__.o +# Necessary to create built-in.a +obj- := __dummy__.a else obj-$(CONFIG_TDX_CFG_BLOCK) += ../../toradex/common/tdx-cfg-block.o obj-y += ../../toradex/common/tdx-common.o diff --git a/board/microchip/mpfs_icicle/mpfs_icicle.c b/board/microchip/mpfs_icicle/mpfs_icicle.c index 4d7d843dfa3..6b6984eae3f 100644 --- a/board/microchip/mpfs_icicle/mpfs_icicle.c +++ b/board/microchip/mpfs_icicle/mpfs_icicle.c @@ -9,6 +9,7 @@ #include <init.h> #include <asm/global_data.h> #include <asm/io.h> +#include <asm/sections.h> DECLARE_GLOBAL_DATA_PTR; @@ -50,6 +51,68 @@ static void read_device_serial_number(u8 *response, u8 response_size) response_buf[idx] = readb(MPFS_SYS_SERVICE_MAILBOX + idx); } +#if defined(CONFIG_MULTI_DTB_FIT) +int board_fit_config_name_match(const char *name) +{ + const void *fdt; + int list_len; + + /* + * If there's not a HSS provided dtb, there's no point re-selecting + * since we'd just end up re-selecting the same dtb again. + */ + if (!gd->arch.firmware_fdt_addr) + return -EINVAL; + + fdt = (void *)gd->arch.firmware_fdt_addr; + + list_len = fdt_stringlist_count(fdt, 0, "compatible"); + if (list_len < 1) + return -EINVAL; + + for (int i = 0; i < list_len; i++) { + int len, match; + const char *compat; + char *devendored; + + compat = fdt_stringlist_get(fdt, 0, "compatible", i, &len); + if (!compat) + return -EINVAL; + + strtok((char *)compat, ","); + + devendored = strtok(NULL, ","); + if (!devendored) + return -EINVAL; + + match = strcmp(devendored, name); + if (!match) + return 0; + } + + return -EINVAL; +} +#endif + +int board_fdt_blob_setup(void **fdtp) +{ + fdtp = (void *)_end; + + /* + * The devicetree provided by the previous stage is very minimal due to + * severe space constraints. The firmware performs no fixups etc. + * U-Boot, if providing a devicetree, almost certainly has a better + * more complete one than the firmware so that provided by the firmware + * is ignored for OF_SEPARATE. + */ + if (IS_ENABLED(CONFIG_OF_BOARD) && !IS_ENABLED(CONFIG_MULTI_DTB_FIT)) { + if (gd->arch.firmware_fdt_addr) + fdtp = (void *)(uintptr_t)gd->arch.firmware_fdt_addr; + } + + return 0; +} + int board_init(void) { /* For now nothing to do here. */ diff --git a/board/phytec/common/Makefile b/board/phytec/common/Makefile index 8126f7356e1..948f9dab626 100644 --- a/board/phytec/common/Makefile +++ b/board/phytec/common/Makefile @@ -3,8 +3,8 @@ # Author: Teresa Remmet <t.remmet@phytec.de> ifdef CONFIG_XPL_BUILD -# necessary to create built-in.o -obj- := __dummy__.o +# necessary to create built-in.a +obj- := __dummy__.a endif obj-y += phytec_som_detection.o phytec_som_detection_blocks.o diff --git a/board/phytec/phycore_am62x/rm-cfg.yaml b/board/phytec/phycore_am62x/rm-cfg.yaml index e4221f82f92..26d99b03b80 100644 --- a/board/phytec/phycore_am62x/rm-cfg.yaml +++ b/board/phytec/phycore_am62x/rm-cfg.yaml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ -# Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/ +# Copyright (C) 2022-2024 Texas Instruments Incorporated - https://www.ti.com/ # -# Resource management configuration for AM62 +# Resource management configuration for AM62X # --- @@ -244,7 +244,7 @@ rm-cfg: subhdr: magic: 0x7B25 size: 8 - resasg_entries_size: 960 + resasg_entries_size: 976 reserved: 0 resasg_entries: - @@ -285,11 +285,23 @@ rm-cfg: reserved: 0 - start_resource: 0 - num_resource: 4 + num_resource: 2 type: 320 host_id: 12 reserved: 0 - + start_resource: 2 + num_resource: 2 + type: 320 + host_id: 35 + reserved: 0 + - + start_resource: 2 + num_resource: 2 + type: 320 + host_id: 36 + reserved: 0 + - start_resource: 4 num_resource: 4 type: 320 @@ -501,13 +513,13 @@ rm-cfg: reserved: 0 - start_resource: 44 - num_resource: 36 + num_resource: 35 type: 1802 host_id: 35 reserved: 0 - start_resource: 44 - num_resource: 36 + num_resource: 35 type: 1802 host_id: 36 reserved: 0 @@ -543,7 +555,7 @@ rm-cfg: reserved: 0 - start_resource: 909 - num_resource: 627 + num_resource: 626 type: 1805 host_id: 128 reserved: 0 diff --git a/board/qualcomm/MAINTAINERS b/board/qualcomm/MAINTAINERS new file mode 100644 index 00000000000..3767a2a7949 --- /dev/null +++ b/board/qualcomm/MAINTAINERS @@ -0,0 +1,24 @@ +# This MAINTAINERS file is for folks with an interest in a particular platform +# or board under ARM SNAPDRAGON + +QUALCOMM DRAGONWING QCS615 +M: Aswin Murugan <aswin.murugan@oss.qualcomm.com> +S: Maintained +N: qcs615 + +# RB3 Gen 2 and similar boards +QUALCOMM DRAGONWING QCS6490 +M: Casey Connolly <casey.connolly@linaro.org> +S: Maintained +N: qcs6490 +N: sc7280 + +QUALCOMM DRAGONWING QCS8300 +M: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com> +S: Maintained +N: qcs8300 + +QUALCOMM DRAGONWING QCS9100 +M: Varadarajan Narayanan <quic_varada@quicinc.com> +S: Maintained +N: qcs9100 diff --git a/board/raidsonic/ib62x0/MAINTAINERS b/board/raidsonic/ib62x0/MAINTAINERS index 423aa0cf253..2822eb0d29d 100644 --- a/board/raidsonic/ib62x0/MAINTAINERS +++ b/board/raidsonic/ib62x0/MAINTAINERS @@ -1,5 +1,5 @@ IB62X0 BOARD -M: Luka Perkov <luka@openwrt.org> +M: Tony Dinh <mibodhi@gmail.com> S: Maintained F: board/raidsonic/ib62x0/ F: include/configs/ib62x0.h diff --git a/board/samsung/coreprimevelte/MAINTAINERS b/board/samsung/coreprimevelte/MAINTAINERS index 0902117e8b3..9dccd041ffb 100644 --- a/board/samsung/coreprimevelte/MAINTAINERS +++ b/board/samsung/coreprimevelte/MAINTAINERS @@ -1,5 +1,5 @@ Samsung Galaxy Core Prime VE LTE support -M: Duje Mihanović <duje.mihanovic@skole.hr> +M: Duje Mihanović <duje@dujemihanovic.xyz> S: Maintained T: git git://git.dujemihanovic.xyz/u-boot.git F: board/samsung/coreprimevelte/ diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c index 0bef68d2fb2..3bbd95201b5 100644 --- a/board/samsung/e850-96/e850-96.c +++ b/board/samsung/e850-96/e850-96.c @@ -19,8 +19,17 @@ int dram_init_banksize(void) int board_init(void) { + return 0; +} + +int board_late_init(void) +{ int err; + /* + * Do this in board_late_init() to make sure MMC is not probed before + * efi_init_early(). + */ err = load_ldfw(); if (err) printf("ERROR: LDFW loading failed (%d)\n", err); diff --git a/board/samsung/origen/Makefile b/board/samsung/origen/Makefile index 940f689a601..30c637e322a 100644 --- a/board/samsung/origen/Makefile +++ b/board/samsung/origen/Makefile @@ -3,8 +3,8 @@ # Copyright (C) 2011 Samsung Electronics ifdef CONFIG_XPL_BUILD -# necessary to create built-in.o -obj- := __dummy__.o +# necessary to create built-in.a +obj- := __dummy__.a hostprogs-y := tools/mkorigenspl always := $(hostprogs-y) diff --git a/board/samsung/smdkv310/Makefile b/board/samsung/smdkv310/Makefile index b7f9d5a254c..360300a7851 100644 --- a/board/samsung/smdkv310/Makefile +++ b/board/samsung/smdkv310/Makefile @@ -3,8 +3,8 @@ # Copyright (C) 2011 Samsung Electronics ifdef CONFIG_XPL_BUILD -# necessary to create built-in.o -obj- := __dummy__.o +# necessary to create built-in.a +obj- := __dummy__.a hostprogs-y := tools/mksmdkv310spl always := $(hostprogs-y) diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c index d97945e58fc..43f4edc39e9 100644 --- a/board/sandbox/sandbox.c +++ b/board/sandbox/sandbox.c @@ -101,7 +101,6 @@ enum env_location env_get_location(enum env_operation op, int prio) int dram_init(void) { - gd->ram_size = CFG_SYS_SDRAM_SIZE; return 0; } diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 84799879e85..1b4b7d87163 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -296,6 +296,11 @@ M: Adam Sampson <ats@offog.org> S: Maintained F: configs/Linksprite_pcDuino3_Nano_defconfig +LIONTRON H-A133L BOARD +M: Andre Przywara <andre.przywara@arm.com> +S: Maintained +F: configs/liontron-h-a133l_defconfig + MARSBOARD-A10 BOARD M: Aleksei Mamlin <mamlinav@gmail.com> S: Maintained @@ -596,6 +601,11 @@ M: Peter Korsgaard <peter@korsgaard.com> S: Maintained F: configs/Yones_Toptech_BS1078_V2_defconfig +YUZUKIHD CHAMELEON BOARD +M: Andre Przywara <andre.przywara@arm.com> +S: Maintained +F: configs/yuzukihd-chameleon_defconfig + ZEROPI BOARD M: Yu-Tung Chang <mtwget@gmail.com> S: Maintained diff --git a/board/sunxi/board.c b/board/sunxi/board.c index feec95658a2..943b6221b8a 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -114,7 +114,7 @@ void i2c_init_board(void) clock_twi_onoff(5, 1); sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI); sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI); -#elif CONFIG_MACH_SUN50I_H616 +#elif defined(CONFIG_MACH_SUN50I_H616) clock_twi_onoff(5, 1); sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI); sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI); @@ -435,7 +435,7 @@ static void mmc_pinmux_setup(int sdc) sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP); sunxi_gpio_set_drv(pin, 2); } -#elif defined(CONFIG_MACH_SUN50I_H616) +#elif defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_A133) /* SDC2: PC0-PC1, PC5-PC6, PC8-PC11, PC13-PC16 */ for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(16); pin++) { if (pin > SUNXI_GPC(1) && pin < SUNXI_GPC(5)) diff --git a/board/thead/th1520_lpi4a/spl.c b/board/thead/th1520_lpi4a/spl.c index 25dfa387c36..d75fa6f3eff 100644 --- a/board/thead/th1520_lpi4a/spl.c +++ b/board/thead/th1520_lpi4a/spl.c @@ -39,6 +39,9 @@ void board_init_f(ulong dummy) if (ret) panic("failed to bind CPU: %d\n", ret); + riscv_cpu_setup(); + th1520_kick_secondary_cores(); + spl_dram_init(); icache_enable(); diff --git a/board/toradex/common/Makefile b/board/toradex/common/Makefile index 7e3905445a5..24496a7c997 100644 --- a/board/toradex/common/Makefile +++ b/board/toradex/common/Makefile @@ -3,8 +3,8 @@ # Common for all Toradex modules ifeq ($(CONFIG_XPL_BUILD),y) -# Necessary to create built-in.o -obj- := __dummy__.o +# Necessary to create built-in.a +obj- := __dummy__.a else obj-$(CONFIG_TDX_CFG_BLOCK) += tdx-cfg-block.o obj-y += tdx-common.o diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 8ffe7429901..ceb58da6d3c 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * (C) Copyright 2014 - 2022, Xilinx, Inc. - * (C) Copyright 2022 - 2023, Advanced Micro Devices, Inc. + * (C) Copyright 2022 - 2025, Advanced Micro Devices, Inc. * * Michal Simek <michal.simek@amd.com> */ @@ -712,3 +712,34 @@ phys_addr_t board_get_usable_ram_top(phys_size_t total_size) } #endif + +#if IS_ENABLED(CONFIG_BOARD_RNG_SEED) +/* Use hardware rng to seed Linux random. */ +__weak int board_rng_seed(struct abuf *buf) +{ + struct udevice *dev; + ulong len = 64; + u64 *data; + + if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) { + printf("No RNG device\n"); + return -ENODEV; + } + + data = malloc(len); + if (!data) { + printf("Out of memory\n"); + return -ENOMEM; + } + + if (dm_rng_read(dev, data, len)) { + printf("Reading RNG failed\n"); + free(data); + return -EIO; + } + + abuf_init_set(buf, data, len); + + return 0; +} +#endif diff --git a/boot/Kconfig b/boot/Kconfig index b0548358e8b..2ff6f003738 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -11,6 +11,17 @@ config ANDROID_BOOT_IMAGE This enables support for booting images which use the Android image format header. +config ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR + bool "Android Boot Image ignore addr" + default n + help + This ignore kernel/ramdisk load addr specified in androidboot header. + + There is a concern on exposing the whole memory to image loading is + dangerous. Also, since it's not always possible to change the load + addr by repacking the boot.img (mainly due to AVB signature mismatch), + we need a way to use kernel_addr_r and ramdisk_addr_r. + config TIMESTAMP bool "Show image date and time when displaying image information" default y if CMD_DATE diff --git a/boot/bootm.c b/boot/bootm.c index 108ca7fb472..4bdca22ea8c 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -623,12 +623,16 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) */ if (os.type == IH_TYPE_KERNEL_NOLOAD && os.comp != IH_COMP_NONE) { ulong req_size = ALIGN(image_len * 4, SZ_1M); + phys_addr_t addr; - load = lmb_alloc(req_size, SZ_2M); - if (!load) + err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, &addr, + req_size, LMB_NONE); + if (err) return 1; - os.load = load; - images->ep = load; + + load = (ulong)addr; + os.load = (ulong)addr; + images->ep = (ulong)addr; debug("Allocated %lx bytes at %lx for kernel (size %lx) decompression\n", req_size, load, image_len); } @@ -698,9 +702,18 @@ static int bootm_load_os(struct bootm_headers *images, int boot_progress) images->os.end = relocated_addr + image_size; } - if (CONFIG_IS_ENABLED(LMB)) - lmb_reserve(images->os.load, (load_end - images->os.load), - LMB_NONE); + if (CONFIG_IS_ENABLED(LMB)) { + phys_addr_t load; + + load = (phys_addr_t)images->os.load; + err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &load, + (load_end - images->os.load), LMB_NONE); + if (err) { + log_err("Unable to allocate memory %#lx for loading OS\n", + images->os.load); + return 1; + } + } return 0; } diff --git a/boot/bootm_os.c b/boot/bootm_os.c index a3c7cb5332e..88f7c183867 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -402,6 +402,17 @@ static int do_bootm_elf(int flag, struct bootm_info *bmi) if (flag != BOOTM_STATE_OS_GO) return 0; + /* + * Required per RISC-V boot protocol: + * a0(argc) = hartid of the current core + * a1(argv) = address of the devicetree in memory + * https://www.kernel.org/doc/html/latest/arch/riscv/boot.html#register-state + */ +#if defined(CONFIG_RISCV) + bmi->argc = gd->arch.boot_hart; + bmi->argv = (char **)bmi->images->ft_addr; +#endif + bootelf(bmi->images->ep, flags, bmi->argc, bmi->argv); return 1; diff --git a/boot/image-android.c b/boot/image-android.c index 459cdb8456c..1cd2060bb3f 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -268,7 +268,8 @@ static ulong android_image_get_kernel_addr(struct andr_image_data *img_data, * * Otherwise, we will return the actual value set by the user. */ - if (img_data->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR) { + if (img_data->kernel_addr == ANDROID_IMAGE_DEFAULT_KERNEL_ADDR || + IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR)) { if (comp == IH_COMP_NONE) return img_data->kernel_ptr; return env_get_ulong("kernel_addr_r", 16, 0); @@ -464,7 +465,8 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, */ if (img_data.header_version > 2) { /* Ramdisk can't be used in-place, copy it to ramdisk_addr_r */ - if (img_data.ramdisk_addr == ANDROID_IMAGE_DEFAULT_RAMDISK_ADDR) { + if (img_data.ramdisk_addr == ANDROID_IMAGE_DEFAULT_RAMDISK_ADDR || + IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR)) { ramdisk_ptr = env_get_ulong("ramdisk_addr_r", 16, 0); if (!ramdisk_ptr) { printf("Invalid ramdisk_addr_r to copy ramdisk into\n"); @@ -489,7 +491,8 @@ int android_image_get_ramdisk(const void *hdr, const void *vendor_boot_img, /* Ramdisk can be used in-place, use current ptr */ if (img_data.ramdisk_addr == 0 || img_data.ramdisk_addr == ANDROID_IMAGE_DEFAULT_RAMDISK_ADDR || - img_data.ramdisk_addr == img_data.kernel_addr) { + img_data.ramdisk_addr == img_data.kernel_addr || + IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE_IGNORE_BLOB_ADDR)) { *rd_data = img_data.ramdisk_ptr; } else { ramdisk_ptr = img_data.ramdisk_addr; @@ -677,7 +680,7 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img, { struct andr_image_data img_data; const struct andr_boot_img_hdr_v0 *hdr; - const struct andr_vnd_boot_img_hdr *vhdr; + const struct andr_vnd_boot_img_hdr *vhdr = NULL; hdr = map_sysmem(hdr_addr, sizeof(*hdr)); if (vendor_boot_img != -1) diff --git a/boot/image-board.c b/boot/image-board.c index 514f8e63f9c..005d60caf5c 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -16,6 +16,7 @@ #include <fpga.h> #include <image.h> #include <init.h> +#include <lmb.h> #include <log.h> #include <mapmem.h> #include <rtc.h> @@ -538,6 +539,7 @@ int boot_get_ramdisk(char const *select, struct bootm_headers *images, int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end) { + int err; char *s; phys_addr_t initrd_high; int initrd_copy_to_ram = 1; @@ -559,25 +561,30 @@ int boot_ramdisk_high(ulong rd_data, ulong rd_len, ulong *initrd_start, if (rd_data) { if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */ + phys_addr_t initrd_addr; + debug(" in-place initrd\n"); *initrd_start = rd_data; *initrd_end = rd_data + rd_len; - lmb_reserve(rd_data, rd_len, LMB_NONE); + initrd_addr = (phys_addr_t)rd_data; + err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &initrd_addr, + rd_len, LMB_NONE); + if (err) { + puts("in-place initrd alloc failed\n"); + goto error; + } } else { - if (initrd_high) - *initrd_start = - (ulong)lmb_alloc_base(rd_len, - 0x1000, - initrd_high, - LMB_NONE); - else - *initrd_start = (ulong)lmb_alloc(rd_len, - 0x1000); + enum lmb_mem_type type = initrd_high ? + LMB_MEM_ALLOC_MAX : LMB_MEM_ALLOC_ANY; - if (*initrd_start == 0) { + err = lmb_alloc_mem(type, 0x1000, &initrd_high, rd_len, + LMB_NONE); + if (err) { puts("ramdisk - allocation error\n"); goto error; } + + *initrd_start = (ulong)initrd_high; bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK); *initrd_end = *initrd_start + rd_len; @@ -828,9 +835,10 @@ int boot_get_loadable(struct bootm_headers *images) */ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end) { - int barg; + int barg, err; char *cmdline; char *s; + phys_addr_t addr; /* * Help the compiler detect that this function is only called when @@ -840,12 +848,14 @@ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end) return 0; barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE); - cmdline = (char *)(ulong)lmb_alloc_base(barg, 0xf, - env_get_bootm_mapsize() + env_get_bootm_low(), - LMB_NONE); - if (!cmdline) + addr = env_get_bootm_mapsize() + env_get_bootm_low(); + + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0xf, &addr, barg, LMB_NONE); + if (err) return -1; + cmdline = (char *)(uintptr_t)addr; + s = env_get("bootargs"); if (!s) s = ""; @@ -874,14 +884,16 @@ int boot_get_cmdline(ulong *cmd_start, ulong *cmd_end) */ int boot_get_kbd(struct bd_info **kbd) { - *kbd = (struct bd_info *)(ulong)lmb_alloc_base(sizeof(struct bd_info), - 0xf, - env_get_bootm_mapsize() + - env_get_bootm_low(), - LMB_NONE); - if (!*kbd) + int err; + phys_addr_t addr; + + addr = env_get_bootm_mapsize() + env_get_bootm_low(); + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0xf, &addr, + sizeof(struct bd_info), LMB_NONE); + if (err) return -1; + *kbd = (struct bd_info *)(uintptr_t)addr; **kbd = *gd->bd; debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 1c5d9426b86..3f0ac54f76f 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -72,13 +72,15 @@ static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr) static void boot_fdt_reserve_region(u64 addr, u64 size, u32 flags) { long ret; + phys_addr_t rsv_addr; - ret = lmb_reserve(addr, size, flags); + rsv_addr = (phys_addr_t)addr; + ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &rsv_addr, size, flags); if (!ret) { debug(" reserving fdt memory region: addr=%llx size=%llx flags=%x\n", (unsigned long long)addr, (unsigned long long)size, flags); - } else if (ret != -EEXIST) { + } else if (ret != -EEXIST && ret != -EINVAL) { puts("ERROR: reserving fdt memory region failed "); printf("(addr=%llx size=%llx flags=%x)\n", (unsigned long long)addr, @@ -155,7 +157,7 @@ void boot_fdt_add_mem_rsv_regions(void *fdt_blob) */ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) { - u64 start, size, usable, addr, low, mapsize; + u64 start, size, usable, low, mapsize; void *fdt_blob = *of_flat_tree; void *of_start = NULL; char *fdt_high; @@ -163,6 +165,7 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) int bank; int err; int disable_relocation = 0; + phys_addr_t addr; /* nothing to do */ if (*of_size == 0) @@ -180,23 +183,32 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) /* If fdt_high is set use it to select the relocation address */ fdt_high = env_get("fdt_high"); if (fdt_high) { - ulong desired_addr = hextoul(fdt_high, NULL); + ulong high_addr = hextoul(fdt_high, NULL); - if (desired_addr == ~0UL) { + if (high_addr == ~0UL) { /* All ones means use fdt in place */ of_start = fdt_blob; - lmb_reserve(map_to_sysmem(of_start), of_len, LMB_NONE); - disable_relocation = 1; - } else if (desired_addr) { - addr = lmb_alloc_base(of_len, 0x1000, desired_addr, - LMB_NONE); - of_start = map_sysmem(addr, of_len); - if (of_start == NULL) { - puts("Failed using fdt_high value for Device Tree"); + addr = map_to_sysmem(fdt_blob); + err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, + of_len, LMB_NONE); + if (err) { + printf("Failed to reserve memory for fdt at %#llx\n", + (u64)addr); goto error; } + + disable_relocation = 1; } else { - addr = lmb_alloc(of_len, 0x1000); + enum lmb_mem_type type = high_addr ? + LMB_MEM_ALLOC_MAX : LMB_MEM_ALLOC_ANY; + + addr = high_addr; + err = lmb_alloc_mem(type, 0x1000, &addr, of_len, + LMB_NONE); + if (err) { + puts("Failed to allocate memory for Device Tree relocation\n"); + goto error; + } of_start = map_sysmem(addr, of_len); } } else { @@ -218,11 +230,15 @@ int boot_relocate_fdt(char **of_flat_tree, ulong *of_size) * for LMB allocation. */ usable = min(start + size, low + mapsize); - addr = lmb_alloc_base(of_len, 0x1000, usable, LMB_NONE); - of_start = map_sysmem(addr, of_len); - /* Allocation succeeded, use this block. */ - if (of_start != NULL) - break; + addr = usable; + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, 0x1000, + &addr, of_len, LMB_NONE); + if (!err) { + of_start = map_sysmem(addr, of_len); + /* Allocation succeeded, use this block. */ + if (of_start) + break; + } /* * Reduce the mapping size in the next bank @@ -675,7 +691,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) /* Delete the old LMB reservation */ if (CONFIG_IS_ENABLED(LMB) && lmb) - lmb_free(map_to_sysmem(blob), fdt_totalsize(blob)); + lmb_free(map_to_sysmem(blob), fdt_totalsize(blob), LMB_NONE); ret = fdt_shrink_to_minimum(blob, 0); if (ret < 0) @@ -683,8 +699,17 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, bool lmb) of_size = ret; /* Create a new LMB reservation */ - if (CONFIG_IS_ENABLED(LMB) && lmb) - lmb_reserve(map_to_sysmem(blob), of_size, LMB_NONE); + if (CONFIG_IS_ENABLED(LMB) && lmb) { + phys_addr_t fdt_addr; + + fdt_addr = map_to_sysmem(blob); + ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &fdt_addr, + of_size, LMB_NONE); + if (ret) { + printf("Failed to reserve memory for the fdt at %#llx\n", + (u64)fdt_addr); + } + } if (IS_ENABLED(CONFIG_OF_BOARD_SETUP_EXTENDED) && !skip_board_fixup) ft_board_setup_ex(blob, gd->bd); diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c index 82f217aaf86..eb4d7723481 100644 --- a/boot/pxe_utils.c +++ b/boot/pxe_utils.c @@ -1348,7 +1348,7 @@ static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long bas case T_ONTIMEOUT: err = parse_sliteral(&p, &label_name); - if (label_name) { + if (err >= 0 && label_name) { if (cfg->default_label) free(cfg->default_label); @@ -1360,7 +1360,7 @@ static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long bas case T_FALLBACK: err = parse_sliteral(&p, &label_name); - if (label_name) { + if (err >= 0 && label_name) { if (cfg->fallback_label) free(cfg->fallback_label); diff --git a/boot/scene_menu.c b/boot/scene_menu.c index 8db6a2b2f4d..23404172093 100644 --- a/boot/scene_menu.c +++ b/boot/scene_menu.c @@ -571,14 +571,15 @@ int scene_menu_display(struct scene_obj_menu *menu) return log_msg_ret("txt", -EINVAL); str = expo_get_str(exp, txt->gen.str_id); - printf("%s\n\n", str); + printf("%s\n\n", str ? str : ""); } if (list_empty(&menu->item_head)) return 0; pointer = scene_obj_find(scn, menu->pointer_id, SCENEOBJT_TEXT); - pstr = expo_get_str(scn->expo, pointer->gen.str_id); + if (pointer) + pstr = expo_get_str(scn->expo, pointer->gen.str_id); list_for_each_entry(item, &menu->item_head, sibling) { struct scene_obj_txt *key = NULL, *label = NULL; diff --git a/cmd/Kconfig b/cmd/Kconfig index ed741d43cea..1e86773a143 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -153,6 +153,7 @@ config CMD_CONFIG bool "config" default SANDBOX select BUILD_BIN2C + select GZIP help Print ".config" contents. @@ -189,6 +190,12 @@ config CMD_FWU_METADATA help Command to read the metadata and dump it's contents +config CMD_HELP + bool "help" + default y + help + Command to show help information about other commands. + config CMD_HISTORY bool "history" depends on CMDLINE_EDITING @@ -1864,12 +1871,6 @@ config CMD_DHCP6 if CMD_DHCP6 -config DHCP6_PXE_CLIENTARCH - hex - default 0x16 if ARM64 - default 0x15 if ARM - default 0xFF - config DHCP6_PXE_DHCP_OPTION bool "Request & store 'pxe_configfile' from DHCP6 server" @@ -1977,12 +1978,22 @@ config BOOTP_PXE help Supported for ARM, ARM64, and x86 for now. -config BOOTP_PXE_CLIENTARCH - hex - depends on BOOTP_PXE - default 0x16 if ARM64 - default 0x15 if ARM - default 0x0 if X86 +config DHCP_PXE_CLIENTARCH + hex "DCHCP client system architecture type" + depends on BOOTP_PXE || CMD_DHCP6 + default 0x16 if ARM64 # arm 64 uboot + default 0x15 if ARM # arm 32 uboot + default 0x0 if X86 # x86 BIOS + default 0xFF # DHCP option not sent + help + DHCP option 93 (defined in RFC4578) or DHCPv6 option 61 (defined in + RFC 5970) is used to transmit the client system architecture type + to the DHCP server. The DHCP server may use this information to + choose the boot file. For a complete list of assigned values see + https://www.iana.org/assignments/dhcpv6-parameters#processor-architecture. + + If the value is set to the reserved value 0xFF, the DHCP option will + not be sent by U-Boot. config BOOTP_PXE_DHCP_OPTION bool "Request & store 'pxe_configfile' from BOOTP/DHCP server" @@ -2004,23 +2015,6 @@ config BOOTP_RANDOM_XID Selecting this will allow for a random transaction ID to get selected for each BOOTP/DHCPv4 exchange. -if CMD_DHCP6 - -config DHCP6_PXE_CLIENTARCH - hex - default 0x16 if ARM64 - default 0x15 if ARM - default 0xFF - -config DHCP6_PXE_DHCP_OPTION - bool "Request & store 'pxe_configfile' from DHCP6 server" - -config DHCP6_ENTERPRISE_ID - int "Enterprise ID to send in DHCPv6 Vendor Class Option" - default 0 - -endif - config CMD_TFTPPUT bool "tftp put" depends on CMD_TFTPBOOT @@ -2086,12 +2080,6 @@ config CMD_CDP and to retrieve configuration data including the VLAN id using the proprietary Cisco Discovery Protocol (CDP). -config CMD_SNTP - bool "sntp" - select PROT_UDP - help - Synchronize RTC via network - config CMD_LINK_LOCAL bool "linklocal" depends on (LIB_RAND || LIB_HW_RAND) @@ -2169,6 +2157,13 @@ config CMD_PING help Send ICMP ECHO_REQUEST to network host +config CMD_SNTP + bool "sntp" + select PROT_UDP if NET + select PROT_UDP_LWIP if NET_LWIP + help + Synchronize RTC via network + config CMD_TFTPBOOT bool "tftp" select PROT_UDP_LWIP if NET_LWIP diff --git a/cmd/Makefile b/cmd/Makefile index 80cf70b7fe8..40f6ac4a85e 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -7,7 +7,7 @@ ifndef CONFIG_XPL_BUILD # core command obj-y += boot.o obj-$(CONFIG_CMD_BOOTM) += bootm.o -obj-y += help.o +obj-$(CONFIG_CMD_HELP) += help.o obj-y += panic.o obj-y += version.o @@ -133,7 +133,8 @@ obj-$(CONFIG_CMD_NAND) += nand.o ifdef CONFIG_NET obj-$(CONFIG_CMD_NET) += net.o net-common.o else ifdef CONFIG_NET_LWIP -obj-$(CONFIG_CMD_NET) += net-lwip.o net-common.o +obj-$(CONFIG_CMD_NET) += net-common.o +obj-y += lwip/ endif obj-$(CONFIG_ENV_SUPPORT) += nvedit.o obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o diff --git a/cmd/abootimg.c b/cmd/abootimg.c index 44de00fb9c9..6fb52153786 100644 --- a/cmd/abootimg.c +++ b/cmd/abootimg.c @@ -96,7 +96,7 @@ static int abootimg_get_dtb_load_addr(int argc, char *const argv[]) return CMD_RET_USAGE; struct andr_image_data img_data = {0}; const struct andr_boot_img_hdr_v0 *hdr; - const struct andr_vnd_boot_img_hdr *vhdr; + const struct andr_vnd_boot_img_hdr *vhdr = NULL; hdr = map_sysmem(abootimg_addr(), sizeof(*hdr)); if (get_avendor_bootimg_addr() != -1) diff --git a/cmd/booti.c b/cmd/booti.c index 7e6d9426299..e6f67d6e136 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -30,6 +30,7 @@ static int booti_start(struct bootm_info *bmi) uint8_t *temp; ulong dest; ulong dest_end; + phys_addr_t ep_addr; unsigned long comp_len; unsigned long decomp_len; int ctype; @@ -88,7 +89,14 @@ static int booti_start(struct bootm_info *bmi) images->os.start = relocated_addr; images->os.end = relocated_addr + image_size; - lmb_reserve(images->ep, le32_to_cpu(image_size), LMB_NONE); + ep_addr = (phys_addr_t)images->ep; + ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &ep_addr, + le32_to_cpu(image_size), LMB_NONE); + if (ret) { + printf("Failed to allocate memory for the image at %#llx\n", + (unsigned long long)images->ep); + return 1; + } /* * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not diff --git a/cmd/bootz.c b/cmd/bootz.c index 99318ff213f..44af7d012aa 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -28,6 +28,7 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, { ulong zi_start, zi_end; struct bootm_info bmi; + phys_addr_t ep_addr; int ret; bootm_init(&bmi); @@ -56,7 +57,14 @@ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, if (ret != 0) return 1; - lmb_reserve(images->ep, zi_end - zi_start, LMB_NONE); + ep_addr = (phys_addr_t)images->ep; + ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &ep_addr, zi_end - zi_start, + LMB_NONE); + if (ret) { + printf("Failed to allocate memory for the image at %#llx\n", + (unsigned long long)images->ep); + return 1; + } /* * Handle the BOOTM_STATE_FINDOTHER state ourselves as we do not diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 6e14d34a6bd..8ac0fb98e02 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -35,6 +35,7 @@ static int avail_row; #define EFICONFIG_DESCRIPTION_MAX 32 #define EFICONFIG_OPTIONAL_DATA_MAX 64 +#define EFICONFIG_URI_MAX 512 #define EFICONFIG_MENU_HEADER_ROW_NUM 3 #define EFICONFIG_MENU_DESC_ROW_NUM 5 @@ -539,6 +540,40 @@ struct efi_device_path *eficonfig_create_device_path(struct efi_device_path *dp_ } /** + * eficonfig_create_uri_device_path() - Create an URI based device path + * @uri_str: URI string to be added to the device path + * + * Take the u16 string, convert it to a u8 string, and create a URI + * device path. This will be used for the EFI HTTP boot. + * + * Return: pointer to the URI device path on success, NULL on failure + */ +static struct efi_device_path *eficonfig_create_uri_device_path(u16 *uri_str) +{ + char *pos, *p; + u32 len = 0; + efi_uintn_t uridp_len; + struct efi_device_path_uri *uridp; + + len = utf16_utf8_strlen(uri_str); + + uridp_len = sizeof(struct efi_device_path) + len + 1; + uridp = efi_alloc(uridp_len + sizeof(EFI_DP_END)); + if (!uridp) + return NULL; + + uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI; + uridp->dp.length = uridp_len; + p = (char *)&uridp->uri; + utf16_utf8_strcpy(&p, uri_str); + pos = (char *)uridp + uridp_len; + memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END)); + + return &uridp->dp; +} + +/** * eficonfig_file_selected() - handler of file selection * * @data: pointer to the data of selected entry @@ -984,6 +1019,22 @@ static efi_status_t eficonfig_boot_add_optional_data(void *data) } /** + * eficonfig_boot_add_uri() - handle user input for HTTP Boot URI + * + * @data: pointer to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_add_uri(void *data) +{ + struct eficonfig_select_file_info *file_info = data; + + return handle_user_input(file_info->uri, EFICONFIG_URI_MAX, 24, + "\n ** Edit URI **\n" + "\n" + " enter HTTP Boot URI:"); +} + +/** * eficonfig_boot_edit_save() - handler to save the boot option * * @data: pointer to the internal boot option structure @@ -998,7 +1049,8 @@ static efi_status_t eficonfig_boot_edit_save(void *data) bo->edit_completed = false; return EFI_NOT_READY; } - if (u16_strlen(bo->file_info.current_path) == 0) { + if (u16_strlen(bo->file_info.current_path) == 0 && + u16_strlen(bo->file_info.uri) == 0) { eficonfig_print_msg("File is not selected!"); bo->edit_completed = false; return EFI_NOT_READY; @@ -1024,9 +1076,19 @@ efi_status_t eficonfig_process_clear_file_selection(void *data) file_info->current_path[0] = u'\0'; file_info->dp_volume = NULL; + if (file_info->uri) + file_info->uri[0] = u'\0'; + return EFI_ABORTED; } +static struct eficonfig_item select_boot_file_menu_items[] = { + {"Select File", eficonfig_process_select_file}, + {"Enter URI", eficonfig_boot_add_uri}, + {"Clear", eficonfig_process_clear_file_selection}, + {"Quit", eficonfig_process_quit}, +}; + static struct eficonfig_item select_file_menu_items[] = { {"Select File", eficonfig_process_select_file}, {"Clear", eficonfig_process_clear_file_selection}, @@ -1042,16 +1104,30 @@ static struct eficonfig_item select_file_menu_items[] = { efi_status_t eficonfig_process_show_file_option(void *data) { efi_status_t ret; + unsigned int menu_count; struct efimenu *efi_menu; + struct eficonfig_item *menu_items; + struct eficonfig_select_file_info *file_info = data; + + menu_items = file_info->uri ? select_boot_file_menu_items : + select_file_menu_items; + + menu_count = file_info->uri ? + ARRAY_SIZE(select_boot_file_menu_items) : + ARRAY_SIZE(select_file_menu_items); + + menu_items[0].data = data; + menu_items[1].data = data; + menu_items[2].data = data; - select_file_menu_items[0].data = data; - select_file_menu_items[1].data = data; - efi_menu = eficonfig_create_fixed_menu(select_file_menu_items, - ARRAY_SIZE(select_file_menu_items)); + efi_menu = eficonfig_create_fixed_menu(menu_items, menu_count); if (!efi_menu) return EFI_OUT_OF_RESOURCES; - ret = eficonfig_process_common(efi_menu, " ** Update File **", + ret = eficonfig_process_common(efi_menu, + file_info->uri ? + " ** Update File/URI **" : + " ** Update File **", eficonfig_menu_desc, eficonfig_display_statusline, eficonfig_print_entry, @@ -1121,6 +1197,14 @@ out: file_info->current_path[len] = u'\0'; file_info->current_volume = tmp->current_volume; file_info->dp_volume = tmp->dp_volume; + + /* + * File being selected, set the URI string to + * null so that the file gets picked as the + * boot image. + */ + if (file_info->uri) + file_info->uri[0] = u'\0'; } list_for_each_safe(pos, n, &tmp->filepath_list) { @@ -1224,6 +1308,12 @@ static efi_status_t prepare_file_selection_entry(struct efimenu *efi_menu, char efi_handle_t handle; char *devname; + /* Check for URI based boot file */ + if (file_info->uri && utf16_utf8_strlen(file_info->uri)) + return create_boot_option_entry(efi_menu, title, file_info->uri, + eficonfig_process_show_file_option, + file_info); + devname = calloc(1, EFICONFIG_VOLUME_PATH_MAX + 1); if (!devname) return EFI_OUT_OF_RESOURCES; @@ -1341,6 +1431,27 @@ out: } /** + * fill_dp_uri() - copy the URI string in the device path + * @dp: pointer to the URI device path + * @uri_str: URI string to be copied + * + * Copy the passed URI string to the URI device path. This + * requires utf8_utf16_strcpy() to copy the u16 string to + * the u8 array in the device path structure. + * + * Return: None + */ +static void fill_dp_uri(struct efi_device_path *dp, u16 **uri_str) +{ + u16 *p = *uri_str; + struct efi_device_path_uri *uridp; + + uridp = (struct efi_device_path_uri *)dp; + + utf8_utf16_strcpy(&p, uridp->uri); +} + +/** * fill_file_info() - fill the file info from efi_device_path structure * * @dp: pointer to the device path @@ -1392,10 +1503,13 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo size_t len; efi_status_t ret; char *tmp = NULL, *p; + u16 *current_path = NULL; struct efi_load_option lo = {0}; efi_uintn_t dp_size; struct efi_device_path *dp = NULL; efi_uintn_t size = load_option_size; + struct efi_device_path *dp_volume = NULL; + struct efi_device_path *uri_dp = NULL; struct efi_device_path *device_dp = NULL; struct efi_device_path *initrd_dp = NULL; struct efi_device_path *fdt_dp = NULL; @@ -1464,6 +1578,12 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo goto out; } + bo->file_info.uri = calloc(1, EFICONFIG_URI_MAX * sizeof(u16)); + if (!bo->file_info.uri) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + /* copy the preset value */ if (load_option) { ret = efi_deserialize_load_option(&lo, load_option, &size); @@ -1481,7 +1601,10 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo u16_strcpy(bo->description, lo.label); /* EFI image file path is a first instance */ - if (lo.file_path) + if (lo.file_path && EFI_DP_TYPE(lo.file_path, MESSAGING_DEVICE, + MSG_URI)) + fill_dp_uri(lo.file_path, &bo->file_info.uri); + else if (lo.file_path) fill_file_info(lo.file_path, &bo->file_info, device_dp); /* Initrd file path (optional) is placed at second instance. */ @@ -1512,6 +1635,9 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo goto out; } + if (utf16_utf8_strlen(bo->file_info.uri)) + uri_dp = eficonfig_create_uri_device_path(bo->file_info.uri); + if (bo->initrd_info.dp_volume) { dp = eficonfig_create_device_path(bo->initrd_info.dp_volume, bo->initrd_info.current_path); @@ -1536,7 +1662,10 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo efi_free_pool(dp); } - dp = eficonfig_create_device_path(bo->file_info.dp_volume, bo->file_info.current_path); + dp_volume = bo->file_info.dp_volume; + current_path = bo->file_info.current_path; + dp = uri_dp ? + uri_dp : eficonfig_create_device_path(dp_volume, current_path); if (!dp) { ret = EFI_OUT_OF_RESOURCES; goto out; @@ -1560,6 +1689,7 @@ out: free(tmp); free(bo->optional_data); free(bo->description); + free(bo->file_info.uri); free(bo->file_info.current_path); free(bo->initrd_info.current_path); free(bo->fdt_info.current_path); diff --git a/cmd/help.c b/cmd/help.c index 56579e28d31..1be83ba607d 100644 --- a/cmd/help.c +++ b/cmd/help.c @@ -9,13 +9,9 @@ static int do_help(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { -#ifdef CONFIG_CMDLINE struct cmd_tbl *start = ll_entry_start(struct cmd_tbl, cmd); const int len = ll_entry_count(struct cmd_tbl, cmd); return _do_help(start, len, cmdtp, flag, argc, argv); -#else - return 0; -#endif } U_BOOT_CMD( @@ -27,7 +23,6 @@ U_BOOT_CMD( " - print detailed usage of 'command'" ); -#ifdef CONFIG_CMDLINE /* * This does not use the U_BOOT_CMD macro as ? can't be used in symbol names * nor can we rely on the CONFIG_SYS_LONGHELP helper macro @@ -39,4 +34,3 @@ ll_entry_declare(struct cmd_tbl, question_mark, cmd) = { "" #endif /* CONFIG_SYS_LONGHELP */ }; -#endif diff --git a/cmd/load.c b/cmd/load.c index 899bb4f598e..159767aa7f7 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -178,17 +178,20 @@ static ulong load_serial(long offset) #endif { void *dst; + phys_addr_t dst_addr; - ret = lmb_reserve(store_addr, binlen, LMB_NONE); + dst_addr = (phys_addr_t)store_addr; + ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &dst_addr, + binlen, LMB_NONE); if (ret) { printf("\nCannot overwrite reserved area (%08lx..%08lx)\n", store_addr, store_addr + binlen); return ret; } - dst = map_sysmem(store_addr, binlen); + dst = map_sysmem(dst_addr, binlen); memcpy(dst, binbuf, binlen); unmap_sysmem(dst); - lmb_free(store_addr, binlen); + lmb_free(dst_addr, binlen, LMB_NONE); } if ((store_addr) < start_addr) start_addr = store_addr; diff --git a/cmd/lwip/Makefile b/cmd/lwip/Makefile new file mode 100644 index 00000000000..a7f8976af3f --- /dev/null +++ b/cmd/lwip/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_CMD_DHCP) += dhcp.o +obj-$(CONFIG_CMD_DNS) += dns.o +obj-$(CONFIG_CMD_PING) += ping.o +obj-$(CONFIG_CMD_SNTP) += sntp.o +obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o +obj-$(CONFIG_CMD_WGET) += wget.o diff --git a/cmd/lwip/dhcp.c b/cmd/lwip/dhcp.c new file mode 100644 index 00000000000..3894d71f654 --- /dev/null +++ b/cmd/lwip/dhcp.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2024-2025 Linaro Ltd. */ + +#include <command.h> +#include <net.h> + +U_BOOT_CMD(dhcp, 3, 1, do_dhcp, + "boot image via network using DHCP/TFTP protocol", + "[loadAddress] [[hostIPaddr:]bootfilename]"); diff --git a/net/lwip/dns.c b/cmd/lwip/dns.c index 6862869d9e3..b5fccc7433e 100644 --- a/net/lwip/dns.c +++ b/cmd/lwip/dns.c @@ -9,6 +9,9 @@ #include <net.h> #include <time.h> +U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname", + "hostname [envvar]"); + #define DNS_RESEND_MS 1000 #define DNS_TIMEOUT_MS 10000 @@ -36,21 +39,18 @@ static void dns_cb(const char *name, const ip_addr_t *ipaddr, void *arg) return; } + dns_cb_arg->host_ipaddr.addr = ipaddr->addr; + if (dns_cb_arg->var) env_set(dns_cb_arg->var, ipstr); - - printf("%s\n", ipstr); } static int dns_loop(struct udevice *udev, const char *name, const char *var) { struct dns_cb_arg dns_cb_arg = { }; - bool has_server = false; struct netif *netif; ip_addr_t ipaddr; - ip_addr_t ns; ulong start; - char *nsenv; int ret; dns_cb_arg.var = var; @@ -59,22 +59,7 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var) if (!netif) return CMD_RET_FAILURE; - dns_init(); - - nsenv = env_get("dnsip"); - if (nsenv && ipaddr_aton(nsenv, &ns)) { - dns_setserver(0, &ns); - has_server = true; - } - - nsenv = env_get("dnsip2"); - if (nsenv && ipaddr_aton(nsenv, &ns)) { - dns_setserver(1, &ns); - has_server = true; - } - - if (!has_server) { - log_err("No valid name server (dnsip/dnsip2)\n"); + if (net_lwip_dns_init()) { net_lwip_remove_netif(netif); return CMD_RET_FAILURE; } @@ -92,7 +77,6 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var) net_lwip_rx(udev, netif); if (dns_cb_arg.done) break; - sys_check_timeouts(); if (ctrlc()) { printf("\nAbort\n"); break; @@ -103,8 +87,11 @@ static int dns_loop(struct udevice *udev, const char *name, const char *var) net_lwip_remove_netif(netif); - if (dns_cb_arg.done && dns_cb_arg.host_ipaddr.addr != 0) + if (dns_cb_arg.done && dns_cb_arg.host_ipaddr.addr != 0) { + if (!var) + printf("%s\n", ipaddr_ntoa(&ipaddr)); return CMD_RET_SUCCESS; + } return CMD_RET_FAILURE; } diff --git a/net/lwip/ping.c b/cmd/lwip/ping.c index d8042ceecf9..87f8e958e48 100644 --- a/net/lwip/ping.c +++ b/cmd/lwip/ping.c @@ -13,6 +13,9 @@ #include <net.h> #include <time.h> +U_BOOT_CMD(ping, 2, 1, do_ping, "send ICMP ECHO_REQUEST to network host", + "pingAddressOrHostName"); + #define PING_DELAY_MS 1000 #define PING_COUNT 5 /* Ping identifier - must fit on a u16_t */ @@ -136,7 +139,6 @@ static int ping_loop(struct udevice *udev, const ip_addr_t *addr) ping_send(&ctx); do { - sys_check_timeouts(); net_lwip_rx(udev, netif); if (ctx.alive) break; @@ -165,7 +167,7 @@ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc < 2) return CMD_RET_USAGE; - if (!ipaddr_aton(argv[1], &addr)) + if (net_lwip_dns_resolve(argv[1], &addr)) return CMD_RET_USAGE; restart: diff --git a/cmd/lwip/sntp.c b/cmd/lwip/sntp.c new file mode 100644 index 00000000000..ae02bb11040 --- /dev/null +++ b/cmd/lwip/sntp.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2025 Linaro Ltd. */ + +#include <command.h> +#include <console.h> +#include <dm/device.h> +#include <env.h> +#include <lwip/apps/sntp.h> +#include <lwip/timeouts.h> +#include <net.h> + +U_BOOT_CMD(sntp, 2, 1, do_sntp, "synchronize RTC via network", + "[NTPServerNameOrIp]"); + +#define SNTP_TIMEOUT 10000 + +static enum done_state { + NOT_DONE = 0, + SUCCESS, + ABORTED, + TIMED_OUT +} sntp_state; + +static void no_response(void *arg) +{ + sntp_state = TIMED_OUT; +} + +/* Called by lwIP via the SNTP_SET_SYSTEM_TIME() macro */ +void sntp_set_system_time(uint32_t seconds) +{ + char *toff; + int net_ntp_time_offset = 0; + + toff = env_get("timeoffset"); + if (toff) + net_ntp_time_offset = simple_strtol(toff, NULL, 10); + + net_sntp_set_rtc(seconds + net_ntp_time_offset); + sntp_state = SUCCESS; +} + +static bool ntp_server_known(void) +{ + int i; + + for (i = 0; i < SNTP_MAX_SERVERS; i++) { + const ip_addr_t *ip = sntp_getserver(i); + + if (ip && ip->addr) + return true; + } + + return false; +} + +static int sntp_loop(struct udevice *udev, ip_addr_t *srvip) +{ + struct netif *netif; + + netif = net_lwip_new_netif(udev); + if (!netif) + return -1; + + sntp_state = NOT_DONE; + + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_servermode_dhcp(CONFIG_IS_ENABLED(CMD_DHCP)); + if (srvip) { + sntp_setserver(0, srvip); + } else { + if (!ntp_server_known()) { + log_err("error: ntpserverip not set\n"); + return -1; + } + } + sntp_init(); + + sys_timeout(SNTP_TIMEOUT, no_response, NULL); + while (sntp_state == NOT_DONE) { + net_lwip_rx(udev, netif); + sys_check_timeouts(); + if (ctrlc()) { + printf("\nAbort\n"); + sntp_state = ABORTED; + break; + } + } + sys_untimeout(no_response, NULL); + + sntp_stop(); + net_lwip_remove_netif(netif); + + if (sntp_state == SUCCESS) + return 0; + + return -1; +} + +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + ip_addr_t *srvip; + char *server; + ip_addr_t ipaddr; + + switch (argc) { + case 1: + srvip = NULL; + server = env_get("ntpserverip"); + if (server) { + if (!ipaddr_aton(server, &ipaddr)) { + printf("ntpserverip is invalid\n"); + return CMD_RET_FAILURE; + } + srvip = &ipaddr; + } + break; + case 2: + if (net_lwip_dns_resolve(argv[1], &ipaddr)) + return CMD_RET_FAILURE; + srvip = &ipaddr; + break; + default: + return CMD_RET_USAGE; + } + + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; + + if (sntp_loop(eth_get_dev(), srvip) < 0) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} diff --git a/cmd/lwip/tftp.c b/cmd/lwip/tftp.c new file mode 100644 index 00000000000..6bb7a3733a2 --- /dev/null +++ b/cmd/lwip/tftp.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2024-2025 Linaro Ltd. */ + +#include <command.h> +#include <net.h> + +U_BOOT_CMD(tftpboot, 3, 0, do_tftpb, + "boot image via network using TFTP protocol", + "[loadAddress] [[hostIPaddr:]bootfilename]"); diff --git a/cmd/lwip/wget.c b/cmd/lwip/wget.c new file mode 100644 index 00000000000..fc9bc11cd83 --- /dev/null +++ b/cmd/lwip/wget.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* Copyright (C) 2024-2025 Linaro Ltd. */ + +#include <command.h> +#include <env.h> +#include <image.h> +#include <net.h> +#include <lwip/altcp_tls.h> + +U_BOOT_CMD(wget, 4, 1, do_wget, + "boot image via network using HTTP/HTTPS protocol" +#if defined(CONFIG_WGET_CACERT) + "\nwget cacert - configure wget root certificates" +#endif + , + "[loadAddress] url\n" + "wget [loadAddress] [host:]path\n" + " - load file" +#if defined(CONFIG_WGET_CACERT) + "\nwget cacert <address> <length>\n" + " - provide CA certificates (0 0 to remove current)" + "\nwget cacert none|optional|required\n" + " - set server certificate verification mode (default: optional)" +#if defined(CONFIG_WGET_BUILTIN_CACERT) + "\nwget cacert builtin\n" + " - use the builtin CA certificates" +#endif +#endif +); + +#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) +char *cacert; +size_t cacert_size; +enum auth_mode cacert_auth_mode = AUTH_OPTIONAL; + +#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) +extern const char builtin_cacert[]; +extern const size_t builtin_cacert_size; +bool cacert_initialized; +#endif + +static int _set_cacert(const void *addr, size_t sz) +{ + mbedtls_x509_crt crt; + void *p; + int ret; + + if (cacert) + free(cacert); + + if (!addr) { + cacert = NULL; + cacert_size = 0; + return CMD_RET_SUCCESS; + } + + p = malloc(sz); + if (!p) + return CMD_RET_FAILURE; + cacert = p; + cacert_size = sz; + + memcpy(cacert, (void *)addr, sz); + + mbedtls_x509_crt_init(&crt); + ret = mbedtls_x509_crt_parse(&crt, cacert, cacert_size); + if (ret) { + if (!wget_info->silent) + printf("Could not parse certificates (%d)\n", ret); + free(cacert); + cacert = NULL; + cacert_size = 0; + return CMD_RET_FAILURE; + } + +#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) + cacert_initialized = true; +#endif + return CMD_RET_SUCCESS; +} + +#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) +int set_cacert_builtin(void) +{ + cacert_auth_mode = AUTH_REQUIRED; + return _set_cacert(builtin_cacert, builtin_cacert_size); +} +#endif +#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */ + +#if CONFIG_IS_ENABLED(WGET_CACERT) +static int set_auth(enum auth_mode auth) +{ + cacert_auth_mode = auth; + + return CMD_RET_SUCCESS; +} + +static int set_cacert(char * const saddr, char * const ssz) +{ + ulong addr, sz; + + addr = hextoul(saddr, NULL); + sz = hextoul(ssz, NULL); + + return _set_cacert((void *)addr, sz); +} +#endif + +/* + * Legacy syntax support + * Convert [<server_name_or_ip>:]filename into a URL if needed + */ +static int parse_legacy_arg(char *arg, char *nurl, size_t rem) +{ + char *p = nurl; + size_t n; + char *col = strchr(arg, ':'); + char *env; + char *server; + char *path; + + if (strstr(arg, "http") == arg) { + n = snprintf(nurl, rem, "%s", arg); + if (n < 0 || n > rem) + return -1; + return 0; + } + + n = snprintf(p, rem, "%s", "http://"); + if (n < 0 || n > rem) + return -1; + p += n; + rem -= n; + + if (col) { + n = col - arg; + server = arg; + path = col + 1; + } else { + env = env_get("httpserverip"); + if (!env) + env = env_get("serverip"); + if (!env) { + log_err("error: httpserver/serverip has to be set\n"); + return -1; + } + n = strlen(env); + server = env; + path = arg; + } + + if (rem < n) + return -1; + strncpy(p, server, n); + p += n; + rem -= n; + if (rem < 1) + return -1; + *p = '/'; + p++; + rem--; + n = strlen(path); + if (rem < n) + return -1; + strncpy(p, path, n); + p += n; + rem -= n; + if (rem < 1) + return -1; + *p = '\0'; + + return 0; +} + +int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) +{ + char *end; + char *url; + ulong dst_addr; + char nurl[1024]; + +#if CONFIG_IS_ENABLED(WGET_CACERT) + if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert"))) + return set_cacert(argv[2], argv[3]); + if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert"))) { +#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) + if (!strncmp(argv[2], "builtin", strlen("builtin"))) + return set_cacert_builtin(); +#endif + if (!strncmp(argv[2], "none", strlen("none"))) + return set_auth(AUTH_NONE); + if (!strncmp(argv[2], "optional", strlen("optional"))) + return set_auth(AUTH_OPTIONAL); + if (!strncmp(argv[2], "required", strlen("required"))) + return set_auth(AUTH_REQUIRED); + return CMD_RET_USAGE; + } +#endif + + if (argc < 2 || argc > 3) + return CMD_RET_USAGE; + + dst_addr = hextoul(argv[1], &end); + if (end == (argv[1] + strlen(argv[1]))) { + if (argc < 3) + return CMD_RET_USAGE; + url = argv[2]; + } else { + dst_addr = image_load_addr; + url = argv[1]; + } + + if (parse_legacy_arg(url, nurl, sizeof(nurl))) + return CMD_RET_FAILURE; + + wget_info = &default_wget_info; + if (wget_do_request(dst_addr, nurl)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} diff --git a/cmd/net-lwip.c b/cmd/net-lwip.c deleted file mode 100644 index cecf8d02555..00000000000 --- a/cmd/net-lwip.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* Copyright (C) 2024 Linaro Ltd. */ - -#include <command.h> -#include <net.h> - -#if defined(CONFIG_CMD_DHCP) -U_BOOT_CMD(dhcp, 3, 1, do_dhcp, - "boot image via network using DHCP/TFTP protocol", - "[loadAddress] [[hostIPaddr:]bootfilename]"); -#endif - -#if defined(CONFIG_CMD_PING) -U_BOOT_CMD(ping, 2, 1, do_ping, "send ICMP ECHO_REQUEST to network host", - "pingAddress"); -#endif - -#if defined(CONFIG_CMD_TFTPBOOT) -U_BOOT_CMD(tftpboot, 3, 0, do_tftpb, - "boot image via network using TFTP protocol", - "[loadAddress] [[hostIPaddr:]bootfilename]"); -#endif - -#if defined(CONFIG_CMD_DNS) -U_BOOT_CMD(dns, 3, 1, do_dns, "lookup the IP of a hostname", - "hostname [envvar]"); -#endif - -#if defined(CONFIG_CMD_WGET) -U_BOOT_CMD(wget, 4, 1, do_wget, - "boot image via network using HTTP/HTTPS protocol" -#if defined(CONFIG_WGET_CACERT) - "\nwget cacert - configure wget root certificates" -#endif - , - "[loadAddress] url\n" - "wget [loadAddress] [host:]path\n" - " - load file" -#if defined(CONFIG_WGET_CACERT) - "\nwget cacert <address> <length>\n" - " - provide CA certificates (0 0 to remove current)" - "\nwget cacert none|optional|required\n" - " - set server certificate verification mode (default: optional)" -#if defined(CONFIG_WGET_BUILTIN_CACERT) - "\nwget cacert builtin\n" - " - use the builtin CA certificates" -#endif -#endif -); -#endif diff --git a/cmd/smbios.c b/cmd/smbios.c index 562dd7959be..ed419f19028 100644 --- a/cmd/smbios.c +++ b/cmd/smbios.c @@ -280,7 +280,7 @@ static void smbios_print_type3(struct smbios_type3 *table) int i; u8 *addr = (u8 *)table + offsetof(struct smbios_type3, sku_number); - printf("Baseboard Information\n"); + printf("Chassis Information\n"); smbios_print_str("Manufacturer", table, table->manufacturer); printf("\tType: 0x%02x\n", table->chassis_type); smbios_print_str("Version", table, table->version); diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index a62862e94f9..346e21d27bb 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -113,7 +113,7 @@ static int do_tpm2_pcr_extend(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; if (argc == 4) { algo = tpm2_name_to_algorithm(argv[3]); - if (algo < 0) + if (algo == TPM2_ALG_INVAL) return CMD_RET_FAILURE; } algo_len = tpm2_algorithm_to_len(algo); @@ -157,7 +157,7 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; if (argc == 4) { algo = tpm2_name_to_algorithm(argv[3]); - if (algo < 0) + if (algo == TPM2_ALG_INVAL) return CMD_RET_FAILURE; } algo_len = tpm2_algorithm_to_len(algo); @@ -288,7 +288,7 @@ static int do_tpm2_pcrallocate(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_USAGE; algo = tpm2_name_to_algorithm(argv[1]); - if (algo == -EINVAL) + if (algo == TPM2_ALG_INVAL) return CMD_RET_USAGE; ret = get_tpm(&dev); diff --git a/common/Makefile b/common/Makefile index 35991562a12..d62ea34599e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -19,6 +19,12 @@ obj-y += version.o # # boards obj-y += board_f.o obj-y += board_r.o +ifdef CONFIG_$(PHASE_)SYS_THUMB_BUILD +ifneq ($(CONFIG_SYS_ARM_ARCH),7) +CFLAGS_REMOVE_board_f.o := $(LTO_CFLAGS) +CFLAGS_REMOVE_board_r.o := $(LTO_CFLAGS) +endif +endif obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o diff --git a/common/cli_readline.c b/common/cli_readline.c index 4e6797a1944..0cb43e62000 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -332,8 +332,8 @@ int cread_line_process_ch(struct cli_line_state *cls, char ichar) if (cls->num) { uint base, wlen; - for (base = cls->num - 1; - base >= 0 && buf[base] == ' ';) + for (base = cls->num; + base > 0 && buf[base - 1] == ' ';) base--; for (; base > 0 && buf[base - 1] != ' ';) base--; diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 880192043c4..9a17ccb2d3d 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -80,7 +80,7 @@ config SPL_MAX_SIZE default 0x1b000 if AM33XX && !TI_SECURE_DEVICE default 0xec00 if OMAP34XX default 0x10000 if ARCH_MX6 && !MX6_OCRAM_256KB - default 0xbfa0 if MACH_SUN50I_H616 + default 0xbfa0 if MACH_SUN50I_H616 || MACH_SUN50I_A133 default 0x7000 if RCAR_GEN3 default 0x5fa0 if SUNXI_SRAM_ADDRESS = 0x0 default 0x7fa0 if ARCH_SUNXI @@ -423,7 +423,7 @@ config SPL_STACK default 0x91ffb8 if ARCH_MX6 && !MX6_OCRAM_256KB default 0x118000 if MACH_SUN50I_H6 default 0x52a00 if MACH_SUN50I_H616 - default 0x40000 if MACH_SUN8I_R528 + default 0x40000 if MACH_SUN8I_R528 || MACH_SUN50I_A133 default 0x54000 if MACH_SUN50I || MACH_SUN50I_H5 default 0x18000 if MACH_SUN9I default 0x8000 if ARCH_SUNXI diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 86506d6905c..25f3c822a49 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -73,7 +73,7 @@ static int spl_fit_get_image_name(const struct spl_fit_info *ctx, const char **outname) { struct udevice *sysinfo; - const char *name, *str; + const char *name, *str, *end; __maybe_unused int node; int len, i; bool found = true; @@ -83,11 +83,17 @@ static int spl_fit_get_image_name(const struct spl_fit_info *ctx, debug("cannot find property '%s': %d\n", type, len); return -EINVAL; } + /* A string property should be NUL terminated */ + end = name + len - 1; + if (!len || *end) { + debug("malformed property '%s'\n", type); + return -EINVAL; + } str = name; for (i = 0; i < index; i++) { str = strchr(str, '\0') + 1; - if (!str || (str - name >= len)) { + if (str > end) { found = false; break; } @@ -199,7 +205,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size, * the image gets loaded to the address pointed to by the * load_addr member in this struct, if load_addr is not 0 * - * Return: 0 on success, -EPERM if this image is not the correct phase + * Return: 0 on success, -EBADSLT if this image is not the correct phase * (for CONFIG_BOOTMETH_VBE_SIMPLE_FW), or another negative error number on * other error. */ @@ -235,7 +241,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset, return ret; } else { log_debug("- phase mismatch, skipping this image\n"); - return -EPERM; + return -EBADSLT; } } @@ -474,7 +480,7 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, image_info.load_addr = (ulong)tmpbuffer; ret = load_simple_fit(info, offset, ctx, node, &image_info); - if (ret == -EPERM) + if (ret == -EBADSLT) continue; else if (ret < 0) break; @@ -702,13 +708,51 @@ static int spl_simple_fit_read(struct spl_fit_info *ctx, */ size = get_aligned_image_size(info, size, 0); buf = board_spl_fit_buffer_addr(size, size, 1); + if (!buf) { + /* + * We assume that none of the board will ever use 0x0 as a + * valid load address. Theoretically some board could use it, + * but this is extremely unlikely. + */ + return -EIO; + } count = info->read(info, offset, size, buf); + if (!count) { + /* + * FIT could not be read. This means we should free the + * memory allocated by board_spl_fit_buffer_addr(). + * Unfortunately, we don't know what memory allocation + * mechanism was used: + * - For the SPL_SYS_MALLOC_SIMPLE case nothing could + * be done. The memory just could not be freed. + * - For statically allocated memory buffer we can try + * to reuse previously allocated memory (example: + * board_spl_fit_buffer_addr() function from the + * file test/image/spl_load.c). + * - For normall malloc() -- memory leak can't be easily + * avoided. To somehow reduce memory consumption the + * next calls of board_spl_fit_buffer_addr() could + * reallocate previously allocated buffer and use + * them again. This is somethat similar to the approach + * used for statically allocated buffer. + * + * Please note: + * - FIT images with data placed outside of the FIT + * structure will cause small memory leak (several + * kilobytes), + * - FIT images with data placed inside to the FIT + * structure may cause huge memory leak (up to + * several megabytes). Do NOT use such images! + */ + return -EIO; + } + ctx->fit = buf; debug("fit read offset %lx, size=%lu, dst=%p, count=%lu\n", offset, size, buf, count); - return (count == 0) ? -EIO : 0; + return 0; } static int spl_simple_fit_parse(struct spl_fit_info *ctx) @@ -834,7 +878,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, image_info.load_addr = 0; ret = load_simple_fit(info, offset, &ctx, node, &image_info); - if (ret < 0 && ret != -EPERM) { + if (ret < 0 && ret != -EBADSLT) { printf("%s: can't load image loadables index %d (ret = %d)\n", __func__, index, ret); return ret; diff --git a/configs/am62x_a53_usbdfu.config b/configs/am62x_a53_usbdfu.config index 16cd4c89f41..373b1d0ed64 100644 --- a/configs/am62x_a53_usbdfu.config +++ b/configs/am62x_a53_usbdfu.config @@ -1,4 +1,3 @@ -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_RAM_SUPPORT=y CONFIG_SPL_RAM_DEVICE=y diff --git a/configs/am64x_evm_a53_defconfig b/configs/am64x_evm_a53_defconfig index 8f7d098f770..fd2b28a1c6e 100644 --- a/configs/am64x_evm_a53_defconfig +++ b/configs/am64x_evm_a53_defconfig @@ -1,7 +1,6 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_TI_COMMON_CMD_OPTIONS=y CONFIG_SPL_GPIO=y @@ -144,6 +143,8 @@ CONFIG_TI_ICSSG_PRUETH=y CONFIG_NVME_PCI=y CONFIG_PCI_CONFIG_HOST_BRIDGE=y CONFIG_PCIE_CDNS_TI=y +CONFIG_PCI_ENDPOINT=y +CONFIG_PCIE_CDNS_TI_EP=y CONFIG_PHY=y CONFIG_SPL_PHY=y CONFIG_PHY_CADENCE_TORRENT=y diff --git a/configs/am64x_evm_r5_defconfig b/configs/am64x_evm_r5_defconfig index 6f9ec2c21e8..fdf5d7803bb 100644 --- a/configs/am64x_evm_r5_defconfig +++ b/configs/am64x_evm_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x80000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig index 86fa5d30373..438ec8a1c56 100644 --- a/configs/am65x_evm_a53_defconfig +++ b/configs/am65x_evm_a53_defconfig @@ -1,7 +1,6 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_TI_COMMON_CMD_OPTIONS=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig index f783b6882dc..7d3eb6f8c93 100644 --- a/configs/am65x_evm_r5_defconfig +++ b/configs/am65x_evm_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x55000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/am65x_evm_r5_usbdfu_defconfig b/configs/am65x_evm_r5_usbdfu_defconfig index b0d333d95c2..3ac494f0126 100644 --- a/configs/am65x_evm_r5_usbdfu_defconfig +++ b/configs/am65x_evm_r5_usbdfu_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x57000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/am65x_evm_r5_usbmsc_defconfig b/configs/am65x_evm_r5_usbmsc_defconfig index 5722e9efd17..63ba94ff90e 100644 --- a/configs/am65x_evm_r5_usbmsc_defconfig +++ b/configs/am65x_evm_r5_usbmsc_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x55000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/amd_versal2_mini_defconfig b/configs/amd_versal2_mini_defconfig index e1c5d9b7fb9..e0f43352236 100644 --- a/configs/amd_versal2_mini_defconfig +++ b/configs/amd_versal2_mini_defconfig @@ -32,6 +32,7 @@ CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SYS_LONGHELP is not set CONFIG_SYS_PROMPT="versal2> " # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -63,6 +64,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_GPIO is not set # CONFIG_I2C is not set # CONFIG_INPUT is not set diff --git a/configs/amd_versal2_mini_emmc_defconfig b/configs/amd_versal2_mini_emmc_defconfig index 42bab43a72b..d95c4b3d199 100644 --- a/configs/amd_versal2_mini_emmc_defconfig +++ b/configs/amd_versal2_mini_emmc_defconfig @@ -26,6 +26,7 @@ CONFIG_BOARD_EARLY_INIT_R=y CONFIG_SYS_PROMPT="versal2> " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -54,6 +55,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set CONFIG_MMC_HS200_SUPPORT=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y diff --git a/configs/amd_versal2_mini_ospi_defconfig b/configs/amd_versal2_mini_ospi_defconfig index c2934625f2e..3de6e292c08 100644 --- a/configs/amd_versal2_mini_ospi_defconfig +++ b/configs/amd_versal2_mini_ospi_defconfig @@ -9,7 +9,7 @@ CONFIG_SYS_MALLOC_LEN=0x20000 CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_NR_DRAM_BANKS=3 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBF20000 +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBFF8000 CONFIG_ENV_SIZE=0x80 CONFIG_DEFAULT_DEVICE_TREE="amd-versal2-mini" CONFIG_SYS_LOAD_ADDR=0xBBF80000 @@ -30,6 +30,7 @@ CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SYS_LONGHELP is not set CONFIG_SYS_PROMPT="versal2> " # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -57,6 +58,8 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set +# CONFIG_ZYNQMP_FIRMWARE is not set # CONFIG_GPIO is not set # CONFIG_I2C is not set # CONFIG_INPUT is not set diff --git a/configs/amd_versal2_mini_qspi_defconfig b/configs/amd_versal2_mini_qspi_defconfig index 1c61ae821a9..03f3bd48806 100644 --- a/configs/amd_versal2_mini_qspi_defconfig +++ b/configs/amd_versal2_mini_qspi_defconfig @@ -30,6 +30,7 @@ CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SYS_LONGHELP is not set CONFIG_SYS_PROMPT="versal2> " # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -57,6 +58,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_GPIO is not set # CONFIG_I2C is not set # CONFIG_INPUT is not set diff --git a/configs/amd_versal2_virt_defconfig b/configs/amd_versal2_virt_defconfig index 3ead9f058b3..062cae70eb0 100644 --- a/configs/amd_versal2_virt_defconfig +++ b/configs/amd_versal2_virt_defconfig @@ -1,5 +1,5 @@ CONFIG_ARM=y -CONFIG_COUNTER_FREQUENCY=375000 +CONFIG_COUNTER_FREQUENCY=100000000 CONFIG_POSITION_INDEPENDENT=y CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864 CONFIG_ARCH_VERSAL2=y @@ -43,6 +43,7 @@ CONFIG_CMD_MMC=y CONFIG_MMC_SPEED_MODE_SET=y CONFIG_CMD_OPTEE=y CONFIG_CMD_MTD=y +CONFIG_CMD_POWEROFF=y CONFIG_CMD_SF_TEST=y CONFIG_CMD_SPI=y CONFIG_CMD_UFS=y @@ -130,6 +131,9 @@ CONFIG_CADENCE_QSPI=y CONFIG_CADENCE_OSPI_VERSAL=y CONFIG_ZYNQ_SPI=y CONFIG_ZYNQMP_GQSPI=y +CONFIG_SPI_STACKED_PARALLEL=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_PSCI=y CONFIG_TEE=y CONFIG_OPTEE=y CONFIG_TPM2_TIS_SPI=y diff --git a/configs/arbel_evb_defconfig b/configs/arbel_evb_defconfig index f5c05fd4616..34c4e9a3f74 100644 --- a/configs/arbel_evb_defconfig +++ b/configs/arbel_evb_defconfig @@ -41,7 +41,6 @@ CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_DHCP6=y CONFIG_DHCP6_PXE_DHCP_OPTION=y CONFIG_DHCP6_ENTERPRISE_ID=311 -CONFIG_BOOTP_PXE_DHCP_OPTION=y CONFIG_IPV6_ROUTER_DISCOVERY=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y diff --git a/configs/astro_mcf5373l_defconfig b/configs/astro_mcf5373l_defconfig deleted file mode 100644 index 8dd369d68a1..00000000000 --- a/configs/astro_mcf5373l_defconfig +++ /dev/null @@ -1,51 +0,0 @@ -CONFIG_M68K=y -CONFIG_TEXT_BASE=0x00000000 -CONFIG_SYS_MALLOC_LEN=0x20000 -CONFIG_ENV_SIZE=0x8000 -CONFIG_ENV_SECT_SIZE=0x8000 -CONFIG_DEFAULT_DEVICE_TREE="astro_mcf5373l" -CONFIG_SYS_MONITOR_LEN=262144 -CONFIG_SYS_LOAD_ADDR=0x20000 -CONFIG_ENV_ADDR=0x1FF8000 -CONFIG_TARGET_ASTRO_MCF5373L=y -CONFIG_SYS_MONITOR_BASE=0x00000400 -CONFIG_BOOTDELAY=1 -CONFIG_USE_BOOTARGS=y -CONFIG_BOOTARGS=" console=ttyS2,115200 rootfstype=romfs loaderversion=$loaderversion" -CONFIG_USE_BOOTCOMMAND=y -CONFIG_BOOTCOMMAND="protect off 0x80000 0x1ffffff;run env_check;run xilinxload&&run alteraload&&bootm 0x80000;update;reset" -CONFIG_SYS_PBSIZE=281 -# CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_MISC_INIT_R=y -CONFIG_SYS_MALLOC_BOOTPARAMS=y -CONFIG_HUSH_PARSER=y -# CONFIG_AUTO_COMPLETE is not set -CONFIG_SYS_PROMPT="URMEL > " -CONFIG_CMD_IMLS=y -CONFIG_CMD_FPGA_LOADMK=y -CONFIG_CMD_I2C=y -# CONFIG_CMD_SETEXPR is not set -CONFIG_CMD_CACHE=y -CONFIG_CMD_JFFS2=y -CONFIG_NO_NET=y -CONFIG_FPGA_ALTERA=y -CONFIG_FPGA_CYCLON2=y -CONFIG_FPGA_XILINX=y -CONFIG_FPGA_SPARTAN3=y -CONFIG_SYS_FPGA_PROG_FEEDBACK=y -CONFIG_DM_I2C=y -CONFIG_SYS_I2C_FSL=y -CONFIG_MTD=y -CONFIG_MTD_NOR_FLASH=y -CONFIG_FLASH_CFI_DRIVER=y -CONFIG_FLASH_SHOW_PROGRESS=0 -CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y -CONFIG_SYS_FLASH_PROTECTION=y -CONFIG_SYS_FLASH_CFI=y -CONFIG_SYS_MAX_FLASH_SECT=259 -CONFIG_DM_RTC=y -CONFIG_MCFRTC=y -CONFIG_SYS_MCFRTC_BASE=0xFC0A8000 -CONFIG_MCFUART=y -CONFIG_WDT=y -CONFIG_WDT_MCF=y diff --git a/configs/bk4r1_defconfig b/configs/bk4r1_defconfig index a4174d9219b..fd3b6188776 100644 --- a/configs/bk4r1_defconfig +++ b/configs/bk4r1_defconfig @@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_VF610=y CONFIG_TEXT_BASE=0x3f401000 CONFIG_SYS_MALLOC_LEN=0x402000 -CONFIG_SYS_MALLOC_F_LEN=0x800 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0x200000 diff --git a/configs/e850-96_defconfig b/configs/e850-96_defconfig index e07e4cffd0a..f0e9ff7c447 100644 --- a/configs/e850-96_defconfig +++ b/configs/e850-96_defconfig @@ -19,6 +19,7 @@ CONFIG_ANDROID_BOOT_IMAGE=y CONFIG_BOOTSTD_FULL=y CONFIG_DEFAULT_FDT_FILE="exynos850-e850-96.dtb" # CONFIG_DISPLAY_CPUINFO is not set +CONFIG_BOARD_LATE_INIT=y CONFIG_CMD_BOOTEFI_SELFTEST=y CONFIG_CMD_ABOOTIMG=y CONFIG_CMD_NVEDIT_EFI=y diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig index 0e0f764d2c7..c15372edc9c 100644 --- a/configs/imx8mm_evk_defconfig +++ b/configs/imx8mm_evk_defconfig @@ -21,6 +21,11 @@ CONFIG_SPL_BSS_START_ADDR=0x910000 CONFIG_SPL_BSS_MAX_SIZE=0x2000 CONFIG_SYS_LOAD_ADDR=0x40480000 CONFIG_SPL=y +CONFIG_EFI_MM_COMM_TEE=y +CONFIG_EFI_VAR_BUF_SIZE=139264 +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_FIT=y CONFIG_FIT_EXTERNAL_OFFSET=0x3000 CONFIG_SPL_LOAD_FIT=y @@ -46,16 +51,25 @@ CONFIG_SYS_PROMPT="u-boot=> " CONFIG_CMD_CPU=y # CONFIG_CMD_EXPORTENV is not set # CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_CRC32 is not set CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_OPTEE_RPMB=y +CONFIG_CMD_OPTEE=y CONFIG_CMD_USB_SDP=y CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_TIME=y +CONFIG_CMD_GETTIME=y +CONFIG_CMD_TIMER=y CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y CONFIG_ENV_OVERWRITE=y @@ -70,8 +84,10 @@ CONFIG_SPL_CLK_COMPOSITE_CCF=y CONFIG_CLK_COMPOSITE_CCF=y CONFIG_SPL_CLK_IMX8MM=y CONFIG_CLK_IMX8MM=y +CONFIG_DFU_MMC=y CONFIG_MXC_GPIO=y CONFIG_DM_I2C=y +CONFIG_SUPPORT_EMMC_RPMB=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_IO_VOLTAGE=y CONFIG_MMC_UHS_SUPPORT=y @@ -103,6 +119,8 @@ CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y CONFIG_SYSRESET_PSCI=y CONFIG_SYSRESET_WATCHDOG=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_DM_THERMAL=y CONFIG_USB=y CONFIG_SPL_USB_HOST=y @@ -118,3 +136,4 @@ CONFIG_SDP_LOADADDR=0x40400000 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_SPL_USB_SDP_SUPPORT=y CONFIG_IMX_WATCHDOG=y +CONFIG_SHA384=y diff --git a/configs/imx8mn_evk_defconfig b/configs/imx8mn_evk_defconfig index 6a0e46b14ab..127903045e5 100644 --- a/configs/imx8mn_evk_defconfig +++ b/configs/imx8mn_evk_defconfig @@ -23,6 +23,12 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0x42000000 CONFIG_SPL=y CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 +CONFIG_EFI_SET_TIME=y +CONFIG_EFI_MM_COMM_TEE=y +CONFIG_EFI_VAR_BUF_SIZE=139264 +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_FIT=y CONFIG_FIT_EXTERNAL_OFFSET=0x3000 CONFIG_SPL_LOAD_FIT=y @@ -55,13 +61,22 @@ CONFIG_CMD_CPU=y # CONFIG_CMD_EXPORTENV is not set # CONFIG_CMD_IMPORTENV is not set CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_CRC32 is not set CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_OPTEE_RPMB=y +CONFIG_CMD_OPTEE=y CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_RTC=y +CONFIG_CMD_TIME=y +CONFIG_CMD_GETTIME=y +CONFIG_CMD_TIMER=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_OF_CONTROL=y @@ -73,8 +88,10 @@ CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_SPL_DM=y CONFIG_SPL_CLK_IMX8MN=y CONFIG_CLK_IMX8MN=y +CONFIG_DFU_MMC=y CONFIG_MXC_GPIO=y CONFIG_DM_I2C=y +CONFIG_SUPPORT_EMMC_RPMB=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_IO_VOLTAGE=y CONFIG_SPL_MMC_IO_VOLTAGE=y @@ -99,11 +116,16 @@ CONFIG_DM_REGULATOR=y CONFIG_SPL_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y +CONFIG_DM_RTC=y +CONFIG_RTC_EMULATION=y CONFIG_DM_SERIAL=y CONFIG_MXC_UART=y CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y CONFIG_SYSRESET_PSCI=y CONFIG_SYSRESET_WATCHDOG=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_DM_THERMAL=y CONFIG_IMX_WATCHDOG=y +CONFIG_SHA384=y diff --git a/configs/imx8mp_evk_defconfig b/configs/imx8mp_evk_defconfig index d3b51134ee6..46039fd0c03 100644 --- a/configs/imx8mp_evk_defconfig +++ b/configs/imx8mp_evk_defconfig @@ -23,6 +23,11 @@ CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_SYS_LOAD_ADDR=0x40480000 CONFIG_SPL=y CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000 +CONFIG_EFI_MM_COMM_TEE=y +CONFIG_EFI_VAR_BUF_SIZE=139264 +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_FIT=y CONFIG_FIT_EXTERNAL_OFFSET=0x3000 CONFIG_SPL_LOAD_FIT=y @@ -51,16 +56,20 @@ CONFIG_SYS_PROMPT="u-boot=> " CONFIG_CMD_CPU=y # CONFIG_CMD_EXPORTENV is not set # CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_CRC32 is not set CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_OPTEE=y CONFIG_CMD_USB=y CONFIG_CMD_USB_SDP=y CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_OF_CONTROL=y @@ -76,6 +85,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y CONFIG_CLK_COMPOSITE_CCF=y CONFIG_CLK_IMX8MP=y +CONFIG_DFU_MMC=y CONFIG_USB_FUNCTION_FASTBOOT=y CONFIG_FASTBOOT_BUF_ADDR=0x42800000 CONFIG_FASTBOOT_BUF_SIZE=0x20000000 @@ -89,6 +99,7 @@ CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_LED=y CONFIG_LED_GPIO=y +CONFIG_SUPPORT_EMMC_RPMB=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_IO_VOLTAGE=y CONFIG_MMC_UHS_SUPPORT=y @@ -124,6 +135,8 @@ CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y CONFIG_SYSRESET_PSCI=y CONFIG_SYSRESET_WATCHDOG=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_USB=y # CONFIG_SPL_DM_USB is not set CONFIG_DM_USB_GADGET=y @@ -139,3 +152,4 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL" CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_IMX_WATCHDOG=y +CONFIG_SHA384=y diff --git a/configs/imx8mq_evk_defconfig b/configs/imx8mq_evk_defconfig index a9262833486..21bb04d18a8 100644 --- a/configs/imx8mq_evk_defconfig +++ b/configs/imx8mq_evk_defconfig @@ -27,6 +27,10 @@ CONFIG_SYS_LOAD_ADDR=0x40480000 CONFIG_SPL=y CONFIG_IMX_BOOTAUX=y CONFIG_REMAKE_ELF=y +CONFIG_EFI_MM_COMM_TEE=y +CONFIG_EFI_VAR_BUF_SIZE=139264 +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_FIT=y CONFIG_FIT_EXTERNAL_OFFSET=0x3000 CONFIG_SPL_LOAD_FIT=y @@ -53,15 +57,19 @@ CONFIG_SYS_PROMPT="u-boot=> " # CONFIG_BOOTM_NETBSD is not set # CONFIG_CMD_EXPORTENV is not set # CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_CRC32 is not set CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y CONFIG_CMD_FUSE=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_OPTEE_RPMB=y CONFIG_CMD_USB=y # CONFIG_CMD_MDIO is not set CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_OF_CONTROL=y @@ -72,9 +80,11 @@ CONFIG_ENV_MMC_DEVICE_INDEX=1 CONFIG_USE_ETHPRIME=y CONFIG_ETHPRIME="FEC" CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000 +CONFIG_DFU_MMC=y CONFIG_MXC_GPIO=y CONFIG_DM_I2C=y CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SUPPORT_EMMC_RPMB=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_FSL_USDHC=y CONFIG_PHYLIB=y @@ -96,8 +106,11 @@ CONFIG_DM_REGULATOR_GPIO=y CONFIG_SPL_POWER_I2C=y CONFIG_DM_SERIAL=y CONFIG_MXC_UART=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_DM_THERMAL=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_DWC3=y CONFIG_USB_DWC3=y +CONFIG_SHA384=y diff --git a/configs/imx93_11x11_evk_defconfig b/configs/imx93_11x11_evk_defconfig index ba2da308705..cb4a542cbf1 100644 --- a/configs/imx93_11x11_evk_defconfig +++ b/configs/imx93_11x11_evk_defconfig @@ -26,6 +26,12 @@ CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x88000000 CONFIG_SYS_MEMTEST_START=0x80000000 CONFIG_SYS_MEMTEST_END=0x90000000 CONFIG_REMAKE_ELF=y +CONFIG_EFI_SET_TIME=y +CONFIG_EFI_MM_COMM_TEE=y +CONFIG_EFI_VAR_BUF_SIZE=139264 +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_BOOTCOMMAND="bootflow scan -lb; run bsp_bootcmd" CONFIG_DEFAULT_FDT_FILE="imx93-11x11-evk.dtb" CONFIG_SYS_CBSIZE=2048 @@ -51,6 +57,7 @@ CONFIG_SPL_WATCHDOG=y CONFIG_SYS_PROMPT="u-boot=> " CONFIG_CMD_CPU=y CONFIG_CMD_ERASEENV=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_CRC32 is not set CONFIG_CMD_MEMTEST=y CONFIG_CMD_CLK=y @@ -60,9 +67,11 @@ CONFIG_CMD_GPIO=y CONFIG_CMD_GPT=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_OPTEE_RPMB=y CONFIG_CMD_POWEROFF=y CONFIG_CMD_SNTP=y CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y CONFIG_CMD_GETTIME=y @@ -89,10 +98,12 @@ CONFIG_ADC=y CONFIG_ADC_IMX93=y CONFIG_SPL_CLK_IMX93=y CONFIG_CLK_IMX93=y +CONFIG_DFU_MMC=y CONFIG_IMX_RGPIO2P=y CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_IMX_LPI2C=y +CONFIG_SUPPORT_EMMC_RPMB=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_IO_VOLTAGE=y CONFIG_MMC_UHS_SUPPORT=y @@ -122,9 +133,12 @@ CONFIG_FSL_LPUART=y CONFIG_SYSRESET=y CONFIG_SYSRESET_CMD_POWEROFF=y CONFIG_SYSRESET_PSCI=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_DM_THERMAL=y CONFIG_ULP_WATCHDOG=y CONFIG_WDT=y +CONFIG_SHA384=y CONFIG_LZO=y CONFIG_BZIP2=y CONFIG_UTHREAD=y diff --git a/configs/iot2050_defconfig b/configs/iot2050_defconfig index 55477c85807..a88e697d9fa 100644 --- a/configs/iot2050_defconfig +++ b/configs/iot2050_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_ARCH_K3=y # CONFIG_TI_SECURE_DEVICE is not set -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/j7200_evm_a72_defconfig b/configs/j7200_evm_a72_defconfig index c9b8e02812b..3987bab5679 100644 --- a/configs/j7200_evm_a72_defconfig +++ b/configs/j7200_evm_a72_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_TI_COMMON_CMD_OPTIONS=y CONFIG_SPL_GPIO=y diff --git a/configs/j7200_evm_r5_defconfig b/configs/j7200_evm_r5_defconfig index f5480b16df8..dca757fe057 100644 --- a/configs/j7200_evm_r5_defconfig +++ b/configs/j7200_evm_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x70000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/j721e_beagleboneai64_a72_defconfig b/configs/j721e_beagleboneai64_a72_defconfig index d3f118a9429..00ed3d91242 100644 --- a/configs/j721e_beagleboneai64_a72_defconfig +++ b/configs/j721e_beagleboneai64_a72_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/j721e_beagleboneai64_r5_defconfig b/configs/j721e_beagleboneai64_r5_defconfig index dad3173daa3..99e96c90ef9 100644 --- a/configs/j721e_beagleboneai64_r5_defconfig +++ b/configs/j721e_beagleboneai64_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x70000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig index a27b7c712b4..02e3ac343d9 100644 --- a/configs/j721e_evm_a72_defconfig +++ b/configs/j721e_evm_a72_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig index 15aa0f2a3e4..3a54a4c97d1 100644 --- a/configs/j721e_evm_r5_defconfig +++ b/configs/j721e_evm_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x70000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig index 36b6c6ade0b..ac584f50b94 100644 --- a/configs/j721s2_evm_a72_defconfig +++ b/configs/j721s2_evm_a72_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_TI_COMMON_CMD_OPTIONS=y CONFIG_SPL_GPIO=y diff --git a/configs/j721s2_evm_r5_defconfig b/configs/j721s2_evm_r5_defconfig index fe95f2c29bc..f4c0862d0a8 100644 --- a/configs/j721s2_evm_r5_defconfig +++ b/configs/j721s2_evm_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x10000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/j784s4_evm_a72_defconfig b/configs/j784s4_evm_a72_defconfig index faa3e26afaa..6b1306cf7af 100644 --- a/configs/j784s4_evm_a72_defconfig +++ b/configs/j784s4_evm_a72_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_TI_COMMON_CMD_OPTIONS=y CONFIG_SPL_GPIO=y diff --git a/configs/j784s4_evm_r5_defconfig b/configs/j784s4_evm_r5_defconfig index 78d89bebd19..9e4170028f4 100644 --- a/configs/j784s4_evm_r5_defconfig +++ b/configs/j784s4_evm_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x10000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/legoev3_defconfig b/configs/legoev3_defconfig index ff4d78a6d47..dee19a95d55 100644 --- a/configs/legoev3_defconfig +++ b/configs/legoev3_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_DAVINCI=y CONFIG_TEXT_BASE=0xc1080000 CONFIG_SYS_MALLOC_LEN=0x110000 @@ -12,6 +13,9 @@ CONFIG_SF_DEFAULT_SPEED=50000000 CONFIG_ENV_SIZE=0x4000 CONFIG_DEFAULT_DEVICE_TREE="da850-lego-ev3" CONFIG_SYS_LOAD_ADDR=0xc0700000 +CONFIG_LTO=y +CONFIG_HAS_BOARD_SIZE_LIMIT=y +CONFIG_BOARD_SIZE_LIMIT=262144 CONFIG_DYNAMIC_SYS_CLK_FREQ=y CONFIG_BOOTDELAY=0 CONFIG_AUTOBOOT_KEYED=y @@ -31,7 +35,6 @@ CONFIG_HUSH_PARSER=y # CONFIG_BOOTM_RTEMS is not set # CONFIG_BOOTM_VXWORKS is not set CONFIG_CMD_ASKENV=y -CONFIG_CRC32_VERIFY=y CONFIG_CMD_MX_CYCLIC=y CONFIG_CMD_MMC=y CONFIG_CMD_SPI=y @@ -56,4 +59,3 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_DAVINCI_SPI=y -CONFIG_REGEX=y diff --git a/configs/liontron-h-a133l_defconfig b/configs/liontron-h-a133l_defconfig new file mode 100644 index 00000000000..65c4359593f --- /dev/null +++ b/configs/liontron-h-a133l_defconfig @@ -0,0 +1,36 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun50i-a133-liontron-h-a133l" +CONFIG_SPL=y +CONFIG_DRAM_SUNXI_DX_ODT=0x7070707 +CONFIG_DRAM_SUNXI_DX_DRI=0xd0d0d0d +CONFIG_DRAM_SUNXI_CA_DRI=0xe0e +CONFIG_DRAM_SUNXI_PARA0=0xd0a050c +CONFIG_DRAM_SUNXI_MR11=0x4 +CONFIG_DRAM_SUNXI_MR12=0x72 +CONFIG_DRAM_SUNXI_MR14=0x7 +CONFIG_DRAM_SUNXI_TPR1=0x26 +CONFIG_DRAM_SUNXI_TPR2=0x6060606 +CONFIG_DRAM_SUNXI_TPR3=0x84040404 +CONFIG_DRAM_SUNXI_TPR6=0x48000000 +CONFIG_DRAM_SUNXI_TPR10=0x273333 +CONFIG_DRAM_SUNXI_TPR11=0x231d151c +CONFIG_DRAM_SUNXI_TPR12=0x1212110e +CONFIG_DRAM_SUNXI_TPR13=0x7521 +CONFIG_DRAM_SUNXI_TPR14=0x2023211f +CONFIG_MACH_SUN50I_A133=y +CONFIG_SUNXI_DRAM_A133_LPDDR4=y +CONFIG_DRAM_CLK=792 +CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +CONFIG_R_I2C_ENABLE=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_I2C=y +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_SYS_I2C_SLAVE=0x7f +CONFIG_SYS_I2C_SPEED=400000 +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_AXP803_POWER=y +CONFIG_AXP_DCDC5_VOLT=1100 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y diff --git a/configs/ls1021aqds_nor_SECURE_BOOT_defconfig b/configs/ls1021aqds_nor_SECURE_BOOT_defconfig index ad4b58e517b..3934d259887 100644 --- a/configs/ls1021aqds_nor_SECURE_BOOT_defconfig +++ b/configs/ls1021aqds_nor_SECURE_BOOT_defconfig @@ -24,7 +24,6 @@ CONFIG_FSL_QIXIS=y # CONFIG_QIXIS_I2C_ACCESS is not set CONFIG_SYS_MEMTEST_START=0x80000000 CONFIG_SYS_MEMTEST_END=0x9fffffff -# CONFIG_SYS_MALLOC_F is not set CONFIG_DYNAMIC_SYS_CLK_FREQ=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig index 38bb415bb81..503afd1847b 100644 --- a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig +++ b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig @@ -21,7 +21,6 @@ CONFIG_PCIE1=y CONFIG_PCIE2=y CONFIG_SYS_MEMTEST_START=0x80000000 CONFIG_SYS_MEMTEST_END=0x9fffffff -# CONFIG_SYS_MALLOC_F is not set CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/mangopi_mq_r_defconfig b/configs/mangopi_mq_r_defconfig index df3dec704f4..9017df040cf 100644 --- a/configs/mangopi_mq_r_defconfig +++ b/configs/mangopi_mq_r_defconfig @@ -6,10 +6,10 @@ CONFIG_DRAM_SUNXI_ODT_EN=0 CONFIG_DRAM_SUNXI_TPR0=0x004a2195 CONFIG_DRAM_SUNXI_TPR11=0x340000 CONFIG_DRAM_SUNXI_TPR12=0x46 +CONFIG_DRAM_SUNXI_TPR13=0x34000100 CONFIG_MACH_SUN8I_R528=y CONFIG_DRAM_CLK=792 CONFIG_DRAM_ZQ=8092667 CONFIG_SUNXI_MINIMUM_DRAM_MB=128 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set -CONFIG_DRAM_SUNXI_TPR13=0x34000100 CONFIG_CONS_INDEX=4 diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig index e8109fbe6c0..75a655a0e0d 100644 --- a/configs/mx6sabresd_defconfig +++ b/configs/mx6sabresd_defconfig @@ -40,6 +40,8 @@ CONFIG_SPL_WATCHDOG=y CONFIG_HUSH_PARSER=y CONFIG_SYS_MAXARGS=32 CONFIG_CMD_BOOTZ=y +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set CONFIG_CMD_SPL=y CONFIG_CMD_SPL_WRITE_SIZE=0x20000 CONFIG_CMD_GPIO=y @@ -65,7 +67,6 @@ CONFIG_EFI_PARTITION=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_OF_CONTROL=y CONFIG_OF_LIST="imx6q-sabresd imx6qp-sabresd imx6dl-sabresd" -CONFIG_MULTI_DTB_FIT=y CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_MMC=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y diff --git a/configs/pcm052_defconfig b/configs/pcm052_defconfig index 7cfeee3cafe..64f5f777e5c 100644 --- a/configs/pcm052_defconfig +++ b/configs/pcm052_defconfig @@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_VF610=y CONFIG_TEXT_BASE=0x3f401000 CONFIG_SYS_MALLOC_LEN=0x202000 -CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xA0000 diff --git a/configs/phycore_am62ax_a53_defconfig b/configs/phycore_am62ax_a53_defconfig index 35d693a17ed..bdd7e288aa4 100644 --- a/configs/phycore_am62ax_a53_defconfig +++ b/configs/phycore_am62ax_a53_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/phycore_am62x_a53_defconfig b/configs/phycore_am62x_a53_defconfig index 5e89076774e..910a41fa052 100644 --- a/configs/phycore_am62x_a53_defconfig +++ b/configs/phycore_am62x_a53_defconfig @@ -1,7 +1,6 @@ CONFIG_ARM=y CONFIG_ARM_SMCCC=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/phycore_am64x_a53_defconfig b/configs/phycore_am64x_a53_defconfig index a8bf7d7339b..9f98b3522dc 100644 --- a/configs/phycore_am64x_a53_defconfig +++ b/configs/phycore_am64x_a53_defconfig @@ -1,7 +1,6 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/phycore_am64x_r5_defconfig b/configs/phycore_am64x_r5_defconfig index 8a8fe70e25c..189d0706ce5 100644 --- a/configs/phycore_am64x_r5_defconfig +++ b/configs/phycore_am64x_r5_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x80000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/qcm6490_defconfig b/configs/qcm6490_defconfig index ba26924da16..5ddc5ab3ef8 100644 --- a/configs/qcm6490_defconfig +++ b/configs/qcm6490_defconfig @@ -19,9 +19,3 @@ CONFIG_TEXT_BASE=0x9fc00000 CONFIG_REMAKE_ELF=y CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs6490-rb3gen2" - -# Enable capsule updates -CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y -CONFIG_EFI_CAPSULE_ON_DISK=y -CONFIG_EFI_IGNORE_OSINDICATIONS=y -CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y diff --git a/configs/qcom_defconfig b/configs/qcom_defconfig index 5eb027ba27b..84cc4cf82d8 100644 --- a/configs/qcom_defconfig +++ b/configs/qcom_defconfig @@ -6,6 +6,9 @@ CONFIG_ARCH_SNAPDRAGON=y CONFIG_NR_DRAM_BANKS=24 CONFIG_DEFAULT_DEVICE_TREE="qcom/sdm845-db845c" CONFIG_SYS_LOAD_ADDR=0xA0000000 +CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +CONFIG_EFI_CAPSULE_ON_DISK=y +CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_BUTTON_CMD=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y @@ -51,6 +54,8 @@ CONFIG_CLK_QCOM_APQ8016=y CONFIG_CLK_QCOM_APQ8096=y CONFIG_CLK_QCOM_QCM2290=y CONFIG_CLK_QCOM_QCS404=y +CONFIG_CLK_QCOM_QCS615=y +CONFIG_CLK_QCOM_QCS8300=y CONFIG_CLK_QCOM_SA8775P=y CONFIG_CLK_QCOM_SDM845=y CONFIG_CLK_QCOM_SM6115=y @@ -143,3 +148,5 @@ CONFIG_VIDEO_FONT_16X32=y CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_NO_FB_CLEAR=y CONFIG_VIDEO_SIMPLE=y +CONFIG_WDT=y +CONFIG_WDT_QCOM=y diff --git a/configs/qcom_ipq5424_mmc_defconfig b/configs/qcom_ipq5424_mmc_defconfig new file mode 100644 index 00000000000..e508c0cf508 --- /dev/null +++ b/configs/qcom_ipq5424_mmc_defconfig @@ -0,0 +1,56 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864 +CONFIG_ARCH_SNAPDRAGON=y +CONFIG_TEXT_BASE=0x8a380000 +CONFIG_NR_DRAM_BANKS=24 +CONFIG_ENV_SIZE=0x40000 +CONFIG_ENV_OFFSET=0 +CONFIG_DEFAULT_DEVICE_TREE="qcom/ipq5424-rdp466" +CONFIG_SYS_LOAD_ADDR=0x50000000 +CONFIG_DEBUG_UART_BASE=0x1a84000 +CONFIG_DEBUG_UART_CLOCK=14745600 +CONFIG_DEBUG_UART=y +CONFIG_REMAKE_ELF=y +# CONFIG_EFI_LOADER is not set +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +# CONFIG_BOOTSTD is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_USE_PREBOOT=y +CONFIG_SYS_PBSIZE=1024 +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_EFI_PARTITION=y +CONFIG_OF_LIVE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_CLK=y +CONFIG_CLK_QCOM_IPQ5424=y +CONFIG_MSM_GPIO=y +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_MSM=y +CONFIG_MTD=y +CONFIG_DM_MDIO=y +CONFIG_DM_ETH_PHY=y +CONFIG_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_QCOM=y +CONFIG_RGMII=y +CONFIG_PHY=y +CONFIG_PHY_QCOM_QMP_UFS=y +CONFIG_PHY_QCOM_QUSB2=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_QCOM_IPQ5424=y +CONFIG_DEBUG_UART_MSM_GENI=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_MSM_SERIAL=y +CONFIG_MSM_GENI_SERIAL=y +CONFIG_SOC_QCOM=y diff --git a/configs/qcom_ipq9574_mmc_defconfig b/configs/qcom_ipq9574_mmc_defconfig index c7ce4f5c237..720220dc98a 100644 --- a/configs/qcom_ipq9574_mmc_defconfig +++ b/configs/qcom_ipq9574_mmc_defconfig @@ -28,8 +28,6 @@ CONFIG_CMD_PART=y CONFIG_EFI_PARTITION=y CONFIG_OF_LIVE=y CONFIG_ENV_IS_IN_MMC=y -CONFIG_USE_ENV_DEFAULT_ENV_TEXT_FILE=y -CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="board/qualcomm/default.env" CONFIG_CLK=y CONFIG_CLK_QCOM_IPQ9574=y CONFIG_MSM_GPIO=y diff --git a/configs/qcom_qcs615_defconfig b/configs/qcom_qcs615_defconfig new file mode 100644 index 00000000000..2468267b955 --- /dev/null +++ b/configs/qcom_qcs615_defconfig @@ -0,0 +1,22 @@ +# Configuration for building U-Boot to be flashed +# to the uefi partition of QCS615 dev boards with +# the "Linux Embedded" partition layout (which have +# a dedicated "uefi" partition for edk2/U-Boot) + +#include "qcom_defconfig" + +# Otherwise buildman thinks this isn't an ARM platform +CONFIG_ARM=y + +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_DEBUG_UART_BASE=0x880000 +CONFIG_DEBUG_UART_MSM_GENI=y +CONFIG_DEBUG_UART_CLOCK=14745600 + +CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs615-ride" + +CONFIG_REMAKE_ELF=y + +# Address where U-Boot will be loaded +CONFIG_TEXT_BASE=0x9fc00000 diff --git a/configs/qcom_qcs8300_defconfig b/configs/qcom_qcs8300_defconfig new file mode 100644 index 00000000000..5fffcddc16e --- /dev/null +++ b/configs/qcom_qcs8300_defconfig @@ -0,0 +1,21 @@ +# Configuration for building U-Boot to be flashed +# to the uefi partition of QCS8300 dev boards with +# the "Linux Embedded" partition layout (which have +# a dedicated "uefi_a" partition for edk2/U-Boot) + +#include "qcom_defconfig" + +# Otherwise buildman thinks this isn't an ARM platform +CONFIG_ARM=y + +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_DEBUG_UART_BASE=0x99C000 +CONFIG_DEBUG_UART_MSM_GENI=y +CONFIG_DEBUG_UART_CLOCK=14745600 + +# Address where U-Boot will be loaded +CONFIG_TEXT_BASE=0xaf000000 +CONFIG_REMAKE_ELF=y + +CONFIG_DEFAULT_DEVICE_TREE="qcom/qcs8300-ride" diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 72bd255eafa..39afb837e41 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_KVM_VIRT_INS=y CONFIG_ARCH_QEMU=y CONFIG_SYS_MALLOC_LEN=0x1000000 CONFIG_BLOBLIST_SIZE_RELOC=0x2000 diff --git a/configs/qemu_arm64_lwip_defconfig b/configs/qemu_arm64_lwip_defconfig index 814e98729a3..e8f976efaf7 100644 --- a/configs/qemu_arm64_lwip_defconfig +++ b/configs/qemu_arm64_lwip_defconfig @@ -5,6 +5,7 @@ CONFIG_ARCH_QEMU=y CONFIG_NET_LWIP=y CONFIG_CMD_DNS=y +CONFIG_CMD_SNTP=y CONFIG_CMD_WGET=y CONFIG_EFI_HTTP_BOOT=y CONFIG_WGET_HTTPS=y diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index f13001390d4..92ba48f6af9 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_KVM_VIRT_INS=y CONFIG_ARM_SMCCC=y CONFIG_ARCH_QEMU=y CONFIG_SYS_MALLOC_LEN=0x1000000 diff --git a/configs/r8a779g0_whitehawk_defconfig b/configs/r8a779g0_whitehawk_defconfig index fefe356ed2b..41217fa5776 100644 --- a/configs/r8a779g0_whitehawk_defconfig +++ b/configs/r8a779g0_whitehawk_defconfig @@ -26,7 +26,9 @@ CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_RENESAS_RAVB=y CONFIG_BAUDRATE=921600 -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xeb300000 +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_HAVE_INIT_STACK=y +CONFIG_SPL_STACK=0xe6400000 CONFIG_SPL_DM_SPI=y CONFIG_SPL_TEXT_BASE=0xeb210000 CONFIG_SPL_STACK_R_ADDR=0x44000000 diff --git a/configs/r8a779g3_sparrowhawk_defconfig b/configs/r8a779g3_sparrowhawk_defconfig index 47fc536df81..9aa8dc83317 100644 --- a/configs/r8a779g3_sparrowhawk_defconfig +++ b/configs/r8a779g3_sparrowhawk_defconfig @@ -24,12 +24,19 @@ CONFIG_CMD_REMOTEPROC=y CONFIG_GPIO_HOG=y CONFIG_REMOTEPROC_RENESAS_APMU=y CONFIG_BITBANGMII=y +CONFIG_CMD_PCI=y CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_NVME_PCI=y +CONFIG_PCI=y +CONFIG_PCI_RCAR_GEN4=y +CONFIG_PCI_REGION_MULTI_ENTRY=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_RENESAS_RAVB=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xeb300000 +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_HAVE_INIT_STACK=y +CONFIG_SPL_STACK=0xe6400000 CONFIG_SPL_DM_SPI=y CONFIG_SPL_TEXT_BASE=0xeb210000 CONFIG_SPL_STACK_R_ADDR=0x44000000 diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 34e89bf6b3e..1cefaa0a138 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -31,7 +31,6 @@ CONFIG_ANDROID_AB=y CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y CONFIG_CMD_BOOTZ=y -CONFIG_CMD_BOOTEFI_HELLO=y # CONFIG_CMD_ELF is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 4f6943d1a4b..d6768e291d0 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -59,7 +59,6 @@ CONFIG_CMD_BOOTM_PRE_LOAD=y CONFIG_CMD_BOOTZ=y CONFIG_BOOTM_OPENRTOS=y CONFIG_BOOTM_OSE=y -CONFIG_CMD_BOOTEFI_HELLO=y CONFIG_CMD_BOOTMENU=y CONFIG_CMD_ABOOTIMG=y CONFIG_CMD_ASKENV=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 67c0ed7353e..f0a69a414db 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -30,7 +30,6 @@ CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y CONFIG_CMD_BOOTZ=y # CONFIG_CMD_BOOTEFI_BOOTMGR is not set -CONFIG_CMD_BOOTEFI_HELLO=y # CONFIG_CMD_ELF is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 2a8e79a95c7..a0702d6f6e1 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -66,7 +66,6 @@ CONFIG_SPL_SPI_LOAD=y CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y CONFIG_CMD_BOOTZ=y -CONFIG_CMD_BOOTEFI_HELLO=y # CONFIG_CMD_ELF is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 76b0ef1fcb6..f1c48c84b62 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -45,7 +45,6 @@ CONFIG_SPL_RTC=y CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y CONFIG_CMD_BOOTZ=y -CONFIG_CMD_BOOTEFI_HELLO=y # CONFIG_CMD_ELF is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig index e1a0555744c..9d75bb5f933 100644 --- a/configs/sandbox_vpl_defconfig +++ b/configs/sandbox_vpl_defconfig @@ -58,7 +58,6 @@ CONFIG_VPL_TEXT_BASE=0x100000 CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y CONFIG_CMD_BOOTZ=y -CONFIG_CMD_BOOTEFI_HELLO=y # CONFIG_CMD_ELF is not set CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y diff --git a/configs/th1520_lpi4a_defconfig b/configs/th1520_lpi4a_defconfig index 243b89f753d..78e3b25ab82 100644 --- a/configs/th1520_lpi4a_defconfig +++ b/configs/th1520_lpi4a_defconfig @@ -90,6 +90,7 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_SNPS=y # CONFIG_MTD is not set +CONFIG_PINCTRL=y # CONFIG_POWER is not set CONFIG_RAM=y CONFIG_SPL_RAM=y diff --git a/configs/verdin-am62_a53_defconfig b/configs/verdin-am62_a53_defconfig index 4b8e7d9f490..584c416bd83 100644 --- a/configs/verdin-am62_a53_defconfig +++ b/configs/verdin-am62_a53_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y diff --git a/configs/verdin-am62p_a53_defconfig b/configs/verdin-am62p_a53_defconfig index e4a28050079..28f48ba773e 100644 --- a/configs/verdin-am62p_a53_defconfig +++ b/configs/verdin-am62p_a53_defconfig @@ -1,6 +1,5 @@ CONFIG_ARM=y CONFIG_ARCH_K3=y -CONFIG_SYS_MALLOC_LEN=0x2000000 CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y @@ -19,7 +18,6 @@ CONFIG_SPL_MMC=y CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y CONFIG_SPL_STACK_R_ADDR=0x82000000 -CONFIG_SPL_TEXT_BASE=0x80080000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y CONFIG_SPL_BSS_START_ADDR=0x80c80000 CONFIG_SPL_BSS_MAX_SIZE=0x80000 @@ -73,7 +71,6 @@ CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_READ=y -CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_USB=y CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_BOOTCOUNT=y @@ -171,7 +168,6 @@ CONFIG_DM_REGULATOR_TPS65219=y CONFIG_K3_SYSTEM_CONTROLLER=y CONFIG_REMOTEPROC_TI_K3_ARM64=y CONFIG_REMOTEPROC_TI_K3_DSP=y -CONFIG_REMOTEPROC_TI_K3_R5F=y CONFIG_RESET_TI_SCI=y CONFIG_DM_SERIAL=y CONFIG_SOC_DEVICE=y diff --git a/configs/verdin-am62p_r5_defconfig b/configs/verdin-am62p_r5_defconfig index bbdc803eb3a..42361523ab3 100644 --- a/configs/verdin-am62p_r5_defconfig +++ b/configs/verdin-am62p_r5_defconfig @@ -18,7 +18,6 @@ CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y CONFIG_SPL_STACK_R_ADDR=0x82000000 CONFIG_SPL_SYS_MALLOC_F_LEN=0x8000 -CONFIG_SPL_TEXT_BASE=0x43c00000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y CONFIG_SPL_BSS_START_ADDR=0x43c4b000 CONFIG_SPL_BSS_MAX_SIZE=0x3000 @@ -49,7 +48,6 @@ CONFIG_SPL_DM_MAILBOX=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_POWER_DOMAIN=y CONFIG_SPL_RAM_DEVICE=y -CONFIG_SPL_REMOTEPROC=y CONFIG_CMD_DFU=y CONFIG_OF_CONTROL=y CONFIG_SPL_OF_CONTROL=y @@ -89,7 +87,6 @@ CONFIG_PINCTRL_SINGLE=y CONFIG_POWER_DOMAIN=y CONFIG_TI_POWER_DOMAIN=y CONFIG_K3_SYSTEM_CONTROLLER=y -CONFIG_REMOTEPROC_TI_K3_ARM64=y CONFIG_RESET_TI_SCI=y CONFIG_SPECIFY_CONSOLE_INDEX=y CONFIG_DM_SERIAL=y diff --git a/configs/vf610twr_defconfig b/configs/vf610twr_defconfig index 0bb21f58a7c..556190728e1 100644 --- a/configs/vf610twr_defconfig +++ b/configs/vf610twr_defconfig @@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_VF610=y CONFIG_TEXT_BASE=0x3f401000 CONFIG_SYS_MALLOC_LEN=0x202000 -CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_OFFSET=0xC0000 diff --git a/configs/vf610twr_nand_defconfig b/configs/vf610twr_nand_defconfig index a7e8cf2f7bb..7fe9d822110 100644 --- a/configs/vf610twr_nand_defconfig +++ b/configs/vf610twr_nand_defconfig @@ -4,7 +4,6 @@ CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_VF610=y CONFIG_TEXT_BASE=0x3f401000 CONFIG_SYS_MALLOC_LEN=0x0220000 -CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_OFFSET=0x180000 diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig index 605a30b9987..59f33f669cb 100644 --- a/configs/xilinx_versal_mini_defconfig +++ b/configs/xilinx_versal_mini_defconfig @@ -33,6 +33,7 @@ CONFIG_CLOCKS=y # CONFIG_SYS_LONGHELP is not set CONFIG_SYS_PROMPT="Versal> " # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -60,6 +61,7 @@ CONFIG_SYS_ALT_MEMTEST=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_MMC is not set CONFIG_ARM_DCC=y # CONFIG_GZIP is not set diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig index 90d6abd490e..92d08120237 100644 --- a/configs/xilinx_versal_mini_emmc0_defconfig +++ b/configs/xilinx_versal_mini_emmc0_defconfig @@ -31,6 +31,7 @@ CONFIG_CLOCKS=y CONFIG_SYS_PROMPT="Versal> " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -59,6 +60,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y CONFIG_ARM_DCC=y diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig index df6a4165015..2c3775c3075 100644 --- a/configs/xilinx_versal_mini_emmc1_defconfig +++ b/configs/xilinx_versal_mini_emmc1_defconfig @@ -31,6 +31,7 @@ CONFIG_CLOCKS=y CONFIG_SYS_PROMPT="Versal> " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -59,6 +60,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y CONFIG_ARM_DCC=y diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig index af9ce499169..11811f3c0fd 100644 --- a/configs/xilinx_versal_mini_ospi_defconfig +++ b/configs/xilinx_versal_mini_ospi_defconfig @@ -31,6 +31,7 @@ CONFIG_BOARD_EARLY_INIT_R=y CONFIG_SYS_PROMPT="Versal> " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -54,6 +55,7 @@ CONFIG_SYS_PROMPT="Versal> " # CONFIG_CMD_SETEXPR is not set CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_MMC is not set CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig index ecb3b16033c..47737ce0f8f 100644 --- a/configs/xilinx_versal_mini_qspi_defconfig +++ b/configs/xilinx_versal_mini_qspi_defconfig @@ -32,6 +32,7 @@ CONFIG_SYS_PROMPT="Versal> " # CONFIG_SYS_XTRACE is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -56,6 +57,7 @@ CONFIG_SYS_PROMPT="Versal> " # CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG is not set CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_GPIO is not set # CONFIG_I2C is not set # CONFIG_INPUT is not set diff --git a/configs/xilinx_versal_net_mini_defconfig b/configs/xilinx_versal_net_mini_defconfig index 7cae88b0d9f..27a163a9ae5 100644 --- a/configs/xilinx_versal_net_mini_defconfig +++ b/configs/xilinx_versal_net_mini_defconfig @@ -33,6 +33,7 @@ CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SYS_LONGHELP is not set CONFIG_SYS_PROMPT="Versal NET> " # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -64,6 +65,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_GPIO is not set # CONFIG_I2C is not set # CONFIG_INPUT is not set diff --git a/configs/xilinx_versal_net_mini_emmc_defconfig b/configs/xilinx_versal_net_mini_emmc_defconfig index 30f4885d149..8d3561fee6d 100644 --- a/configs/xilinx_versal_net_mini_emmc_defconfig +++ b/configs/xilinx_versal_net_mini_emmc_defconfig @@ -26,6 +26,7 @@ CONFIG_BOARD_EARLY_INIT_R=y CONFIG_SYS_PROMPT="Versal NET> " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -54,6 +55,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set CONFIG_MMC_HS200_SUPPORT=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y diff --git a/configs/xilinx_versal_net_mini_ospi_defconfig b/configs/xilinx_versal_net_mini_ospi_defconfig index 18ec7372258..aadfcfcf9db 100644 --- a/configs/xilinx_versal_net_mini_ospi_defconfig +++ b/configs/xilinx_versal_net_mini_ospi_defconfig @@ -30,6 +30,7 @@ CONFIG_BOARD_EARLY_INIT_R=y CONFIG_SYS_PROMPT="Versal NET> " # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -53,6 +54,7 @@ CONFIG_SYS_PROMPT="Versal NET> " # CONFIG_CMD_SETEXPR is not set CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_MMC is not set CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y diff --git a/configs/xilinx_versal_net_mini_qspi_defconfig b/configs/xilinx_versal_net_mini_qspi_defconfig index 5241da6c63b..ed4c3893315 100644 --- a/configs/xilinx_versal_net_mini_qspi_defconfig +++ b/configs/xilinx_versal_net_mini_qspi_defconfig @@ -31,6 +31,7 @@ CONFIG_SYS_PROMPT="Versal NET> " # CONFIG_SYS_XTRACE is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -55,6 +56,7 @@ CONFIG_SYS_PROMPT="Versal NET> " # CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG is not set CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_GPIO is not set # CONFIG_I2C is not set # CONFIG_INPUT is not set diff --git a/configs/xilinx_versal_net_virt_defconfig b/configs/xilinx_versal_net_virt_defconfig index c9866deeaeb..c13bdb2e545 100644 --- a/configs/xilinx_versal_net_virt_defconfig +++ b/configs/xilinx_versal_net_virt_defconfig @@ -73,6 +73,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SIMPLE_PM_BUS=y CONFIG_CLK_VERSAL=y CONFIG_DFU_RAM=y +CONFIG_ZYNQMP_FIRMWARE=y CONFIG_ARM_FFA_TRANSPORT=y CONFIG_FPGA_XILINX=y CONFIG_FPGA_VERSALPL=y diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 5dc43ba00fd..d8f4b884e76 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -81,6 +81,7 @@ CONFIG_DFU_MMC=y CONFIG_DFU_RAM=y CONFIG_DFU_SF=y CONFIG_SYS_DFU_DATA_BUF_SIZE=0x1800000 +CONFIG_ZYNQMP_FIRMWARE=y CONFIG_ARM_FFA_TRANSPORT=y CONFIG_FPGA_XILINX=y CONFIG_FPGA_VERSALPL=y diff --git a/configs/xilinx_zynqmp_kria_defconfig b/configs/xilinx_zynqmp_kria_defconfig index 22ba8a7cc15..3e2ac614405 100644 --- a/configs/xilinx_zynqmp_kria_defconfig +++ b/configs/xilinx_zynqmp_kria_defconfig @@ -46,6 +46,7 @@ CONFIG_USE_PREBOOT=y CONFIG_SYS_PBSIZE=2073 CONFIG_BOARD_EARLY_INIT_R=y CONFIG_CLOCKS=y +CONFIG_BOARD_RNG_SEED=y CONFIG_SPL_MAX_SIZE=0x40000 # CONFIG_SPL_BINMAN_SYMBOLS is not set # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig index 736d4bd4efc..f164580c501 100644 --- a/configs/xilinx_zynqmp_mini_defconfig +++ b/configs/xilinx_zynqmp_mini_defconfig @@ -26,6 +26,7 @@ CONFIG_CLOCKS=y # CONFIG_SYS_LONGHELP is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -56,6 +57,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_DM_MAILBOX is not set # CONFIG_MMC is not set CONFIG_ARM_DCC=y diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig index 85a6af45c57..8a8a9b0b463 100644 --- a/configs/xilinx_zynqmp_mini_emmc0_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig @@ -40,6 +40,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x1000000 # CONFIG_AUTO_COMPLETE is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -71,6 +72,7 @@ CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_SIMPLE_BUS is not set # CONFIG_DM_MAILBOX is not set CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_SDHCI=y diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig index 4c01a43b6e4..3fc4f2f9b86 100644 --- a/configs/xilinx_zynqmp_mini_emmc1_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig @@ -40,6 +40,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x1000000 # CONFIG_AUTO_COMPLETE is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -71,6 +72,7 @@ CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_SIMPLE_BUS is not set # CONFIG_DM_MAILBOX is not set CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_SDHCI=y diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig index afb50a9ff43..cfcb4321b1f 100644 --- a/configs/xilinx_zynqmp_mini_nand_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_defconfig @@ -27,6 +27,7 @@ CONFIG_CLOCKS=y # CONFIG_SYS_LONGHELP is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -51,6 +52,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_DM_MAILBOX is not set # CONFIG_MMC is not set CONFIG_DM_MTD=y diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig index a40a4493d5d..9af0b717ba9 100644 --- a/configs/xilinx_zynqmp_mini_nand_single_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig @@ -27,6 +27,7 @@ CONFIG_CLOCKS=y # CONFIG_SYS_LONGHELP is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -51,6 +52,7 @@ CONFIG_OF_EMBED=y CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_SIMPLE_BUS is not set # CONFIG_DM_MAILBOX is not set # CONFIG_MMC is not set CONFIG_DM_MTD=y diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig index 0367c043574..3f2d44d038e 100644 --- a/configs/xilinx_zynqmp_mini_qspi_defconfig +++ b/configs/xilinx_zynqmp_mini_qspi_defconfig @@ -43,6 +43,7 @@ CONFIG_SPL_SYS_MALLOC_SIZE=0x1000000 # CONFIG_SYS_LONGHELP is not set # CONFIG_CMD_BDI is not set # CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_HELP is not set # CONFIG_CMD_BOOTD is not set # CONFIG_CMD_BOOTM is not set # CONFIG_CMD_BOOTI is not set @@ -73,6 +74,7 @@ CONFIG_ENV_RELOC_GD_ENV_ADDR=y CONFIG_NO_NET=y # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_SIMPLE_BUS is not set # CONFIG_FIRMWARE is not set # CONFIG_GPIO is not set # CONFIG_I2C is not set diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index a0067793a41..65c8a4bbaad 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -163,7 +163,6 @@ CONFIG_MTD_RAW_NAND=y CONFIG_NAND_ARASAN=y CONFIG_SYS_NAND_ONFI_DETECTION=y CONFIG_SYS_NAND_MAX_CHIPS=2 -CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MACRONIX=y @@ -182,6 +181,7 @@ CONFIG_PHY_NATSEMI=y CONFIG_PHY_REALTEK=y CONFIG_PHY_TI_DP83867=y CONFIG_PHY_VITESSE=y +CONFIG_PHY_XILINX=y CONFIG_PHY_XILINX_GMII2RGMII=y CONFIG_PHY_FIXED=y CONFIG_DM_ETH_PHY=y diff --git a/configs/yuzukihd-chameleon_defconfig b/configs/yuzukihd-chameleon_defconfig new file mode 100644 index 00000000000..6cefcb77a28 --- /dev/null +++ b/configs/yuzukihd-chameleon_defconfig @@ -0,0 +1,29 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="allwinner/sun50i-h618-yuzukihd-chameleon" +CONFIG_SPL=y +CONFIG_DRAM_SUNXI_DX_ODT=0x03030303 +CONFIG_DRAM_SUNXI_DX_DRI=0x0e0e0e0e +CONFIG_DRAM_SUNXI_CA_DRI=0x1c12 +CONFIG_DRAM_SUNXI_TPR6=0x33808080 +CONFIG_DRAM_SUNXI_TPR10=0x002f0006 +CONFIG_DRAM_SUNXI_TPR11=0xddddcccc +CONFIG_DRAM_SUNXI_TPR12=0xeddc7564 +CONFIG_MACH_SUN50I_H616=y +CONFIG_SUNXI_DRAM_H616_DDR3_1333=y +CONFIG_DRAM_CLK=648 +CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +CONFIG_R_I2C_ENABLE=y +CONFIG_SPL_SPI_SUNXI=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_I2C=y +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_SYS_I2C_SLAVE=0x7f +CONFIG_SYS_I2C_SPEED=400000 +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_AXP313_POWER=y +CONFIG_AXP_DCDC3_VOLT=1500 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_MUSB_GADGET=y diff --git a/disk/part_efi.c b/disk/part_efi.c index 68ba1d11e7b..fb1ed534f86 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -215,6 +215,34 @@ int get_disk_guid(struct blk_desc *desc, char *guid) return 0; } +int part_get_gpt_pte(struct blk_desc *desc, int part, gpt_entry *gpt_e) +{ + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz); + gpt_entry *gpt_pte = NULL; + + /* "part" argument must be at least 1 */ + if (part < 1) { + log_debug("Invalid Argument(s)\n"); + return -EINVAL; + } + + /* This function validates AND fills in the GPT header and PTE */ + if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1) + return -EINVAL; + + if (part > le32_to_cpu(gpt_head->num_partition_entries) || + !is_pte_valid(&gpt_pte[part - 1])) { + log_debug("Invalid partition number %d\n", part); + free(gpt_pte); + return -EPERM; + } + + memcpy(gpt_e, &gpt_pte[part - 1], sizeof(*gpt_e)); + + free(gpt_pte); + return 0; +} + static void __maybe_unused part_print_efi(struct blk_desc *desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz); @@ -260,45 +288,32 @@ static void __maybe_unused part_print_efi(struct blk_desc *desc) static int __maybe_unused part_get_info_efi(struct blk_desc *desc, int part, struct disk_partition *info) { - ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, desc->blksz); - gpt_entry *gpt_pte = NULL; - - /* "part" argument must be at least 1 */ - if (part < 1) { - log_debug("Invalid Argument(s)\n"); - return -EINVAL; - } - - /* This function validates AND fills in the GPT header and PTE */ - if (find_valid_gpt(desc, gpt_head, &gpt_pte) != 1) - return -EINVAL; + gpt_entry gpt_pte = {}; + int ret; - if (part > le32_to_cpu(gpt_head->num_partition_entries) || - !is_pte_valid(&gpt_pte[part - 1])) { - log_debug("Invalid partition number %d\n", part); - free(gpt_pte); - return -EPERM; - } + ret = part_get_gpt_pte(desc, part, &gpt_pte); + if (ret) + return ret; /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */ - info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba); + info->start = (lbaint_t)le64_to_cpu(gpt_pte.starting_lba); /* The ending LBA is inclusive, to calculate size, add 1 to it */ - info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1 + info->size = (lbaint_t)le64_to_cpu(gpt_pte.ending_lba) + 1 - info->start; info->blksz = desc->blksz; snprintf((char *)info->name, sizeof(info->name), "%s", - print_efiname(&gpt_pte[part - 1])); + print_efiname(&gpt_pte)); strcpy((char *)info->type, "U-Boot"); - info->bootable = get_bootable(&gpt_pte[part - 1]); - info->type_flags = gpt_pte[part - 1].attributes.fields.type_guid_specific; + info->bootable = get_bootable(&gpt_pte); + info->type_flags = gpt_pte.attributes.fields.type_guid_specific; if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) { - uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, + uuid_bin_to_str(gpt_pte.unique_partition_guid.b, (char *)disk_partition_uuid(info), UUID_STR_FORMAT_GUID); } if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) { - uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b, + uuid_bin_to_str(gpt_pte.partition_type_guid.b, (char *)disk_partition_type_guid(info), UUID_STR_FORMAT_GUID); } @@ -306,8 +321,6 @@ static int __maybe_unused part_get_info_efi(struct blk_desc *desc, int part, log_debug("start 0x" LBAF ", size 0x" LBAF ", name %s\n", info->start, info->size, info->name); - /* Remember to free pte */ - free(gpt_pte); return 0; } diff --git a/doc/README.SNTP b/doc/README.SNTP deleted file mode 100644 index da9ec459ad4..00000000000 --- a/doc/README.SNTP +++ /dev/null @@ -1,17 +0,0 @@ -To use SNTP support, add define CONFIG_CMD_SNTP to the -configuration file of the board. - -The "sntp" command gets network time from NTP time server and -syncronize RTC of the board. This command needs the command line -parameter of server's IP address or environment variable -"ntpserverip". The network time is sent as UTC. So if you want to -set local time to RTC, set the offset in second from UTC to the -environment variable "time offset". - -If the DHCP server provides time server's IP or time offset, you -don't need to set the above environment variables yourself. - -Current limitations of SNTP support: -1. The roundtrip time is ignored. -2. Only the 1st NTP server IP, in the option ntp-servers of DHCP, will - be used. diff --git a/doc/README.pxe b/doc/README.pxe index 9fff2cd5ae9..ba189080e8c 100644 --- a/doc/README.pxe +++ b/doc/README.pxe @@ -178,7 +178,8 @@ devicetree-overlay <path> [...] - if this label is chosen, use tftp to retrieve kaslrseed - set this label to request random number from hwrng as kaslr seed. append <string> - use <string> as the kernel command line when booting this - label. + label. Environment variable references like ${var} are + substituted before boot. initrd <path> - if this label is chosen, use tftp to retrieve the initrd at <path>. it will be stored at the address indicated in diff --git a/doc/api/index.rst b/doc/api/index.rst index 506843ed74a..cf9d21e4c1c 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -17,7 +17,6 @@ U-Boot API documentation interrupt led linker_lists - lmb logging nvmem part diff --git a/doc/api/linker_lists.rst b/doc/api/linker_lists.rst index 3cd447f187d..9e6849d5e75 100644 --- a/doc/api/linker_lists.rst +++ b/doc/api/linker_lists.rst @@ -130,17 +130,17 @@ the compiler cannot update the alignment of the linker_list item. In the first case, an 8-byte 'fill' region is added:: __u_boot_list_2_driver_2_testbus_drv - 0x0000000000270018 0x80 test/built-in.o + 0x0000000000270018 0x80 test/built-in.a 0x0000000000270018 _u_boot_list_2_driver_2_testbus_drv __u_boot_list_2_driver_2_testfdt1_drv - 0x0000000000270098 0x80 test/built-in.o + 0x0000000000270098 0x80 test/built-in.a 0x0000000000270098 _u_boot_list_2_driver_2_testfdt1_drv *fill* 0x0000000000270118 0x8 __u_boot_list_2_driver_2_testfdt_drv - 0x0000000000270120 0x80 test/built-in.o + 0x0000000000270120 0x80 test/built-in.a 0x0000000000270120 _u_boot_list_2_driver_2_testfdt_drv __u_boot_list_2_driver_2_testprobe_drv - 0x00000000002701a0 0x80 test/built-in.o + 0x00000000002701a0 0x80 test/built-in.a 0x00000000002701a0 _u_boot_list_2_driver_2_testprobe_drv With this, the linker_list no-longer works since items after testfdt1_drv diff --git a/doc/api/lmb.rst b/doc/api/lmb.rst deleted file mode 100644 index 2095bfa1618..00000000000 --- a/doc/api/lmb.rst +++ /dev/null @@ -1,7 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0+ - -Logical memory blocks -===================== - -.. kernel-doc:: include/lmb.h - :internal: diff --git a/doc/board/qualcomm/board.rst b/doc/board/qualcomm/board.rst index 003d59a18eb..642c5095261 100644 --- a/doc/board/qualcomm/board.rst +++ b/doc/board/qualcomm/board.rst @@ -23,10 +23,7 @@ Installation ------------ Build ^^^^^ - - $ ./tools/buildman/buildman -o .output qcom - -This will build ``.output/u-boot-nodtb.bin`` using the ``qcom_defconfig``. +We will build ``u-boot-nodtb.bin`` from the u-boot source tree. Generate FIT image (optional) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -81,19 +78,20 @@ Steps: - Build u-boot -As above:: +Use the following commands:: - ./tools/buildman/buildman -o .output qcom + make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig + make CROSS_COMPILE=aarch64-linux-gnu- O=.output -j$(nproc) Or for db410c (and other boards not supported by the generic target):: make CROSS_COMPILE=aarch64-linux-gnu- O=.output dragonboard410c_defconfig - make O=.output -j$(nproc) + make CROSS_COMPILE=aarch64-linux-gnu- O=.output -j$(nproc) Or for smartphones:: make CROSS_COMPILE=aarch64-linux-gnu- O=.output qcom_defconfig qcom-phone.config - make O=.output -j$(nproc) + make CROSS_COMPILE=aarch64-linux-gnu- O=.output -j$(nproc) - gzip u-boot:: @@ -119,6 +117,13 @@ Or with no FIT image:: mkbootimg --kernel u-boot-nodtb.bin.gz-dtb \ --output boot.img --pagesize 4096 --base 0x80000000 +Other devices with boot image version 2 can be built like this example:: + + mkbootimg --pagesize 4096 --header_version 2 \ + --kernel_offset 0x00008000 --kernel u-boot-nodtb.bin.gz \ + --dtb_offset 0x01f00000 --dtb dts/upstream/src/arm64/qcom/qcm6490-fairphone-fp5.dtb \ + --output boot.img + - Flash boot.img using fastboot and erase dtbo to avoid conflicts with our DTB: .. code-block:: bash diff --git a/doc/board/qualcomm/dragonwing.rst b/doc/board/qualcomm/dragonwing.rst new file mode 100644 index 00000000000..d4899415309 --- /dev/null +++ b/doc/board/qualcomm/dragonwing.rst @@ -0,0 +1,49 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. sectionauthor:: Balaji Selvanathan <balaji.selvanathan@oss.qualcomm.com> + +Qualcomm DragonWing +======================================== + +Qualcomm DragonWing are industrial-grade boards that provides various series +of processors such as IQ6 (QCS615), IQ8 (QCS8300) and IQ9 (QCS9100). +These SoCs are used for factory/industry based applications. +More information can be found on the `Qualcomm's IQ6 product page`_, +`Qualcomm's IQ8 product page`_ and `Qualcomm's IQ9 product page`_. + +.. _Qualcomm's IQ6 product page: https://docs.qualcomm.com/bundle/publicresource/87-83838-1_REV_A_Qualcomm_IQ6_Series_Product_Brief.pdf +.. _Qualcomm's IQ8 product page: https://docs.qualcomm.com/bundle/publicresource/87-83839-1_REV_A_Qualcomm_IQ8_Series_Product_Brief________.pdf +.. _Qualcomm's IQ9 product page: https://docs.qualcomm.com/bundle/publicresource/87-83840-1_REV_A_Qualcomm_IQ9_Series_Product_Brief.pdf + +Installation +------------ +First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``QCS615``, ``QCS8300`` or ``QCS9100``:: + + $ export CROSS_COMPILE=<aarch64 toolchain prefix> + $ make qcom_qcs8300_defconfig + $ make -j8 u-boot.mbn + +Although the board does not have secure boot set up by default, +the firmware still expects firmware ELF images to be "signed". The signature +does not provide any security in this case, but it provides the firmware with +some required metadata. + +To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_:: + + $ qtestsign -v6 aboot -o u-boot.mbn u-boot.elf + +Then flash the resulting ``u-boot.mbn`` to the ``uefi_a`` partition +on your device with ``fastboot flash uefi_a u-boot.mbn``. + +U-Boot should be running after a reboot (``fastboot reboot``). + +Note that fastboot is not yet supported in U-Boot on Dragonwing boards, as a result, to flash +back the original firmware, or new versoins of the U-Boot, EDL mode must be used. + +A tool like bkerler's `edl`_ can be used for flashing with the firehose loader (for example, for QCS9100 +the firehose loader can be obtained from `dragonwing IQ9 bootbinaries`.) :: + +$ edl.py --loader /path/to/prog_firehose_ddr.elf w uefi_a u-boot.mbn + +.. _qtestsign: https://github.com/msm8916-mainline/qtestsign +.. _edl: https://github.com/bkerler/edl +.. _dragonwing IQ9 bootbinaries: https://artifacts.codelinaro.org/ui/native/qli-ci/flashable-binaries/qimpsdk/qcs9075-rb8-core-kit diff --git a/doc/board/qualcomm/index.rst b/doc/board/qualcomm/index.rst index e2fcbfa19c2..ccf834208e9 100644 --- a/doc/board/qualcomm/index.rst +++ b/doc/board/qualcomm/index.rst @@ -8,6 +8,7 @@ Qualcomm dragonboard410c rb3gen2 + dragonwing board phones debugging diff --git a/doc/board/qualcomm/rdp.rst b/doc/board/qualcomm/rdp.rst index fd14f1d9829..99cf8eba57c 100644 --- a/doc/board/qualcomm/rdp.rst +++ b/doc/board/qualcomm/rdp.rst @@ -21,13 +21,16 @@ First, setup ``CROSS_COMPILE`` for aarch64. Then, build U-Boot for ``IPQ9574``:: This will build ``u-boot.elf`` in the configured output directory. -Although the RDPs do not have secure boot set up by default, the firmware still -expects firmware ELF images to be "signed". The signature does not provide any -security in this case, but it provides the firmware with some required metadata. +The firmware expects the ELF images to be in MBN format. The `elftombn.py` tool +can be used to convert the ELF images to MBN format. -To "sign" ``u-boot.elf`` you can use e.g. `qtestsign`_:: + IPQ9574: (MBN version 6) - $ qtestsign -v6 aboot -o u-boot.mbn u-boot.elf + $ python elftombn.py -f u-boot.elf -o u-boot.mbn -v6 + + IPQ5424: (MBN version 7) + + $ python elftombn.py -f u-boot.elf -o u-boot.mbn -v7 Then install the resulting ``u-boot.mbn`` to the ``0:APPSBL`` partition on your device with:: @@ -51,5 +54,5 @@ U-Boot should be running after a reboot (``reset``). Note that the support added is very basic. Restoring the original U-Boot on boards with older version of the software requires a debugger. -.. _qtestsign: https://github.com/msm8916-mainline/qtestsign +.. _elftombn.py: https://git.codelinaro.org/clo/qsdk/oss/system/tools/meta/-/tree/NHSS.QSDK.13.0.5.r2/scripts?ref_type=heads .. _edl: https://github.com/bkerler/edl diff --git a/doc/develop/crash_dumps.rst b/doc/develop/crash_dumps.rst index 4237b073bc9..c84b85b3364 100644 --- a/doc/develop/crash_dumps.rst +++ b/doc/develop/crash_dumps.rst @@ -89,15 +89,15 @@ File u-boot.map contains the memory layout of the U-Boot binary. Here we find these lines:: .text.do_undefined - 0x00000000000101fc 0xc cmd/built-in.o + 0x00000000000101fc 0xc cmd/built-in.a .text.exception_complete - 0x0000000000010208 0x90 cmd/built-in.o + 0x0000000000010208 0x90 cmd/built-in.a ... .text.cmd_process - 0x00000000000213b8 0x164 common/built-in.o + 0x00000000000213b8 0x164 common/built-in.a 0x00000000000213b8 cmd_process .text.cmd_process_error - 0x000000000002151c 0x40 common/built-in.o + 0x000000000002151c 0x40 common/built-in.a 0x000000000002151c cmd_process_error So the error occurred at the start of function do\_undefined() and this diff --git a/doc/develop/distro.rst b/doc/develop/distro.rst index 1d2f9c4c32b..01efce40a29 100644 --- a/doc/develop/distro.rst +++ b/doc/develop/distro.rst @@ -92,6 +92,13 @@ That said, we have some differences to these documents, namely: * If ``-`` is passed as fdt argument and ``CONFIG_SUPPORT_PASSING_ATAGS`` is enabled, then no device tree will be used (legacy booting / pre-dtb kernel). +* The ``append`` string may use environment variables. For example, an + A/B boot setup could use ``append root=PARTLABEL=root_${bootslot}`` + to set the root filesystem to the right one for the selected slot, + assuming the ``bootslot`` environment variable is set before the + extlinux.conf file is processed, and the partition is labeled to + match. + See also doc/README.pxe under 'pxe file format'. One example extlinux.conf generated by the Fedora installer is:: diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 0c83ef109ab..3c044e67927 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -46,6 +46,7 @@ Implementation cedit event global_data + lmb logging makefiles menus diff --git a/doc/develop/lmb.rst b/doc/develop/lmb.rst new file mode 100644 index 00000000000..b9d0f09c2bb --- /dev/null +++ b/doc/develop/lmb.rst @@ -0,0 +1,166 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Logical Memory Blocks (LMB) +=========================== + +U-Boot has support for reserving chunks of memory which is primarily +used for loading images to the DRAM memory, before these are booted, +or written to non-volatile storage medium. This functionality is +provided through the Logical Memory Blocks (LMB) module. + +Introduction +------------ + +The LMB module manages allocation requests for memory region not +occupied by the U-Boot image. Allocation requests that are made +through malloc() and similar functions result in memory getting +allocated from the heap region, which is part of the U-Boot +image. Typically, the heap memory is a few MiB in size. Loading an +image like the linux kernel might require lot more memory than what +the heap can provide. Such allocations are usually handled through the +LMB module. + +The U-Boot image typically gets relocated to the top of the usable +DRAM memory region. A typical memory layout looks as follows:: + + + + + + | | + | | + | | + | | + | | + --- +--------------+ <--- U-Boot ram top + | | | + | | Text | + | +--------------+ + | | | + | | Data | + | +--------------+ + | | | + | | BSS | + U-Boot Image +--------------+ + | | | + | | Heap | + | | | + | +--------------+ + | | | + | | | + | | Stack | + | | | + | | | + --- +--------------+ + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + | | + +--------------+ <--- ram start + + + +The region of memory below the U-Boot image is the one controlled by +the LMB module. + + +Types of LMB Allocations +------------------------ + +There are two classes of allocation requests that get made to the LMB +module. One type of allocation requests are requesting memory of a +particular number of bytes. This type of allocation is similar to that +done using the malloc type of function calls. The other type of +allocations, are requests made for a specific memory address. The +second type of allocations are usually made for loading images to a +particular memory address. + + +LMB design Pre 2025.01 +---------------------- + +The earlier versions of U-Boot (pre 2025.01 release) +had a local memory map based LMB implementation whereby it was +possible to declare the LMB map inside a function or a C file. This +design resulted in temporary, non-global LMB maps, which also allowed +for re-use of memory. This meant that it was possible to use a region +of memory to load some image, and subsequently the same region of +memory could be used for loading a different image. A typical example +of this usage would be loading an image to a memory address, followed +by writing that image to some non-volatile storage medium. Once this +is done, the same address can be used for loading a different image +and then writing it to it's non-volatile storage +destination. Typically, environment variables like `loadaddr`, +`kernel_addr_r`, `ramdisk_addr_r` are used for loading images to +memory regions. + + +Current LMB implementation +-------------------------- + +Changes were made in the 2025.01 release to make the LMB memory map +global and persistent. With this, the LMB memory map is the same +across all of U-Boot, and also persists as long as U-Boot is +active. Even with this change, there has been consistency as far as +re-use of memory is concerned to maintain backward compatibility. It +is allowed for re-requesting the same region of memory if the memory +region has a particular attribute (LMB_NONE). + +As part of the platform boot, DRAM memory available for use in U-Boot +gets added to the LMB memory map. Any allocation requests made +subsequently will be made from this memory added as part of the board +init. + + +Allocation API +-------------- + +Any request for non-heap memory can be made through the LMB allocation +API. + +.. code-block:: c + + int lmb_alloc_mem(enum lmb_mem_type type, u64 align, + phys_addr_t *addr, phys_size_t size, + u32 flags); + +Correspondingly, the allocated memory can be free'd + +.. code-block:: c + + long lmb_free(phys_addr_t base, phys_size_t size, u32 flags); + +For a detailed API description, please refer to the header file. + + +UEFI allocations with LMB as the backend +---------------------------------------- + +The UEFI specification describes boot-time API's for allocation of +memory. These API's use the same memory that is being used by the LMB +module. Pre 2025.01 release, there wasn't any synchronisation between +the EFI sub-system and the LMB module about the memory that was +getting allocated by each of these modules. This was the primary +reason for making the LMB memory map global and persistent. With this +change, the EFI memory allocation API's have also been changed to use +the LMB module as the backend for the allocation requests. Any other +sub-system which might wish to use the same memory region for it's use +can then use the LMB as the backend for the memory allocations and +it's associated book-keeping. + + +API documentation +----------------- + +.. kernel-doc:: include/lmb.h + diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst index fee7cca2628..f2ffcf3d331 100644 --- a/doc/develop/release_cycle.rst +++ b/doc/develop/release_cycle.rst @@ -1,4 +1,4 @@ -.. |next_ver| replace:: v2025.07 +.. |next_ver| replace:: v2025.10 Release Cycle ============= @@ -53,15 +53,15 @@ Examples:: Current Status -------------- -* U-Boot v2025.04 was released on Monday, 07 April 2025. +* U-Boot v2025.07 was released on Monday, 07 July 2025. -* The Merge Window for the next release (|next_ver|) was **closed** with the -rc1 - release on Monday, 28 April 2025. +* The Merge Window for the next release (|next_ver|) is **open** until the -rc1 + release on Monday, 28 July 2025. -* The next branch is now **closed** until the -rc2 release on Monday, 12 May +* The next branch is now **closed** until the -rc2 release on Monday, 11 August 2025. -* Release "|next_ver|" is scheduled for Monday, 07 July 2025. +* Release "|next_ver|" is scheduled for Monday, 06 October 2025. Future Releases --------------- @@ -69,28 +69,28 @@ Future Releases .. The following commented out dates are for when release candidates are planned to be tagged. -For the next scheduled release, release candidates were made on:: +.. For the next scheduled release, release candidates were made on:: -* U-Boot |next_ver|-rc1 was released on Mon 28 April 2025. +.. * U-Boot |next_ver|-rc1 was released on Mon 28 July 2025. -* U-Boot |next_ver|-rc2 was released on Mon 12 May 2025. +.. * U-Boot |next_ver|-rc2 was released on Mon 11 August 2025. -* U-Boot |next_ver|-rc3 was released on Mon 26 May 2025. +.. * U-Boot |next_ver|-rc3 was released on Mon 25 August 2025. -* U-Boot |next_ver|-rc4 was released on Mon 09 June 2025. +.. * U-Boot |next_ver|-rc4 was released on Mon 08 September 2025. -.. * U-Boot |next_ver|-rc5 was released on Mon 23 June 2025. +.. * U-Boot |next_ver|-rc5 was released on Mon 22 September 2025. Please note that the following dates are planned only and may be deviated from as needed. -* "v2025.07": end of MW = Mon, Apr 28, 2025; release = Mon, Jul 07, 2025 - * "v2025.10": end of MW = Mon, Jul 28, 2025; release = Mon, Oct 06, 2025 * "v2026.01": end of MW = Mon, Oct 27, 2025; release = Mon, Jan 05, 2026 -* "v2025.04": end of MW = Mon, Jan 26, 2026; release = Mon, Apr 06, 2026 +* "v2026.04": end of MW = Mon, Jan 26, 2026; release = Mon, Apr 06, 2026 + +* "v2026.07": end of MW = Mon, Apr 27, 2026; release = Mon, Jul 06, 2026 Previous Releases ----------------- @@ -99,6 +99,8 @@ Note: these statistics are generated by our fork of `gitdm <https://source.denx.de/u-boot/gitdm>`_, which was originally created by Jonathan Corbet. +* :doc:`statistics/u-boot-stats-v2025.07` which was released on 07 July 2025. + * :doc:`statistics/u-boot-stats-v2025.04` which was released on 07 April 2025. * :doc:`statistics/u-boot-stats-v2025.01` which was released on 06 January 2025. diff --git a/doc/develop/statistics/u-boot-stats-v2025.07.rst b/doc/develop/statistics/u-boot-stats-v2025.07.rst new file mode 100644 index 00000000000..32f7df393de --- /dev/null +++ b/doc/develop/statistics/u-boot-stats-v2025.07.rst @@ -0,0 +1,990 @@ +:orphan: + +Release Statistics for U-Boot v2025.07 +====================================== + +* Processed 1780 changesets from 225 developers + +* 24 employers found + +* A total of 200374 lines added, 64238 removed (delta 136136) + +.. table:: Developers with the most changesets + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Simon Glass 172 (9.7%) + Svyatoslav Ryhel 117 (6.6%) + Marek Vasut 110 (6.2%) + Tom Rini 91 (5.1%) + Heinrich Schuchardt 68 (3.8%) + Jerome Forissier 52 (2.9%) + Jonas Karlman 49 (2.8%) + Andre Przywara 44 (2.5%) + Casey Connolly 37 (2.1%) + Patrice Chotard 32 (1.8%) + Yao Zi 29 (1.6%) + Stephan Gerhold 26 (1.5%) + Quentin Schulz 25 (1.4%) + Christian Marangi 22 (1.2%) + Adam Ford 22 (1.2%) + Alif Zakuan Yuslaimi 22 (1.2%) + Paul Barker 19 (1.1%) + Wadim Egorov 17 (1.0%) + Adriano Cordova 17 (1.0%) + Dinesh Maniyam 17 (1.0%) + Ilias Apalodimas 15 (0.8%) + Sam Edwards 15 (0.8%) + Venkatesh Yadav Abbarapu 14 (0.8%) + Varadarajan Narayanan 14 (0.8%) + Dario Binacchi 14 (0.8%) + Sughosh Ganu 14 (0.8%) + Daniel Schultz 14 (0.8%) + Miquel Raynal 14 (0.8%) + Alice Guo 13 (0.7%) + Michal Simek 13 (0.7%) + Siddharth Vadapalli 13 (0.7%) + Jiaxun Yang 13 (0.7%) + Patrick Delaunay 12 (0.7%) + Patrick Rudolph 12 (0.7%) + Neil Armstrong 12 (0.7%) + Paul HENRYS 12 (0.7%) + Judith Mendez 11 (0.6%) + Heiko Stuebner 11 (0.6%) + Tien Fong Chee 11 (0.6%) + Sam Day 11 (0.6%) + Vincent Stehlé 10 (0.6%) + Nishanth Menon 10 (0.6%) + Anshul Dalal 9 (0.5%) + Bryan Brattlof 9 (0.5%) + Alexander Graf 9 (0.5%) + Alexander Dahl 9 (0.5%) + Weijie Gao 8 (0.4%) + Minda Chen 8 (0.4%) + Santhosh Kumar K 8 (0.4%) + Peng Fan 7 (0.4%) + Raymond Mao 7 (0.4%) + Neha Malcom Francis 7 (0.4%) + Mayuresh Chitale 7 (0.4%) + Aristo Chen 7 (0.4%) + Jernej Skrabec 7 (0.4%) + Samuel Holland 7 (0.4%) + Tingting Meng 7 (0.4%) + Greg Malysa 7 (0.4%) + Nathan Barrett-Morrison 7 (0.4%) + Fabio Estevam 6 (0.3%) + E Shattow 6 (0.3%) + Tony Dinh 6 (0.3%) + Lukasz Czechowski 6 (0.3%) + Naresh Kumar Ravulapalli 6 (0.3%) + Michael Trimarchi 6 (0.3%) + Primoz Fiser 6 (0.3%) + Udit Kumar 6 (0.3%) + Prasad Kummari 6 (0.3%) + Harrison Mutai 6 (0.3%) + Hector Martin 6 (0.3%) + Huan Zhou 6 (0.3%) + Leonard Anderweit 6 (0.3%) + Manorit Chawdhry 6 (0.3%) + Gabriel Dalimonte 6 (0.3%) + Maks Mishin 6 (0.3%) + Manikandan Muralidharan 6 (0.3%) + Mattijs Korpershoek 5 (0.3%) + Justin Klaassen 5 (0.3%) + Andrew Davis 5 (0.3%) + Padmarao Begari 5 (0.3%) + Jonathan Currier 5 (0.3%) + Ye Li 5 (0.3%) + Bernhard Messerklinger 5 (0.3%) + Hrushikesh Salunke 5 (0.3%) + Jorge Ramirez-Ortiz 5 (0.3%) + Anurag Dutta 5 (0.3%) + Jeremy Compostella 5 (0.3%) + Harsha Vardhan V M 5 (0.3%) + Anton Moryakov 5 (0.3%) + Baocheng Su 5 (0.3%) + Hari Nagalla 5 (0.3%) + Mikhail Kshevetskiy 4 (0.2%) + Alper Nebi Yasak 4 (0.2%) + Aniket Limaye 4 (0.2%) + Cheick Traore 4 (0.2%) + Heiko Schocher 3 (0.2%) + Sumit Garg 3 (0.2%) + Alexey Minnekhanov 3 (0.2%) + Rui Miguel Silva 3 (0.2%) + Rasmus Villemoes 3 (0.2%) + Martin Schiller 3 (0.2%) + Keerthy 3 (0.2%) + Mike Looijmans 3 (0.2%) + Lionel Debieve 3 (0.2%) + Zixun LI 3 (0.2%) + Vitor Soares 3 (0.2%) + Liya Huang 3 (0.2%) + Evgeny Bachinin 3 (0.2%) + Sinthu Raja 3 (0.2%) + Marius Dinu 2 (0.1%) + Shiji Yang 2 (0.1%) + Kory Maincent 2 (0.1%) + Yang Xiwen 2 (0.1%) + Peter Robinson 2 (0.1%) + Benjamin ROBIN 2 (0.1%) + Michael Bode 2 (0.1%) + Alexander Sverdlin 2 (0.1%) + Benjamin Schneider 2 (0.1%) + Christoph Fritz 2 (0.1%) + Vaishnav Achath 2 (0.1%) + Pascal Zimmermann 2 (0.1%) + Andrew Halaney 2 (0.1%) + Takahiro Kuwano 2 (0.1%) + Walter Schweizer 2 (0.1%) + Pawel Kochanowski 2 (0.1%) + Emanuele Ghidoli 2 (0.1%) + Stefano Babic 2 (0.1%) + Elaine Zhang 2 (0.1%) + Steven Liu 2 (0.1%) + Xuhui Lin 2 (0.1%) + Chukun Pan 2 (0.1%) + Muhammad Hazim Izzat Zamri 2 (0.1%) + Josua Mayer 2 (0.1%) + Jesse Taube 2 (0.1%) + Artur Kowalski 2 (0.1%) + Jonathan Humphreys 2 (0.1%) + 牛 志宏 2 (0.1%) + Daniel Golle 2 (0.1%) + Nathan Morrisson 2 (0.1%) + Jim Liu 2 (0.1%) + Ernest Van Hoecke 2 (0.1%) + Jonas Schwöbel 2 (0.1%) + David Lechner 1 (0.1%) + Fiona Klute 1 (0.1%) + Duje Mihanović 1 (0.1%) + Akashdeep Kaur 1 (0.1%) + Baruch Siach 1 (0.1%) + Sam Protsenko 1 (0.1%) + Ivan Pang 1 (0.1%) + Jan Čermák 1 (0.1%) + Hiago De Franco 1 (0.1%) + Hugo Villeneuve 1 (0.1%) + Tim Harvey 1 (0.1%) + BehradElmi 1 (0.1%) + Wojciech Szamocki 1 (0.1%) + Martin Kaistra 1 (0.1%) + Frantisek Bohacek 1 (0.1%) + Eddie Kovsky 1 (0.1%) + Jayanth Dodderi Chidanand 1 (0.1%) + Olaf Baehring 1 (0.1%) + Simon Holesch 1 (0.1%) + Thomas Schaefer 1 (0.1%) + Michael Walle 1 (0.1%) + No generic patch CC mail please 1 (0.1%) + Nikunj Kela 1 (0.1%) + Naresh Solanki 1 (0.1%) + Andy Shevchenko 1 (0.1%) + Jiehui He 1 (0.1%) + Ilya Katsnelson 1 (0.1%) + Prasanth Babu Mantena 1 (0.1%) + Chen-Yu Tsai 1 (0.1%) + Ben Wolsieffer 1 (0.1%) + ZhiJie.zhang 1 (0.1%) + Christophe Roullier 1 (0.1%) + Alexander Vickberg 1 (0.1%) + Carlos López 1 (0.1%) + Christoph Niedermaier 1 (0.1%) + Boon Khai Ng 1 (0.1%) + Bhavya Kapoor 1 (0.1%) + Love Kumar 1 (0.1%) + Nicolas Frattaroli 1 (0.1%) + Lin Jinhan 1 (0.1%) + Joseph Chen 1 (0.1%) + Yifeng Zhao 1 (0.1%) + Sean Edmond 1 (0.1%) + Mathieu Othacehe 1 (0.1%) + Jean-Jacques Hiblot 1 (0.1%) + Ezra Buehler 1 (0.1%) + Parth Pancholi 1 (0.1%) + Lucien.Jheng 1 (0.1%) + Mauro Salvini 1 (0.1%) + Bruno Leite 1 (0.1%) + Chris Packham 1 (0.1%) + yan wang 1 (0.1%) + Parvathi Pudi 1 (0.1%) + Martin Schwan 1 (0.1%) + Viorel Suman 1 (0.1%) + Rafael Beims 1 (0.1%) + Christian Kohlschütter 1 (0.1%) + Luke Wang 1 (0.1%) + Xu Zhang 1 (0.1%) + Andreas Dannenberg 1 (0.1%) + Andrew Goodbody 1 (0.1%) + Gary Bisson 1 (0.1%) + Oskar Nilsson 1 (0.1%) + Sukrut Bellary 1 (0.1%) + Richard Genoud 1 (0.1%) + Gowtham Tammana 1 (0.1%) + Vishal Mahaveer 1 (0.1%) + Masahisa Kojima 1 (0.1%) + Jimmy Ho 1 (0.1%) + Junhui Liu 1 (0.1%) + Baltazár Radics 1 (0.1%) + Arseniy Krasnov 1 (0.1%) + Robert Nelson 1 (0.1%) + Dragan Simic 1 (0.1%) + Vignesh Raghavendra 1 (0.1%) + Linus Walleij 1 (0.1%) + J. Neuschäfer 1 (0.1%) + Alexander Stein 1 (0.1%) + Stefan Eichenberger 1 (0.1%) + Michael Chang 1 (0.1%) + Hironori KIKUCHI 1 (0.1%) + Tomas Peterka 1 (0.1%) + Balamanikandan Gunasundar 1 (0.1%) + ==================================== ===== + + +.. table:: Developers with the most changed lines + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Tom Rini 78284 (33.7%) + Patrice Chotard 20809 (9.0%) + Manorit Chawdhry 17813 (7.7%) + Svyatoslav Ryhel 16864 (7.3%) + Simon Glass 8757 (3.8%) + Marek Vasut 8650 (3.7%) + Robert Nelson 5921 (2.6%) + Vitor Soares 4567 (2.0%) + Bernhard Messerklinger 3955 (1.7%) + Elaine Zhang 3663 (1.6%) + Yao Zi 3317 (1.4%) + Dinesh Maniyam 3269 (1.4%) + Jonas Karlman 3191 (1.4%) + Christian Marangi 3131 (1.3%) + Jerome Forissier 2676 (1.2%) + Joseph Chen 2480 (1.1%) + Nathan Barrett-Morrison 2115 (0.9%) + Tingting Meng 2075 (0.9%) + Peng Fan 1544 (0.7%) + Dario Binacchi 1387 (0.6%) + Varadarajan Narayanan 1338 (0.6%) + Miquel Raynal 1244 (0.5%) + Jesse Taube 1242 (0.5%) + Gabriel Dalimonte 1162 (0.5%) + Heiko Stuebner 1114 (0.5%) + Adriano Cordova 1013 (0.4%) + Tien Fong Chee 987 (0.4%) + Ye Li 982 (0.4%) + Heinrich Schuchardt 981 (0.4%) + Patrick Delaunay 944 (0.4%) + Andre Przywara 912 (0.4%) + Alice Guo 906 (0.4%) + Greg Malysa 875 (0.4%) + Paul HENRYS 823 (0.4%) + Lucien.Jheng 818 (0.4%) + Casey Connolly 780 (0.3%) + Neil Armstrong 745 (0.3%) + Manikandan Muralidharan 737 (0.3%) + Huan Zhou 722 (0.3%) + Paul Barker 686 (0.3%) + Minda Chen 667 (0.3%) + Fabio Estevam 598 (0.3%) + Nishanth Menon 574 (0.2%) + Steven Liu 556 (0.2%) + Alexander Graf 511 (0.2%) + Lionel Debieve 501 (0.2%) + Ilias Apalodimas 486 (0.2%) + Xuhui Lin 476 (0.2%) + Sughosh Ganu 473 (0.2%) + Andrew Davis 461 (0.2%) + Jiaxun Yang 449 (0.2%) + Neha Malcom Francis 437 (0.2%) + Jernej Skrabec 431 (0.2%) + Baocheng Su 424 (0.2%) + Wadim Egorov 421 (0.2%) + Alif Zakuan Yuslaimi 416 (0.2%) + Prasad Kummari 404 (0.2%) + Hari Nagalla 402 (0.2%) + Cheick Traore 391 (0.2%) + Simon Holesch 388 (0.2%) + Samuel Holland 337 (0.1%) + Hector Martin 334 (0.1%) + Harsha Vardhan V M 326 (0.1%) + Jonas Schwöbel 302 (0.1%) + Alexey Minnekhanov 290 (0.1%) + Primoz Fiser 266 (0.1%) + Alexander Dahl 256 (0.1%) + Siddharth Vadapalli 248 (0.1%) + Michael Trimarchi 217 (0.1%) + Alper Nebi Yasak 210 (0.1%) + Stephan Gerhold 204 (0.1%) + Chukun Pan 191 (0.1%) + Venkatesh Yadav Abbarapu 189 (0.1%) + Adam Ford 186 (0.1%) + Evgeny Bachinin 181 (0.1%) + Michael Bode 179 (0.1%) + Patrick Rudolph 175 (0.1%) + Judith Mendez 168 (0.1%) + Heiko Schocher 158 (0.1%) + Aniket Limaye 157 (0.1%) + Anshul Dalal 155 (0.1%) + Jonathan Humphreys 152 (0.1%) + Rui Miguel Silva 151 (0.1%) + Luke Wang 150 (0.1%) + Sam Day 127 (0.1%) + E Shattow 127 (0.1%) + Raymond Mao 121 (0.1%) + Quentin Schulz 116 (0.0%) + Ilya Katsnelson 116 (0.0%) + Harrison Mutai 108 (0.0%) + Hrushikesh Salunke 105 (0.0%) + Bryan Brattlof 104 (0.0%) + Michal Simek 103 (0.0%) + Jonathan Currier 103 (0.0%) + Mike Looijmans 99 (0.0%) + Jiehui He 96 (0.0%) + Tomas Peterka 78 (0.0%) + Justin Klaassen 77 (0.0%) + Jeremy Compostella 75 (0.0%) + Santhosh Kumar K 74 (0.0%) + Lin Jinhan 73 (0.0%) + Balamanikandan Gunasundar 73 (0.0%) + Andreas Dannenberg 65 (0.0%) + Ernest Van Hoecke 64 (0.0%) + Sam Edwards 62 (0.0%) + Christoph Fritz 61 (0.0%) + Weijie Gao 60 (0.0%) + Keerthy 59 (0.0%) + Vishal Mahaveer 59 (0.0%) + Mayuresh Chitale 57 (0.0%) + Leonard Anderweit 57 (0.0%) + Kory Maincent 55 (0.0%) + Jim Liu 54 (0.0%) + Walter Schweizer 53 (0.0%) + Masahisa Kojima 52 (0.0%) + Udit Kumar 50 (0.0%) + Mikhail Kshevetskiy 48 (0.0%) + Pascal Zimmermann 42 (0.0%) + Muhammad Hazim Izzat Zamri 42 (0.0%) + Nathan Morrisson 41 (0.0%) + Daniel Schultz 40 (0.0%) + Sumit Garg 39 (0.0%) + Dragan Simic 37 (0.0%) + Boon Khai Ng 35 (0.0%) + Jorge Ramirez-Ortiz 32 (0.0%) + Chen-Yu Tsai 32 (0.0%) + Tony Dinh 31 (0.0%) + Naresh Kumar Ravulapalli 31 (0.0%) + Anton Moryakov 31 (0.0%) + Rasmus Villemoes 30 (0.0%) + Vaishnav Achath 30 (0.0%) + Artur Kowalski 30 (0.0%) + Love Kumar 29 (0.0%) + Sinthu Raja 28 (0.0%) + Jean-Jacques Hiblot 28 (0.0%) + Lukasz Czechowski 26 (0.0%) + Nikunj Kela 23 (0.0%) + Sean Edmond 23 (0.0%) + Daniel Golle 22 (0.0%) + Mattijs Korpershoek 21 (0.0%) + Zixun LI 19 (0.0%) + Wojciech Szamocki 19 (0.0%) + Anurag Dutta 18 (0.0%) + Padmarao Begari 17 (0.0%) + Bhavya Kapoor 17 (0.0%) + Aristo Chen 16 (0.0%) + Christophe Roullier 16 (0.0%) + Hironori KIKUCHI 16 (0.0%) + Jayanth Dodderi Chidanand 15 (0.0%) + Olaf Baehring 15 (0.0%) + Vincent Stehlé 14 (0.0%) + Maks Mishin 13 (0.0%) + Andy Shevchenko 13 (0.0%) + Viorel Suman 13 (0.0%) + Michael Chang 13 (0.0%) + Andrew Halaney 12 (0.0%) + Prasanth Babu Mantena 12 (0.0%) + Rafael Beims 12 (0.0%) + Baltazár Radics 12 (0.0%) + Benjamin ROBIN 11 (0.0%) + Mathieu Othacehe 11 (0.0%) + Junhui Liu 11 (0.0%) + Stefan Eichenberger 11 (0.0%) + Alexander Sverdlin 10 (0.0%) + Sam Protsenko 10 (0.0%) + Pawel Kochanowski 9 (0.0%) + Josua Mayer 9 (0.0%) + Fiona Klute 9 (0.0%) + Martin Kaistra 8 (0.0%) + Michael Walle 8 (0.0%) + Nicolas Frattaroli 8 (0.0%) + Liya Huang 7 (0.0%) + Peter Robinson 7 (0.0%) + No generic patch CC mail please 7 (0.0%) + ZhiJie.zhang 7 (0.0%) + Gowtham Tammana 7 (0.0%) + Shiji Yang 6 (0.0%) + Parvathi Pudi 5 (0.0%) + Emanuele Ghidoli 4 (0.0%) + Stefano Babic 4 (0.0%) + David Lechner 4 (0.0%) + Frantisek Bohacek 4 (0.0%) + Martin Schwan 4 (0.0%) + Andrew Goodbody 4 (0.0%) + Gary Bisson 4 (0.0%) + J. Neuschäfer 4 (0.0%) + Martin Schiller 3 (0.0%) + Yang Xiwen 3 (0.0%) + Benjamin Schneider 3 (0.0%) + 牛 志宏 3 (0.0%) + Duje Mihanović 3 (0.0%) + Thomas Schaefer 3 (0.0%) + Parth Pancholi 3 (0.0%) + Mauro Salvini 3 (0.0%) + Bruno Leite 3 (0.0%) + Christian Kohlschütter 3 (0.0%) + Xu Zhang 3 (0.0%) + Arseniy Krasnov 3 (0.0%) + Alexander Stein 3 (0.0%) + Marius Dinu 2 (0.0%) + Takahiro Kuwano 2 (0.0%) + Ivan Pang 2 (0.0%) + Hiago De Franco 2 (0.0%) + Eddie Kovsky 2 (0.0%) + Chris Packham 2 (0.0%) + Sukrut Bellary 2 (0.0%) + Jimmy Ho 2 (0.0%) + Akashdeep Kaur 1 (0.0%) + Baruch Siach 1 (0.0%) + Jan Čermák 1 (0.0%) + Hugo Villeneuve 1 (0.0%) + Tim Harvey 1 (0.0%) + BehradElmi 1 (0.0%) + Naresh Solanki 1 (0.0%) + Ben Wolsieffer 1 (0.0%) + Alexander Vickberg 1 (0.0%) + Carlos López 1 (0.0%) + Christoph Niedermaier 1 (0.0%) + Yifeng Zhao 1 (0.0%) + Ezra Buehler 1 (0.0%) + yan wang 1 (0.0%) + Oskar Nilsson 1 (0.0%) + Richard Genoud 1 (0.0%) + Vignesh Raghavendra 1 (0.0%) + Linus Walleij 1 (0.0%) + ==================================== ===== + + +.. table:: Developers with the most lines removed + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Patrice Chotard 19307 (30.1%) + Jesse Taube 1211 (1.9%) + Fabio Estevam 561 (0.9%) + Primoz Fiser 241 (0.4%) + Prasad Kummari 191 (0.3%) + Andrew Davis 129 (0.2%) + Samuel Holland 129 (0.2%) + Jiaxun Yang 74 (0.1%) + Quentin Schulz 67 (0.1%) + E Shattow 51 (0.1%) + Judith Mendez 45 (0.1%) + Jonathan Humphreys 44 (0.1%) + Hrushikesh Salunke 37 (0.1%) + Dragan Simic 37 (0.1%) + Lionel Debieve 31 (0.0%) + Tomas Peterka 29 (0.0%) + Chen-Yu Tsai 26 (0.0%) + Stephan Gerhold 15 (0.0%) + Tony Dinh 11 (0.0%) + Baltazár Radics 9 (0.0%) + Heiko Schocher 4 (0.0%) + Mauro Salvini 3 (0.0%) + Jorge Ramirez-Ortiz 2 (0.0%) + No generic patch CC mail please 2 (0.0%) + Arseniy Krasnov 2 (0.0%) + Jimmy Ho 2 (0.0%) + Olaf Baehring 1 (0.0%) + Benjamin ROBIN 1 (0.0%) + Pawel Kochanowski 1 (0.0%) + Liya Huang 1 (0.0%) + Parvathi Pudi 1 (0.0%) + Stefano Babic 1 (0.0%) + Alexander Stein 1 (0.0%) + Hugo Villeneuve 1 (0.0%) + ==================================== ===== + + +.. table:: Developers with the most signoffs (total 449) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Caleb Connolly 87 (19.4%) + Michal Simek 34 (7.6%) + Heiko Stuebner 19 (4.2%) + Jonas Karlman 15 (3.3%) + Patrice Chotard 14 (3.1%) + Mattijs Korpershoek 12 (2.7%) + Vasileios Bimpikas 12 (2.7%) + Utsav Agarwal 12 (2.7%) + Arturs Artamonovs 12 (2.7%) + Casey Connolly 12 (2.7%) + Ian Roberts 11 (2.4%) + Oliver Gaskell 11 (2.4%) + Alice Guo 11 (2.4%) + Peng Fan 11 (2.4%) + Tien Fong Chee 10 (2.2%) + Andre Przywara 7 (1.6%) + Alper Nebi Yasak 7 (1.6%) + Ilias Apalodimas 7 (1.6%) + Greg Malysa 7 (1.6%) + Patrick Delaunay 7 (1.6%) + Mark Kettenis 6 (1.3%) + Dario Binacchi 6 (1.3%) + Judith Mendez 5 (1.1%) + Michael Trimarchi 5 (1.1%) + Wadim Egorov 5 (1.1%) + Neil Armstrong 5 (1.1%) + Nathan Barrett-Morrison 4 (0.9%) + Svyatoslav Ryhel 4 (0.9%) + Gatien Chevallier 3 (0.7%) + Li Hua Qian 3 (0.7%) + Jan Kiszka 3 (0.7%) + Anurag Dutta 3 (0.7%) + Sughosh Ganu 3 (0.7%) + Neha Malcom Francis 3 (0.7%) + Simon Glass 3 (0.7%) + Tom Rini 3 (0.7%) + Fabio Estevam 2 (0.4%) + Primoz Fiser 2 (0.4%) + Heiko Schocher 2 (0.4%) + Ranjani Vaidyanathan 2 (0.4%) + Mahesh Rao 2 (0.4%) + Stephen Boyd 2 (0.4%) + Angelo Dureghello 2 (0.4%) + Piotr Wojtaszczyk 2 (0.4%) + Andrew Halaney 2 (0.4%) + Heinrich Schuchardt 2 (0.4%) + Ye Li 2 (0.4%) + Andrew Davis 1 (0.2%) + Lionel Debieve 1 (0.2%) + Arseniy Krasnov 1 (0.2%) + Heiko Thiery 1 (0.2%) + Wolfgang Birkner 1 (0.2%) + Haibo Chen 1 (0.2%) + Frank Li 1 (0.2%) + Mark Brown 1 (0.2%) + Ashok Reddy Soma 1 (0.2%) + ZHANG Yuntian 1 (0.2%) + Pan Bian 1 (0.2%) + Richard Weinberger 1 (0.2%) + Ji Luo 1 (0.2%) + Jindong Yue 1 (0.2%) + Francesco Dolcini 1 (0.2%) + Thomas Bourgoin 1 (0.2%) + Raphael Gallais-Pou 1 (0.2%) + Finley Xiao 1 (0.2%) + Basharath Hussain Khaja 1 (0.2%) + Gabriel Nesteruk 1 (0.2%) + AngeloGioacchino Del Regno 1 (0.2%) + Sparsh Kumar 1 (0.2%) + Sebin Francis 1 (0.2%) + Sam Shih 1 (0.2%) + Peter Geis 1 (0.2%) + Viacheslav Bocharov 1 (0.2%) + Beleswar Padhi 1 (0.2%) + Ryan Eatmon 1 (0.2%) + Charan Pedumuru 1 (0.2%) + Walter Schweizer 1 (0.2%) + Prasanth Babu Mantena 1 (0.2%) + Viorel Suman 1 (0.2%) + Nathan Morrisson 1 (0.2%) + Boon Khai Ng 1 (0.2%) + Udit Kumar 1 (0.2%) + Muhammad Hazim Izzat Zamri 1 (0.2%) + Keerthy 1 (0.2%) + Manikandan Muralidharan 1 (0.2%) + Aniket Limaye 1 (0.2%) + Patrick Rudolph 1 (0.2%) + Jonas Schwöbel 1 (0.2%) + Nishanth Menon 1 (0.2%) + Tingting Meng 1 (0.2%) + Marek Vasut 1 (0.2%) + Manorit Chawdhry 1 (0.2%) + ==================================== ===== + + +.. table:: Developers with the most reviews (total 1002) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Kever Yang 116 (11.6%) + Simon Glass 64 (6.4%) + Ilias Apalodimas 53 (5.3%) + Neil Armstrong 52 (5.2%) + Tom Rini 52 (5.2%) + Leo Yu-Chi Liang 45 (4.5%) + Mattijs Korpershoek 40 (4.0%) + Paul Barker 37 (3.7%) + Marek Vasut 33 (3.3%) + Quentin Schulz 32 (3.2%) + Heinrich Schuchardt 30 (3.0%) + Caleb Connolly 27 (2.7%) + Peng Fan 27 (2.7%) + Tien Fong Chee 26 (2.6%) + Sumit Garg 25 (2.5%) + Patrice Chotard 20 (2.0%) + Patrick Delaunay 20 (2.0%) + E Shattow 19 (1.9%) + Stefan Roese 18 (1.8%) + Bryan Brattlof 17 (1.7%) + Jonas Karlman 16 (1.6%) + Heiko Schocher 16 (1.6%) + Andrew Davis 16 (1.6%) + Matthias Brugger 14 (1.4%) + Jerome Forissier 13 (1.3%) + Daniel Schwierzeck 12 (1.2%) + Jernej Skrabec 12 (1.2%) + Fabio Estevam 9 (0.9%) + Udit Kumar 9 (0.9%) + Andre Przywara 8 (0.8%) + Neha Malcom Francis 8 (0.8%) + Hal Feng 8 (0.8%) + Christopher Obbard 8 (0.8%) + Casey Connolly 7 (0.7%) + Wadim Egorov 6 (0.6%) + Ye Li 6 (0.6%) + Eugen Hristev 6 (0.6%) + Michael Trimarchi 5 (0.5%) + Francesco Dolcini 4 (0.4%) + Roger Quadros 4 (0.4%) + Peter Robinson 4 (0.4%) + Svyatoslav Ryhel 3 (0.3%) + Dhruva Gole 3 (0.3%) + Jaehoon Chung 3 (0.3%) + Tobias Waldekranz 3 (0.3%) + Fabrice Gasnier 3 (0.3%) + Daniel Schultz 3 (0.3%) + Siddharth Vadapalli 3 (0.3%) + Alice Guo 2 (0.2%) + Nishanth Menon 2 (0.2%) + Tudor Ambarus 2 (0.2%) + Joao Marcos Costa 2 (0.2%) + Richard Henderson 2 (0.2%) + Judith Mendez 1 (0.1%) + Sughosh Ganu 1 (0.1%) + Frank Li 1 (0.1%) + AngeloGioacchino Del Regno 1 (0.1%) + Linus Walleij 1 (0.1%) + Ramon Fried 1 (0.1%) + Lukasz Majewski 1 (0.1%) + Maxim Moskalets 1 (0.1%) + Vladimir Oltean 1 (0.1%) + Paul Kocialkowski 1 (0.1%) + Anand Moon 1 (0.1%) + Boris Brezillon 1 (0.1%) + Krzysztof Kozlowski 1 (0.1%) + Sean Anderson 1 (0.1%) + Icenowy Zheng 1 (0.1%) + Yixun Lan 1 (0.1%) + Teresa Remmet 1 (0.1%) + Anshul Dalal 1 (0.1%) + Michael Walle 1 (0.1%) + Alexander Sverdlin 1 (0.1%) + Andy Shevchenko 1 (0.1%) + Love Kumar 1 (0.1%) + Leonard Anderweit 1 (0.1%) + Harrison Mutai 1 (0.1%) + Adam Ford 1 (0.1%) + Christian Marangi 1 (0.1%) + Yao Zi 1 (0.1%) + ==================================== ===== + + +.. table:: Developers with the most test credits (total 89) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + E Shattow 7 (7.9%) + Love Kumar 7 (7.9%) + Ion Agorria 7 (7.9%) + Christopher Obbard 6 (6.7%) + Danila Tikhonov 6 (6.7%) + Jens Reidel 6 (6.7%) + Sumit Garg 4 (4.5%) + Zixun LI 4 (4.5%) + Simon Glass 3 (3.4%) + Neil Armstrong 3 (3.4%) + Sughosh Ganu 3 (3.4%) + Mattijs Korpershoek 2 (2.2%) + Quentin Schulz 2 (2.2%) + Heinrich Schuchardt 2 (2.2%) + Patrice Chotard 2 (2.2%) + Fabio Estevam 2 (2.2%) + Daniel Schultz 2 (2.2%) + Dang Huynh 2 (2.2%) + Peter Robinson 1 (1.1%) + Vladimir Oltean 1 (1.1%) + Adam Ford 1 (1.1%) + Yao Zi 1 (1.1%) + Michal Simek 1 (1.1%) + Prasanth Babu Mantena 1 (1.1%) + Jonathan Humphreys 1 (1.1%) + Tony Dinh 1 (1.1%) + Niklas Sombert 1 (1.1%) + Weizhao Ouyang 1 (1.1%) + Marcel Ziswiler 1 (1.1%) + Faqiang Zhu 1 (1.1%) + Ryan Walklin 1 (1.1%) + Tim Harvey 1 (1.1%) + Nicolas Frattaroli 1 (1.1%) + Raymond Mao 1 (1.1%) + Sam Day 1 (1.1%) + Alexey Minnekhanov 1 (1.1%) + Huan Zhou 1 (1.1%) + ==================================== ===== + + +.. table:: Developers who gave the most tested-by credits (total 89) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Casey Connolly 19 (21.3%) + Svyatoslav Ryhel 8 (9.0%) + Simon Glass 7 (7.9%) + Neil Armstrong 6 (6.7%) + Ilias Apalodimas 6 (6.7%) + Minda Chen 5 (5.6%) + Mattijs Korpershoek 4 (4.5%) + Heinrich Schuchardt 4 (4.5%) + Jerome Forissier 4 (4.5%) + Marek Vasut 3 (3.4%) + Quentin Schulz 2 (2.2%) + Thomas Schaefer 2 (2.2%) + Michal Simek 1 (1.1%) + Raymond Mao 1 (1.1%) + Tom Rini 1 (1.1%) + Paul Barker 1 (1.1%) + Peng Fan 1 (1.1%) + Patrick Delaunay 1 (1.1%) + Jonas Karlman 1 (1.1%) + Jernej Skrabec 1 (1.1%) + Wadim Egorov 1 (1.1%) + Michael Trimarchi 1 (1.1%) + Heiko Stuebner 1 (1.1%) + Jiaxun Yang 1 (1.1%) + Junhui Liu 1 (1.1%) + Eddie Kovsky 1 (1.1%) + Bruno Leite 1 (1.1%) + Weijie Gao 1 (1.1%) + Venkatesh Yadav Abbarapu 1 (1.1%) + Hari Nagalla 1 (1.1%) + Adriano Cordova 1 (1.1%) + ==================================== ===== + + +.. table:: Developers with the most report credits (total 41) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Da Xue 6 (14.6%) + Heinrich Schuchardt 4 (9.8%) + Tom Rini 4 (9.8%) + Zixun LI 3 (7.3%) + Francesco Dolcini 2 (4.9%) + Nathaniel Hourt 2 (4.9%) + Kuba Szczodrzyński 2 (4.9%) + Quentin Schulz 1 (2.4%) + Jernej Skrabec 1 (2.4%) + Yao Zi 1 (2.4%) + Tony Dinh 1 (2.4%) + Niklas Sombert 1 (2.4%) + Weizhao Ouyang 1 (2.4%) + Tim Harvey 1 (2.4%) + Sam Day 1 (2.4%) + Anshul Dalal 1 (2.4%) + Heiko Thiery 1 (2.4%) + Keerthy 1 (2.4%) + Enric Balletbo i Serra 1 (2.4%) + Chirag Shilwant 1 (2.4%) + Prashant Shivhare 1 (2.4%) + Chintan Vankar 1 (2.4%) + Parth Pancholi 1 (2.4%) + Christoph Niedermaier 1 (2.4%) + Mikhail Kshevetskiy 1 (2.4%) + ==================================== ===== + + +.. table:: Developers who gave the most report credits (total 41) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Alexander Graf 7 (17.1%) + Tom Rini 4 (9.8%) + Jerome Forissier 4 (9.8%) + Simon Glass 3 (7.3%) + Mattijs Korpershoek 3 (7.3%) + Andre Przywara 3 (7.3%) + Yao Zi 2 (4.9%) + Andrew Davis 2 (4.9%) + Heinrich Schuchardt 1 (2.4%) + Anshul Dalal 1 (2.4%) + Casey Connolly 1 (2.4%) + Ilias Apalodimas 1 (2.4%) + Marek Vasut 1 (2.4%) + Weijie Gao 1 (2.4%) + Adriano Cordova 1 (2.4%) + Fabio Estevam 1 (2.4%) + Adam Ford 1 (2.4%) + Bryan Brattlof 1 (2.4%) + Alice Guo 1 (2.4%) + Alexander Sverdlin 1 (2.4%) + Bhavya Kapoor 1 (2.4%) + ==================================== ===== + + +.. table:: Top changeset contributors by employer + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + (Unknown) 747 (42.0%) + Google LLC 172 (9.7%) + Linaro 169 (9.5%) + Texas Instruments 126 (7.1%) + Konsulko Group 91 (5.1%) + DENX Software Engineering 68 (3.8%) + Renesas Electronics 68 (3.8%) + ARM 61 (3.4%) + ST Microelectronics 52 (2.9%) + Intel 50 (2.8%) + AMD 39 (2.2%) + Phytec 38 (2.1%) + NXP 27 (1.5%) + Amarula Solutions 20 (1.1%) + Bootlin 17 (1.0%) + Toradex 10 (0.6%) + Rockchip 9 (0.5%) + Siemens 8 (0.4%) + Red Hat 3 (0.2%) + BayLibre SAS 1 (0.1%) + Collabora Ltd. 1 (0.1%) + linutronix 1 (0.1%) + Nokia 1 (0.1%) + Socionext Inc. 1 (0.1%) + ==================================== ===== + + +.. table:: Top lines changed by employer + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + Konsulko Group 78284 (33.7%) + (Unknown) 59242 (25.5%) + ST Microelectronics 22661 (9.8%) + Texas Instruments 21551 (9.3%) + Google LLC 8757 (3.8%) + Rockchip 7249 (3.1%) + DENX Software Engineering 7195 (3.1%) + Linaro 5651 (2.4%) + Toradex 4661 (2.0%) + Intel 4500 (1.9%) + NXP 3595 (1.5%) + Renesas Electronics 2880 (1.2%) + Amarula Solutions 1604 (0.7%) + Bootlin 1300 (0.6%) + ARM 1049 (0.5%) + AMD 742 (0.3%) + Phytec 522 (0.2%) + Siemens 483 (0.2%) + Socionext Inc. 52 (0.0%) + Nokia 19 (0.0%) + Red Hat 14 (0.0%) + Collabora Ltd. 8 (0.0%) + linutronix 8 (0.0%) + BayLibre SAS 2 (0.0%) + ==================================== ===== + + +.. table:: Employers with the most signoffs (total 449) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + (Unknown) 125 (27.8%) + Linaro 114 (25.4%) + Analog Devices 47 (10.5%) + AMD 34 (7.6%) + NXP 31 (6.9%) + ST Microelectronics 27 (6.0%) + Texas Instruments 22 (4.9%) + Amarula Solutions 11 (2.4%) + ARM 7 (1.6%) + Siemens 7 (1.6%) + Phytec 5 (1.1%) + Konsulko Group 3 (0.7%) + Google LLC 3 (0.7%) + DENX Software Engineering 2 (0.4%) + Red Hat 2 (0.4%) + BayLibre SAS 2 (0.4%) + Canonical 2 (0.4%) + Rockchip 1 (0.2%) + Toradex 1 (0.2%) + Renesas Electronics 1 (0.2%) + Collabora Ltd. 1 (0.2%) + Xilinx 1 (0.2%) + ==================================== ===== + + +.. table:: Employers with the most hackers (total 230) + :widths: auto + + ==================================== ===== + Name Count + ==================================== ===== + (Unknown) 129 (56.1%) + Texas Instruments 27 (11.7%) + Linaro 11 (4.8%) + Toradex 7 (3.0%) + Rockchip 6 (2.6%) + AMD 5 (2.2%) + NXP 5 (2.2%) + ST Microelectronics 5 (2.2%) + Intel 5 (2.2%) + ARM 4 (1.7%) + Phytec 4 (1.7%) + Siemens 3 (1.3%) + DENX Software Engineering 3 (1.3%) + Bootlin 3 (1.3%) + Amarula Solutions 2 (0.9%) + Red Hat 2 (0.9%) + Renesas Electronics 2 (0.9%) + Konsulko Group 1 (0.4%) + Google LLC 1 (0.4%) + BayLibre SAS 1 (0.4%) + Collabora Ltd. 1 (0.4%) + Socionext Inc. 1 (0.4%) + Nokia 1 (0.4%) + linutronix 1 (0.4%) + ==================================== ===== diff --git a/doc/usage/cmd/gpt.rst b/doc/usage/cmd/gpt.rst index 8534f78cbac..13e8783be9b 100644 --- a/doc/usage/cmd/gpt.rst +++ b/doc/usage/cmd/gpt.rst @@ -54,7 +54,7 @@ partition string * name=<NAME> - The partition name, required * start=<BYTES> - The partition start offset in bytes, required - * size=<BYTES> - The partition size in bytes or "-" to expand it to the whole free area + * size=<BYTES> - The partition size in bytes or "-" for the last partition to expand it to the whole free area * bootable - Set the legacy bootable flag * uuid=<UUID> - The partition UUID, optional if CONFIG_RANDOM_UUID=y is enabled * type=<UUID> - The partition type GUID, requires CONFIG_PARTITION_TYPE_GUID=y @@ -63,6 +63,23 @@ partition string If 'uuid' is not specified, but CONFIG_RANDOM_UUID is enabled, a random UUID will be generated for the partition + If 'type' is not specified or without CONFIG_PARTITION_TYPE_GUID=y, + the used partition type GUID is PARTITION_BASIC_DATA_GUID. + + Some strings can be also used at the place of the known partition type GUID: + * "mbr" = LEGACY_MBR_PARTITION_GUID (024DEE41-33E7-11D3-9D69-0008C781F39F) + * "msft" = PARTITION_MSFT_RESERVED_GUID (E3C9E316-0B5C-4DB8-817D-F92DF00215AE) + * "data" = PARTITION_BASIC_DATA_GUID (EBD0A0A2-B9E5-4433-87C0-68B6B72699C7) + * "linux" = PARTITION_LINUX_FILE_SYSTEM_DATA_GUID (0FC63DAF-8483-4772-8E79-3D69D8477DE4) + * "raid" = PARTITION_LINUX_RAID_GUID (A19D880F-05FC-4D3B-A006-743F0F84911E) + * "swap" = PARTITION_LINUX_SWAP_GUID (0657FD6D-A4AB-43C4-84E5-0933C84B4F4F) + * "lvm" = PARTITION_LINUX_LVM_GUID (E6D6D379-F507-44C2-A23C-238F2A3DF928) + * "u-boot-env" = PARTITION_U_BOOT_ENVIRONMENT(3DE21764-95BD-54BD-A5C3-4ABE786F38A8) + * "system" = PARTITION_SYSTEM_GUID (C12A7328-F81F-11D2-BA4B-00A0C93EC93B) + + The GPT partitions layout and associated 'type' are also printed with the + :doc:`part command <part>` command by typing "part list". + gpt enumerate ~~~~~~~~~~~~~ @@ -162,16 +179,17 @@ Examples Create 6 partitions on a disk:: - => setenv gpt_parts 'uuid_disk=bec9fc2a-86c1-483d-8a0e-0109732277d7; - name=boot,start=4M,size=128M,bootable,type=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7, - name=rootfs,size=3072M,type=0fc63daf-8483-4772-8e79-3d69d8477de4; - name=system-data,size=512M,type=0fc63daf-8483-4772-8e79-3d69d8477de4; - name=[ext],size=-,type=0fc63daf-8483-4772-8e79-3d69d8477de4; - name=user,size=-,type=0fc63daf-8483-4772-8e79-3d69d8477de4; - name=modules,size=100M,type=0fc63daf-8483-4772-8e79-3d69d8477de4; - name=ramdisk,size=8M,type=0fc63daf-8483-4772-8e79-3d69d8477de4 + => setenv gpt_parts 'uuid_disk=bec9fc2a-86c1-483d-8a0e-0109732277d7;\ + name=boot,start=4M,size=128M,bootable,type=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7;\ + name=rootfs,size=3072M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\ + name=system-data,size=512M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\ + name=user,size=512M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\ + name=modules,size=100M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\ + name=ramdisk,size=8M,type=0fc63daf-8483-4772-8e79-3d69d8477de4;\ + name=[ext],size=-,type=0fc63daf-8483-4772-8e79-3d69d8477de4' => gpt write mmc 0 $gpt_parts +Last partition "[ext]" with '-' is extended up to the end of the disk Verify that the device matches the partition layout described in the variable $gpt_parts:: @@ -228,3 +246,60 @@ Swap the order of the 'boot' and 'rootfs' partition table entries:: => gpt setenv mmc 0 boot => echo ${gpt_partition_entry} 2 + +Other example: a disk with known partition types:: + + => setenv gpt_parts 'name=u-boot,size=32M,type=data;\ + name=env,size=1M,type=u-boot-env; + name=ESP,size=128M,type=system; + name=rootfs,size=3072M,type=linux; + name=swap,size=100M,type=swap; + name=user,size=-,type=linux' + => gpt write mmc 0 $gpt_parts + + => part list mmc 0 + Partition Map for mmc device 0 -- Partition Type: EFI + Part Start LBA End LBA Name + Attributes + Type GUID + Partition GUID + 1 0x00000022 0x00010021 "u-boot" + attrs: 0x0000000000000000 + type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7 + (data) + guid: 502d48f6-81c0-488f-bdc0-ad602498f3ce + 2 0x00010022 0x00010821 "env" + attrs: 0x0000000000000000 + type: 3de21764-95bd-54bd-a5c3-4abe786f38a8 + (u-boot-env) + guid: 9dc62338-459a-485e-bd8f-b3fbf728d9c0 + 3 0x00010822 0x00050821 "ESP" + attrs: 0x0000000000000000 + type: c12a7328-f81f-11d2-ba4b-00a0c93ec93b + (EFI System Partition) + guid: 8a3a1168-6af8-4ba7-a95d-9cd0d14e1b3d + 4 0x00050822 0x00650821 "rootfs" + attrs: 0x0000000000000000 + type: 0fc63daf-8483-4772-8e79-3d69d8477de4 + (linux) + guid: 411ffebc-8a19-469d-99a9-0982409a6851 + 5 0x00650822 0x00682821 "swap" + attrs: 0x0000000000000000 + type: 0657fd6d-a4ab-43c4-84e5-0933c84b4f4f + (swap) + guid: f8ec0410-95ec-4e3e-8b98-fb8cf271a201 + 6 0x00682822 0x01dacbde "user" + attrs: 0x0000000000000000 + type: 0fc63daf-8483-4772-8e79-3d69d8477de4 + (linux) + guid: c5543e1c-566d-4502-99ad-20545007e673 + +Modifying GPT partition layout from U-Boot:: + + => gpt read mmc 0 current_partitions + => env edit current_partitions + edit: uuid_disk=[...];name=part1,start=0x4000,size=0x4000,uuid=[...]; + name=part2,start=0xc000,size=0xc000,uuid=[...];[ . . . ] + + => gpt write mmc 0 $current_partitions + => gpt verify mmc 0 $current_partitions diff --git a/doc/usage/cmd/sntp.rst b/doc/usage/cmd/sntp.rst new file mode 100644 index 00000000000..d97f83053f7 --- /dev/null +++ b/doc/usage/cmd/sntp.rst @@ -0,0 +1,72 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +.. index:: + single: sntp (command) + +sntp command +============ + +Synopsis +-------- + +:: + + sntp [serverip] + sntp [servername] # NET_LWIP=y && CMD_DNS=y only + + +Description +----------- + +The sntp command gets the current time from an NTP time server and +syncronizes the Real Time Clock (RTC) of the board. This command needs +the server's IP address to be given on the command line or via the +`ntpserverip` environment variable. + +The address of the NTP server does not need to be given if the DHCP server +provides one. The legacy network stack (`CONFIG_NET=y`) can only use the +first NTP server provided in the `ntp-servers` DHCP option. + +When the network stack is lwIP (`CONFIG_NET_LWIP=y`) and the dns command +is enabled (`CONFIG_CMD_DNS=y`), then the sntp command accepts a server +name as an argument. + +The network time is sent as UTC. So, if you want to set the RTC to any local +time different from UTC, you need to set the `timeoffset` environment variable. + +Round-trip delay compensation is not implemented/not enabled. In practice +this should not matter much given that the RTC API does not have sub-second +resolution, and round-trip times are typically 10 to 100 ms at most. + +Examples +-------- + +:: + + => setenv ntpserverip 109.190.177.205 + => date + Date: 2025-06-16 (Monday) Time: 15:19:35 + => date reset + Reset RTC... + Date: 2000-01-01 (Saturday) Time: 0:00:00 + => date + Date: 2000-01-01 (Saturday) Time: 0:00:03 + => sntp + Date: 2025-06-16 Time: 15:19:43 + => date + Date: 2025-06-16 (Monday) Time: 15:19:47 + => setenv timeoffset 7200 + => sntp + Date: 2025-06-16 Time: 17:19:55 + => date + Date: 2025-06-16 (Monday) Time: 17:19:57 + +With `CONFIG_NET_LWIP=y` and `CONFIG_CMD_DNS=y`: + +:: + + => date reset + Reset RTC... + Date: 2000-01-01 (Saturday) Time: 0:00:00 + => sntp 0.us.pool.ntp.org + Date: 2025-06-16 Time: 15:10:59 diff --git a/doc/usage/cmd/wget.rst b/doc/usage/cmd/wget.rst index 44033aaff39..06df2842549 100644 --- a/doc/usage/cmd/wget.rst +++ b/doc/usage/cmd/wget.rst @@ -185,13 +185,6 @@ TCP Selective Acknowledgments in the legacy network stack can be enabled via CONFIG_PROT_TCP_SACK=y. This will improve the download speed. Selective Acknowledgments are enabled by default with lwIP. -.. note:: - - U-Boot currently has no way to verify certificates for HTTPS. - A place to store the root CA certificates is needed, and then MBed TLS would - need to walk the entire chain. Therefore, man-in-the middle attacks are - possible and HTTPS should not be relied upon for payload authentication. - Return value ------------ diff --git a/doc/usage/index.rst b/doc/usage/index.rst index c5b45fd9290..e9e0bd04e05 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -119,6 +119,7 @@ Shell commands cmd/sleep cmd/sm cmd/smbios + cmd/sntp cmd/sound cmd/source cmd/tcpm diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index 4f358657444..f5bcd406a50 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -24,6 +24,7 @@ config L2X0_CACHE config ANDES_L2_CACHE bool "Andes L2 cache driver" + depends on RISCV select CACHE help Support Andes L2 cache controller in AE350 platform. diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index ef1e5355be8..e6483ddc88b 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -225,7 +225,7 @@ config CLK_VERSACLOCK config CLK_VERSAL bool "Enable clock driver support for Versal" depends on (ARCH_VERSAL || ARCH_VERSAL_NET) - imply ZYNQMP_FIRMWARE + depends on ZYNQMP_FIRMWARE help This clock driver adds support for clock realted settings for Versal platform. diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index a8239e228cf..4f67c958d0f 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -108,6 +108,8 @@ static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020; #define PLLCTRL_POST_SRC_MASK (0x7 << PLLCTRL_POST_SRC_SHFT) #define PLLCTRL_PRE_SRC_SHFT 20 #define PLLCTRL_PRE_SRC_MASK (0x7 << PLLCTRL_PRE_SRC_SHFT) +#define PLL_TO_LPD_DIV_SHIFT 8 +#define PLL_TO_LPD_DIV_MASK (0x3f << PLL_TO_LPD_DIV_SHIFT) #define NUM_MIO_PINS 77 @@ -334,6 +336,8 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id) return CRF_APB_TOPSW_LSBUS_CTRL; case iopll_to_fpd: return CRL_APB_IOPLL_TO_FPD_CTRL; + case dpll_to_lpd: + return CRF_APB_DPLL_TO_LPD_CTRL; default: debug("Invalid clk id%d\n", id); } @@ -397,6 +401,22 @@ static ulong zynqmp_clk_get_pll_rate(struct zynqmp_clk_priv *priv, if (clk_ctrl & (1 << 16)) freq /= 2; + if (id == dpll) { + u32 dpll_lpd_reg, cross_div; + + dpll_lpd_reg = zynqmp_clk_get_register(dpll_to_lpd); + + ret = zynqmp_mmio_read(dpll_lpd_reg, &cross_div); + if (ret) { + printf("%s mio read fail\n", __func__); + return -EIO; + } + + cross_div = (cross_div & PLL_TO_LPD_DIV_MASK) >> + PLL_TO_LPD_DIV_SHIFT; + freq /= cross_div; + } + return freq; } diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 3ea01f3c969..34e41461e72 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -31,6 +31,14 @@ config CLK_QCOM_IPQ4019 on the Snapdragon IPQ4019 SoC. This driver supports the clocks and resets exposed by the GCC hardware block. +config CLK_QCOM_IPQ5424 + bool "Qualcomm IPQ5424 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Qualcomm IPQ5424 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + config CLK_QCOM_IPQ9574 bool "Qualcomm IPQ9574 GCC" select CLK_QCOM @@ -55,6 +63,22 @@ config CLK_QCOM_QCS404 on the Snapdragon QCS404 SoC. This driver supports the clocks and resets exposed by the GCC hardware block. +config CLK_QCOM_QCS615 + bool "Qualcomm QCS615 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon QCS615 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + +config CLK_QCOM_QCS8300 + bool "Qualcomm QCS8300 GCC" + select CLK_QCOM + help + Say Y here to enable support for the Global Clock Controller + on the Snapdragon QCS8300 SoC. This driver supports the clocks + and resets exposed by the GCC hardware block. + config CLK_QCOM_SA8775P bool "Qualcomm SA8775 GCC" select CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index e13fc8c1071..b3d95b0faa3 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -7,9 +7,12 @@ obj-$(CONFIG_CLK_QCOM_SDM845) += clock-sdm845.o obj-$(CONFIG_CLK_QCOM_APQ8016) += clock-apq8016.o obj-$(CONFIG_CLK_QCOM_APQ8096) += clock-apq8096.o obj-$(CONFIG_CLK_QCOM_IPQ4019) += clock-ipq4019.o +obj-$(CONFIG_CLK_QCOM_IPQ5424) += clock-ipq5424.o obj-$(CONFIG_CLK_QCOM_IPQ9574) += clock-ipq9574.o obj-$(CONFIG_CLK_QCOM_QCM2290) += clock-qcm2290.o obj-$(CONFIG_CLK_QCOM_QCS404) += clock-qcs404.o +obj-$(CONFIG_CLK_QCOM_QCS8300) += clock-qcs8300.o +obj-$(CONFIG_CLK_QCOM_QCS615) += clock-qcs615.o obj-$(CONFIG_CLK_QCOM_SA8775P) += clock-sa8775p.o obj-$(CONFIG_CLK_QCOM_SC7280) += clock-sc7280.o obj-$(CONFIG_CLK_QCOM_SM6115) += clock-sm6115.o diff --git a/drivers/clk/qcom/clock-ipq5424.c b/drivers/clk/qcom/clock-ipq5424.c new file mode 100644 index 00000000000..40823a30ead --- /dev/null +++ b/drivers/clk/qcom/clock-ipq5424.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Clock drivers for Qualcomm ipq5424 + * + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include <linux/types.h> +#include <linux/kernel.h> +#include <clk-uclass.h> +#include <dm.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <linux/bug.h> +#include <linux/bitops.h> +#include <dt-bindings/clock/qcom,ipq5424-gcc.h> +#include <dt-bindings/reset/qcom,ipq5424-gcc.h> + +#include "clock-qcom.h" + +#define GCC_IM_SLEEP_CBCR 0x1834020u + +static ulong ipq5424_set_rate(struct clk *clk, ulong rate) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + case GCC_QUPV3_UART1_CLK: + clk_rcg_set_rate_mnd(priv->base, priv->data->clks[clk->id].reg, + 0, 144, 15625, CFG_CLK_SRC_GPLL0, 16); + return rate; + case GCC_SDCC1_APPS_CLK: + clk_rcg_set_rate_mnd(priv->base, priv->data->clks[clk->id].reg, + 5, 0, 0, CFG_CLK_SRC_GPLL2_MAIN, 16); + return rate; + } + return 0; +} + +static const struct gate_clk ipq5424_clks[] = { + GATE_CLK(GCC_QUPV3_UART1_CLK, 0x302c, BIT(0)), + GATE_CLK(GCC_SDCC1_AHB_CLK, 0x3303c, BIT(0)), + GATE_CLK(GCC_SDCC1_APPS_CLK, 0x33004, BIT(1)), + GATE_CLK(GCC_IM_SLEEP_CLK, 0x34020, BIT(0)), +}; + +static int ipq5424_enable(struct clk *clk) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + if (clk->id >= ARRAY_SIZE(ipq5424_clks) || !ipq5424_clks[clk->id].reg) + return -EINVAL; + + qcom_gate_clk_en(priv, clk->id); + + return 0; +} + +static const struct qcom_reset_map ipq5424_gcc_resets[] = { + [GCC_SDCC_BCR] = { 0x33000 }, +}; + +static struct msm_clk_data ipq5424_gcc_data = { + .resets = ipq5424_gcc_resets, + .num_resets = ARRAY_SIZE(ipq5424_gcc_resets), + .clks = ipq5424_clks, + .num_clks = ARRAY_SIZE(ipq5424_clks), + + .enable = ipq5424_enable, + .set_rate = ipq5424_set_rate, +}; + +static const struct udevice_id gcc_ipq5424_of_match[] = { + { + .compatible = "qcom,ipq5424-gcc", + .data = (ulong)&ipq5424_gcc_data, + }, + { } +}; + +static int ipq5424_clk_probe(struct udevice *dev) +{ + /* Enable the sleep clock needed for the MMC block reset */ + writel(BIT(0), GCC_IM_SLEEP_CBCR); + + return 0; +} + +U_BOOT_DRIVER(gcc_ipq5424) = { + .name = "gcc_ipq5424", + .id = UCLASS_NOP, + .of_match = gcc_ipq5424_of_match, + .probe = ipq5424_clk_probe, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF, +}; diff --git a/drivers/clk/qcom/clock-qcom.h b/drivers/clk/qcom/clock-qcom.h index 1b60882dae4..3a4550d8536 100644 --- a/drivers/clk/qcom/clock-qcom.h +++ b/drivers/clk/qcom/clock-qcom.h @@ -13,6 +13,7 @@ #define CFG_CLK_SRC_GPLL0 (1 << 8) #define CFG_CLK_SRC_GPLL0_AUX2 (2 << 8) #define CFG_CLK_SRC_GPLL2 (2 << 8) +#define CFG_CLK_SRC_GPLL2_MAIN (2 << 8) #define CFG_CLK_SRC_GPLL9 (2 << 8) #define CFG_CLK_SRC_GPLL0_ODD (3 << 8) #define CFG_CLK_SRC_GPLL6 (4 << 8) diff --git a/drivers/clk/qcom/clock-qcs615.c b/drivers/clk/qcom/clock-qcs615.c new file mode 100644 index 00000000000..4700baba8c9 --- /dev/null +++ b/drivers/clk/qcom/clock-qcs615.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Clock drivers for Qualcomm qcs615 + * + * (C) Copyright 2024 Linaro Ltd. + */ + +#include <linux/types.h> +#include <clk-uclass.h> +#include <dm.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <linux/bug.h> +#include <linux/bitops.h> +#include <dt-bindings/clock/qcom,qcs615-gcc.h> +#include "clock-qcom.h" + +#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf034 +#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf01c +#define USB3_PRIM_PHY_AUX_CMD_RCGR 0xf060 + +#define GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT BIT(10) +#define GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT BIT(11) +#define GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT BIT(12) +#define GCC_QUPV3_WRAP0_S3_CLK_ENA_BIT BIT(13) +#define GCC_QUPV3_WRAP0_S4_CLK_ENA_BIT BIT(14) +#define GCC_QUPV3_WRAP0_S5_CLK_ENA_BIT BIT(15) + +#define GCC_QUPV3_WRAP1_S0_CLK_ENA_BIT BIT(22) +#define GCC_QUPV3_WRAP1_S1_CLK_ENA_BIT BIT(23) +#define GCC_QUPV3_WRAP1_S2_CLK_ENA_BIT BIT(24) +#define GCC_QUPV3_WRAP1_S3_CLK_ENA_BIT BIT(25) +#define GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT BIT(26) +#define GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT BIT(27) + +static ulong qcs615_set_rate(struct clk *clk, ulong rate) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + if (clk->id < priv->data->num_clks) + debug("%s: %s, requested rate=%ld\n", __func__, + priv->data->clks[clk->id].name, rate); + + switch (clk->id) { + case GCC_USB30_PRIM_MOCK_UTMI_CLK: + WARN(rate != 19200000, "Unexpected rate for USB30_PRIM_MOCK_UTMI_CLK: %lu\n", rate); + clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO); + return rate; + case GCC_USB30_PRIM_MASTER_CLK: + WARN(rate != 200000000, "Unexpected rate for USB30_PRIM_MASTER_CLK: %lu\n", rate); + clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR, + 5, 0, 0, CFG_CLK_SRC_GPLL0, 8); + clk_rcg_set_rate(priv->base, USB3_PRIM_PHY_AUX_CMD_RCGR, 0, 0); + return rate; + default: + return 0; + } +} + +static const struct gate_clk qcs615_clks[] = { + GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0xf078, BIT(0)), + GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0xf010, BIT(0)), + GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0xf07c, BIT(0)), + GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0xf014, BIT(0)), + GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0xf018, BIT(0)), + GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0xf050, BIT(0)), + GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0xf054, BIT(0)), + GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0xf058, BIT(0)), + GATE_CLK(GCC_QUPV3_WRAP0_S0_CLK, 0x5200c, GCC_QUPV3_WRAP0_S0_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP0_S1_CLK, 0x5200c, GCC_QUPV3_WRAP0_S1_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP0_S2_CLK, 0x5200c, GCC_QUPV3_WRAP0_S2_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP0_S3_CLK, 0x5200c, GCC_QUPV3_WRAP0_S3_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP0_S4_CLK, 0x5200c, GCC_QUPV3_WRAP0_S4_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP0_S5_CLK, 0x5200c, GCC_QUPV3_WRAP0_S5_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP1_S0_CLK, 0x5200c, GCC_QUPV3_WRAP1_S0_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP1_S1_CLK, 0x5200c, GCC_QUPV3_WRAP1_S1_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP1_S2_CLK, 0x5200c, GCC_QUPV3_WRAP1_S2_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP1_S3_CLK, 0x5200c, GCC_QUPV3_WRAP1_S3_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP1_S4_CLK, 0x5200c, GCC_QUPV3_WRAP1_S4_CLK_ENA_BIT), + GATE_CLK(GCC_QUPV3_WRAP1_S5_CLK, 0x5200c, GCC_QUPV3_WRAP1_S5_CLK_ENA_BIT), + GATE_CLK(GCC_DISP_HF_AXI_CLK, 0xb038, BIT(0)), + GATE_CLK(GCC_DISP_AHB_CLK, 0xb032, BIT(0)) +}; + +static int qcs615_enable(struct clk *clk) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + if (priv->data->num_clks < clk->id) { + debug("%s: unknown clk id %lu\n", __func__, clk->id); + return 0; + } + + debug("%s: clk %ld: %s\n", __func__, clk->id, qcs615_clks[clk->id].name); + + switch (clk->id) { + case GCC_AGGRE_USB3_PRIM_AXI_CLK: + qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK); + fallthrough; + case GCC_USB30_PRIM_MASTER_CLK: + qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK); + qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK); + break; + } + + qcom_gate_clk_en(priv, clk->id); + + return 0; +} + +static const struct qcom_reset_map qcs615_gcc_resets[] = { + [GCC_EMAC_BCR] = { 0x6000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0xd000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0xd004 }, + [GCC_USB30_PRIM_BCR] = { 0xf000 }, + [GCC_USB2_PHY_SEC_BCR] = { 0x50018 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50020 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x5001c }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_COM_BCR] = { 0x6f010 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB20_SEC_BCR] = { 0xa6000 }, + [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x50008 }, + [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x50000 }, + [GCC_SDCC1_BCR] = { 0x12000 }, + [GCC_SDCC2_BCR] = { 0x14000 } +}; + +static const struct qcom_power_map qcs615_gdscs[] = { + [UFS_PHY_GDSC] = { 0x77004 }, + [USB30_PRIM_GDSC] = { 0xf004 }, +}; + +static struct msm_clk_data sa8775_gcc_data = { + .resets = qcs615_gcc_resets, + .num_resets = ARRAY_SIZE(qcs615_gcc_resets), + .clks = qcs615_clks, + .num_clks = ARRAY_SIZE(qcs615_clks), + + .power_domains = qcs615_gdscs, + .num_power_domains = ARRAY_SIZE(qcs615_gdscs), + + .enable = qcs615_enable, + .set_rate = qcs615_set_rate, +}; + +static const struct udevice_id gcc_qcs615_of_match[] = { + { + .compatible = "qcom,qcs615-gcc", + .data = (ulong)&sa8775_gcc_data, + }, + { } +}; + +U_BOOT_DRIVER(gcc_qcs615) = { + .name = "gcc_qcs615", + .id = UCLASS_NOP, + .of_match = gcc_qcs615_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF, +}; diff --git a/drivers/clk/qcom/clock-qcs8300.c b/drivers/clk/qcom/clock-qcs8300.c new file mode 100644 index 00000000000..cd8aecdf788 --- /dev/null +++ b/drivers/clk/qcom/clock-qcs8300.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved. + * + */ + +#include <linux/types.h> +#include <clk-uclass.h> +#include <dm.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <linux/bug.h> +#include <linux/bitops.h> +#include <dt-bindings/clock/qcom,qcs8300-gcc.h> +#include "clock-qcom.h" + +#define USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR 0xf038 +#define USB30_PRIM_MASTER_CLK_CMD_RCGR 0xf020 + +static ulong qcs8300_set_rate(struct clk *clk, ulong rate) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + if (clk->id < priv->data->num_clks) + debug("%s: %s, requested rate=%ld\n", + __func__, priv->data->clks[clk->id].name, rate); + + switch (clk->id) { + case GCC_USB30_PRIM_MOCK_UTMI_CLK: + WARN(rate != 19200000, "Unexpected rate for USB30_PRIM_MOCK_UTMI_CLK: %lu\n", rate); + clk_rcg_set_rate(priv->base, USB30_PRIM_MOCK_UTMI_CLK_CMD_RCGR, 0, CFG_CLK_SRC_CXO); + return rate; + case GCC_USB30_PRIM_MASTER_CLK: + WARN(rate != 200000000, "Unexpected rate for USB30_PRIM_MASTER_CLK: %lu\n", rate); + clk_rcg_set_rate_mnd(priv->base, USB30_PRIM_MASTER_CLK_CMD_RCGR, + 1, 0, 0, CFG_CLK_SRC_GPLL0_ODD, 8); + clk_rcg_set_rate(priv->base, 0xf064, 0, 0); + return rate; + default: + return 0; + } +} + +static const struct gate_clk qcs8300_clks[] = { + GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x1b088, BIT(0)), + GATE_CLK(GCC_USB30_PRIM_MASTER_CLK, 0x1b018, BIT(0)), + GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x1b084, BIT(0)), + GATE_CLK(GCC_USB30_PRIM_SLEEP_CLK, 0x1b020, BIT(0)), + GATE_CLK(GCC_USB30_PRIM_MOCK_UTMI_CLK, 0x1b024, BIT(0)), + GATE_CLK(GCC_USB3_PRIM_PHY_AUX_CLK, 0x1b05c, BIT(0)), + GATE_CLK(GCC_USB3_PRIM_PHY_COM_AUX_CLK, 0x1b060, BIT(0)), + GATE_CLK(GCC_UFS_PHY_AHB_CLK, 0x83020, BIT(0)), + GATE_CLK(GCC_UFS_PHY_AXI_CLK, 0x83018, BIT(0)), + GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x830d4, BIT(0)), + GATE_CLK(GCC_UFS_PHY_UNIPRO_CORE_CLK, 0x83064, BIT(0)), +}; + +static int qcs8300_enable(struct clk *clk) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + if (priv->data->num_clks < clk->id) { + debug("%s: unknown clk id %lu\n", __func__, clk->id); + return 0; + } + + debug("%s: clk %ld: %s\n", __func__, clk->id, qcs8300_clks[clk->id].name); + + switch (clk->id) { + case GCC_AGGRE_USB3_PRIM_AXI_CLK: + qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK); + fallthrough; + case GCC_USB30_PRIM_MASTER_CLK: + qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_AUX_CLK); + qcom_gate_clk_en(priv, GCC_USB3_PRIM_PHY_COM_AUX_CLK); + break; + } + + qcom_gate_clk_en(priv, clk->id); + + return 0; +} + +static const struct qcom_reset_map qcs8300_gcc_resets[] = { + [GCC_EMAC0_BCR] = { 0xb6000 }, + [GCC_PCIE_0_BCR] = { 0xa9000 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0xbf000 }, + [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0xbf008 }, + [GCC_PCIE_0_PHY_BCR] = { 0xa9144 }, + [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0xbf00c }, + [GCC_PCIE_1_BCR] = { 0x77000 }, + [GCC_PCIE_1_LINK_DOWN_BCR] = { 0xae084 }, + [GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0xae090 }, + [GCC_PCIE_1_PHY_BCR] = { 0xae08c }, + [GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0xae094 }, + [GCC_SDCC1_BCR] = { 0x20000 }, + [GCC_UFS_PHY_BCR] = { 0x83000 }, + [GCC_USB20_PRIM_BCR] = { 0x1c000 }, + [GCC_USB2_PHY_PRIM_BCR] = { 0x5c01c }, + [GCC_USB2_PHY_SEC_BCR] = { 0x5c020 }, + [GCC_USB30_PRIM_BCR] = { 0x1b000 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x5c008 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x5c000 }, + [GCC_USB3_PHY_TERT_BCR] = { 0x5c024 }, + [GCC_USB3_UNIPHY_MP0_BCR] = { 0x5c00c }, + [GCC_USB3_UNIPHY_MP1_BCR] = { 0x5c010 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x5c004 }, + [GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x5c014 }, + [GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x5c018 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x76000 }, + [GCC_VIDEO_BCR] = { 0x34000 }, +}; + +static const struct qcom_power_map qcs8300_gdscs[] = { + [GCC_UFS_PHY_GDSC] = { 0x83004 }, + [GCC_USB30_PRIM_GDSC] = { 0x1B004 }, +}; + +static struct msm_clk_data qcs8300_gcc_data = { + .resets = qcs8300_gcc_resets, + .num_resets = ARRAY_SIZE(qcs8300_gcc_resets), + .clks = qcs8300_clks, + .num_clks = ARRAY_SIZE(qcs8300_clks), + + .power_domains = qcs8300_gdscs, + .num_power_domains = ARRAY_SIZE(qcs8300_gdscs), + + .enable = qcs8300_enable, + .set_rate = qcs8300_set_rate, +}; + +static const struct udevice_id gcc_qcs8300_of_match[] = { + { + .compatible = "qcom,qcs8300-gcc", + .data = (ulong)&qcs8300_gcc_data, + }, + { } +}; + +U_BOOT_DRIVER(gcc_qcs8300) = { + .name = "gcc_qcs8300", + .id = UCLASS_NOP, + .of_match = gcc_qcs8300_of_match, + .bind = qcom_cc_bind, + .flags = DM_FLAG_PRE_RELOC | DM_FLAG_DEFAULT_PD_CTRL_OFF, +}; diff --git a/drivers/clk/qcom/clock-sc7280.c b/drivers/clk/qcom/clock-sc7280.c index 9aff8a847ad..47e0ca5f0e5 100644 --- a/drivers/clk/qcom/clock-sc7280.c +++ b/drivers/clk/qcom/clock-sc7280.c @@ -205,7 +205,7 @@ static const char *const sc7280_rcg_names[] = { "GCC_PCIE_1_AUX_CLK_SRC", }; -static struct msm_clk_data qcs404_gcc_data = { +static struct msm_clk_data sc7280_gcc_data = { .resets = sc7280_gcc_resets, .num_resets = ARRAY_SIZE(sc7280_gcc_resets), .clks = sc7280_clks, @@ -225,7 +225,7 @@ static struct msm_clk_data qcs404_gcc_data = { static const struct udevice_id gcc_sc7280_of_match[] = { { .compatible = "qcom,gcc-sc7280", - .data = (ulong)&qcs404_gcc_data, + .data = (ulong)&sc7280_gcc_data, }, { } }; diff --git a/drivers/clk/qcom/clock-sm8250.c b/drivers/clk/qcom/clock-sm8250.c index 26396847d85..cc481258d22 100644 --- a/drivers/clk/qcom/clock-sm8250.c +++ b/drivers/clk/qcom/clock-sm8250.c @@ -360,7 +360,7 @@ static const char *const sm8250_rcg_names[] = { "GCC_PCIE_2_AUX_CMD_RCGR", }; -static struct msm_clk_data qcs404_gcc_data = { +static struct msm_clk_data sm8250_gcc_data = { .resets = sm8250_gcc_resets, .num_resets = ARRAY_SIZE(sm8250_gcc_resets), .clks = sm8250_clks, @@ -381,7 +381,7 @@ static struct msm_clk_data qcs404_gcc_data = { static const struct udevice_id gcc_sm8250_of_match[] = { { .compatible = "qcom,gcc-sm8250", - .data = (ulong)&qcs404_gcc_data, + .data = (ulong)&sm8250_gcc_data, }, {} }; diff --git a/drivers/dfu/dfu_scsi.c b/drivers/dfu/dfu_scsi.c index 7ec34a8f7e3..d99b05d23ac 100644 --- a/drivers/dfu/dfu_scsi.c +++ b/drivers/dfu/dfu_scsi.c @@ -342,11 +342,6 @@ int dfu_fill_entity_scsi(struct dfu_entity *dfu, char *devstr, char **argv, int return -EINVAL; } - if (scsi_scan(false)) { - pr_err("Couldn't init scsi device.\n"); - return -ENODEV; - } - ret = find_scsi_device(dfu->data.scsi.lun, &scsi); if (ret < 0) { pr_err("Couldn't find scsi device no. %d.\n", dfu->data.scsi.lun); diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 8789b1ea141..a094e6c3afe 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -29,6 +29,7 @@ config TI_SCI_PROTOCOL config ZYNQMP_FIRMWARE bool "ZynqMP Firmware interface" + depends on ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2 select FIRMWARE help Firmware interface driver is used by different diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 2940181e83e..d18ae523b6b 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -422,6 +422,30 @@ U_BOOT_DRIVER(zynqmp_power) = { }; #endif +smc_call_handler_t __data smc_call_handler; + +static int smc_call_legacy(u32 api_id, u32 arg0, u32 arg1, u32 arg2, + u32 arg3, u32 *ret_payload) +{ + struct pt_regs regs; + + regs.regs[0] = PM_SIP_SVC | api_id; + regs.regs[1] = ((u64)arg1 << 32) | arg0; + regs.regs[2] = ((u64)arg3 << 32) | arg2; + + smc_call(®s); + + if (ret_payload) { + ret_payload[0] = (u32)regs.regs[0]; + ret_payload[1] = upper_32_bits(regs.regs[0]); + ret_payload[2] = (u32)regs.regs[1]; + ret_payload[3] = upper_32_bits(regs.regs[1]); + ret_payload[4] = (u32)regs.regs[2]; + } + + return (ret_payload) ? ret_payload[0] : 0; +} + int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 *ret_payload) { @@ -450,38 +474,20 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, PAYLOAD_ARG_CNT); if (ret) return ret; + + return (ret_payload) ? ret_payload[0] : 0; #else return -EPERM; #endif - } else { - /* - * Added SIP service call Function Identifier - * Make sure to stay in x0 register - */ - struct pt_regs regs; - - regs.regs[0] = PM_SIP_SVC | api_id; - regs.regs[1] = ((u64)arg1 << 32) | arg0; - regs.regs[2] = ((u64)arg3 << 32) | arg2; - - smc_call(®s); - - if (ret_payload) { - ret_payload[0] = (u32)regs.regs[0]; - ret_payload[1] = upper_32_bits(regs.regs[0]); - ret_payload[2] = (u32)regs.regs[1]; - ret_payload[3] = upper_32_bits(regs.regs[1]); - ret_payload[4] = (u32)regs.regs[2]; - } - } - return (ret_payload) ? ret_payload[0] : 0; + + return smc_call_handler(api_id, arg0, arg1, arg2, arg3, ret_payload); } static const struct udevice_id zynqmp_firmware_ids[] = { - { .compatible = "xlnx,zynqmp-firmware" }, - { .compatible = "xlnx,versal-firmware"}, - { .compatible = "xlnx,versal-net-firmware"}, + { .compatible = "xlnx,zynqmp-firmware", .data = (ulong)smc_call_legacy }, + { .compatible = "xlnx,versal-firmware", .data = (ulong)smc_call_legacy}, + { .compatible = "xlnx,versal-net-firmware", .data = (ulong)smc_call_legacy }, { } }; @@ -490,6 +496,10 @@ static int zynqmp_firmware_bind(struct udevice *dev) int ret; struct udevice *child; + smc_call_handler = (smc_call_handler_t)dev_get_driver_data(dev); + if (!smc_call_handler) + return -EINVAL; + if ((IS_ENABLED(CONFIG_XPL_BUILD) && IS_ENABLED(CONFIG_SPL_POWER_DOMAIN) && IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) || diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c index a2f3b160a73..5f4aae47d6d 100644 --- a/drivers/fpga/intel_sdm_mb.c +++ b/drivers/fpga/intel_sdm_mb.c @@ -687,7 +687,8 @@ static int send_bitstream(const void *rbf_data, size_t rbf_size) debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n", wr_ret, rbf_data, buf_size); - if (wr_ret) + if (wr_ret != INTEL_SIP_SMC_STATUS_OK && + wr_ret != INTEL_SIP_SMC_STATUS_BUSY) continue; rbf_size -= buf_size; diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index 6783fc756f4..7de332c66ae 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -202,7 +202,7 @@ static int msm_gpio_get_value(struct udevice *dev, unsigned int gpio) if (qcom_is_special_pin(priv->pin_data, gpio)) return msm_gpio_get_value_special(priv, gpio); - return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) >> GPIO_IN); + return !!(readl(priv->base + GPIO_IN_OUT_REG(dev, gpio)) & BIT(GPIO_IN)); } static int msm_gpio_get_function_special(struct msm_gpio_bank *priv, diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c index d1999d21feb..012881de05b 100644 --- a/drivers/i2c/muxes/i2c-mux-uclass.c +++ b/drivers/i2c/muxes/i2c-mux-uclass.c @@ -40,6 +40,11 @@ static int i2c_mux_child_post_bind(struct udevice *dev) struct i2c_mux_bus *plat = dev_get_parent_plat(dev); int channel; + ofnode node = dev_ofnode(dev); + + if (!ofnode_has_property(node, "reg")) + return 0; + channel = dev_read_u32_default(dev, "reg", -1); if (channel < 0) return -EINVAL; diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c index fa3ac2d9e37..8bfdffd56f5 100644 --- a/drivers/mmc/rpmb.c +++ b/drivers/mmc/rpmb.c @@ -11,7 +11,7 @@ #include <log.h> #include <memalign.h> #include <mmc.h> -#include <sdhci.h> +#include <asm/byteorder.h> #include <u-boot/sha256.h> #include "mmc_private.h" @@ -91,7 +91,6 @@ static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, { struct mmc_cmd cmd = {0}; struct mmc_data data; - struct sdhci_host *host = mmc->priv; int ret; ret = mmc_set_blockcount(mmc, count, is_rel_write); @@ -106,9 +105,6 @@ static int mmc_rpmb_request(struct mmc *mmc, const struct s_rpmb *s, cmd.cmdarg = 0; cmd.resp_type = MMC_RSP_R1; - if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) - cmd.resp_type = MMC_RSP_R1; - data.src = (const char *)s; data.blocks = 1; data.blocksize = MMC_MAX_BLOCK_LEN; diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index 9dc1ceaa09b..3b86bc9b18c 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -54,16 +54,30 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host) u32 sdmmc_mask = ((priv->smplsel & 0x7) << SYSMGR_SDMMC_SMPLSEL_SHIFT) | ((priv->drvsel & 0x7) << SYSMGR_SDMMC_DRVSEL_SHIFT); + /* Get clock manager base address */ + struct udevice *clkmgr_dev; + int ret = uclass_get_device_by_name(UCLASS_CLK, "clock-controller@ffd10000", &clkmgr_dev); + + if (ret) { + printf("Failed to get clkmgr device: %d\n", ret); + return ret; + } + + fdt_addr_t clkmgr_base = dev_read_addr(clkmgr_dev); + + if (clkmgr_base == FDT_ADDR_T_NONE) { + printf("Failed to read base address from clkmgr DT node\n"); + return -EINVAL; + } + /* Disable SDMMC clock. */ - clrbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN, + clrbits_le32(clkmgr_base + CLKMGR_PERPLL_EN, CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); debug("%s: drvsel %d smplsel %d\n", __func__, priv->drvsel, priv->smplsel); #if !defined(CONFIG_XPL_BUILD) && defined(CONFIG_SPL_ATF) - int ret; - ret = socfpga_secure_reg_write32(SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC, sdmmc_mask); if (ret) { @@ -78,7 +92,7 @@ static int socfpga_dwmci_clksel(struct dwmci_host *host) #endif /* Enable SDMMC clock */ - setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN, + setbits_le32(clkmgr_base + CLKMGR_PERPLL_EN, CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK); return 0; diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 2375b15539b..3b682918b03 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -1127,6 +1127,28 @@ static int arasan_sdhci_probe(struct udevice *dev) if (arasan_sdhci_is_compatible(dev, SDHCI_COMPATIBLE_VERSAL_NET_EMMC)) priv->internal_phy_reg = true; + ret = reset_get_bulk(dev, &priv->resets); + if (ret == -ENOTSUPP || ret == -ENOENT) { + dev_warn(dev, "Reset not found\n"); + } else if (ret) { + dev_err(dev, "Reset failed\n"); + return ret; + } + + if (!ret) { + ret = reset_assert_bulk(&priv->resets); + if (ret) { + dev_err(dev, "Reset assert failed\n"); + return ret; + } + + ret = reset_deassert_bulk(&priv->resets); + if (ret) { + dev_err(dev, "Reset release failed\n"); + return ret; + } + } + ret = clk_get_by_index(dev, 0, &clk); if (ret < 0) { dev_err(dev, "failed to get clock\n"); diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index f2ecf47f8d4..fe8c76acac6 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -43,6 +43,22 @@ static SPINAND_OP_VARIANTS(read_cache_variants_f, SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0)); +static SPINAND_OP_VARIANTS(read_cache_variants_1gq5, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + +static SPINAND_OP_VARIANTS(read_cache_variants_2gq5, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 4, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + static SPINAND_OP_VARIANTS(write_cache_variants, SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), SPINAND_PROG_LOAD(true, 0, NULL, 0)); @@ -329,6 +345,36 @@ static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GQ4RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F2GQ4UExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd2), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F2GQ4RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xc2), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), SPINAND_INFO("GD5F1GQ4UFxxG", SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), @@ -343,12 +389,152 @@ static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(4, 512), - SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq5xexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GQ5RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x41), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq5xexxg_ecc_get_status)), + SPINAND_INFO("GD5F2GQ5UExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x52), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq5xexxg_ecc_get_status)), + SPINAND_INFO("GD5F2GQ5RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x42), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq5xexxg_ecc_get_status)), + SPINAND_INFO("GD5F4GQ6UExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x55), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq5xexxg_ecc_get_status)), + SPINAND_INFO("GD5F4GQ6RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x45), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 2, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, &write_cache_variants, &update_cache_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, gd5fxgq5xexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GM7UExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x91), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GM7RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x81), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F2GM7UExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F2GM7RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x82), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F4GM8UExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x95), + NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F4GM8RExxG", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x85), + NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F2GQ5xExxH", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22), + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_2gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GQ5RExxH", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x21), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), + SPINAND_INFO("GD5F1GQ4RExxH", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xc9), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), + NAND_ECCREQ(4, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants_1gq5, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, + gd5fxgq4uexxg_ecc_get_status)), }; static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 0f93c25e3fe..fce3ef910cb 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -716,7 +716,7 @@ static int _dw_free_pkt(struct dw_eth_dev *priv) ulong desc_start = (ulong)desc_p; ulong desc_end = desc_start + roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); - ulong data_start = desc_p->dmamac_addr; + ulong data_start = dev_bus_to_phys(priv->dev, desc_p->dmamac_addr); ulong data_end = data_start + roundup(CFG_ETH_BUFSIZE, ARCH_DMA_MINALIGN); /* Invalidate the descriptor buffer data */ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 409049137cc..8ffd88c722d 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -389,6 +389,16 @@ config PCIE_DW_QCOM Say Y here if you want to enable DW PCIe controller support on Qualcomm SoCs. +config PCI_RCAR_GEN4 + bool "Renesas R-Car Gen4 PCIe driver" + depends on RCAR_GEN4 + select DM_RESET + select DM_GPIO + select PCIE_DW_COMMON + help + Say Y here if you want to enable PCIe controller support on + Renesas R-Car Gen4 SoCs. + config PCIE_ROCKCHIP bool "Enable Rockchip PCIe driver" depends on ARCH_ROCKCHIP diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ba53f594963..a0420e733ed 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_PCIE_IMX) += pcie_imx.o obj-$(CONFIG_PCI_MVEBU) += pci_mvebu.o obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o obj-$(CONFIG_PCI_RCAR_GEN3) += pci-rcar-gen3.o +obj-$(CONFIG_PCI_RCAR_GEN4) += pci-rcar-gen4.o obj-$(CONFIG_SH7751_PCI) +=pci_sh7751.o obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o obj-$(CONFIG_PCIE_IPROC) += pcie_iproc.o diff --git a/drivers/pci/pci-rcar-gen4.c b/drivers/pci/pci-rcar-gen4.c new file mode 100644 index 00000000000..87cd69f989d --- /dev/null +++ b/drivers/pci/pci-rcar-gen4.c @@ -0,0 +1,565 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * PCIe controller driver for Renesas R-Car Gen4 Series SoCs + * Copyright (C) 2025 Marek Vasut <marek.vasut+renesas@mailbox.org> + * Based on Linux kernel driver + * Copyright (C) 2022-2023 Renesas Electronics Corporation + * + * The r8a779g0 (R-Car V4H) controller requires a specific firmware to be + * provided, to initialize the PHY. Otherwise, the PCIe controller will not + * work. + */ + +#include <asm-generic/gpio.h> +#include <asm/arch/gpio.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <clk.h> +#include <command.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <env.h> +#include <log.h> +#include <reset.h> + +#include <linux/bitfield.h> +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/iopoll.h> + +#include "pcie_dw_common.h" + +/* Renesas-specific */ +/* PCIe Mode Setting Register 0 */ +#define PCIEMSR0 0x0000 +#define APP_SRIS_MODE BIT(6) +#define DEVICE_TYPE_EP 0 +#define DEVICE_TYPE_RC BIT(4) +#define BIFUR_MOD_SET_ON BIT(0) + +/* PCIe Interrupt Status 0 */ +#define PCIEINTSTS0 0x0084 + +/* PCIe Interrupt Status 0 Enable */ +#define PCIEINTSTS0EN 0x0310 +#define MSI_CTRL_INT BIT(26) +#define SMLH_LINK_UP BIT(7) +#define RDLH_LINK_UP BIT(6) + +/* PCIe DMA Interrupt Status Enable */ +#define PCIEDMAINTSTSEN 0x0314 +#define PCIEDMAINTSTSEN_INIT GENMASK(15, 0) + +/* Port Logic Registers 89 */ +#define PRTLGC89 0x0b70 + +/* Port Logic Registers 90 */ +#define PRTLGC90 0x0b74 + +/* PCIe Reset Control Register 1 */ +#define PCIERSTCTRL1 0x0014 +#define APP_HOLD_PHY_RST BIT(16) +#define APP_LTSSM_ENABLE BIT(0) + +/* PCIe Power Management Control */ +#define PCIEPWRMNGCTRL 0x0070 +#define APP_CLK_REQ_N BIT(11) +#define APP_CLK_PM_EN BIT(10) + +#define RCAR_NUM_SPEED_CHANGE_RETRIES 10 +#define RCAR_MAX_LINK_SPEED 4 + +#define RCAR_GEN4_PCIE_EP_FUNC_DBI_OFFSET 0x1000 +#define RCAR_GEN4_PCIE_EP_FUNC_DBI2_OFFSET 0x800 + +#define RCAR_GEN4_PCIE_FIRMWARE_NAME "rcar_gen4_pcie.bin" +#define RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR 0xc000 + +#define PCIE_T_PVPERL_MS 100 + +/** + * struct rcar_gen4_pcie - Renesas R-Car Gen4 DW PCIe controller state + * + * @rcar: The common PCIe DW structure + * @pwr_rst: The PWR reset of the PCIe core + * @core_clk: The core clock of the PCIe core + * @ref_clk: The reference clock of the PCIe core and possibly bus + * @pe_rst: PERST GPIO + * @app_base: The base address of application register space + * @dbi2_base: The base address of DBI2 register space + * @phy_base: The base address of PHY register space + * @max_link_speed: Maximum PCIe link speed supported by the setup + * @num_lanes: Number of PCIe lanes used by the setup + * @firmware: PHY firmware + * @firmware_size: PHY firmware size in Bytes + */ +struct rcar_gen4_pcie { + /* Must be first member of the struct */ + struct pcie_dw dw; + struct reset_ctl pwr_rst; + struct clk *core_clk; + struct clk *ref_clk; + struct gpio_desc pe_rst; + void *app_base; + void *dbi2_base; + void *phy_base; + u32 max_link_speed; + u32 num_lanes; + u16 *firmware; + u32 firmware_size; +}; + +/* Common */ +static bool rcar_gen4_pcie_link_up(struct rcar_gen4_pcie *rcar) +{ + u32 val, mask; + + val = readl(rcar->app_base + PCIEINTSTS0); + mask = RDLH_LINK_UP | SMLH_LINK_UP; + + return (val & mask) == mask; +} + +/* + * Manually initiate the speed change. Return 0 if change succeeded; otherwise + * -ETIMEDOUT. + */ +static int rcar_gen4_pcie_speed_change(struct rcar_gen4_pcie *rcar) +{ + u32 val; + int i; + + clrbits_le32(rcar->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL, + PORT_LOGIC_SPEED_CHANGE); + + setbits_le32(rcar->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL, + PORT_LOGIC_SPEED_CHANGE); + + for (i = 0; i < RCAR_NUM_SPEED_CHANGE_RETRIES; i++) { + val = readl(rcar->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + if (!(val & PORT_LOGIC_SPEED_CHANGE)) + return 0; + mdelay(10); + } + + return -ETIMEDOUT; +} + +/* + * SoC datasheet suggests checking port logic register bits during firmware + * write. If read returns non-zero value, then this function returns -EAGAIN + * indicating that the write needs to be done again. If read returns zero, + * then return 0 to indicate success. + */ +static int rcar_gen4_pcie_reg_test_bit(struct rcar_gen4_pcie *rcar, + u32 offset, u32 mask) +{ + if (readl(rcar->dw.dbi_base + offset) & mask) + return -EAGAIN; + + return 0; +} + +static int rcar_gen4_pcie_download_phy_firmware(struct rcar_gen4_pcie *rcar) +{ + /* The check_addr values are magical numbers in the datasheet */ + static const u32 check_addr[] = { + 0x00101018, + 0x00101118, + 0x00101021, + 0x00101121, + }; + unsigned int i, timeout; + u32 data; + int ret; + + for (i = 0; i < rcar->firmware_size / 2; i++) { + data = rcar->firmware[i]; + timeout = 100; + do { + writel(RCAR_GEN4_PCIE_FIRMWARE_BASE_ADDR + i, rcar->dw.dbi_base + PRTLGC89); + writel(data, rcar->dw.dbi_base + PRTLGC90); + if (!rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC89, BIT(30))) + break; + if (!(--timeout)) + return -ETIMEDOUT; + udelay(100); + } while (1); + } + + setbits_le32(rcar->phy_base + 0x0f8, BIT(17)); + + for (i = 0; i < ARRAY_SIZE(check_addr); i++) { + timeout = 100; + do { + writel(check_addr[i], rcar->dw.dbi_base + PRTLGC89); + ret = rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC89, BIT(30)); + ret |= rcar_gen4_pcie_reg_test_bit(rcar, PRTLGC90, BIT(0)); + if (!ret) + break; + if (!(--timeout)) + return -ETIMEDOUT; + udelay(100); + } while (1); + } + + return ret; +} + +static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable) +{ + u32 val; + int ret; + + if (!enable) { + clrbits_le32(rcar->app_base + PCIERSTCTRL1, APP_LTSSM_ENABLE); + return 0; + } + + setbits_le32(rcar->dw.dbi_base + PCIE_PORT_FORCE, + PORT_FORCE_DO_DESKEW_FOR_SRIS); + + setbits_le32(rcar->app_base + PCIEMSR0, APP_SRIS_MODE); + + /* + * The R-Car Gen4 datasheet doesn't describe the PHY registers' name. + * But, the initialization procedure describes these offsets. So, + * this driver has magical offset numbers. + */ + clrsetbits_le32(rcar->phy_base + 0x700, BIT(28), 0); + clrsetbits_le32(rcar->phy_base + 0x700, BIT(20), 0); + clrsetbits_le32(rcar->phy_base + 0x700, BIT(12), 0); + clrsetbits_le32(rcar->phy_base + 0x700, BIT(4), 0); + + clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(23, 22), BIT(22)); + clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(18, 16), GENMASK(17, 16)); + clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(7, 6), BIT(6)); + clrsetbits_le32(rcar->phy_base + 0x148, GENMASK(2, 0), GENMASK(11, 0)); + clrsetbits_le32(rcar->phy_base + 0x1d4, GENMASK(16, 15), GENMASK(16, 15)); + clrsetbits_le32(rcar->phy_base + 0x514, BIT(26), BIT(26)); + clrsetbits_le32(rcar->phy_base + 0x0f8, BIT(16), 0); + clrsetbits_le32(rcar->phy_base + 0x0f8, BIT(19), BIT(19)); + + clrbits_le32(rcar->app_base + PCIERSTCTRL1, APP_HOLD_PHY_RST); + + ret = readl_poll_timeout(rcar->phy_base + 0x0f8, val, !(val & BIT(18)), 10000); + if (ret < 0) + return ret; + + ret = rcar_gen4_pcie_download_phy_firmware(rcar); + if (ret) + return ret; + + setbits_le32(rcar->app_base + PCIERSTCTRL1, APP_LTSSM_ENABLE); + + return 0; +} + +/* + * Enable LTSSM of this controller and manually initiate the speed change. + * Always return 0. + */ +static int rcar_gen4_pcie_start_link(struct rcar_gen4_pcie *rcar) +{ + int i, ret; + + ret = rcar_gen4_pcie_ltssm_control(rcar, true); + if (ret) + return ret; + + /* + * Require direct speed change with retrying here if the max_link_speed + * is PCIe Gen2 or higher. + */ + if (rcar->max_link_speed == LINK_SPEED_GEN_1) + return 0; + + for (i = 0; i < RCAR_MAX_LINK_SPEED; i++) { + /* It may not be connected in EP mode yet. So, break the loop */ + if (rcar_gen4_pcie_speed_change(rcar)) + break; + } + + return 0; +} + +static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar) +{ + clrsetbits_le32(rcar->dw.dbi_base + PCIE_PORT_LANE_SKEW, + PORT_LANE_SKEW_INSERT_MASK, + (rcar->num_lanes < 4) ? BIT(6) : 0); + + setbits_le32(rcar->app_base + PCIEPWRMNGCTRL, + APP_CLK_REQ_N | APP_CLK_PM_EN); +} + +static int rcar_gen4_pcie_common_init(struct rcar_gen4_pcie *rcar) +{ + int ret; + + ret = clk_prepare_enable(rcar->core_clk); + if (ret) + return ret; + + ret = reset_assert(&rcar->pwr_rst); + if (ret) + goto err_unprepare; + + setbits_le32(rcar->app_base + PCIEMSR0, + DEVICE_TYPE_RC | + ((rcar->num_lanes < 4) ? BIFUR_MOD_SET_ON : 0)); + + ret = reset_deassert(&rcar->pwr_rst); + if (ret) + goto err_unprepare; + + rcar_gen4_pcie_additional_common_init(rcar); + + return 0; + +err_unprepare: + clk_disable_unprepare(rcar->core_clk); + + return ret; +} + +/* Host mode */ +static int rcar_gen4_pcie_host_init(struct udevice *dev) +{ + struct rcar_gen4_pcie *rcar = dev_get_priv(dev); + int ret; + + dm_gpio_set_value(&rcar->pe_rst, 1); + + ret = rcar_gen4_pcie_common_init(rcar); + if (ret) + return ret; + + /* + * According to the section 3.5.7.2 "RC Mode" in DWC PCIe Dual Mode + * Rev.5.20a and 3.5.6.1 "RC mode" in DWC PCIe RC databook v5.20a, we + * should disable two BARs to avoid unnecessary memory assignment + * during device enumeration. + */ + writel(0x0, rcar->dbi2_base + PCI_BASE_ADDRESS_0); + writel(0x0, rcar->dbi2_base + PCI_BASE_ADDRESS_1); + + /* Disable MSI interrupt signal */ + clrbits_le32(rcar->app_base + PCIEINTSTS0EN, MSI_CTRL_INT); + + mdelay(PCIE_T_PVPERL_MS); /* pe_rst requires 100msec delay */ + + dm_gpio_set_value(&rcar->pe_rst, 0); + + return 0; +} + +static int rcar_gen4_pcie_load_firmware(struct rcar_gen4_pcie *rcar) +{ + ulong addr, size; + int ret; + + /* + * Run user specified firmware loading script, which loads the + * firmware from whichever location the user decides it should + * load the firmware from, by whatever means the user decides. + */ + ret = run_command_list("run renesas_rcar_gen4_load_firmware", -1, 0); + if (ret) { + printf("Firmware loading script 'renesas_rcar_gen4_load_firmware' not defined or failed.\n"); + goto fail; + } + + /* Find out where the firmware got loaded and how long it is. */ + addr = env_get_hex("renesas_rcar_gen4_load_firmware_addr", 0); + size = env_get_hex("renesas_rcar_gen4_load_firmware_size", 0); + + /* + * Clear the variables set by the firmware loading script, as + * their content would become stale once this function exits. + */ + env_set("renesas_rcar_gen4_load_firmware_addr", NULL); + env_set("renesas_rcar_gen4_load_firmware_size", NULL); + + if (!addr || !size) { + printf("Firmware address (%lx) or size (%lx) are invalid.\n", addr, size); + goto fail; + } + + /* Create local copy of the loaded firmware. */ + rcar->firmware = (u16 *)memdup((void *)addr, size); + if (!rcar->firmware) + return -ENOMEM; + + rcar->firmware_size = size; + + return 0; + +fail: + printf("Define 'renesas_rcar_gen4_load_firmware' script which loads the R-Car\n" + "Gen4 PCIe controller firmware from storage into memory and sets these\n" + "two environment variables:\n" + " renesas_rcar_gen4_load_firmware_addr ... address of firmware in memory\n" + " renesas_rcar_gen4_load_firmware_size ... length of firmware in bytes\n" + "\n" + "Example:\n" + " => env set renesas_rcar_gen4_load_firmware 'env set renesas_rcar_gen4_load_firmware_addr 0x54000000 && load mmc 0:1 ${renesas_rcar_gen4_load_firmware_addr} lib/firmware/rcar_gen4_pcie.bin && env set renesas_rcar_gen4_load_firmware_size ${filesize}'\n" + ); + return -EINVAL; +} + +/** + * rcar_gen4_pcie_probe() - Probe the PCIe bus for active link + * + * @dev: A pointer to the device being operated on + * + * Probe for an active link on the PCIe bus and configure the controller + * to enable this port. + * + * Return: 0 on success, else -ENODEV + */ +static int rcar_gen4_pcie_probe(struct udevice *dev) +{ + struct rcar_gen4_pcie *rcar = dev_get_priv(dev); + struct udevice *ctlr = pci_get_controller(dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + int ret; + + ret = rcar_gen4_pcie_load_firmware(rcar); + if (ret) + return ret; + + rcar->dw.first_busno = dev_seq(dev); + rcar->dw.dev = dev; + + ret = reset_get_by_name(dev, "pwr", &rcar->pwr_rst); + if (ret) + return ret; + + rcar->core_clk = devm_clk_get(dev, "core"); + if (IS_ERR(rcar->core_clk)) + return PTR_ERR(rcar->core_clk); + + rcar->ref_clk = devm_clk_get(dev, "ref"); + if (IS_ERR(rcar->ref_clk)) + return PTR_ERR(rcar->ref_clk); + + ret = clk_prepare_enable(rcar->ref_clk); + if (ret) + return ret; + + ret = gpio_request_by_name(dev, "reset-gpios", 0, &rcar->pe_rst, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + if (ret) + return ret; + + ret = rcar_gen4_pcie_host_init(dev); + if (ret) + return ret; + + pcie_dw_setup_host(&rcar->dw); + + dw_pcie_dbi_write_enable(&rcar->dw, true); + + dw_pcie_link_set_max_link_width(&rcar->dw, rcar->num_lanes); + + ret = rcar_gen4_pcie_start_link(rcar); + if (ret) + return ret; + + dw_pcie_dbi_write_enable(&rcar->dw, false); + + if (!rcar_gen4_pcie_link_up(rcar)) { + printf("PCIE-%d: Link down\n", dev_seq(dev)); + return -ENODEV; + } + + printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev_seq(dev), + pcie_dw_get_link_speed(&rcar->dw), + pcie_dw_get_link_width(&rcar->dw), + hose->first_busno); + + pcie_dw_prog_outbound_atu_unroll(&rcar->dw, PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_MEM, + rcar->dw.mem.phys_start, + rcar->dw.mem.bus_start, rcar->dw.mem.size); + + return 0; +} + +/** + * rcar_gen4_pcie_of_to_plat() - Translate from DT to device state + * + * @dev: A pointer to the device being operated on + * + * Translate relevant data from the device tree pertaining to device @dev into + * state that the driver will later make use of. This state is stored in the + * device's private data structure. + * + * Return: 0 on success, else -EINVAL + */ +static int rcar_gen4_pcie_of_to_plat(struct udevice *dev) +{ + struct rcar_gen4_pcie *rcar = dev_get_priv(dev); + + /* Get the controller base address */ + rcar->dw.dbi_base = (void *)dev_read_addr_name(dev, "dbi"); + if ((fdt_addr_t)rcar->dw.dbi_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the config space base address and size */ + rcar->dw.cfg_base = (void *)dev_read_addr_size_name(dev, "config", + &rcar->dw.cfg_size); + if ((fdt_addr_t)rcar->dw.cfg_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the iATU base address and size */ + rcar->dw.atu_base = (void *)dev_read_addr_name(dev, "atu"); + if ((fdt_addr_t)rcar->dw.atu_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the PHY base address and size */ + rcar->phy_base = (void *)dev_read_addr_name(dev, "phy"); + if ((fdt_addr_t)rcar->phy_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the app base address and size */ + rcar->app_base = (void *)dev_read_addr_name(dev, "app"); + if ((fdt_addr_t)rcar->app_base == FDT_ADDR_T_NONE) + return -EINVAL; + + /* Get the dbi2 base address and size */ + rcar->dbi2_base = (void *)dev_read_addr_name(dev, "dbi2"); + if ((fdt_addr_t)rcar->dbi2_base == FDT_ADDR_T_NONE) + return -EINVAL; + + rcar->max_link_speed = + clamp(dev_read_u32_default(dev, "max-link-speed", + LINK_SPEED_GEN_4), + LINK_SPEED_GEN_1, RCAR_MAX_LINK_SPEED); + + rcar->num_lanes = dev_read_u32_default(dev, "num-lanes", 4); + + return 0; +} + +static const struct dm_pci_ops rcar_gen4_pcie_ops = { + .read_config = pcie_dw_read_config, + .write_config = pcie_dw_write_config, +}; + +static const struct udevice_id rcar_gen4_pcie_ids[] = { + { .compatible = "renesas,rcar-gen4-pcie" }, + { } +}; + +U_BOOT_DRIVER(rcar_gen4_pcie) = { + .name = "rcar_gen4_pcie", + .id = UCLASS_PCI, + .of_match = rcar_gen4_pcie_ids, + .ops = &rcar_gen4_pcie_ops, + .of_to_plat = rcar_gen4_pcie_of_to_plat, + .probe = rcar_gen4_pcie_probe, + .priv_auto = sizeof(struct rcar_gen4_pcie), +}; diff --git a/drivers/pci/pcie_dw_common.c b/drivers/pci/pcie_dw_common.c index 78961271a8e..c4cad019373 100644 --- a/drivers/pci/pcie_dw_common.c +++ b/drivers/pci/pcie_dw_common.c @@ -13,6 +13,7 @@ #include <pci.h> #include <dm/device_compat.h> #include <asm/io.h> +#include <linux/bitfield.h> #include <linux/delay.h> #include "pcie_dw_common.h" @@ -28,6 +29,50 @@ int pcie_dw_get_link_width(struct pcie_dw *pci) PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF; } +void dw_pcie_link_set_max_link_width(struct pcie_dw *pci, u32 num_lanes) +{ + u32 lnkcap, lwsc, plc; + u8 cap; + + if (!num_lanes) + return; + + /* Set the number of lanes */ + plc = readl(pci->dbi_base + PCIE_PORT_LINK_CONTROL); + plc &= ~PORT_LINK_FAST_LINK_MODE; + plc &= ~PORT_LINK_MODE_MASK; + + /* Set link width speed control register */ + lwsc = readl(pci->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + lwsc &= ~PORT_LOGIC_LINK_WIDTH_MASK; + lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES; + switch (num_lanes) { + case 1: + plc |= PORT_LINK_MODE_1_LANES; + break; + case 2: + plc |= PORT_LINK_MODE_2_LANES; + break; + case 4: + plc |= PORT_LINK_MODE_4_LANES; + break; + case 8: + plc |= PORT_LINK_MODE_8_LANES; + break; + default: + dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes); + return; + } + writel(plc, pci->dbi_base + PCIE_PORT_LINK_CONTROL); + writel(lwsc, pci->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + + cap = pcie_dw_find_capability(pci, PCI_CAP_ID_EXP); + lnkcap = readl(pci->dbi_base + cap + PCI_EXP_LNKCAP); + lnkcap &= ~PCI_EXP_LNKCAP_MLW; + lnkcap |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, num_lanes); + writel(lnkcap, pci->dbi_base + cap + PCI_EXP_LNKCAP); +} + static void dw_pcie_writel_ob_unroll(struct pcie_dw *pci, u32 index, u32 reg, u32 val) { diff --git a/drivers/pci/pcie_dw_common.h b/drivers/pci/pcie_dw_common.h index 8cb99a12ea1..5fa50f3dc3a 100644 --- a/drivers/pci/pcie_dw_common.h +++ b/drivers/pci/pcie_dw_common.h @@ -66,8 +66,12 @@ #define LINK_SPEED_GEN_1 0x1 #define LINK_SPEED_GEN_2 0x2 #define LINK_SPEED_GEN_3 0x3 +#define LINK_SPEED_GEN_4 0x4 /* Synopsys-specific PCIe configuration registers */ +#define PCIE_PORT_FORCE 0x708 +#define PORT_FORCE_DO_DESKEW_FOR_SRIS BIT(23) + #define PCIE_PORT_LINK_CONTROL 0x710 #define PORT_LINK_DLL_LINK_EN BIT(5) #define PORT_LINK_FAST_LINK_MODE BIT(7) @@ -78,6 +82,9 @@ #define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7) #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) +#define PCIE_PORT_LANE_SKEW 0x714 +#define PORT_LANE_SKEW_INSERT_MASK GENMASK(23, 0) + #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C #define PORT_LOGIC_N_FTS_MASK GENMASK(7, 0) #define PORT_LOGIC_SPEED_CHANGE BIT(17) @@ -130,6 +137,8 @@ int pcie_dw_get_link_speed(struct pcie_dw *pci); int pcie_dw_get_link_width(struct pcie_dw *pci); +void dw_pcie_link_set_max_link_width(struct pcie_dw *pci, u32 num_lanes); + int pcie_dw_prog_outbound_atu_unroll(struct pcie_dw *pci, int index, int type, u64 cpu_addr, u64 pci_addr, u32 size); diff --git a/drivers/pci/pcie_dw_meson.c b/drivers/pci/pcie_dw_meson.c index bb78e7874b1..483b07ce078 100644 --- a/drivers/pci/pcie_dw_meson.c +++ b/drivers/pci/pcie_dw_meson.c @@ -115,13 +115,9 @@ static void meson_pcie_configure(struct meson_pcie *priv) val &= ~PORT_LINK_FAST_LINK_MODE; val |= PORT_LINK_DLL_LINK_EN; val &= ~PORT_LINK_MODE_MASK; - val |= PORT_LINK_MODE_1_LANES; writel(val, priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL); - val = readl(priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); - val &= ~PORT_LOGIC_LINK_WIDTH_MASK; - val |= PORT_LOGIC_LINK_WIDTH_1_LANES; - writel(val, priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + dw_pcie_link_set_max_link_width(&priv->dw, 1); dw_pcie_dbi_write_enable(&priv->dw, false); } diff --git a/drivers/pci/pcie_dw_qcom.c b/drivers/pci/pcie_dw_qcom.c index 39b4cd4efe2..978754e8472 100644 --- a/drivers/pci/pcie_dw_qcom.c +++ b/drivers/pci/pcie_dw_qcom.c @@ -213,17 +213,6 @@ static void qcom_pcie_clear_hpc(struct qcom_pcie *priv) dw_pcie_dbi_write_enable(&priv->dw, false); } -static void qcom_pcie_set_lanes(struct qcom_pcie *priv, unsigned int lanes) -{ - u8 offset = pcie_dw_find_capability(&priv->dw, PCI_CAP_ID_EXP); - u32 val; - - val = readl(priv->dw.dbi_base + offset + PCI_EXP_LNKCAP); - val &= ~PCI_EXP_LNKCAP_MLW; - val |= FIELD_PREP(PCI_EXP_LNKCAP_MLW, lanes); - writel(val, priv->dw.dbi_base + offset + PCI_EXP_LNKCAP); -} - static int qcom_pcie_config_sid_1_9_0(struct qcom_pcie *priv) { /* iommu map structure */ @@ -299,15 +288,9 @@ static void qcom_pcie_configure(struct qcom_pcie *priv) val &= ~PORT_LINK_FAST_LINK_MODE; val |= PORT_LINK_DLL_LINK_EN; val &= ~PORT_LINK_MODE_MASK; - val |= PORT_LINK_MODE_2_LANES; writel(val, priv->dw.dbi_base + PCIE_PORT_LINK_CONTROL); - val = readl(priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); - val &= ~PORT_LOGIC_LINK_WIDTH_MASK; - val |= PORT_LOGIC_LINK_WIDTH_2_LANES; - writel(val, priv->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); - - qcom_pcie_set_lanes(priv, 2); + dw_pcie_link_set_max_link_width(&priv->dw, 2); dw_pcie_dbi_write_enable(&priv->dw, false); } diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c index ac7faa4cc19..208aa30463a 100644 --- a/drivers/pci/pcie_dw_rockchip.c +++ b/drivers/pci/pcie_dw_rockchip.c @@ -158,8 +158,6 @@ static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg, */ static void rk_pcie_configure(struct rk_pcie *pci) { - u32 val; - dw_pcie_dbi_write_enable(&pci->dw, true); /* Disable BAR 0 and BAR 1 */ @@ -175,43 +173,8 @@ static void rk_pcie_configure(struct rk_pcie *pci) TARGET_LINK_SPEED_MASK, pci->gen); /* Set the number of lanes */ - val = readl(pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL); - val &= ~PORT_LINK_FAST_LINK_MODE; - val |= PORT_LINK_DLL_LINK_EN; - val &= ~PORT_LINK_MODE_MASK; - switch (pci->num_lanes) { - case 1: - val |= PORT_LINK_MODE_1_LANES; - break; - case 2: - val |= PORT_LINK_MODE_2_LANES; - break; - case 4: - val |= PORT_LINK_MODE_4_LANES; - break; - default: - dev_err(pci->dw.dev, "num-lanes %u: invalid value\n", pci->num_lanes); - goto out; - } - writel(val, pci->dw.dbi_base + PCIE_PORT_LINK_CONTROL); - - /* Set link width speed control register */ - val = readl(pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); - val &= ~PORT_LOGIC_LINK_WIDTH_MASK; - switch (pci->num_lanes) { - case 1: - val |= PORT_LOGIC_LINK_WIDTH_1_LANES; - break; - case 2: - val |= PORT_LOGIC_LINK_WIDTH_2_LANES; - break; - case 4: - val |= PORT_LOGIC_LINK_WIDTH_4_LANES; - break; - } - writel(val, pci->dw.dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + dw_pcie_link_set_max_link_width(&pci->dw, pci->num_lanes); -out: dw_pcie_dbi_write_enable(&pci->dw, false); } diff --git a/drivers/pci_endpoint/Kconfig b/drivers/pci_endpoint/Kconfig index 19cfa0aafb5..9900481daa6 100644 --- a/drivers/pci_endpoint/Kconfig +++ b/drivers/pci_endpoint/Kconfig @@ -22,6 +22,12 @@ config PCIE_CADENCE_EP endpoint mode. This PCIe controller may be embedded into many different vendors SoCs. +config PCIE_CDNS_TI_EP + bool "TI K3 PCIe EP support" + help + Say Y here to enable support for the Canence PCIe Controller + in Endpoint Mode on TI's K3 Socs. + config PCI_SANDBOX_EP bool "Sandbox PCIe endpoint controller" depends on PCI_ENDPOINT diff --git a/drivers/pci_endpoint/Makefile b/drivers/pci_endpoint/Makefile index 3cd987259d3..62a865c4463 100644 --- a/drivers/pci_endpoint/Makefile +++ b/drivers/pci_endpoint/Makefile @@ -6,3 +6,4 @@ obj-y += pci_ep-uclass.o obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o obj-$(CONFIG_PCI_SANDBOX_EP) += sandbox-pci_ep.o +obj-$(CONFIG_PCIE_CDNS_TI_EP) += pcie_cdns_ti_ep.o diff --git a/drivers/pci_endpoint/pcie_cdns_ti_ep.c b/drivers/pci_endpoint/pcie_cdns_ti_ep.c new file mode 100644 index 00000000000..661b6ba5b55 --- /dev/null +++ b/drivers/pci_endpoint/pcie_cdns_ti_ep.c @@ -0,0 +1,396 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com + * + * PCIe Endpoint controller driver for TI's K3 SoCs with Cadence PCIe controller + * + * Ported from the Linux driver - drivers/pci/controller/cadence/pci-j721e.c + * + * Author: Hrushikesh Salunke <h-salunke@ti.com> + * + */ + +#include <clk.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <generic-phy.h> +#include <linux/log2.h> +#include <linux/sizes.h> +#include <power-domain.h> +#include <regmap.h> +#include <syscon.h> +#include <pci_ep.h> + +#include "pcie-cadence.h" + +#define PCIE_USER_CMD_STATUS_REG_OFFSET 0x4 +#define LINK_TRAINING_ENABLE BIT(0) + +#define PCIE_MODE_SEL_MASK BIT(7) +#define PCIE_GEN_SEL_MASK GENMASK(1, 0) +#define PCIE_LINK_WIDTH_MASK GENMASK(9, 8) + +struct pcie_cdns_ti_ep_data { + unsigned int quirk_retrain_flag:1; + unsigned int quirk_detect_quiet_flag:1; + unsigned int quirk_disable_flr:1; + unsigned int byte_access_allowed:1; + unsigned int max_lanes; +}; + +struct pcie_cdns_ti_ep { + struct udevice *dev; + void __iomem *intd_cfg_base; + void __iomem *user_cfg_base; + void __iomem *reg_base; + void __iomem *mem_base; + fdt_size_t cfg_size; + struct regmap *syscon_base; + u32 max_link_speed; + u32 num_lanes; + u32 pcie_ctrl_offset; + unsigned int quirk_retrain_flag:1; + unsigned int quirk_detect_quiet_flag:1; + unsigned int quirk_disable_flr:1; + unsigned int byte_access_allowed:1; +}; + +static inline u32 pcie_cdns_ti_ep_user_readl(struct pcie_cdns_ti_ep *pcie, u32 offset) +{ + return readl(pcie->user_cfg_base + offset); +} + +static inline void pcie_cdns_ti_ep_user_writel(struct pcie_cdns_ti_ep *pcie, u32 offset, + u32 val) +{ + writel(val, pcie->user_cfg_base + offset); +} + +static void pcie_cdns_ti_start_link(struct pcie_cdns_ti_ep *pcie) +{ + u32 reg; + + reg = pcie_cdns_ti_ep_user_readl(pcie, PCIE_USER_CMD_STATUS_REG_OFFSET); + reg |= LINK_TRAINING_ENABLE; + pcie_cdns_ti_ep_user_writel(pcie, PCIE_USER_CMD_STATUS_REG_OFFSET, reg); +} + +static int pcie_cdns_reset(struct udevice *dev, struct power_domain *pci_pwrdmn) +{ + int ret; + + ret = power_domain_off(pci_pwrdmn); + if (ret) { + dev_err(dev, "failed to power off\n"); + return ret; + } + + ret = power_domain_on(pci_pwrdmn); + if (ret) { + dev_err(dev, "failed to power on: %d\n", ret); + return ret; + } + + return 0; +} + +static int pcie_cdns_config_serdes(struct udevice *dev) +{ + if (CONFIG_IS_ENABLED(PHY_CADENCE_TORRENT)) { + struct phy serdes; + int ret = 7; + + ret = generic_phy_get_by_name(dev, "pcie-phy", &serdes); + if (ret != 0 && ret != -EBUSY) { + dev_err(dev, "unable to get serdes\n"); + return ret; + } + generic_phy_reset(&serdes); + generic_phy_init(&serdes); + generic_phy_power_on(&serdes); + } else { + dev_info(dev, "Proceeding with the assumption that the SERDES is already configured\n"); + } + return 0; +} + +static int pcie_cdns_ti_ctrl_init(struct pcie_cdns_ti_ep *pcie) +{ + struct regmap *syscon = pcie->syscon_base; + u32 val = 0; + + /* Set mode of operation */ + regmap_update_bits(syscon, pcie->pcie_ctrl_offset, PCIE_MODE_SEL_MASK, + val); + + /* Set link speed */ + regmap_update_bits(syscon, pcie->pcie_ctrl_offset, PCIE_GEN_SEL_MASK, + pcie->max_link_speed - 1); + + /* Set link width */ + regmap_update_bits(syscon, pcie->pcie_ctrl_offset, PCIE_LINK_WIDTH_MASK, + (pcie->num_lanes - 1) << 8); + return 0; +} + +static int pcie_cdns_ti_write_header(struct udevice *dev, uint fn, + struct pci_ep_header *hdr) +{ + struct pcie_cdns_ti_ep *pcie_ep = dev_get_priv(dev); + struct cdns_pcie pcie; + + pcie.reg_base = pcie_ep->reg_base; + + cdns_pcie_ep_fn_writew(&pcie, fn, PCI_DEVICE_ID, hdr->deviceid); + cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_REVISION_ID, hdr->revid); + cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_CLASS_PROG, + hdr->progif_code); + cdns_pcie_ep_fn_writew(&pcie, fn, PCI_CLASS_DEVICE, + hdr->subclass_code | + hdr->baseclass_code << 8); + cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_CACHE_LINE_SIZE, + hdr->cache_line_size); + cdns_pcie_ep_fn_writew(&pcie, fn, PCI_SUBSYSTEM_ID, + hdr->subsys_id); + cdns_pcie_ep_fn_writeb(&pcie, fn, PCI_INTERRUPT_PIN, + hdr->interrupt_pin); + + /* + * Vendor ID can only be modified from function 0, all other functions + * use the same vendor ID as function 0. + */ + if (fn == 0) { + /* Update the vendor IDs. */ + u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) | + CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id); + + cdns_pcie_writel(&pcie, CDNS_PCIE_LM_ID, id); + } + + return 0; +} + +static int pcie_cdns_ti_set_bar(struct udevice *dev, uint fn, + struct pci_bar *ep_bar) +{ + struct pcie_cdns_ti_ep *pcie_ep = dev_get_priv(dev); + struct cdns_pcie pcie; + dma_addr_t bar_phys = ep_bar->phys_addr; + enum pci_barno bar = ep_bar->barno; + int flags = ep_bar->flags; + u32 addr0, addr1, reg, cfg, b, aperture, ctrl; + u64 sz; + + pcie.reg_base = pcie_ep->reg_base; + + /* BAR size is 2^(aperture + 7) */ + sz = max_t(size_t, ep_bar->size, CDNS_PCIE_EP_MIN_APERTURE); + /* + * roundup_pow_of_two() returns an unsigned long, which is not suited + * for 64bit values. + */ + sz = 1ULL << fls64(sz - 1); + aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */ + + if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { + ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS; + } else { + bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH); + bool is_64bits = (sz > SZ_2G) | + !!(ep_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64); + + if (is_64bits && (bar & 1)) + return -EINVAL; + + if (is_64bits && !(flags & PCI_BASE_ADDRESS_MEM_TYPE_64)) + ep_bar->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; + + if (is_64bits && is_prefetch) + ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS; + else if (is_prefetch) + ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS; + else if (is_64bits) + ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS; + else + ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS; + } + + addr0 = lower_32_bits(bar_phys); + addr1 = upper_32_bits(bar_phys); + cdns_pcie_writel(&pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), + addr0); + cdns_pcie_writel(&pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), + addr1); + + /* + * Cadence PCIe controller provides a register interface to configure + * BAR of an Endpoint function. Per function there are two BAR configuration + * registers, out of which first is used to configure BAR_0 to BAR_4 and + * second is used to configure the remaining BARs. + */ + if (bar < BAR_4) { + reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn); + b = bar; + } else { + reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn); + b = bar - BAR_4; + } + + cfg = cdns_pcie_readl(&pcie, reg); + + cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) | + CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b)); + cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) | + CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl)); + cdns_pcie_writel(&pcie, reg, cfg); + + cfg = cdns_pcie_readl(&pcie, reg); + + return 0; +} + +static int pcie_cdns_ti_start(struct udevice *dev) +{ + struct pcie_cdns_ti_ep *pcie = dev_get_priv(dev); + + pcie_cdns_ti_start_link(pcie); + + return 0; +} + +static int pcie_cdns_ti_ep_probe(struct udevice *dev) +{ + struct pcie_cdns_ti_ep *pcie = dev_get_priv(dev); + struct pcie_cdns_ti_ep_data *data; + struct power_domain pci_pwrdmn; + struct clk *clk; + int ret; + + pcie->dev = dev; + data = (struct pcie_cdns_ti_ep_data *)dev_get_driver_data(dev); + if (!data) + return -EINVAL; + + pcie->quirk_retrain_flag = data->quirk_retrain_flag; + pcie->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag; + pcie->quirk_disable_flr = data->quirk_disable_flr; + + if (pcie->num_lanes > data->max_lanes) { + dev_warn(dev, "cannot support %d lanes, defaulting to %d\n", + pcie->num_lanes, data->max_lanes); + pcie->num_lanes = data->max_lanes; + } + + ret = power_domain_get_by_index(dev, &pci_pwrdmn, 0); + if (ret) { + dev_err(dev, "failed to get power domain: %d\n", ret); + return ret; + } + + /* + * Reset the PCIe controller so that newly configured BAR + * values are reflected. + */ + ret = pcie_cdns_reset(dev, &pci_pwrdmn); + if (ret) { + dev_err(dev, "failed to reset controller: %d\n", ret); + return ret; + } + + clk = devm_clk_get(dev, "fck"); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(dev, "failed to get functional clock\n"); + return ret; + } + + ret = pcie_cdns_config_serdes(dev); + if (ret) { + dev_err(dev, "failed to configure serdes: %d\n", ret); + return ret; + } + + ret = pcie_cdns_ti_ctrl_init(pcie); + if (ret) { + dev_err(dev, "failed to initialize controller: %d\n", ret); + return ret; + } + + return 0; +} + +static int pcie_cdns_ti_ep_of_to_plat(struct udevice *dev) +{ + struct pcie_cdns_ti_ep *pcie = dev_get_priv(dev); + struct regmap *syscon; + u32 offset; + int ret; + + pcie->intd_cfg_base = dev_remap_addr_name(dev, "intd_cfg"); + if (!pcie->intd_cfg_base) + return -EINVAL; + + pcie->user_cfg_base = dev_remap_addr_name(dev, "user_cfg"); + if (!pcie->user_cfg_base) + return -EINVAL; + + pcie->reg_base = dev_remap_addr_name(dev, "reg"); + if (!pcie->reg_base) + return -EINVAL; + + pcie->mem_base = dev_remap_addr_name(dev, "mem"); + if (!pcie->mem_base) + return -EINVAL; + + ret = dev_read_u32(dev, "num-lanes", &pcie->num_lanes); + if (ret) + return ret; + + ret = dev_read_u32(dev, "max-link-speed", &pcie->max_link_speed); + if (ret) + return ret; + + syscon = syscon_regmap_lookup_by_phandle(dev, "ti,syscon-pcie-ctrl"); + if (IS_ERR(syscon)) { + if (PTR_ERR(syscon) == -ENODEV) + return 0; + return PTR_ERR(syscon); + } + + ret = dev_read_u32_index(dev, "ti,syscon-pcie-ctrl", 1, &offset); + if (ret) + return ret; + + pcie->syscon_base = syscon; + pcie->pcie_ctrl_offset = offset; + + return 0; +} + +static const struct pci_ep_ops pcie_cdns_ti_ep_ops = { + .write_header = pcie_cdns_ti_write_header, + .set_bar = pcie_cdns_ti_set_bar, + .start = pcie_cdns_ti_start, +}; + +static const struct pcie_cdns_ti_ep_data am64_pcie_ep_data = { + .max_lanes = 1, +}; + +static const struct udevice_id pcie_cdns_ti_ep_ids[] = { + { + .compatible = "ti,am64-pcie-ep", + .data = (ulong)&am64_pcie_ep_data, + }, + {}, +}; + +U_BOOT_DRIVER(pcie_cdns_ti_ep) = { + .name = "pcie_cdns_ti_ep", + .id = UCLASS_PCI_EP, + .of_match = pcie_cdns_ti_ep_ids, + .ops = &pcie_cdns_ti_ep_ops, + .of_to_plat = pcie_cdns_ti_ep_of_to_plat, + .probe = pcie_cdns_ti_ep_probe, + .priv_auto = sizeof(struct pcie_cdns_ti_ep), +}; diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index d4e8ece4935..1f566d082f9 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -240,6 +240,7 @@ struct cdns_torrent_inst { struct cdns_torrent_phy { void __iomem *sd_base; /* SD0801 register base */ + u32 protocol_bitmask; size_t size; struct reset_control *phy_rst; struct udevice *dev; @@ -432,124 +433,155 @@ static int cdns_torrent_phy_configure_multilink(struct cdns_torrent_phy *cdns_ph struct cdns_reg_pairs *reg_pairs; enum cdns_torrent_ssc_mode ssc; struct regmap *regmap; - u32 num_regs; + u32 num_regs, num_protocols, protocol; + + num_protocols = hweight32(cdns_phy->protocol_bitmask); - /* Maximum 2 links (subnodes) are supported */ - if (cdns_phy->nsubnodes != 2) + /* Maximum 2 protocols are supported */ + if (num_protocols > 2) { + dev_err(cdns_phy->dev, "at most 2 protocols are supported\n"); return -EINVAL; + } - phy_t1 = cdns_phy->phys[0].phy_type; - phy_t2 = cdns_phy->phys[1].phy_type; + if (cdns_phy->nsubnodes == 2) { + phy_t1 = cdns_phy->phys[0].phy_type; + phy_t2 = cdns_phy->phys[1].phy_type; + } else { + if (num_protocols != 2) { + dev_err(cdns_phy->dev, "incorrect representation of link\n"); + return -EINVAL; + } + phy_t1 = __ffs(cdns_phy->protocol_bitmask); + phy_t2 = __fls(cdns_phy->protocol_bitmask); + } - /* - * First configure the PHY for first link with phy_t1. Geth the array - * values are [phy_t1][phy_t2][ssc]. + /** + * Configure all links with the protocol phy_t1 first followed by + * configuring all links with the protocol phy_t2. + * + * When phy_t1 = phy_t2, it is a single protocol and configuration + * is performed with a single iteration of the protocol and multiple + * iterations over the sub-nodes (links). + * + * When phy_t1 != phy_t2, there are two protocols and configuration + * is performed by iterating over all sub-nodes matching the first + * protocol and configuring them first, followed by iterating over + * all sub-nodes matching the second protocol and configuring them + * next. */ - for (node = 0; node < cdns_phy->nsubnodes; node++) { - if (node == 1) { - /* - * If fist link with phy_t1 is configured, then - * configure the PHY for second link with phy_t2. - * Get the array values as [phy_t2][phy_t1][ssc] - */ + + for (protocol = 0; protocol < num_protocols; protocol++) { + /** + * For the case where num_protocols is 1, + * phy_t1 = phy_t2 and the swap is unnecessary. + * + * Swapping phy_t1 and phy_t2 is only required when the + * number of protocols is 2 and there are 2 or more links. + */ + if (protocol == 1) { tmp_phy_type = phy_t1; phy_t1 = phy_t2; phy_t2 = tmp_phy_type; } - mlane = cdns_phy->phys[node].mlane; - ssc = cdns_phy->phys[node].ssc_mode; - num_lanes = cdns_phy->phys[node].num_lanes; + for (node = 0; node < cdns_phy->nsubnodes; node++) { + if (cdns_phy->phys[node].phy_type != phy_t1) + continue; - /** - * PHY configuration specific registers: - * link_cmn_vals depend on combination of PHY types being - * configured and are common for both PHY types, so array - * values should be same for [phy_t1][phy_t2][ssc] and - * [phy_t2][phy_t1][ssc]. - * xcvr_diag_vals also depend on combination of PHY types - * being configured, but these can be different for particular - * PHY type and are per lane. - */ - link_cmn_vals = init_data->link_cmn_vals[phy_t1][phy_t2][ssc]; - if (link_cmn_vals) { - reg_pairs = link_cmn_vals->reg_pairs; - num_regs = link_cmn_vals->num_regs; - regmap = cdns_phy->regmap_common_cdb; + mlane = cdns_phy->phys[node].mlane; + ssc = cdns_phy->phys[node].ssc_mode; + num_lanes = cdns_phy->phys[node].num_lanes; /** - * First array value in link_cmn_vals must be of - * PHY_PLL_CFG register + * PHY configuration specific registers: + * link_cmn_vals depend on combination of PHY types being + * configured and are common for both PHY types, so array + * values should be same for [phy_t1][phy_t2][ssc] and + * [phy_t2][phy_t1][ssc]. + * xcvr_diag_vals also depend on combination of PHY types + * being configured, but these can be different for particular + * PHY type and are per lane. */ - regmap_field_write(cdns_phy->phy_pll_cfg, - reg_pairs[0].val); - - for (i = 1; i < num_regs; i++) - regmap_write(regmap, reg_pairs[i].off, - reg_pairs[i].val); - } + link_cmn_vals = init_data->link_cmn_vals[phy_t1][phy_t2][ssc]; + if (link_cmn_vals) { + reg_pairs = link_cmn_vals->reg_pairs; + num_regs = link_cmn_vals->num_regs; + regmap = cdns_phy->regmap_common_cdb; + + /** + * First array value in link_cmn_vals must be of + * PHY_PLL_CFG register + */ + regmap_field_write(cdns_phy->phy_pll_cfg, + reg_pairs[0].val); + + for (i = 1; i < num_regs; i++) + regmap_write(regmap, reg_pairs[i].off, + reg_pairs[i].val); + } - xcvr_diag_vals = init_data->xcvr_diag_vals[phy_t1][phy_t2][ssc]; - if (xcvr_diag_vals) { - reg_pairs = xcvr_diag_vals->reg_pairs; - num_regs = xcvr_diag_vals->num_regs; - for (i = 0; i < num_lanes; i++) { - regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane]; - for (j = 0; j < num_regs; j++) - regmap_write(regmap, reg_pairs[j].off, - reg_pairs[j].val); + xcvr_diag_vals = init_data->xcvr_diag_vals[phy_t1][phy_t2][ssc]; + if (xcvr_diag_vals) { + reg_pairs = xcvr_diag_vals->reg_pairs; + num_regs = xcvr_diag_vals->num_regs; + for (i = 0; i < num_lanes; i++) { + regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane]; + for (j = 0; j < num_regs; j++) + regmap_write(regmap, reg_pairs[j].off, + reg_pairs[j].val); + } } - } - /* PHY PCS common registers configurations */ - pcs_cmn_vals = init_data->pcs_cmn_vals[phy_t1][phy_t2][ssc]; - if (pcs_cmn_vals) { - reg_pairs = pcs_cmn_vals->reg_pairs; - num_regs = pcs_cmn_vals->num_regs; - regmap = cdns_phy->regmap_phy_pcs_common_cdb; - for (i = 0; i < num_regs; i++) - regmap_write(regmap, reg_pairs[i].off, - reg_pairs[i].val); - } + /* PHY PCS common registers configurations */ + pcs_cmn_vals = init_data->pcs_cmn_vals[phy_t1][phy_t2][ssc]; + if (pcs_cmn_vals) { + reg_pairs = pcs_cmn_vals->reg_pairs; + num_regs = pcs_cmn_vals->num_regs; + regmap = cdns_phy->regmap_phy_pcs_common_cdb; + for (i = 0; i < num_regs; i++) + regmap_write(regmap, reg_pairs[i].off, + reg_pairs[i].val); + } - /* PMA common registers configurations */ - cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc]; - if (cmn_vals) { - reg_pairs = cmn_vals->reg_pairs; - num_regs = cmn_vals->num_regs; - regmap = cdns_phy->regmap_common_cdb; - for (i = 0; i < num_regs; i++) - regmap_write(regmap, reg_pairs[i].off, - reg_pairs[i].val); - } + /* PMA common registers configurations */ + cmn_vals = init_data->cmn_vals[phy_t1][phy_t2][ssc]; + if (cmn_vals) { + reg_pairs = cmn_vals->reg_pairs; + num_regs = cmn_vals->num_regs; + regmap = cdns_phy->regmap_common_cdb; + for (i = 0; i < num_regs; i++) + regmap_write(regmap, reg_pairs[i].off, + reg_pairs[i].val); + } - /* PMA TX lane registers configurations */ - tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc]; - if (tx_ln_vals) { - reg_pairs = tx_ln_vals->reg_pairs; - num_regs = tx_ln_vals->num_regs; - for (i = 0; i < num_lanes; i++) { - regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane]; - for (j = 0; j < num_regs; j++) - regmap_write(regmap, reg_pairs[j].off, - reg_pairs[j].val); + /* PMA TX lane registers configurations */ + tx_ln_vals = init_data->tx_ln_vals[phy_t1][phy_t2][ssc]; + if (tx_ln_vals) { + reg_pairs = tx_ln_vals->reg_pairs; + num_regs = tx_ln_vals->num_regs; + for (i = 0; i < num_lanes; i++) { + regmap = cdns_phy->regmap_tx_lane_cdb[i + mlane]; + for (j = 0; j < num_regs; j++) + regmap_write(regmap, reg_pairs[j].off, + reg_pairs[j].val); + } } - } - /* PMA RX lane registers configurations */ - rx_ln_vals = init_data->rx_ln_vals[phy_t1][phy_t2][ssc]; - if (rx_ln_vals) { - reg_pairs = rx_ln_vals->reg_pairs; - num_regs = rx_ln_vals->num_regs; - for (i = 0; i < num_lanes; i++) { - regmap = cdns_phy->regmap_rx_lane_cdb[i + mlane]; - for (j = 0; j < num_regs; j++) - regmap_write(regmap, reg_pairs[j].off, - reg_pairs[j].val); + /* PMA RX lane registers configurations */ + rx_ln_vals = init_data->rx_ln_vals[phy_t1][phy_t2][ssc]; + if (rx_ln_vals) { + reg_pairs = rx_ln_vals->reg_pairs; + num_regs = rx_ln_vals->num_regs; + for (i = 0; i < num_lanes; i++) { + regmap = cdns_phy->regmap_rx_lane_cdb[i + mlane]; + for (j = 0; j < num_regs; j++) + regmap_write(regmap, reg_pairs[j].off, + reg_pairs[j].val); + } } - } - reset_deassert_bulk(cdns_phy->phys[node].lnk_rst); + reset_deassert_bulk(cdns_phy->phys[node].lnk_rst); + } } /* Take the PHY out of reset */ @@ -575,6 +607,7 @@ static int cdns_torrent_phy_probe(struct udevice *dev) /* Get init data for this phy */ data = (struct cdns_torrent_data *)dev_get_driver_data(dev); cdns_phy->init_data = data; + cdns_phy->protocol_bitmask = 0; cdns_phy->phy_rst = devm_reset_control_get_by_index(dev, 0); if (IS_ERR(cdns_phy->phy_rst)) { @@ -677,6 +710,8 @@ static int cdns_torrent_phy_probe(struct udevice *dev) /* Get SSC mode */ ofnode_read_u32(child, "cdns,ssc-mode", &cdns_phy->phys[node].ssc_mode); + + cdns_phy->protocol_bitmask |= BIT(cdns_phy->phys[node].phy_type); node++; } diff --git a/drivers/phy/qcom/phy-qcom-qmp-ufs.c b/drivers/phy/qcom/phy-qcom-qmp-ufs.c index 449b9767778..f3c606847fb 100644 --- a/drivers/phy/qcom/phy-qcom-qmp-ufs.c +++ b/drivers/phy/qcom/phy-qcom-qmp-ufs.c @@ -86,6 +86,12 @@ enum qphy_reg_layout { QPHY_LAYOUT_SIZE }; +static const unsigned int ufsphy_v2_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_START_CTRL] = QPHY_V2_PCS_UFS_PHY_START, + [QPHY_PCS_READY_STATUS] = QPHY_V2_PCS_UFS_READY_STATUS, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V2_PCS_UFS_POWER_DOWN_CONTROL, +}; + static const unsigned int ufsphy_v3_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_START_CTRL] = QPHY_V3_PCS_UFS_PHY_START, [QPHY_PCS_READY_STATUS] = QPHY_V3_PCS_UFS_READY_STATUS, @@ -715,6 +721,98 @@ static const struct qmp_ufs_init_tbl sc7280_ufsphy_hs_g4_rx[] = { QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL, 0x0f), }; +static const struct qmp_ufs_init_tbl sm6115_ufsphy_serdes[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14), + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), + QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04), + QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00), +}; + +static const struct qmp_ufs_init_tbl sm6115_ufsphy_hs_b_serdes[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44), +}; + +static const struct qmp_ufs_init_tbl sm6115_ufsphy_tx[] = { + QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45), + QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06), +}; + +static const struct qmp_ufs_init_tbl sm6115_ufsphy_rx[] = { + QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24), + QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40), + QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b), + QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04), + QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04), + QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5b), +}; + +static const struct qmp_ufs_init_tbl sm6115_ufsphy_pcs[] = { + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_PWM_GEAR_BAND, 0x15), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SIGDET_CTRL2, 0x6d), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_LARGE_AMP_POST_EMP_LVL, 0x12), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V2_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */ +}; + struct qmp_ufs_offsets { u16 serdes; u16 pcs; @@ -1079,6 +1177,34 @@ static const struct qmp_ufs_cfg sa8775p_ufsphy_cfg = { .regs = ufsphy_v5_regs_layout, }; +static const struct qmp_ufs_cfg sm6115_ufsphy_cfg = { + .lanes = 1, + + .offsets = &qmp_ufs_offsets, + + .tbls = { + .serdes = sm6115_ufsphy_serdes, + .serdes_num = ARRAY_SIZE(sm6115_ufsphy_serdes), + .tx = sm6115_ufsphy_tx, + .tx_num = ARRAY_SIZE(sm6115_ufsphy_tx), + .rx = sm6115_ufsphy_rx, + .rx_num = ARRAY_SIZE(sm6115_ufsphy_rx), + .pcs = sm6115_ufsphy_pcs, + .pcs_num = ARRAY_SIZE(sm6115_ufsphy_pcs), + }, + .tbls_hs_b = { + .serdes = sm6115_ufsphy_hs_b_serdes, + .serdes_num = ARRAY_SIZE(sm6115_ufsphy_hs_b_serdes), + }, + .clk_list = sdm845_ufs_phy_clk_l, + .num_clks = ARRAY_SIZE(sdm845_ufs_phy_clk_l), + .vreg_list = qmp_ufs_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_ufs_vreg_l), + .regs = ufsphy_v2_regs_layout, + + .no_pcs_sw_reset = true, +}; + static void qmp_ufs_configure_lane(void __iomem *base, const struct qmp_ufs_init_tbl tbl[], int num, @@ -1469,9 +1595,11 @@ static const struct udevice_id qmp_ufs_ids[] = { { .compatible = "qcom,sdm845-qmp-ufs-phy", .data = (ulong)&sdm845_ufsphy_cfg }, { .compatible = "qcom,sm8150-qmp-ufs-phy", .data = (ulong)&sm8150_ufsphy_cfg }, { .compatible = "qcom,sm8250-qmp-ufs-phy", .data = (ulong)&sm8250_ufsphy_cfg }, + { .compatible = "qcom,qcs8300-qmp-ufs-phy", .data = (ulong)&sa8775p_ufsphy_cfg }, { .compatible = "qcom,sm8550-qmp-ufs-phy", .data = (ulong)&sm8550_ufsphy_cfg }, { .compatible = "qcom,sm8650-qmp-ufs-phy", .data = (ulong)&sm8650_ufsphy_cfg }, { .compatible = "qcom,sc7280-qmp-ufs-phy", .data = (ulong)&sc7280_ufsphy_cfg, }, + { .compatible = "qcom,qcs615-qmp-ufs-phy", .data = (ulong)&sm6115_ufsphy_cfg, }, { } }; diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 8d47fa0cfd5..5e2808abc8a 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -341,6 +341,14 @@ config SPL_PINCTRL_STMFX This option is an SPL-variant of the SPL_PINCTRL_STMFX option. See the help of PINCTRL_STMFX for details. +config PINCTRL_TH1520 + bool "T-Head TH1520 pinctrl driver" + depends on DM && PINCTRL_FULL + select PINCONF + help + Support pin multiplexing and configuration control blocks on the + T-Head TH1520 SoC. + config ASPEED_AST2500_PINCTRL bool "Aspeed AST2500 pin control driver" depends on DM && PINCTRL_GENERIC && ASPEED_AST2500 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index fc9c604c485..33ff7b95ef2 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o obj-$(CONFIG_$(PHASE_)PINCTRL_SX150X) += pinctrl-sx150x.o obj-$(CONFIG_$(PHASE_)PINCTRL_STMFX) += pinctrl-stmfx.o +obj-$(CONFIG_PINCTRL_TH1520) += pinctrl-th1520.o obj-y += broadcom/ obj-$(CONFIG_PINCTRL_ZYNQMP) += pinctrl-zynqmp.o obj-$(CONFIG_PINCTRL_STARFIVE) += starfive/ diff --git a/drivers/pinctrl/nxp/pinctrl-imx-mmio.c b/drivers/pinctrl/nxp/pinctrl-imx-mmio.c index 6ee108a0120..2f4228a9fc5 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx-mmio.c +++ b/drivers/pinctrl/nxp/pinctrl-imx-mmio.c @@ -187,7 +187,6 @@ int imx_pinctrl_probe_mmio(struct udevice *dev) return -ENOMEM; priv->info = info; - info->mux_mask = ofnode_read_u32_default(node, "fsl,mux_mask", 0); /* * Refer to linux documentation for details: * Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt diff --git a/drivers/pinctrl/nxp/pinctrl-imx8ulp.c b/drivers/pinctrl/nxp/pinctrl-imx8ulp.c index 2df63625191..3e8c080d3fd 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx8ulp.c +++ b/drivers/pinctrl/nxp/pinctrl-imx8ulp.c @@ -11,10 +11,12 @@ static struct imx_pinctrl_soc_info imx8ulp_pinctrl_soc_info0 = { .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG | CFG_IBE_OBE, + .mux_mask = 0xf00, }; static struct imx_pinctrl_soc_info imx8ulp_pinctrl_soc_info1 = { .flags = ZERO_OFFSET_VALID | SHARE_MUX_CONF_REG | CFG_IBE_OBE, + .mux_mask = 0xf00, }; static const struct udevice_id imx8ulp_pinctrl_match[] = { diff --git a/drivers/pinctrl/nxp/pinctrl-imxrt.c b/drivers/pinctrl/nxp/pinctrl-imxrt.c index 39000ceb923..7e55d596248 100644 --- a/drivers/pinctrl/nxp/pinctrl-imxrt.c +++ b/drivers/pinctrl/nxp/pinctrl-imxrt.c @@ -11,6 +11,7 @@ static struct imx_pinctrl_soc_info imxrt_pinctrl_soc_info = { .flags = ZERO_OFFSET_VALID, + .mux_mask = 0x7, }; static const struct udevice_id imxrt_pinctrl_match[] = { diff --git a/drivers/pinctrl/nxp/pinctrl-vf610.c b/drivers/pinctrl/nxp/pinctrl-vf610.c index cbff8dcefd8..7d1b95eaa05 100644 --- a/drivers/pinctrl/nxp/pinctrl-vf610.c +++ b/drivers/pinctrl/nxp/pinctrl-vf610.c @@ -11,6 +11,7 @@ static struct imx_pinctrl_soc_info vf610_pinctrl_soc_info = { .flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID, + .mux_mask = 0x700000, }; static const struct udevice_id vf610_pinctrl_match[] = { diff --git a/drivers/pinctrl/pinctrl-th1520.c b/drivers/pinctrl/pinctrl-th1520.c new file mode 100644 index 00000000000..be7e508f8a4 --- /dev/null +++ b/drivers/pinctrl/pinctrl-th1520.c @@ -0,0 +1,700 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Pinctrl driver for the T-Head TH1520 SoC + * + * Copyright (C) 2023 Emil Renner Berthing <emil.renner.berthing@canonical.com> + * Copyright (C) 2025 Yao Zi <ziyao@disroot.org> + */ + +#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <linux/bitops.h> +#include <linux/string.h> +#include <malloc.h> + +#define TH1520_PADCFG_IE BIT(9) +#define TH1520_PADCFG_SL BIT(8) +#define TH1520_PADCFG_ST BIT(7) +#define TH1520_PADCFG_SPU BIT(6) +#define TH1520_PADCFG_PS BIT(5) +#define TH1520_PADCFG_PE BIT(4) +#define TH1520_PADCFG_BIAS (TH1520_PADCFG_SPU | TH1520_PADCFG_PS | TH1520_PADCFG_PE) +#define TH1520_PADCFG_DS GENMASK(3, 0) + +#define TH1520_PULL_DOWN_OHM 44000 /* typ. 44kOhm */ +#define TH1520_PULL_UP_OHM 48000 /* typ. 48kOhm */ +#define TH1520_PULL_STRONG_OHM 2100 /* typ. 2.1kOhm */ + +#define TH1520_PAD_NO_PADCFG BIT(0) + +enum th1520_muxtype { + TH1520_MUX_____, + TH1520_MUX_GPIO, + TH1520_MUX_PWM, + TH1520_MUX_UART, + TH1520_MUX_IR, + TH1520_MUX_I2C, + TH1520_MUX_SPI, + TH1520_MUX_QSPI, + TH1520_MUX_SDIO, + TH1520_MUX_AUD, + TH1520_MUX_I2S, + TH1520_MUX_MAC0, + TH1520_MUX_MAC1, + TH1520_MUX_DPU0, + TH1520_MUX_DPU1, + TH1520_MUX_ISP, + TH1520_MUX_HDMI, + TH1520_MUX_BSEL, + TH1520_MUX_DBG, + TH1520_MUX_CLK, + TH1520_MUX_JTAG, + TH1520_MUX_ISO, + TH1520_MUX_FUSE, + TH1520_MUX_RST, +}; + +static const char *const th1520_muxtype_string[] = { + [TH1520_MUX_GPIO] = "gpio", + [TH1520_MUX_PWM] = "pwm", + [TH1520_MUX_UART] = "uart", + [TH1520_MUX_IR] = "ir", + [TH1520_MUX_I2C] = "i2c", + [TH1520_MUX_SPI] = "spi", + [TH1520_MUX_QSPI] = "qspi", + [TH1520_MUX_SDIO] = "sdio", + [TH1520_MUX_AUD] = "audio", + [TH1520_MUX_I2S] = "i2s", + [TH1520_MUX_MAC0] = "gmac0", + [TH1520_MUX_MAC1] = "gmac1", + [TH1520_MUX_DPU0] = "dpu0", + [TH1520_MUX_DPU1] = "dpu1", + [TH1520_MUX_ISP] = "isp", + [TH1520_MUX_HDMI] = "hdmi", + [TH1520_MUX_BSEL] = "bootsel", + [TH1520_MUX_DBG] = "debug", + [TH1520_MUX_CLK] = "clock", + [TH1520_MUX_JTAG] = "jtag", + [TH1520_MUX_ISO] = "iso7816", + [TH1520_MUX_FUSE] = "efuse", + [TH1520_MUX_RST] = "reset", +}; + +struct th1520_pin_desc { + unsigned int number; + const char *name; + enum th1520_muxtype muxes[6]; + u8 flags; +}; + +struct th1520_pad_group { + unsigned int npins; + const struct th1520_pin_desc *pins; + const char *name; +}; + +struct th1520_pinctrl { + const struct th1520_pad_group *group; + void __iomem *base; + struct pinctrl_dev *pctl; +}; + +static enum th1520_muxtype th1520_muxtype_get(const char *str) +{ + enum th1520_muxtype mt; + + for (mt = TH1520_MUX_GPIO; mt < ARRAY_SIZE(th1520_muxtype_string); mt++) { + if (!strcmp(str, th1520_muxtype_string[mt])) + return mt; + } + return TH1520_MUX_____; +} + +#define TH1520_PAD(_nr, _name, m0, m1, m2, m3, m4, m5, _flags) \ + { \ + .number = _nr, \ + .name = #_name, \ + .muxes = { \ + TH1520_MUX_##m0, TH1520_MUX_##m1, \ + TH1520_MUX_##m2, TH1520_MUX_##m3, \ + TH1520_MUX_##m4, TH1520_MUX_##m5 \ + }, \ + .flags = _flags, \ + } + +static bool th1520_pad_no_padcfg(const struct th1520_pin_desc *pin) +{ + return pin->flags & TH1520_PAD_NO_PADCFG; +} + +static const struct th1520_pin_desc th1520_group1_pins[] = { + TH1520_PAD(0, OSC_CLK_IN, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), + TH1520_PAD(1, OSC_CLK_OUT, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), + TH1520_PAD(2, SYS_RST_N, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), + TH1520_PAD(3, RTC_CLK_IN, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), + TH1520_PAD(4, RTC_CLK_OUT, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), + /* skip number 5 so we can calculate register offsets and shifts from the pin number */ + TH1520_PAD(6, TEST_MODE, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), + TH1520_PAD(7, DEBUG_MODE, DBG, ____, ____, GPIO, ____, ____, TH1520_PAD_NO_PADCFG), + TH1520_PAD(8, POR_SEL, ____, ____, ____, ____, ____, ____, TH1520_PAD_NO_PADCFG), + TH1520_PAD(9, I2C_AON_SCL, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(10, I2C_AON_SDA, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(11, CPU_JTG_TCLK, JTAG, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(12, CPU_JTG_TMS, JTAG, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(13, CPU_JTG_TDI, JTAG, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(14, CPU_JTG_TDO, JTAG, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(15, CPU_JTG_TRST, JTAG, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(16, AOGPIO_7, CLK, AUD, ____, GPIO, ____, ____, 0), + TH1520_PAD(17, AOGPIO_8, UART, AUD, IR, GPIO, ____, ____, 0), + TH1520_PAD(18, AOGPIO_9, UART, AUD, IR, GPIO, ____, ____, 0), + TH1520_PAD(19, AOGPIO_10, CLK, AUD, ____, GPIO, ____, ____, 0), + TH1520_PAD(20, AOGPIO_11, GPIO, AUD, ____, ____, ____, ____, 0), + TH1520_PAD(21, AOGPIO_12, GPIO, AUD, ____, ____, ____, ____, 0), + TH1520_PAD(22, AOGPIO_13, GPIO, AUD, ____, ____, ____, ____, 0), + TH1520_PAD(23, AOGPIO_14, GPIO, AUD, ____, ____, ____, ____, 0), + TH1520_PAD(24, AOGPIO_15, GPIO, AUD, ____, ____, ____, ____, 0), + TH1520_PAD(25, AUDIO_PA0, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(26, AUDIO_PA1, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(27, AUDIO_PA2, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(28, AUDIO_PA3, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(29, AUDIO_PA4, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(30, AUDIO_PA5, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(31, AUDIO_PA6, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(32, AUDIO_PA7, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(33, AUDIO_PA8, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(34, AUDIO_PA9, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(35, AUDIO_PA10, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(36, AUDIO_PA11, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(37, AUDIO_PA12, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(38, AUDIO_PA13, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(39, AUDIO_PA14, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(40, AUDIO_PA15, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(41, AUDIO_PA16, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(42, AUDIO_PA17, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(43, AUDIO_PA27, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(44, AUDIO_PA28, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(45, AUDIO_PA29, AUD, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(46, AUDIO_PA30, AUD, RST, ____, GPIO, ____, ____, 0), +}; + +static const struct th1520_pin_desc th1520_group2_pins[] = { + TH1520_PAD(0, QSPI1_SCLK, QSPI, ISO, ____, GPIO, FUSE, ____, 0), + TH1520_PAD(1, QSPI1_CSN0, QSPI, ____, I2C, GPIO, FUSE, ____, 0), + TH1520_PAD(2, QSPI1_D0_MOSI, QSPI, ISO, I2C, GPIO, FUSE, ____, 0), + TH1520_PAD(3, QSPI1_D1_MISO, QSPI, ISO, ____, GPIO, FUSE, ____, 0), + TH1520_PAD(4, QSPI1_D2_WP, QSPI, ISO, UART, GPIO, FUSE, ____, 0), + TH1520_PAD(5, QSPI1_D3_HOLD, QSPI, ISO, UART, GPIO, ____, ____, 0), + TH1520_PAD(6, I2C0_SCL, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(7, I2C0_SDA, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(8, I2C1_SCL, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(9, I2C1_SDA, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(10, UART1_TXD, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(11, UART1_RXD, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(12, UART4_TXD, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(13, UART4_RXD, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(14, UART4_CTSN, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(15, UART4_RTSN, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(16, UART3_TXD, DBG, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(17, UART3_RXD, DBG, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(18, GPIO0_18, GPIO, I2C, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(19, GPIO0_19, GPIO, I2C, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(20, GPIO0_20, GPIO, UART, IR, ____, DPU0, DPU1, 0), + TH1520_PAD(21, GPIO0_21, GPIO, UART, IR, ____, DPU0, DPU1, 0), + TH1520_PAD(22, GPIO0_22, GPIO, JTAG, I2C, ____, DPU0, DPU1, 0), + TH1520_PAD(23, GPIO0_23, GPIO, JTAG, I2C, ____, DPU0, DPU1, 0), + TH1520_PAD(24, GPIO0_24, GPIO, JTAG, QSPI, ____, DPU0, DPU1, 0), + TH1520_PAD(25, GPIO0_25, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(26, GPIO0_26, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(27, GPIO0_27, GPIO, ____, I2C, ____, DPU0, DPU1, 0), + TH1520_PAD(28, GPIO0_28, GPIO, ____, I2C, ____, DPU0, DPU1, 0), + TH1520_PAD(29, GPIO0_29, GPIO, ____, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(30, GPIO0_30, GPIO, ____, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(31, GPIO0_31, GPIO, ____, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(32, GPIO1_0, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(33, GPIO1_1, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(34, GPIO1_2, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(35, GPIO1_3, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(36, GPIO1_4, GPIO, JTAG, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(37, GPIO1_5, GPIO, ____, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(38, GPIO1_6, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(39, GPIO1_7, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(40, GPIO1_8, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(41, GPIO1_9, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(42, GPIO1_10, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(43, GPIO1_11, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(44, GPIO1_12, GPIO, QSPI, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(45, GPIO1_13, GPIO, UART, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(46, GPIO1_14, GPIO, UART, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(47, GPIO1_15, GPIO, UART, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(48, GPIO1_16, GPIO, UART, ____, ____, DPU0, DPU1, 0), + TH1520_PAD(49, CLK_OUT_0, BSEL, CLK, ____, GPIO, ____, ____, 0), + TH1520_PAD(50, CLK_OUT_1, BSEL, CLK, ____, GPIO, ____, ____, 0), + TH1520_PAD(51, CLK_OUT_2, BSEL, CLK, ____, GPIO, ____, ____, 0), + TH1520_PAD(52, CLK_OUT_3, BSEL, CLK, ____, GPIO, ____, ____, 0), + TH1520_PAD(53, GPIO1_21, JTAG, ____, ISP, GPIO, ____, ____, 0), + TH1520_PAD(54, GPIO1_22, JTAG, ____, ISP, GPIO, ____, ____, 0), + TH1520_PAD(55, GPIO1_23, JTAG, ____, ISP, GPIO, ____, ____, 0), + TH1520_PAD(56, GPIO1_24, JTAG, ____, ISP, GPIO, ____, ____, 0), + TH1520_PAD(57, GPIO1_25, JTAG, ____, ISP, GPIO, ____, ____, 0), + TH1520_PAD(58, GPIO1_26, GPIO, ____, ISP, ____, ____, ____, 0), + TH1520_PAD(59, GPIO1_27, GPIO, ____, ISP, ____, ____, ____, 0), + TH1520_PAD(60, GPIO1_28, GPIO, ____, ISP, ____, ____, ____, 0), + TH1520_PAD(61, GPIO1_29, GPIO, ____, ISP, ____, ____, ____, 0), + TH1520_PAD(62, GPIO1_30, GPIO, ____, ISP, ____, ____, ____, 0), +}; + +static const struct th1520_pin_desc th1520_group3_pins[] = { + TH1520_PAD(0, UART0_TXD, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(1, UART0_RXD, UART, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(2, QSPI0_SCLK, QSPI, PWM, I2S, GPIO, ____, ____, 0), + TH1520_PAD(3, QSPI0_CSN0, QSPI, PWM, I2S, GPIO, ____, ____, 0), + TH1520_PAD(4, QSPI0_CSN1, QSPI, PWM, I2S, GPIO, ____, ____, 0), + TH1520_PAD(5, QSPI0_D0_MOSI, QSPI, PWM, I2S, GPIO, ____, ____, 0), + TH1520_PAD(6, QSPI0_D1_MISO, QSPI, PWM, I2S, GPIO, ____, ____, 0), + TH1520_PAD(7, QSPI0_D2_WP, QSPI, PWM, I2S, GPIO, ____, ____, 0), + TH1520_PAD(8, QSPI1_D3_HOLD, QSPI, ____, I2S, GPIO, ____, ____, 0), + TH1520_PAD(9, I2C2_SCL, I2C, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(10, I2C2_SDA, I2C, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(11, I2C3_SCL, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(12, I2C3_SDA, I2C, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(13, GPIO2_13, GPIO, SPI, ____, ____, ____, ____, 0), + TH1520_PAD(14, SPI_SCLK, SPI, UART, IR, GPIO, ____, ____, 0), + TH1520_PAD(15, SPI_CSN, SPI, UART, IR, GPIO, ____, ____, 0), + TH1520_PAD(16, SPI_MOSI, SPI, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(17, SPI_MISO, SPI, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(18, GPIO2_18, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(19, GPIO2_19, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(20, GPIO2_20, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(21, GPIO2_21, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(22, GPIO2_22, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(23, GPIO2_23, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(24, GPIO2_24, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(25, GPIO2_25, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(26, SDIO0_WPRTN, SDIO, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(27, SDIO0_DETN, SDIO, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(28, SDIO1_WPRTN, SDIO, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(29, SDIO1_DETN, SDIO, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(30, GPIO2_30, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(31, GPIO2_31, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(32, GPIO3_0, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(33, GPIO3_1, GPIO, MAC1, ____, ____, ____, ____, 0), + TH1520_PAD(34, GPIO3_2, GPIO, PWM, ____, ____, ____, ____, 0), + TH1520_PAD(35, GPIO3_3, GPIO, PWM, ____, ____, ____, ____, 0), + TH1520_PAD(36, HDMI_SCL, HDMI, PWM, ____, GPIO, ____, ____, 0), + TH1520_PAD(37, HDMI_SDA, HDMI, PWM, ____, GPIO, ____, ____, 0), + TH1520_PAD(38, HDMI_CEC, HDMI, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(39, GMAC0_TX_CLK, MAC0, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(40, GMAC0_RX_CLK, MAC0, ____, ____, GPIO, ____, ____, 0), + TH1520_PAD(41, GMAC0_TXEN, MAC0, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(42, GMAC0_TXD0, MAC0, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(43, GMAC0_TXD1, MAC0, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(44, GMAC0_TXD2, MAC0, UART, ____, GPIO, ____, ____, 0), + TH1520_PAD(45, GMAC0_TXD3, MAC0, I2C, ____, GPIO, ____, ____, 0), + TH1520_PAD(46, GMAC0_RXDV, MAC0, I2C, ____, GPIO, ____, ____, 0), + TH1520_PAD(47, GMAC0_RXD0, MAC0, I2C, ____, GPIO, ____, ____, 0), + TH1520_PAD(48, GMAC0_RXD1, MAC0, I2C, ____, GPIO, ____, ____, 0), + TH1520_PAD(49, GMAC0_RXD2, MAC0, SPI, ____, GPIO, ____, ____, 0), + TH1520_PAD(50, GMAC0_RXD3, MAC0, SPI, ____, GPIO, ____, ____, 0), + TH1520_PAD(51, GMAC0_MDC, MAC0, SPI, MAC1, GPIO, ____, ____, 0), + TH1520_PAD(52, GMAC0_MDIO, MAC0, SPI, MAC1, GPIO, ____, ____, 0), + TH1520_PAD(53, GMAC0_COL, MAC0, PWM, ____, GPIO, ____, ____, 0), + TH1520_PAD(54, GMAC0_CRS, MAC0, PWM, ____, GPIO, ____, ____, 0), +}; + +static const struct th1520_pad_group th1520_group1 = { + .name = "th1520-group1", + .pins = th1520_group1_pins, + .npins = ARRAY_SIZE(th1520_group1_pins), +}; + +static const struct th1520_pad_group th1520_group2 = { + .name = "th1520-group2", + .pins = th1520_group2_pins, + .npins = ARRAY_SIZE(th1520_group2_pins), +}; + +static const struct th1520_pad_group th1520_group3 = { + .name = "th1520-group3", + .pins = th1520_group3_pins, + .npins = ARRAY_SIZE(th1520_group3_pins), +}; + +static void __iomem *th1520_padcfg(struct th1520_pinctrl *thp, + unsigned int pin) +{ + return thp->base + 4 * (pin / 2); +} + +static unsigned int th1520_padcfg_shift(unsigned int pin) +{ + return 16 * (pin & BIT(0)); +} + +static void __iomem *th1520_muxcfg(struct th1520_pinctrl *thp, + unsigned int pin) +{ + return thp->base + 0x400 + 4 * (pin / 8); +} + +static unsigned int th1520_muxcfg_shift(unsigned int pin) +{ + return 4 * (pin & GENMASK(2, 0)); +} + +static const u8 th1520_drive_strength_in_ma[16] = { + 1, 2, 3, 5, 7, 8, 10, 12, 13, 15, 16, 18, 20, 21, 23, 25, +}; + +static u16 th1520_drive_strength_from_ma(u32 arg) +{ + u16 ds; + + for (ds = 0; ds < TH1520_PADCFG_DS; ds++) { + if (arg <= th1520_drive_strength_in_ma[ds]) + return ds; + } + return TH1520_PADCFG_DS; +} + +static int th1520_padcfg_rmw(struct th1520_pinctrl *thp, unsigned int pin, + u32 mask, u32 value) +{ + void __iomem *padcfg = th1520_padcfg(thp, pin); + unsigned int shift = th1520_padcfg_shift(pin); + u32 tmp; + + mask <<= shift; + value <<= shift; + + tmp = readl_relaxed(padcfg); + tmp = (tmp & ~mask) | value; + writel_relaxed(tmp, padcfg); + + return 0; +} + +static int th1520_pinconf_apply_one(struct th1520_pinctrl *thp, + const struct th1520_pin_desc *desc, + enum pin_config_param param, u32 arg) + +{ + u16 mask = 0, value = 0; + + if (th1520_pad_no_padcfg(desc)) + return -EOPNOTSUPP; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + mask |= TH1520_PADCFG_BIAS; + value &= ~TH1520_PADCFG_BIAS; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + if (arg == 0) + return -EOPNOTSUPP; + mask |= TH1520_PADCFG_BIAS; + value &= ~TH1520_PADCFG_BIAS; + value |= TH1520_PADCFG_PE; + break; + case PIN_CONFIG_BIAS_PULL_UP: + if (arg == 0) + return -EOPNOTSUPP; + mask |= TH1520_PADCFG_BIAS; + value &= ~TH1520_PADCFG_BIAS; + if (arg == TH1520_PULL_STRONG_OHM) + value |= TH1520_PADCFG_SPU; + else + value |= TH1520_PADCFG_PE | TH1520_PADCFG_PS; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + mask |= TH1520_PADCFG_DS; + value &= ~TH1520_PADCFG_DS; + value |= th1520_drive_strength_from_ma(arg); + break; + case PIN_CONFIG_INPUT_ENABLE: + mask |= TH1520_PADCFG_IE; + if (arg) + value |= TH1520_PADCFG_IE; + else + value &= ~TH1520_PADCFG_IE; + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + mask |= TH1520_PADCFG_ST; + if (arg) + value |= TH1520_PADCFG_ST; + else + value &= ~TH1520_PADCFG_ST; + break; + case PIN_CONFIG_SLEW_RATE: + mask |= TH1520_PADCFG_SL; + if (arg) + value |= TH1520_PADCFG_SL; + else + value &= ~TH1520_PADCFG_SL; + break; + default: + return -EOPNOTSUPP; + } + + return th1520_padcfg_rmw(thp, desc->number, mask, value); +} + +static int th1520_pinmux_apply_one(struct th1520_pinctrl *thp, + const struct th1520_pin_desc *desc, + enum th1520_muxtype muxtype) +{ + void __iomem *muxcfg = th1520_muxcfg(thp, desc->number); + unsigned int shift = th1520_muxcfg_shift(desc->number); + u32 mask, value, tmp; + + for (value = 0; value < ARRAY_SIZE(desc->muxes); value++) { + if (desc->muxes[value] == muxtype) + break; + } + if (value == ARRAY_SIZE(desc->muxes)) { + pr_err("invalid mux %s for pin \"%s\"\n", + th1520_muxtype_string[muxtype], desc->name); + return -EINVAL; + } + + mask = GENMASK(3, 0) << shift; + value = value << shift; + + tmp = readl_relaxed(muxcfg); + tmp = (tmp & ~mask) | value; + writel_relaxed(tmp, muxcfg); + + return 0; +} + +const struct pinconf_param th1520_pinconf_params[] = { + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, + { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, + { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, + { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, + { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, + { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 }, +}; + +static const struct th1520_pin_desc * +th1520_pinctrl_search_pin(struct th1520_pinctrl *thp, + const char *name) +{ + const struct th1520_pad_group *pg = thp->group; + int i; + + for (i = 0; i < pg->npins; i++) { + if (!strcmp(pg->pins[i].name, name)) + return &pg->pins[i]; + } + + return NULL; +} + +static int th1520_pinctrl_apply_group(struct th1520_pinctrl *thp, ofnode group) +{ + struct th1520_pin_desc const **pins; + enum th1520_muxtype muxtype; + int pin_count, ret, i, j; + const char *muxname; + + pin_count = ofnode_read_string_count(group, "pins"); + if (pin_count < 0) { + pr_err("missing property pins"); + return -EINVAL; + } + + pins = calloc(pin_count, sizeof(pins[0])); + if (!pins) + return -ENOMEM; + + for (i = 0; i < pin_count; i++) { + const char *pinname; + + ret = ofnode_read_string_index(group, "pins", i, &pinname); + if (ret) + goto out; + + pins[i] = th1520_pinctrl_search_pin(thp, pinname); + if (!pins[i]) { + pr_err("unknown pin name \"%s\"\n", pinname); + goto out; + } + } + + for (i = 0; i < ARRAY_SIZE(th1520_pinconf_params); i++) { + const struct pinconf_param *param = &th1520_pinconf_params[i]; + u32 val; + + ret = ofnode_read_u32(group, param->property, &val); + if (ret == -EINVAL) + continue; + else if (ret) + val = param->default_value; + + for (j = 0; j < pin_count; j++) { + ret = th1520_pinconf_apply_one(thp, pins[j], + param->param, val); + if (ret) { + pr_err("failed to apply pinconf for \"%s\": %d\n", + pins[j]->name, ret); + goto out; + } + } + } + + muxname = ofnode_read_string(group, "function"); + if (!muxname) + goto out; + + muxtype = th1520_muxtype_get(muxname); + if (!muxtype) { + pr_err("invalid mux type \"%s\"", muxname); + ret = -EINVAL; + goto out; + } + + for (i = 0; i < pin_count; i++) { + ret = th1520_pinmux_apply_one(thp, pins[i], muxtype); + if (ret) { + pr_err("failed to set pinmux function: %d\n", ret); + break; + } + } + +out: + free(pins); + + return ret; +} + +static int th1520_pinctrl_set_state(struct udevice *dev, struct udevice *pcfg) +{ + struct th1520_pinctrl *thp = dev_get_priv(dev); + ofnode group; + int ret = 0; + + dev_for_each_subnode(group, pcfg) { + ret = th1520_pinctrl_apply_group(thp, group); + if (ret) { + pr_err("failed to apply pin group \"%s\": %d\n", + ofnode_get_name(group), ret); + break; + } + } + + return ret; +} + +static int th1520_pinctrl_get_pins_count(struct udevice *dev) +{ + struct th1520_pinctrl *thp = dev_get_priv(dev); + + return thp->group->npins; +} + +static const char *th1520_pinctrl_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + struct th1520_pinctrl *p = dev_get_priv(dev); + + if (selector >= p->group->npins) + return ERR_PTR(-EINVAL); + + return p->group->pins[selector].name; +} + +static int th1520_pinctrl_get_pin_muxing(struct udevice *dev, + unsigned int selector, + char *buf, int size) +{ + struct th1520_pinctrl *thp = dev_get_priv(dev); + const struct th1520_pad_group *group = thp->group; + const struct th1520_pin_desc *desc; + void __iomem *muxcfg; + unsigned int shift; + u32 val; + + if (selector >= group->npins) + return -EINVAL; + + desc = &group->pins[selector]; + if (th1520_pad_no_padcfg(desc)) { + strlcpy(buf, "unsupported", size - 1); + return 0; + } + + muxcfg = th1520_muxcfg(thp, desc->number); + shift = th1520_muxcfg_shift(desc->number); + + val = (readl_relaxed(muxcfg) >> shift) & GENMASK(3, 0); + strlcpy(buf, th1520_muxtype_string[desc->muxes[val]], size); + + return 0; +} + +static const struct pinctrl_ops th1520_pinctrl_ops = { + .get_pins_count = th1520_pinctrl_get_pins_count, + .get_pin_name = th1520_pinctrl_get_pin_name, + .get_pin_muxing = th1520_pinctrl_get_pin_muxing, + .set_state = th1520_pinctrl_set_state, +}; + +static int th1520_pinctrl_probe(struct udevice *dev) +{ + struct th1520_pinctrl *thp = dev_get_priv(dev); + struct clk clk; + u32 pin_group; + int ret; + + thp->base = dev_read_addr_ptr(dev); + if (!thp->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) { + pr_err("failed to enable pinctrl clock: %d\n", ret); + return ret; + } + + ret = dev_read_u32(dev, "thead,pad-group", &pin_group); + if (ret) { + pr_err("failed to read thead,pad-group property: %d\n", ret); + return ret; + } + + switch (pin_group) { + case 1: + thp->group = &th1520_group1; + break; + case 2: + thp->group = &th1520_group2; + break; + case 3: + thp->group = &th1520_group3; + break; + default: + pr_err("invalid thead,pad-group property: %u\n", pin_group); + return -EINVAL; + } + + return 0; +} + +static const struct udevice_id th1520_pinctrl_ids[] = { + { .compatible = "thead,th1520-pinctrl"}, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(th1520_pinctrl) = { + .name = "th1520-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = th1520_pinctrl_ids, + .probe = th1520_pinctrl_probe, + .priv_auto = sizeof(struct th1520_pinctrl), + .ops = &th1520_pinctrl_ops, +}; diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index e567cb113a3..21f81b66099 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -27,6 +27,13 @@ config PINCTRL_QCOM_IPQ4019 Say Y here to enable support for pinctrl on the IPQ4019 SoC, as well as the associated GPIO driver. +config PINCTRL_QCOM_IPQ5424 + bool "Qualcomm IPQ5424 Pinctrl" + select PINCTRL_QCOM + help + Say Y here to enable support for pinctrl on the IPQ5424 SoC, + as well as the associated GPIO driver. + config PINCTRL_QCOM_IPQ9574 bool "Qualcomm IPQ9574 Pinctrl" select PINCTRL_QCOM diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index 6ffc6d48c15..6cb53838e71 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_PINCTRL_QCOM) += pinctrl-qcom.o obj-$(CONFIG_PINCTRL_QCOM_APQ8016) += pinctrl-apq8016.o obj-$(CONFIG_PINCTRL_QCOM_IPQ4019) += pinctrl-ipq4019.o +obj-$(CONFIG_PINCTRL_QCOM_IPQ5424) += pinctrl-ipq5424.o obj-$(CONFIG_PINCTRL_QCOM_IPQ9574) += pinctrl-ipq9574.o obj-$(CONFIG_PINCTRL_QCOM_APQ8096) += pinctrl-apq8096.o obj-$(CONFIG_PINCTRL_QCOM_QCM2290) += pinctrl-qcm2290.o diff --git a/drivers/pinctrl/qcom/pinctrl-ipq5424.c b/drivers/pinctrl/qcom/pinctrl-ipq5424.c new file mode 100644 index 00000000000..cde990a32ef --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-ipq5424.c @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2016-2018,2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include <dm.h> + +#include "pinctrl-qcom.h" + +#define MAX_PIN_NAME_LEN 32 +static char pin_name[MAX_PIN_NAME_LEN] __section(".data"); + +enum ipq5424_functions { + msm_mux_atest_char, + msm_mux_atest_char0, + msm_mux_atest_char1, + msm_mux_atest_char2, + msm_mux_atest_char3, + msm_mux_atest_tic, + msm_mux_audio_pri, + msm_mux_audio_pri0, + msm_mux_audio_pri1, + msm_mux_audio_sec, + msm_mux_audio_sec0, + msm_mux_audio_sec1, + msm_mux_core_voltage, + msm_mux_cri_trng0, + msm_mux_cri_trng1, + msm_mux_cri_trng2, + msm_mux_cri_trng3, + msm_mux_cxc_clk, + msm_mux_cxc_data, + msm_mux_dbg_out, + msm_mux_gcc_plltest, + msm_mux_gcc_tlmm, + msm_mux_gpio, + msm_mux_i2c0_scl, + msm_mux_i2c0_sda, + msm_mux_i2c1_scl, + msm_mux_i2c1_sda, + msm_mux_i2c11, + msm_mux_mac0, + msm_mux_mac1, + msm_mux_mdc_mst, + msm_mux_mdc_slv, + msm_mux_mdio_mst, + msm_mux_mdio_slv, + msm_mux_pcie0_clk, + msm_mux_pcie0_wake, + msm_mux_pcie1_clk, + msm_mux_pcie1_wake, + msm_mux_pcie2_clk, + msm_mux_pcie2_wake, + msm_mux_pcie3_clk, + msm_mux_pcie3_wake, + msm_mux_pll_test, + msm_mux_prng_rosc0, + msm_mux_prng_rosc1, + msm_mux_prng_rosc2, + msm_mux_prng_rosc3, + msm_mux_PTA0_0, + msm_mux_PTA0_1, + msm_mux_PTA0_2, + msm_mux_PTA10, + msm_mux_PTA11, + msm_mux_pwm0, + msm_mux_pwm1, + msm_mux_pwm2, + msm_mux_qdss_cti_trig_in_a0, + msm_mux_qdss_cti_trig_out_a0, + msm_mux_qdss_cti_trig_in_a1, + msm_mux_qdss_cti_trig_out_a1, + msm_mux_qdss_cti_trig_in_b0, + msm_mux_qdss_cti_trig_out_b0, + msm_mux_qdss_cti_trig_in_b1, + msm_mux_qdss_cti_trig_out_b1, + msm_mux_qdss_traceclk_a, + msm_mux_qdss_tracectl_a, + msm_mux_qdss_tracedata_a, + msm_mux_qspi_clk, + msm_mux_qspi_cs, + msm_mux_qspi_data, + msm_mux_resout, + msm_mux_rx0, + msm_mux_rx1, + msm_mux_rx2, + msm_mux_sdc_clk, + msm_mux_sdc_cmd, + msm_mux_sdc_data, + msm_mux_spi0_clk, + msm_mux_spi0_cs, + msm_mux_spi0_miso, + msm_mux_spi0_mosi, + msm_mux_spi1, + msm_mux_spi10, + msm_mux_spi11, + msm_mux_tsens_max, + msm_mux_uart0, + msm_mux_uart1, + msm_mux_wci_txd, + msm_mux_wci_rxd, + msm_mux_wsi_clk, + msm_mux_wsi_data, + msm_mux__, +}; + +#define MSM_PIN_FUNCTION(fname) \ + [msm_mux_##fname] = {#fname, msm_mux_##fname} + +static const struct pinctrl_function ipq5424_functions[] = { + MSM_PIN_FUNCTION(atest_char), + MSM_PIN_FUNCTION(atest_char0), + MSM_PIN_FUNCTION(atest_char1), + MSM_PIN_FUNCTION(atest_char2), + MSM_PIN_FUNCTION(atest_char3), + MSM_PIN_FUNCTION(atest_tic), + MSM_PIN_FUNCTION(audio_pri), + MSM_PIN_FUNCTION(audio_pri0), + MSM_PIN_FUNCTION(audio_pri1), + MSM_PIN_FUNCTION(audio_sec), + MSM_PIN_FUNCTION(audio_sec0), + MSM_PIN_FUNCTION(audio_sec1), + MSM_PIN_FUNCTION(core_voltage), + MSM_PIN_FUNCTION(cri_trng0), + MSM_PIN_FUNCTION(cri_trng1), + MSM_PIN_FUNCTION(cri_trng2), + MSM_PIN_FUNCTION(cri_trng3), + MSM_PIN_FUNCTION(cxc_clk), + MSM_PIN_FUNCTION(cxc_data), + MSM_PIN_FUNCTION(dbg_out), + MSM_PIN_FUNCTION(gcc_plltest), + MSM_PIN_FUNCTION(gcc_tlmm), + MSM_PIN_FUNCTION(gpio), + MSM_PIN_FUNCTION(i2c0_scl), + MSM_PIN_FUNCTION(i2c0_sda), + MSM_PIN_FUNCTION(i2c1_scl), + MSM_PIN_FUNCTION(i2c1_sda), + MSM_PIN_FUNCTION(i2c11), + MSM_PIN_FUNCTION(mac0), + MSM_PIN_FUNCTION(mac1), + MSM_PIN_FUNCTION(mdc_mst), + MSM_PIN_FUNCTION(mdc_slv), + MSM_PIN_FUNCTION(mdio_mst), + MSM_PIN_FUNCTION(mdio_slv), + MSM_PIN_FUNCTION(pcie0_clk), + MSM_PIN_FUNCTION(pcie0_wake), + MSM_PIN_FUNCTION(pcie1_clk), + MSM_PIN_FUNCTION(pcie1_wake), + MSM_PIN_FUNCTION(pcie2_clk), + MSM_PIN_FUNCTION(pcie2_wake), + MSM_PIN_FUNCTION(pcie3_clk), + MSM_PIN_FUNCTION(pcie3_wake), + MSM_PIN_FUNCTION(pll_test), + MSM_PIN_FUNCTION(prng_rosc0), + MSM_PIN_FUNCTION(prng_rosc1), + MSM_PIN_FUNCTION(prng_rosc2), + MSM_PIN_FUNCTION(prng_rosc3), + MSM_PIN_FUNCTION(PTA0_0), + MSM_PIN_FUNCTION(PTA0_1), + MSM_PIN_FUNCTION(PTA0_2), + MSM_PIN_FUNCTION(PTA10), + MSM_PIN_FUNCTION(PTA11), + MSM_PIN_FUNCTION(pwm0), + MSM_PIN_FUNCTION(pwm1), + MSM_PIN_FUNCTION(pwm2), + MSM_PIN_FUNCTION(qdss_cti_trig_in_a0), + MSM_PIN_FUNCTION(qdss_cti_trig_out_a0), + MSM_PIN_FUNCTION(qdss_cti_trig_in_a1), + MSM_PIN_FUNCTION(qdss_cti_trig_out_a1), + MSM_PIN_FUNCTION(qdss_cti_trig_in_b0), + MSM_PIN_FUNCTION(qdss_cti_trig_out_b0), + MSM_PIN_FUNCTION(qdss_cti_trig_in_b1), + MSM_PIN_FUNCTION(qdss_cti_trig_out_b1), + MSM_PIN_FUNCTION(qdss_traceclk_a), + MSM_PIN_FUNCTION(qdss_tracectl_a), + MSM_PIN_FUNCTION(qdss_tracedata_a), + MSM_PIN_FUNCTION(qspi_clk), + MSM_PIN_FUNCTION(qspi_cs), + MSM_PIN_FUNCTION(qspi_data), + MSM_PIN_FUNCTION(resout), + MSM_PIN_FUNCTION(rx0), + MSM_PIN_FUNCTION(rx1), + MSM_PIN_FUNCTION(rx2), + MSM_PIN_FUNCTION(sdc_clk), + MSM_PIN_FUNCTION(sdc_cmd), + MSM_PIN_FUNCTION(sdc_data), + MSM_PIN_FUNCTION(spi0_clk), + MSM_PIN_FUNCTION(spi0_cs), + MSM_PIN_FUNCTION(spi0_miso), + MSM_PIN_FUNCTION(spi0_mosi), + MSM_PIN_FUNCTION(spi1), + MSM_PIN_FUNCTION(spi10), + MSM_PIN_FUNCTION(spi11), + MSM_PIN_FUNCTION(tsens_max), + MSM_PIN_FUNCTION(uart0), + MSM_PIN_FUNCTION(uart1), + MSM_PIN_FUNCTION(wci_txd), + MSM_PIN_FUNCTION(wci_rxd), + MSM_PIN_FUNCTION(wsi_clk), + MSM_PIN_FUNCTION(wsi_data), +}; + +typedef unsigned int msm_pin_function[10]; + +#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9)\ + [id] = { msm_mux_gpio, /* gpio mode */ \ + msm_mux_##f1, \ + msm_mux_##f2, \ + msm_mux_##f3, \ + msm_mux_##f4, \ + msm_mux_##f5, \ + msm_mux_##f6, \ + msm_mux_##f7, \ + msm_mux_##f8, \ + msm_mux_##f9, \ + } + +static const msm_pin_function ipq5424_pin_functions[] = { + PINGROUP(0, sdc_data, qspi_data, pwm2, wci_txd, wci_rxd, _, _, _, _), + PINGROUP(1, sdc_data, qspi_data, pwm2, wci_txd, wci_rxd, _, _, _, _), + PINGROUP(2, sdc_data, qspi_data, pwm2, _, _, _, _, _, _), + PINGROUP(3, sdc_data, qspi_data, pwm2, _, _, _, _, _, _), + PINGROUP(4, sdc_cmd, qspi_cs, _, _, _, _, _, _, _), + PINGROUP(5, sdc_clk, qspi_clk, _, _, _, _, _, _, _), + PINGROUP(6, spi0_clk, pwm1, _, cri_trng0, qdss_tracedata_a, _, _, _, _), + PINGROUP(7, spi0_cs, pwm1, _, cri_trng1, qdss_tracedata_a, _, _, _, _), + PINGROUP(8, spi0_miso, pwm1, wci_txd, wci_rxd, _, cri_trng2, qdss_tracedata_a, _, _), + PINGROUP(9, spi0_mosi, pwm1, _, cri_trng3, qdss_tracedata_a, _, _, _, _), + PINGROUP(10, uart0, pwm0, spi11, _, wci_txd, wci_rxd, _, qdss_tracedata_a, _), + PINGROUP(11, uart0, pwm0, spi1, _, wci_txd, wci_rxd, _, qdss_tracedata_a, _), + PINGROUP(12, uart0, pwm0, spi11, _, prng_rosc0, qdss_tracedata_a, _, _, _), + PINGROUP(13, uart0, pwm0, spi11, _, prng_rosc1, qdss_tracedata_a, _, _, _), + PINGROUP(14, i2c0_scl, tsens_max, _, prng_rosc2, qdss_tracedata_a, _, _, _, _), + PINGROUP(15, i2c0_sda, _, prng_rosc3, qdss_tracedata_a, _, _, _, _, _), + PINGROUP(16, core_voltage, i2c1_scl, _, _, _, _, _, _, _), + PINGROUP(17, core_voltage, i2c1_sda, _, _, _, _, _, _, _), + PINGROUP(18, _, _, _, _, _, _, _, _, _), + PINGROUP(19, _, _, _, _, _, _, _, _, _), + PINGROUP(20, mdc_slv, atest_char0, _, qdss_tracedata_a, _, _, _, _, _), + PINGROUP(21, mdio_slv, atest_char1, _, qdss_tracedata_a, _, _, _, _, _), + PINGROUP(22, mdc_mst, atest_char2, _, _, _, _, _, _, _), + PINGROUP(23, mdio_mst, atest_char3, _, _, _, _, _, _, _), + PINGROUP(24, pcie0_clk, PTA10, mac0, _, wsi_clk, _, atest_char, qdss_cti_trig_out_a0, _), + PINGROUP(25, _, _, _, _, _, _, _, _, _), + PINGROUP(26, pcie0_wake, PTA10, mac0, _, wsi_data, _, qdss_cti_trig_in_a0, _, _), + PINGROUP(27, pcie1_clk, i2c11, PTA10, wsi_clk, qdss_cti_trig_out_a1, _, _, _, _), + PINGROUP(28, _, _, _, _, _, _, _, _, _), + PINGROUP(29, pcie1_wake, i2c11, wsi_data, qdss_cti_trig_in_a1, _, _, _, _, _), + PINGROUP(30, pcie2_clk, PTA11, mac1, qdss_cti_trig_out_b0, _, _, _, _, _), + PINGROUP(31, _, _, _, _, _, _, _, _, _), + PINGROUP(32, pcie2_wake, PTA11, mac1, audio_pri0, audio_pri0, qdss_cti_trig_in_b0, _, _, _), + PINGROUP(33, pcie3_clk, PTA11, audio_pri1, audio_pri1, qdss_cti_trig_out_b1, _, _, _, _), + PINGROUP(34, _, _, _, _, _, _, _, _, _), + PINGROUP(35, pcie3_wake, audio_sec1, audio_sec1, qdss_cti_trig_in_b1, _, _, _, _, _), + PINGROUP(36, audio_pri, spi1, audio_sec0, audio_sec0, qdss_tracedata_a, _, _, _, _), + PINGROUP(37, audio_pri, spi1, rx2, qdss_tracedata_a, _, _, _, _, _), + PINGROUP(38, audio_pri, spi1, pll_test, rx1, qdss_tracedata_a, _, _, _, _), + PINGROUP(39, audio_pri, rx0, _, qdss_tracedata_a, _, _, _, _, _), + PINGROUP(40, PTA0_0, wci_txd, wci_rxd, _, atest_tic, _, _, _, _), + PINGROUP(41, PTA0_1, wci_txd, wci_rxd, cxc_data, _, _, _, _, _), + PINGROUP(42, PTA0_2, cxc_clk, _, _, _, _, _, _, _), + PINGROUP(43, uart1, gcc_plltest, _, _, _, _, _, _, _), + PINGROUP(44, uart1, gcc_tlmm, _, _, _, _, _, _, _), + PINGROUP(45, spi10, rx2, audio_sec, gcc_plltest, _, qdss_traceclk_a, _, _, _), + PINGROUP(46, spi1, rx1, audio_sec, dbg_out, qdss_tracectl_a, _, _, _, _), + PINGROUP(47, spi10, rx0, audio_sec, _, _, _, _, _, _), + PINGROUP(48, spi10, audio_sec, _, _, _, _, _, _, _), + PINGROUP(49, resout, _, _, _, _, _, _, _, _), +}; + +static const char *ipq5424_get_function_name(struct udevice *dev, + unsigned int selector) +{ + return ipq5424_functions[selector].name; +} + +static const char *ipq5424_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + snprintf(pin_name, MAX_PIN_NAME_LEN, "gpio%u", selector); + return pin_name; +} + +static int ipq5424_get_function_mux(unsigned int pin, unsigned int selector) +{ + unsigned int i; + const msm_pin_function *func = ipq5424_pin_functions + pin; + + for (i = 0; i < 10; i++) + if ((*func)[i] == selector) + return i; + + debug("Can't find requested function for pin:selector %u:%u\n", + pin, selector); + + return -EINVAL; +} + +static const struct msm_pinctrl_data ipq5424_data = { + .pin_data = { + .pin_count = 49, + }, + .functions_count = ARRAY_SIZE(ipq5424_functions), + .get_function_name = ipq5424_get_function_name, + .get_function_mux = ipq5424_get_function_mux, + .get_pin_name = ipq5424_get_pin_name, +}; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,ipq5424-tlmm", .data = (ulong)&ipq5424_data }, + { /* Sentinal */ } +}; + +U_BOOT_DRIVER(pinctrl_ipq5424) = { + .name = "pinctrl_ipq5424", + .id = UCLASS_NOP, + .of_match = msm_pinctrl_ids, + .ops = &msm_pinctrl_ops, + .bind = msm_pinctrl_bind, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6467f20422b..79b879d68d1 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -94,6 +94,13 @@ config RTC_DS1374 Support for Dallas Semiconductor (now Maxim) DS1374 and compatible Real Time Clock devices. +config RTC_DS1672 + bool "Enable DS1672 driver" + depends on DM_RTC + help + Support for Dallas Semiconductor (now Maxim) DS1672 compatible + Real Time Clock devices. + config RTC_DS3231 bool "Enable DS3231 driver" help diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 99b5a2a346a..a4ede413cd1 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_RTC_DS1307) += ds1307.o obj-$(CONFIG_RTC_DS1338) += ds1307.o obj-$(CONFIG_RTC_DS1337) += ds1337.o obj-$(CONFIG_RTC_DS1374) += ds1374.o +obj-$(CONFIG_RTC_DS1672) += ds1672.o obj-$(CONFIG_RTC_DS3231) += ds3231.o obj-$(CONFIG_RTC_DS3232) += ds3232.o obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o diff --git a/drivers/rtc/ds1672.c b/drivers/rtc/ds1672.c new file mode 100644 index 00000000000..4705e5abc93 --- /dev/null +++ b/drivers/rtc/ds1672.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Analog Devices DS1672 I2C RTC driver + * + * Copyright 2025 Gateworks Corporation. + */ +#include <dm.h> +#include <i2c.h> +#include <rtc.h> +#include <dm/device_compat.h> + +/* Registers */ +#define DS1672_REG_CNT_BASE 0 +#define DS1672_REG_CONTROL 4 +#define DS1672_REG_TRICKLE 5 + +#define DS1672_REG_CONTROL_EOSC 0x80 + +static int ds1672_read_time(struct udevice *dev, struct rtc_time *tm) +{ + time64_t secs; + u8 regs[4]; + int ret; + + ret = dm_i2c_read(dev, DS1672_REG_CONTROL, regs, 1); + if (ret) + return ret; + + if (regs[0] & DS1672_REG_CONTROL_EOSC) { + dev_err(dev, "Oscillator not enabled. Set time to enable.\n"); + return -EINVAL; + } + + ret = dm_i2c_read(dev, DS1672_REG_CNT_BASE, regs, 4); + if (ret) + return ret; + dev_dbg(dev, "raw read: 0x%02x 0x%02x 0x%02x 0x%02x\n", + regs[0], regs[1], regs[2], regs[3]); + secs = ((unsigned long)regs[3] << 24) | (regs[2] << 16) | (regs[1] << 8) | regs[0]; + rtc_to_tm(secs, tm); + + dev_dbg(dev, "read %lld %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n", secs, + tm->tm_year, tm->tm_mon, tm->tm_mday, + tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec); + + return 0; +} + +static int ds1672_set_time(struct udevice *dev, const struct rtc_time *tm) +{ + time64_t secs = rtc_mktime(tm); + u8 regs[5]; + + dev_dbg(dev, "set %4d-%02d-%02d (wday=%d) %2d:%02d:%02d %lld\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, + tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec, + secs); + + if (tm->tm_year < 2000) { + dev_err(dev, "year %d (before 2000) not supported\n", + tm->tm_year); + return -EINVAL; + } + + regs[0] = secs & 0x000000ff; + regs[1] = (secs & 0x0000ff00) >> 8; + regs[2] = (secs & 0x00ff0000) >> 16; + regs[3] = (secs & 0xff000000) >> 24; + regs[4] = 0; /* set control reg to enable counting */ + + return dm_i2c_write(dev, DS1672_REG_CNT_BASE, regs, 5); +} + +static int ds1672_reset(struct udevice *dev) +{ + u8 regs[5] = { 0 }; + + return dm_i2c_write(dev, DS1672_REG_CNT_BASE, regs, 5); +} + +static int ds1672_read8(struct udevice *dev, unsigned int reg) +{ + return dm_i2c_reg_read(dev, reg); +} + +static int ds1672_write8(struct udevice *dev, unsigned int reg, int val) +{ + return dm_i2c_reg_write(dev, reg, val); +} + +static const struct rtc_ops ds1672_rtc_ops = { + .get = ds1672_read_time, + .set = ds1672_set_time, + .reset = ds1672_reset, + .read8 = ds1672_read8, + .write8 = ds1672_write8, +}; + +static int ds1672_probe(struct udevice *dev) +{ + i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS | DM_I2C_CHIP_WR_ADDRESS); + + return 0; +} + +static const struct udevice_id ds1672_of_id[] = { + { .compatible = "dallas,ds1672" }, + { } +}; + +U_BOOT_DRIVER(rtc_max313xx) = { + .name = "rtc-ds1672", + .id = UCLASS_RTC, + .probe = ds1672_probe, + .of_match = ds1672_of_id, + .ops = &ds1672_rtc_ops, +}; diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index fbeb0c6a85c..6dc6fbe5a5b 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -20,7 +20,7 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { - u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data; + u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data, status; u8 opcode, addr_bytes, *rxbuf, dummy_cycles; n_rx = op->data.nbytes; @@ -87,6 +87,16 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, CQSPI_REG_SIZE_ADDRESS_MASK; opcode = CMD_4BYTE_FAST_READ; + + /* Set up command opcode extension. */ + status = readl(priv->regbase + CQSPI_REG_CONFIG); + if (status & CQSPI_REG_CONFIG_DTR_PROTO) { + ret = cadence_qspi_setup_opcode_ext(priv, op, + CQSPI_REG_OP_EXT_STIG_LSB); + if (ret) + return ret; + } + dummy_cycles = 8; writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode, priv->regbase + CQSPI_REG_RD_INSTR); diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 80510f2542b..879e7f8dbfb 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -320,5 +320,7 @@ int cadence_qspi_flash_reset(struct udevice *dev); ofnode cadence_qspi_get_subnode(struct udevice *dev); void cadence_qspi_apb_enable_linear_mode(bool enable); int cadence_device_reset(struct udevice *dev); - +int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, + const struct spi_mem_op *op, + unsigned int shift); #endif /* __CADENCE_QSPI_H__ */ diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index b579699d2eb..6f89d3add5d 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -303,6 +303,10 @@ void cadence_qspi_apb_delay(void *reg_base, tshsl_ns -= sclk_ns + ref_clk_ns; if (tchsh_ns >= sclk_ns + 3 * ref_clk_ns) tchsh_ns -= sclk_ns + 3 * ref_clk_ns; + + if (tshsl_ns < sclk_ns) + tshsl_ns = sclk_ns; + tshsl = DIV_ROUND_UP(tshsl_ns, ref_clk_ns); tchsh = DIV_ROUND_UP(tchsh_ns, ref_clk_ns); tslch = DIV_ROUND_UP(tslch_ns, ref_clk_ns); @@ -380,9 +384,9 @@ int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg) return 0; } -static int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, - const struct spi_mem_op *op, - unsigned int shift) +int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, + const struct spi_mem_op *op, + unsigned int shift) { unsigned int reg; u8 ext; @@ -555,6 +559,9 @@ int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv, u8 opcode; if (priv->dtr) + txlen += txlen & 1; + + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c index f2393c041f4..545561ad116 100644 --- a/drivers/spi/fsl_dspi.c +++ b/drivers/spi/fsl_dspi.c @@ -123,8 +123,10 @@ static uint dspi_read32(uint flags, uint *addr) static void dspi_write32(uint flags, uint *addr, uint val) { - flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ? - out_be32(addr, val) : out_le32(addr, val); + if (flags & DSPI_FLAG_REGMAP_ENDIAN_BIG) + out_be32(addr, val); + else + out_le32(addr, val); } static void dspi_halt(struct fsl_dspi_priv *priv, u8 halt) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index a0f2948335f..45eb9b4d3f9 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -29,6 +29,7 @@ config WATCHDOG_TIMEOUT_MSECS int "Watchdog timeout in msec" default 128000 if ARCH_MX31 || ARCH_MX5 || ARCH_MX6 default 128000 if ARCH_MX7 || ARCH_VF610 + default 30000 if ARCH_SNAPDRAGON default 30000 if ARCH_SOCFPGA default 16000 if ARCH_SUNXI default 5376 if ULP_WATCHDOG @@ -335,6 +336,14 @@ config WDT_K3_RTI_FW_FILE endif +config WDT_QCOM + bool "Qualcomm watchdog timer support" + depends on WDT && ARCH_SNAPDRAGON + imply WATCHDOG + help + Select this to enable Qualcomm watchdog timer, which can be found on + some Qualcomm chips. + config WDT_RENESAS bool "Renesas watchdog timer support" depends on WDT && R8A779F0 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index c4467d6e126..d52d17e1c90 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -55,3 +55,4 @@ obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o obj-$(CONFIG_WDT_TANGIER) += tangier_wdt.o obj-$(CONFIG_WDT_XILINX) += xilinx_wwdt.o obj-$(CONFIG_WDT_ADI) += adi_wdt.o +obj-$(CONFIG_WDT_QCOM) += qcom-wdt.o diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c new file mode 100644 index 00000000000..adbb5aacdc3 --- /dev/null +++ b/drivers/watchdog/qcom-wdt.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) Linaro Ltd. 2024 + * + * Authors: + * Casey Connolly <casey.connolly@linaro.org> + * Paul Sajna <hello@paulsajna.com> + * + * Derived from linux/drivers/watchdog/qcom-wdt.c + */ + +#include <dm.h> +#include <dm/device_compat.h> +#include <wdt.h> +#include <clk.h> + +#include <asm/io.h> + +enum wdt_reg { + WDT_RST, + WDT_EN, + WDT_STS, + WDT_BARK_TIME, + WDT_BITE_TIME, +}; + +struct qcom_wdt_match_data { + const u32 *offset; +}; + +struct qcom_wdt { + void __iomem *base; + ulong clk_rate; + const u32 *layout; +}; + +static const u32 reg_offset_data_kpss[] = { + [WDT_RST] = 0x4, + [WDT_EN] = 0x8, + [WDT_STS] = 0xC, + [WDT_BARK_TIME] = 0x10, + [WDT_BITE_TIME] = 0x14, +}; + +static const struct qcom_wdt_match_data match_data_kpss = { + .offset = reg_offset_data_kpss, +}; + +static void __iomem *wdt_addr(struct qcom_wdt *wdt, enum wdt_reg reg) +{ + return wdt->base + wdt->layout[reg]; +} + +int qcom_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) +{ + struct qcom_wdt *wdt = dev_get_priv(dev); + ulong bark_timeout_s = ((timeout_ms - 1) * wdt->clk_rate) / 1000; + ulong bite_timeout_s = (timeout_ms * wdt->clk_rate) / 1000; + + writel(0, wdt_addr(wdt, WDT_EN)); + writel(BIT(0), wdt_addr(wdt, WDT_RST)); + writel(bark_timeout_s, wdt_addr(wdt, WDT_BARK_TIME)); + writel(bite_timeout_s, wdt_addr(wdt, WDT_BITE_TIME)); + writel(BIT(0), wdt_addr(wdt, WDT_EN)); + if (readl(wdt_addr(wdt, WDT_EN)) != 1) { + dev_err(dev, "Failed to enable Qualcomm watchdog!\n"); + return -EIO; + } + return 0; +} + +int qcom_wdt_stop(struct udevice *dev) +{ + struct qcom_wdt *wdt = dev_get_priv(dev); + + writel(0, wdt_addr(wdt, WDT_EN)); + if (readl(wdt_addr(wdt, WDT_EN))) { + dev_err(dev, "Failed to disable Qualcomm watchdog!\n"); + return -EIO; + } + + return 0; +} + +int qcom_wdt_reset(struct udevice *dev) +{ + struct qcom_wdt *wdt = dev_get_priv(dev); + + writel(1, wdt_addr(wdt, WDT_RST)); + return 0; +} + +static int qcom_wdt_probe(struct udevice *dev) +{ + struct clk clk; + long rate; + int ret; + + struct qcom_wdt *wdt = dev_get_priv(dev); + struct qcom_wdt_match_data *data = (void *)dev_get_driver_data(dev); + + wdt->base = dev_read_addr_ptr(dev); + wdt->layout = data->offset; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + rate = clk_get_rate(&clk); + if (rate <= 0) + return rate < 0 ? (int)rate : -EINVAL; + + wdt->clk_rate = (ulong)rate; + + return 0; +} + +static const struct wdt_ops qcom_wdt_ops = { + .start = qcom_wdt_start, + .stop = qcom_wdt_stop, + .reset = qcom_wdt_reset, +}; + +static const struct udevice_id qcom_wdt_ids[] = { + { .compatible = "qcom,kpss-wdt", .data = (ulong)&match_data_kpss }, + {} +}; + +U_BOOT_DRIVER(qcom_wdt) = { + .name = "qcom_wdt", + .id = UCLASS_WDT, + .of_match = qcom_wdt_ids, + .ops = &qcom_wdt_ops, + .probe = qcom_wdt_probe, + .priv_auto = sizeof(struct qcom_wdt), +}; diff --git a/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi b/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi index f9f6fea03b7..bd366389b23 100644 --- a/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi +++ b/dts/upstream/src/arm64/allwinner/sun50i-a100.dtsi @@ -252,6 +252,7 @@ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins>; + max-frequency = <150000000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -267,6 +268,7 @@ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; + max-frequency = <150000000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -282,6 +284,7 @@ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&mmc2_pins>; + max-frequency = <150000000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/dts/upstream/src/arm64/allwinner/sun50i-a133-liontron-h-a133l.dts b/dts/upstream/src/arm64/allwinner/sun50i-a133-liontron-h-a133l.dts new file mode 100644 index 00000000000..fe77178d3e3 --- /dev/null +++ b/dts/upstream/src/arm64/allwinner/sun50i-a133-liontron-h-a133l.dts @@ -0,0 +1,211 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Arm Ltd. + */ + +/dts-v1/; + +#include "sun50i-a100.dtsi" +#include "sun50i-a100-cpu-opp.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> + +/{ + model = "Liontron H-A133L"; + compatible = "liontron,h-a133l", "allwinner,sun50i-a100"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led { + function = LED_FUNCTION_POWER; + color = <LED_COLOR_ID_BLUE>; + gpios = <&pio 7 16 GPIO_ACTIVE_LOW>; /* PH16 */ + }; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply from a 12V->5V regulator */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_usb1_vbus: regulator-usb1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb1-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_vcc5v>; + enable-active-high; + gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */ + }; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&mmc0 { + vmmc-supply = <®_dcdc1>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + bus-width = <4>; + status = "okay"; +}; + +&mmc2 { + vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_eldo1>; + cap-mmc-hw-reset; + non-removable; + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pb-supply = <®_dcdc1>; + vcc-pc-supply = <®_eldo1>; + vcc-pf-supply = <®_dcdc1>; + vcc-ph-supply = <®_dcdc1>; +}; + +&r_i2c0 { + status = "okay"; + + axp803: pmic@34 { + compatible = "x-powers,axp803"; + reg = <0x34>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +#include "axp803.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-codec-avcc"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dram-1"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-usb-pl"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-io-usb-pd-emmc"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdd-cpux"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-usb-cpus"; +}; + +®_dcdc4 { + regulator-always-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + regulator-name = "vdd-sys"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vcc-dram"; +}; + +/* DCDC6 unused */ +/* DLDO3 unused */ +/* DLDO4 unused */ + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-pc-emmc"; +}; + +/* ELDO2 unused */ +/* ELDO3 unused */ + +®_fldo1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-cpus-usb"; +}; + +/* reg_drivevbus unused */ +/* dc1sw unused */ + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "host"; /* USB A type receptacle, always powered */ + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; diff --git a/dts/upstream/src/arm64/allwinner/sun50i-h618-yuzukihd-chameleon.dts b/dts/upstream/src/arm64/allwinner/sun50i-h618-yuzukihd-chameleon.dts new file mode 100644 index 00000000000..eae56908b9b --- /dev/null +++ b/dts/upstream/src/arm64/allwinner/sun50i-h618-yuzukihd-chameleon.dts @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2024 Arm Ltd. + */ + +/dts-v1/; + +#include "sun50i-h616.dtsi" +#include "sun50i-h616-cpu-opp.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + model = "Yuzuki Chameleon"; + compatible = "yuzukihd,chameleon", "allwinner,sun50i-h618"; + + aliases { + ethernet1 = &sdio_wifi; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply directly from the USB-C socket */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + wifi_pwrseq: pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rtc CLK_OSC32K_FANOUT>; + clock-names = "ext_clock"; + pinctrl-0 = <&x32clk_fanout_pin>; + pinctrl-names = "default"; + reset-gpios = <&pio 6 11 GPIO_ACTIVE_LOW>; /* PG11 */ + }; +}; + +&codec { + allwinner,audio-routing = "Line Out", "LINEOUT"; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ehci3 { + status = "okay"; +}; + +&mmc0 { + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + disable-wp; + vmmc-supply = <®_dldo1>; + status = "okay"; +}; + +&mmc1 { + bus-width = <4>; + mmc-pwrseq = <&wifi_pwrseq>; + non-removable; + vmmc-supply = <®_dldo1>; + vqmmc-supply = <®_dldo1>; + status = "okay"; + + sdio_wifi: wifi@1 { + reg = <1>; + interrupt-parent = <&pio>; + interrupts = <6 12 IRQ_TYPE_LEVEL_LOW>; /* PG12 */ + interrupt-names = "host-wake"; + }; +}; + +&mmc2 { + bus-width = <8>; + cap-mmc-hw-reset; + mmc-ddr-3_3v; + non-removable; + vmmc-supply = <®_dldo1>; + vqmmc-supply = <®_dldo1>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; + +&ohci3 { + status = "okay"; +}; + +&pio { + vcc-pc-supply = <®_dldo1>; + vcc-pf-supply = <®_dldo1>; /* via VCC_IO */ + vcc-pg-supply = <®_dldo1>; + vcc-ph-supply = <®_dldo1>; /* via VCC_IO */ + vcc-pi-supply = <®_dldo1>; +}; + +&r_i2c { + status = "okay"; + + axp313: pmic@36 { + compatible = "x-powers,axp313a"; + reg = <0x36>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&pio>; + interrupts = <2 2 IRQ_TYPE_LEVEL_LOW>; /* PC2 */ + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + + regulators { + /* Supplies VCC-PLL, so needs to be always on. */ + reg_aldo1: aldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc1v8"; + }; + + /* Supplies VCC-IO, so needs to be always on. */ + reg_dldo1: dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3"; + }; + + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <990000>; + regulator-name = "vdd-gpu-sys"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpu"; + }; + + reg_dcdc3: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vdd-dram"; + }; + }; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; + status = "okay"; +}; + +/* Connected to the Bluetooth UART pins of the XR829 Wifi/BT chip. */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; + uart-has-rtscts; + status = "okay"; +}; + +&usbotg { + /* + * PHY0 pins are connected to a USB-C socket, but a role switch + * is not implemented: both CC pins are pulled to GND. + * The VBUS pins power the device, so a fixed peripheral mode + * is the best choice. + * The board can be powered via GPIOs, in this case port0 *can* + * act as a host (with a cable/adapter ignoring CC), as VBUS is + * then provided by the GPIOs. Any user of this setup would + * need to adjust the DT accordingly: dr_mode set to "host", + * enabling OHCI0 and EHCI0. + */ + dr_mode = "peripheral"; + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 6 18 GPIO_ACTIVE_HIGH>; /* PG18 */ + usb0_vbus-supply = <®_vcc5v>; + usb1_vbus-supply = <®_vcc5v>; + usb2_vbus-supply = <®_vcc5v>; + usb3_vbus-supply = <®_vcc5v>; + status = "okay"; +}; diff --git a/env/Kconfig b/env/Kconfig index 58a0666cd49..c30785de48b 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -231,14 +231,6 @@ config ENV_IS_IN_MMC These two #defines specify the offset and size of the environment area within the specified MMC device. - If offset is positive (the usual case), it is treated as relative to - the start of the MMC partition. If offset is negative, it is treated - as relative to the end of the MMC partition. This can be useful if - your board may be fitted with different MMC devices, which have - different sizes for the MMC partitions, and you always want the - environment placed at the very end of the partition, to leave the - maximum possible space before it, to store other data. - These two values are in units of bytes, but must be aligned to an MMC sector boundary. @@ -249,9 +241,6 @@ config ENV_IS_IN_MMC valid backup copy in case the other copy is corrupted, e.g. due to a power failure during a "saveenv" operation. - This value may also be positive or negative; this is handled in the - same way as CONFIG_ENV_OFFSET. - In case CONFIG_ENV_MMC_EMMC_HW_PARTITION is 1 (i.e. environment in eMMC boot partition) then setting CONFIG_ENV_OFFSET_REDUND to the same value as CONFIG_ENV_OFFSET makes use of the second eMMC boot partition for @@ -618,9 +607,18 @@ config ENV_OFFSET Offset from the start of the device (or partition). This offset may be interpreted differently depending on the chosen - ENV_IS_IN_* options. For example, for ENV_IS_IN_MMC=y, this offset may - be negative to indicate an offset backwards from the end of the - partition. See the relevant help messages for more details. + ENV_IS_IN_* options. See the relevant help messages for more details. + +config ENV_OFFSET_RELATIVE_END + bool "Offset is relative to the end of the partition" + depends on ENV_IS_IN_MMC + help + Treat the environment offset as relative to the end of the MMC + hardware partition. This can be useful if your board may be fitted + with different MMC devices, which have different sizes for the MMC + hardware partitions, and you always want the environment placed at the + very end of the partition, to leave the maximum possible space before + it, to store other data. config ENV_OFFSET_REDUND hex "Redundant environment offset" @@ -633,9 +631,19 @@ config ENV_OFFSET_REDUND environment location. This offset may be interpreted differently depending on the chosen - ENV_IS_IN_* options. For example, for ENV_IS_IN_MMC=y, this offset may - be negative to indicate an offset backwards from the end of the - partition. See the relevant help messages for more details. + ENV_IS_IN_* options. See the relevant help messages for more details. + +config ENV_OFFSET_REDUND_RELATIVE_END + bool "Offset is relative to the end of the partition" + depends on SYS_REDUNDAND_ENVIRONMENT + depends on ENV_IS_IN_MMC + help + Treat the redundant environment offset as relative to the end of the + MMC hardware partition. This can be useful if your board may be + fitted with different MMC devices, which have different sizes for the + MMC hardware partitions, and you always want the environment placed at + the very end of the partition, to leave the maximum possible space + before it, to store other data. config ENV_SIZE hex "Environment Size" diff --git a/env/common.c b/env/common.c index 1e23c5de436..05e78d63874 100644 --- a/env/common.c +++ b/env/common.c @@ -82,6 +82,10 @@ int env_do_env_set(int flag, int argc, char *const argv[], int env_flag) } } debug("Final value for argc=%d\n", argc); + /* Exit early if we don't have an env to apply */ + if (argc < 2) + return 0; + name = argv[1]; if (strchr(name, '=')) { diff --git a/env/mmc.c b/env/mmc.c index 11375bd4464..46ffa6386d6 100644 --- a/env/mmc.c +++ b/env/mmc.c @@ -29,11 +29,19 @@ #else /* Default ENV offset when not defined in Device Tree */ +#if !defined(CONFIG_ENV_OFFSET_RELATIVE_END) #define ENV_MMC_OFFSET CONFIG_ENV_OFFSET +#else +#define ENV_MMC_OFFSET (-(CONFIG_ENV_OFFSET)) +#endif #if defined(CONFIG_ENV_OFFSET_REDUND) +#if !defined(CONFIG_ENV_OFFSET_REDUND_RELATIVE_END) #define ENV_MMC_OFFSET_REDUND CONFIG_ENV_OFFSET_REDUND #else +#define ENV_MMC_OFFSET_REDUND (-(CONFIG_ENV_OFFSET_REDUND)) +#endif +#else #define ENV_MMC_OFFSET_REDUND ENV_MMC_INVALID_OFFSET #endif #endif diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c index 02c4ac2cb93..868a2c1804a 100644 --- a/fs/ext4/ext4_journal.c +++ b/fs/ext4/ext4_journal.c @@ -131,6 +131,13 @@ int ext4fs_log_gdt(char *gd_table) struct ext_filesystem *fs = get_fs(); short i; long int var = fs->gdtable_blkno; + + /* Make sure there is enough journal entries */ + if (fs->no_blk_pergdt > MAX_JOURNAL_ENTRIES) { + log_err("*** Not enough journal entries allocated\n"); + return -ENOMEM; + } + for (i = 0; i < fs->no_blk_pergdt; i++) { journal_ptr[gindex]->buf = zalloc(fs->blksz); if (!journal_ptr[gindex]->buf) @@ -580,6 +580,7 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, int ret; loff_t size; loff_t read_len; + phys_addr_t read_addr; /* get the actual size of the file */ ret = info->size(filename, &size); @@ -597,7 +598,9 @@ static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset, lmb_dump_all(); - if (!lmb_alloc_addr(addr, read_len, LMB_NONE)) + read_addr = (phys_addr_t)addr; + if (!lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &read_addr, read_len, + LMB_NONE)) return 0; log_err("** Reading file would overwrite reserved memory **\n"); diff --git a/include/configs/astro_mcf5373l.h b/include/configs/astro_mcf5373l.h deleted file mode 100644 index 65224324fbc..00000000000 --- a/include/configs/astro_mcf5373l.h +++ /dev/null @@ -1,187 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Configuration settings for the Sentec Cobra Board. - * - * (C) Copyright 2003 Josef Baumgartner <josef.baumgartner@telex.de> - */ - -/* - * configuration for ASTRO "Urmel" board. - * Originating from Cobra5272 configuration, messed up by - * Wolfgang Wegner <w.wegner@astro-kom.de> - * Please do not bother the original author with bug reports - * concerning this file. - */ - -#ifndef _CONFIG_ASTRO_MCF5373L_H -#define _CONFIG_ASTRO_MCF5373L_H - -#include <linux/stringify.h> - -/* - * set the card type to actually compile for; either of - * the possibilities listed below has to be used! - */ -#define ASTRO_V532 1 - -#if ASTRO_V532 -#define ASTRO_ID 0xF8 -#elif ASTRO_V512 -#define ASTRO_ID 0xFA -#elif ASTRO_TWIN7S2 -#define ASTRO_ID 0xF9 -#elif ASTRO_V912 -#define ASTRO_ID 0xFC -#elif ASTRO_COFDMDUOS2 -#define ASTRO_ID 0xFB -#else -#error No card type defined! -#endif - -/* I2C */ - -/* - * Defines processor clock - important for correct timings concerning serial - * interface etc. - */ - -#define CFG_SYS_CLK 80000000 -#define CFG_SYS_CPU_CLK (CFG_SYS_CLK * 3) -#define CFG_SYS_SDRAM_SIZE 32 /* SDRAM size in MB */ - -/* - * Define baudrate for UART1 (console output, tftp, ...) - * default value of CONFIG_BAUDRATE for Sentec board: 19200 baud - * CFG_SYS_BAUDRATE_TABLE defines values that can be selected - * in u-boot command interface - */ - -#define CFG_SYS_UART_PORT (2) -#define CFG_SYS_UART2_ALT3_GPIO - -/* here we put our FPGA configuration... */ - -/* Define user parameters that have to be customized most likely */ - -/* AUTOBOOT settings - booting images automatically by u-boot after power on */ - -/* - * The following settings will be contained in the environment block ; if you - * want to use a neutral environment all those settings can be manually set in - * u-boot: 'set' command - */ - -#define CFG_EXTRA_ENV_SETTINGS \ - "loaderversion=11\0" \ - "card_id="__stringify(ASTRO_ID)"\0" \ - "alterafile=0\0" \ - "xilinxfile=0\0" \ - "xilinxload=imxtract 0x540000 $xilinxfile 0x41000000&&"\ - "fpga load 0 0x41000000 $filesize\0" \ - "alteraload=imxtract 0x6c0000 $alterafile 0x41000000&&"\ - "fpga load 1 0x41000000 $filesize\0" \ - "env_default=1\0" \ - "env_check=if test $env_default -eq 1;"\ - " then setenv env_default 0;saveenv;fi\0" - -/* - * "update" is a non-standard command that has to be supplied - * by external update.c; This is not included in mainline because - * it needs non-blocking CFI routines. - */ - -#define CFG_SYS_FPGA_WAIT 1000 - -/* End of user parameters to be customized */ - -/* Defines memory range for test */ - -/* - * Low Level Configuration Settings - * (address mappings, register initial values, etc.) - * You should know what you are doing if you make changes here. - */ - -/* Base register address */ - -#define CFG_SYS_MBAR 0xFC000000 /* Register Base Addrs */ - -/* System Conf. Reg. & System Protection Reg. */ - -#define CFG_SYS_SCR 0x0003; -#define CFG_SYS_SPR 0xffff; - -/* - * Definitions for initial stack pointer and data area (in internal SRAM) - */ -#define CFG_SYS_INIT_RAM_ADDR 0x80000000 -#define CFG_SYS_INIT_RAM_SIZE 0x8000 -#define CFG_SYS_INIT_RAM_CTRL 0x221 - -/* - * Start addresses for the final memory configuration - * (Set up by the startup code) - * for MCF5373, the allowable range is 0x40000000 to 0x7FF00000 - */ -#define CFG_SYS_SDRAM_BASE 0x40000000 - -/* - * Chipselect bank definitions - * - * CS0 - Flash 32MB (first 16MB) - * CS1 - Flash 32MB (second half) - * CS2 - FPGA - * CS3 - FPGA - * CS4 - unused - * CS5 - unused - */ -#define CFG_SYS_CS0_BASE 0 -#define CFG_SYS_CS0_MASK 0x00ff0001 -#define CFG_SYS_CS0_CTRL 0x00001fc0 - -#define CFG_SYS_CS1_BASE 0x01000000 -#define CFG_SYS_CS1_MASK 0x00ff0001 -#define CFG_SYS_CS1_CTRL 0x00001fc0 - -#define CFG_SYS_CS2_BASE 0x20000000 -#define CFG_SYS_CS2_MASK 0x00ff0001 -#define CFG_SYS_CS2_CTRL 0x0000fec0 - -#define CFG_SYS_CS3_BASE 0x21000000 -#define CFG_SYS_CS3_MASK 0x00ff0001 -#define CFG_SYS_CS3_CTRL 0x0000fec0 - -#define CFG_SYS_FLASH_BASE 0x00000000 - -/* Reserve 256 kB for Monitor */ - -/* - * For booting Linux, the board info and command line data - * have to be in the first 8 MB of memory, since this is - * the maximum mapped by the Linux kernel during initialization ?? - */ -#define CFG_SYS_BOOTMAPSZ (CFG_SYS_SDRAM_BASE + \ - (CFG_SYS_SDRAM_SIZE << 20)) - -/* FLASH organization */ - -#define CFG_SYS_FLASH_SIZE 0x2000000 - -#define LDS_BOARD_TEXT \ - . = DEFINED(env_offset) ? env_offset : .; \ - env/embedded.o(.text*) - -/* Cache Configuration */ - -#define ICACHE_STATUS (CFG_SYS_INIT_RAM_ADDR + \ - CFG_SYS_INIT_RAM_SIZE - 8) -#define DCACHE_STATUS (CFG_SYS_INIT_RAM_ADDR + \ - CFG_SYS_INIT_RAM_SIZE - 4) -#define CFG_SYS_ICACHE_INV (CF_CACR_CINVA) -#define CFG_SYS_CACHE_ACR0 (CFG_SYS_SDRAM_BASE | \ - CF_ADDRMASK(CFG_SYS_SDRAM_SIZE) | \ - CF_ACR_EN | CF_ACR_SM_ALL) -#define CFG_SYS_CACHE_ICACR (CF_CACR_EC | CF_CACR_CINVA | \ - CF_CACR_DCM_P) - -#endif /* _CONFIG_ASTRO_MCF5373L_H */ diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index db2ac7f83bb..44d4960d487 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -14,6 +14,8 @@ #define CFG_SYS_SDRAM_BASE 0 #define CFG_SYS_SDRAM_SIZE \ (SB_TO_UL(CONFIG_SANDBOX_RAM_SIZE_MB) << 20) +/** define SB_SDRAM_ALIGN - Alignment of emulated RAM */ +#define SB_SDRAM_ALIGN 0x400000 #define CFG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ 115200} diff --git a/include/dt-bindings/clock/xlnx-zynqmp-clk.h b/include/dt-bindings/clock/xlnx-zynqmp-clk.h deleted file mode 100644 index cdc4c0b9a37..00000000000 --- a/include/dt-bindings/clock/xlnx-zynqmp-clk.h +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Xilinx Zynq MPSoC Firmware layer - * - * Copyright (C) 2014-2018 Xilinx, Inc. - * - */ - -#ifndef _DT_BINDINGS_CLK_ZYNQMP_H -#define _DT_BINDINGS_CLK_ZYNQMP_H - -#define IOPLL 0 -#define RPLL 1 -#define APLL 2 -#define DPLL 3 -#define VPLL 4 -#define IOPLL_TO_FPD 5 -#define RPLL_TO_FPD 6 -#define APLL_TO_LPD 7 -#define DPLL_TO_LPD 8 -#define VPLL_TO_LPD 9 -#define ACPU 10 -#define ACPU_HALF 11 -#define DBF_FPD 12 -#define DBF_LPD 13 -#define DBG_TRACE 14 -#define DBG_TSTMP 15 -#define DP_VIDEO_REF 16 -#define DP_AUDIO_REF 17 -#define DP_STC_REF 18 -#define GDMA_REF 19 -#define DPDMA_REF 20 -#define DDR_REF 21 -#define SATA_REF 22 -#define PCIE_REF 23 -#define GPU_REF 24 -#define GPU_PP0_REF 25 -#define GPU_PP1_REF 26 -#define TOPSW_MAIN 27 -#define TOPSW_LSBUS 28 -#define GTGREF0_REF 29 -#define LPD_SWITCH 30 -#define LPD_LSBUS 31 -#define USB0_BUS_REF 32 -#define USB1_BUS_REF 33 -#define USB3_DUAL_REF 34 -#define USB0 35 -#define USB1 36 -#define CPU_R5 37 -#define CPU_R5_CORE 38 -#define CSU_SPB 39 -#define CSU_PLL 40 -#define PCAP 41 -#define IOU_SWITCH 42 -#define GEM_TSU_REF 43 -#define GEM_TSU 44 -#define GEM0_TX 45 -#define GEM1_TX 46 -#define GEM2_TX 47 -#define GEM3_TX 48 -#define GEM0_RX 49 -#define GEM1_RX 50 -#define GEM2_RX 51 -#define GEM3_RX 52 -#define QSPI_REF 53 -#define SDIO0_REF 54 -#define SDIO1_REF 55 -#define UART0_REF 56 -#define UART1_REF 57 -#define SPI0_REF 58 -#define SPI1_REF 59 -#define NAND_REF 60 -#define I2C0_REF 61 -#define I2C1_REF 62 -#define CAN0_REF 63 -#define CAN1_REF 64 -#define CAN0 65 -#define CAN1 66 -#define DLL_REF 67 -#define ADMA_REF 68 -#define TIMESTAMP_REF 69 -#define AMS_REF 70 -#define PL0_REF 71 -#define PL1_REF 72 -#define PL2_REF 73 -#define PL3_REF 74 -#define WDT 75 -#define IOPLL_INT 76 -#define IOPLL_PRE_SRC 77 -#define IOPLL_HALF 78 -#define IOPLL_INT_MUX 79 -#define IOPLL_POST_SRC 80 -#define RPLL_INT 81 -#define RPLL_PRE_SRC 82 -#define RPLL_HALF 83 -#define RPLL_INT_MUX 84 -#define RPLL_POST_SRC 85 -#define APLL_INT 86 -#define APLL_PRE_SRC 87 -#define APLL_HALF 88 -#define APLL_INT_MUX 89 -#define APLL_POST_SRC 90 -#define DPLL_INT 91 -#define DPLL_PRE_SRC 92 -#define DPLL_HALF 93 -#define DPLL_INT_MUX 94 -#define DPLL_POST_SRC 95 -#define VPLL_INT 96 -#define VPLL_PRE_SRC 97 -#define VPLL_HALF 98 -#define VPLL_INT_MUX 99 -#define VPLL_POST_SRC 100 -#define CAN0_MIO 101 -#define CAN1_MIO 102 -#define ACPU_FULL 103 -#define GEM0_REF 104 -#define GEM1_REF 105 -#define GEM2_REF 106 -#define GEM3_REF 107 -#define GEM0_REF_UNG 108 -#define GEM1_REF_UNG 109 -#define GEM2_REF_UNG 110 -#define GEM3_REF_UNG 111 -#define LPD_WDT 112 - -#endif diff --git a/include/efi_api.h b/include/efi_api.h index eb61eafa028..77a05f752e5 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -238,6 +238,10 @@ enum efi_reset_type { EFI_GUID(0xcce33c35, 0x74ac, 0x4087, 0xbc, 0xe7, \ 0x8b, 0x29, 0xb0, 0x2e, 0xeb, 0x27) +#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \ + EFI_GUID(0x49152e77, 0x1ada, 0x4764, 0xb7, 0xa2, \ + 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b) + struct efi_conformance_profiles_table { u16 version; u16 number_of_profiles; @@ -259,6 +263,22 @@ struct efi_capsule_result_variable_header { efi_status_t capsule_status; } __packed; +/** + * struct efi_system_table_pointer - struct to store the pointer of system + * table. + * @signature: The signature of this struct. + * @efi_system_table_base: The physical address of System Table. + * @crc32: CRC32 checksum + * + * This struct is design for hardware debugger to search through memory to + * get the address of EFI System Table. + */ +struct efi_system_table_pointer { + u64 signature; + efi_physical_addr_t efi_system_table_base; + u32 crc32; +}; + struct efi_memory_range { efi_physical_addr_t address; u64 length; @@ -558,6 +578,57 @@ struct efi_loaded_image { efi_status_t (EFIAPI *unload)(efi_handle_t image_handle); }; +#define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01 +#define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED 0x02 + +#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01 + +/** + * struct efi_debug_image_info_normal - Store Debug Information for normal + * image. + * @image_info_type: the type of image info. + * @loaded_image_protocol_instance: the pointer to struct efi_loaded_image. + * @image_handle: the EFI handle of the image. + * + * This struct is created by efi_load_image() and store the information + * for debugging an normal image. + */ +struct efi_debug_image_info_normal { + u32 image_info_type; + struct efi_loaded_image *loaded_image_protocol_instance; + efi_handle_t image_handle; +}; + +/** + * union efi_debug_image_info - The union to store a pointer for EFI + * DEBUG IMAGE INFO. + * @image_info_type: the type of the image_info if it is not a normal image. + * @normal_image: The pointer to a normal image. + * + * This union is for a pointer that can point to the struct of normal_image. + * Or it points to an image_info_type. + */ +union efi_debug_image_info { + u32 *image_info_type; + struct efi_debug_image_info_normal *normal_image; +}; + +/** + * struct efi_debug_image_info_table_header - store the array of + * struct efi_debug_image_info. + * @update_status: Status to notify this struct is ready to use or not. + * @table_size: The number of elements of efi_debug_image_info_table. + * @efi_debug_image_info_table: The array of efi_debug_image_info. + * + * This struct stores the array of efi_debug_image_info. The + * number of elements is table_size. + */ +struct efi_debug_image_info_table_header { + volatile u32 update_status; + u32 table_size; + union efi_debug_image_info *efi_debug_image_info_table; +}; + #define EFI_DEVICE_PATH_PROTOCOL_GUID \ EFI_GUID(0x09576e91, 0x6d3f, 0x11d2, \ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b) diff --git a/include/efi_config.h b/include/efi_config.h index d7c1601137e..23211e799fc 100644 --- a/include/efi_config.h +++ b/include/efi_config.h @@ -82,6 +82,7 @@ struct eficonfig_item { * @current_volume: pointer to the efi_simple_file_system_protocol * @dp_volume: pointer to device path of the selected device * @current_path: pointer to the selected file path string + * @uri: URI for HTTP Boot * @filepath_list: list_head structure for file path list * @file_selectred: flag indicates file selecting status */ @@ -89,6 +90,7 @@ struct eficonfig_select_file_info { struct efi_simple_file_system_protocol *current_volume; struct efi_device_path *dp_volume; u16 *current_path; + u16 *uri; struct list_head filepath_list; bool file_selected; }; diff --git a/include/efi_loader.h b/include/efi_loader.h index 8fd09aad2d0..3e70ac07055 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -312,6 +312,8 @@ extern const struct efi_hii_config_routing_protocol efi_hii_config_routing; extern const struct efi_hii_config_access_protocol efi_hii_config_access; extern const struct efi_hii_database_protocol efi_hii_database; extern const struct efi_hii_string_protocol efi_hii_string; +/* structure for EFI_DEBUG_SUPPORT_PROTOCOL */ +extern struct efi_debug_image_info_table_header efi_m_debug_info_table_header; uint16_t *efi_dp_str(struct efi_device_path *dp); @@ -643,6 +645,13 @@ efi_status_t efi_tcg2_measure_dtb(void *dtb); efi_status_t efi_root_node_register(void); /* Called by bootefi to initialize runtime */ efi_status_t efi_initialize_system_table(void); +/* Called by bootefi to initialize debug */ +efi_status_t efi_initialize_system_table_pointer(void); +/* Called by efi_load_image for register debug info */ +efi_status_t efi_core_new_debug_image_info_entry(u32 image_info_type, + struct efi_loaded_image *loaded_image, + efi_handle_t image_handle); +void efi_core_remove_debug_image_info_entry(efi_handle_t image_handle); /* efi_runtime_detach() - detach unimplemented runtime functions */ void efi_runtime_detach(void); /* efi_convert_pointer() - convert pointer to virtual address */ @@ -871,6 +880,16 @@ efi_status_t efi_next_variable_name(efi_uintn_t *size, u16 **buf, #define efi_size_in_pages(size) (((size) + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT) /* Allocate boot service data pool memory */ void *efi_alloc(size_t len); +/** + * efi_realloc() - reallocate boot services data pool memory + * + * Reallocate memory from pool for a new size and copy the data from old one. + * + * @ptr: pointer to the buffer + * @size: number of bytes to allocate + * Return: EFI status to indicate success or not + */ +efi_status_t efi_realloc(void **ptr, size_t len); /* Allocate pages on the specified alignment */ void *efi_alloc_aligned_pages(u64 len, int memory_type, size_t align); /* More specific EFI memory allocator, called by EFI payloads */ diff --git a/include/fsl_ifc.h b/include/fsl_ifc.h index 3ac22687930..1c363115beb 100644 --- a/include/fsl_ifc.h +++ b/include/fsl_ifc.h @@ -803,29 +803,29 @@ void init_final_memctl_regs(void); ((struct fsl_ifc_fcm *)CFG_SYS_IFC_ADDR) #define get_ifc_cspr_ext(i) \ - (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext)) + ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext) #define get_ifc_cspr(i) \ - (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr)) + ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr) #define get_ifc_csor_ext(i) \ - (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext)) + ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext) #define get_ifc_csor(i) \ - (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor)) + ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor) #define get_ifc_amask(i) \ - (ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask)) + ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask) #define get_ifc_ftim(i, j) \ - (ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j])) + ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j]) #define set_ifc_cspr_ext(i, v) \ - (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v)) + ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v) #define set_ifc_cspr(i, v) \ - (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v)) + ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v) #define set_ifc_csor_ext(i, v) \ - (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v)) + ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v) #define set_ifc_csor(i, v) \ - (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v)) + ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v) #define set_ifc_amask(i, v) \ - (ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v)) + ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v) #define set_ifc_ftim(i, j, v) \ - (ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v)) + ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v) enum ifc_chip_sel { IFC_CS0, diff --git a/include/image.h b/include/image.h index 37506c81cdb..b695cc39447 100644 --- a/include/image.h +++ b/include/image.h @@ -1689,7 +1689,7 @@ struct sig_header_s { */ int image_pre_load(ulong addr); -#if defined(USE_HOSTCC) +#if defined(USE_HOSTCC) && CONFIG_IS_ENABLED(LIBCRYPTO) /** * rsa_verify_openssl() - Verify a signature against some data with openssl API * diff --git a/include/lmb.h b/include/lmb.h index 606a92cca48..5d5f037ccb9 100644 --- a/include/lmb.h +++ b/include/lmb.h @@ -32,6 +32,18 @@ #define LMB_NONOTIFY BIT(3) /** + * enum lmb_mem_type - type of memory allocation request + * @LMB_MEM_ALLOC_ADDR: request for a particular region of memory + * @LMB_MEM_ALLOC_ANY: allocate any available memory region + * @LMB_MEM_ALLOC_MAX: allocate memory below a particular address + */ +enum lmb_mem_type { + LMB_MEM_ALLOC_ADDR = 1, + LMB_MEM_ALLOC_ANY, + LMB_MEM_ALLOC_MAX, +}; + +/** * enum lmb_map_op - memory map operation */ enum lmb_map_op { @@ -68,6 +80,37 @@ struct lmb { }; /** + * lmb_alloc_mem() - Request LMB memory + * @type: Type of memory allocation request + * @align: Alignment of the memory region requested(0 for none) + * @addr: Base address of the allocated memory region + * @size: Size in bytes of the allocation request + * @flags: Memory region attributes to be set + * + * Allocate a region of memory where the allocation is based on the parameters + * that have been passed to the function.The first parameter specifies the + * type of allocation that is being requested. The second parameter, @align + * is used to specify if the allocation is to be made with a particular + * alignment. Use 0 for no alignment requirements. + * + * The allocated address is returned through the @addr parameter when @type + * is @LMB_MEM_ALLOC_ANY or @LMB_MEM_ALLOC_MAX. If @type is + * @LMB_MEM_ALLOC_ADDR the @addr parameter would contain the address being + * requested. + * + * The flags parameter is used to specify the memory attributes of the + * requested region. + * + * Return: 0 on success, -ve value on failure + * + * When the allocation is of type @LMB_MEM_ALLOC_ADDR, the return value can + * be -EINVAL if the requested memory region is not part of the LMB memory + * map, and -EEXIST if the requested region is already allocated. + */ +int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr, + phys_size_t size, u32 flags); + +/** * lmb_init() - Initialise the LMB module. * * Return: 0 on success, negative error code on failure. @@ -81,65 +124,11 @@ struct lmb { */ int lmb_init(void); -/** - * lmb_add_memory() - Add memory range for LMB allocations. - * - * Add the entire available memory range to the pool of memory that - * can be used by the LMB module for allocations. - */ -void lmb_add_memory(void); - long lmb_add(phys_addr_t base, phys_size_t size); -/** - * lmb_reserve() - Reserve one region with a specific flags bitfield - * @base: Base address of the memory region - * @size: Size of the memory region - * @flags: Flags for the memory region - * - * Return: - * * %0 - Added successfully, or it's already added (only if LMB_NONE) - * * %-EEXIST - The region is already added, and flags != LMB_NONE - * * %-1 - Failure - */ -long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags); - -phys_addr_t lmb_alloc(phys_size_t size, ulong align); phys_size_t lmb_get_free_size(phys_addr_t addr); /** - * lmb_alloc_base() - Allocate specified memory region with specified - * attributes - * @size: Size of the region requested - * @align: Alignment of the memory region requested - * @max_addr: Maximum address of the requested region - * @flags: Memory region attributes to be set - * - * Allocate a region of memory with the attributes specified through the - * parameter. The max_addr parameter is used to specify the maximum address - * below which the requested region should be allocated. - * - * Return: Base address on success, 0 on error. - */ -phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, - uint flags); - -/** - * lmb_alloc_addr() - Allocate specified memory address with specified attributes - * - * @base: Base Address requested - * @size: Size of the region requested - * @flags: Memory region attributes to be set - * - * Allocate a region of memory with the attributes specified through the - * parameter. The base parameter is used to specify the base address - * of the requested region. - * - * Return: 0 on success -1 on error - */ -int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags); - -/** * lmb_is_reserved_flags() - Test if address is in reserved region with flag * bits set * @addr: Address to be tested @@ -153,16 +142,14 @@ int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags); int lmb_is_reserved_flags(phys_addr_t addr, int flags); /** - * lmb_free_flags() - Free up a region of memory + * lmb_free() - Free up a region of memory * @base: Base Address of region to be freed * @size: Size of the region to be freed * @flags: Memory region attributes * * Return: 0 on success, negative error code on failure. */ -long lmb_free_flags(phys_addr_t base, phys_size_t size, uint flags); - -long lmb_free(phys_addr_t base, phys_size_t size); +long lmb_free(phys_addr_t base, phys_size_t size, u32 flags); void lmb_dump_all(void); void lmb_dump_all_force(void); @@ -175,7 +162,7 @@ void lmb_pop(struct lmb *store); static inline int lmb_read_check(phys_addr_t addr, phys_size_t len) { - return lmb_alloc_addr(addr, len, LMB_NONE); + return lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, len, LMB_NONE); } /** diff --git a/include/log.h b/include/log.h index dd44badc361..59c66eb7909 100644 --- a/include/log.h +++ b/include/log.h @@ -176,7 +176,7 @@ int _log_buffer(enum log_category_t cat, enum log_level_t level, #define _LOG_MAX_LEVEL LOGL_INFO #endif -#define log_emer(_fmt...) log(LOG_CATEGORY, LOGL_EMERG, ##_fmt) +#define log_emerg(_fmt...) log(LOG_CATEGORY, LOGL_EMERG, ##_fmt) #define log_alert(_fmt...) log(LOG_CATEGORY, LOGL_ALERT, ##_fmt) #define log_crit(_fmt...) log(LOG_CATEGORY, LOGL_CRIT, ##_fmt) #define log_err(_fmt...) log(LOG_CATEGORY, LOGL_ERR, ##_fmt) diff --git a/include/ndisc.h b/include/ndisc.h index d0fe3acca4a..7d9e58aa1c2 100644 --- a/include/ndisc.h +++ b/include/ndisc.h @@ -10,8 +10,6 @@ #ifndef __NDISC_H__ #define __NDISC_H__ -#include <ndisc.h> - /* struct nd_msg - ICMPv6 Neighbour Discovery message format */ struct nd_msg { struct icmp6hdr icmph; diff --git a/include/net-common.h b/include/net-common.h index c04f86bdfcc..1112af381a9 100644 --- a/include/net-common.h +++ b/include/net-common.h @@ -492,6 +492,17 @@ int dhcp_run(ulong addr, const char *fname, bool autoload); int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); /** + * do_sntp - Run the sntp command + * + * @cmdtp: Unused + * @flag: Command flags (CMD_FLAG_...) + * @argc: Number of arguments + * @argv: List of arguments + * Return: result (see enum command_ret_t) + */ +int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); + +/** * do_tftpb - Run the tftpboot command * * @cmdtp: Command information for tftpboot @@ -574,4 +585,6 @@ extern struct wget_http_info default_wget_info; extern struct wget_http_info *wget_info; int wget_request(ulong dst_addr, char *uri, struct wget_http_info *info); +void net_sntp_set_rtc(u32 seconds); + #endif /* __NET_COMMON_H__ */ diff --git a/include/net-lwip.h b/include/net-lwip.h index b762956e8fd..f54f23471f1 100644 --- a/include/net-lwip.h +++ b/include/net-lwip.h @@ -6,6 +6,20 @@ #include <lwip/ip4.h> #include <lwip/netif.h> +/* HTTPS authentication mode */ +enum auth_mode { + AUTH_NONE, + AUTH_OPTIONAL, + AUTH_REQUIRED, +}; + +extern char *cacert; +extern size_t cacert_size; +extern enum auth_mode cacert_auth_mode; +extern bool cacert_initialized; + +int set_cacert_builtin(void); + enum proto_t { TFTPGET }; @@ -17,12 +31,14 @@ static inline int eth_is_on_demand_init(void) int eth_init_state_only(void); /* Set active state */ +int net_lwip_dns_init(void); int net_lwip_eth_start(void); struct netif *net_lwip_new_netif(struct udevice *udev); struct netif *net_lwip_new_netif_noip(struct udevice *udev); void net_lwip_remove_netif(struct netif *netif); struct netif *net_lwip_get_netif(void); int net_lwip_rx(struct udevice *udev, struct netif *netif); +int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip); /** * wget_validate_uri() - varidate the uri diff --git a/include/part.h b/include/part.h index 7075b2cb116..b772fb34c8a 100644 --- a/include/part.h +++ b/include/part.h @@ -8,7 +8,6 @@ #include <blk.h> #include <u-boot/uuid.h> -#include <linker_lists.h> #include <linux/errno.h> #include <linux/list.h> @@ -647,6 +646,20 @@ int gpt_verify_partitions(struct blk_desc *desc, */ int get_disk_guid(struct blk_desc *desc, char *guid); +/** + * part_get_gpt_pte() - Get the GPT partition table entry of a partition + * + * This function reads the GPT partition table entry (PTE) for a given + * block device and partition number. + * + * @desc: block device descriptor + * @part: partition number for which to return the PTE + * @gpt_e: GPT partition table entry + * + * Return: 0 on success, otherwise error + */ +int part_get_gpt_pte(struct blk_desc *desc, int part, gpt_entry *gpt_e); + #endif #if CONFIG_IS_ENABLED(DOS_PARTITION) diff --git a/include/part_efi.h b/include/part_efi.h index 59b7895b8a2..fb402df6f13 100644 --- a/include/part_efi.h +++ b/include/part_efi.h @@ -138,4 +138,24 @@ typedef struct _legacy_mbr { __le16 signature; } __packed legacy_mbr; +#define EFI_PARTITION_INFO_PROTOCOL_GUID \ + EFI_GUID(0x8cf2f62c, 0xbc9b, 0x4821, 0x80, \ + 0x8d, 0xec, 0x9e, 0xc4, 0x21, 0xa1, 0xa0) + +#define EFI_PARTITION_INFO_PROTOCOL_REVISION 0x0001000 +#define PARTITION_TYPE_OTHER 0x00 +#define PARTITION_TYPE_MBR 0x01 +#define PARTITION_TYPE_GPT 0x02 + +struct efi_partition_info { + u32 revision; + u32 type; + u8 system; + u8 reserved[7]; + union { + struct partition mbr; + gpt_entry gpt; + } info; +} __packed; + #endif /* _DISK_PART_EFI_H */ diff --git a/include/sata.h b/include/sata.h index 8414e77e42b..868e89464f0 100644 --- a/include/sata.h +++ b/include/sata.h @@ -1,6 +1,7 @@ #ifndef __SATA_H__ #define __SATA_H__ -#include <part.h> + +#include <stdbool.h> int sata_probe(int devnum); int sata_remove(int devnum); diff --git a/include/spl_gpio.h b/include/spl_gpio.h index b33261a6485..a8aed4d77b9 100644 --- a/include/spl_gpio.h +++ b/include/spl_gpio.h @@ -9,7 +9,7 @@ #ifndef __SPL_GPIO_H #define __SPL_GPIO_H -#include <asm/gpio.h> +#include <linux/types.h> /* * The functions listed here should be implemented in the SoC GPIO driver. diff --git a/include/tpm-v2.h b/include/tpm-v2.h index ece422df0c7..f3eb2ef5643 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -20,6 +20,7 @@ #define __TPM_V2_H #include <tpm-common.h> +#include <linux/errno.h> struct udevice; @@ -266,6 +267,7 @@ enum tpm2_return_codes { * TPM2 algorithms. */ enum tpm2_algorithms { + TPM2_ALG_INVAL = -EINVAL, TPM2_ALG_SHA1 = 0x04, TPM2_ALG_XOR = 0x0A, TPM2_ALG_SHA256 = 0x0B, diff --git a/include/vsc9953.h b/include/vsc9953.h index fd52c93044b..1a1455af4f9 100644 --- a/include/vsc9953.h +++ b/include/vsc9953.h @@ -8,8 +8,6 @@ #ifndef _VSC9953_H_ #define _VSC9953_H_ -#include <config.h> -#include <miiphy.h> #include <asm/types.h> #include <linux/bitops.h> diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index dc06abc52fc..7ef8a58847f 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -8,6 +8,8 @@ #ifndef _ZYNQMP_FIRMWARE_H_ #define _ZYNQMP_FIRMWARE_H_ +#include <compiler.h> + enum pm_api_id { PM_GET_API_VERSION = 1, PM_SET_CONFIGURATION = 2, @@ -512,4 +514,11 @@ struct zynqmp_ipi_msg { #define PM_REG_PMC_GLOBAL_NODE 0x30000004 #define PMC_MULTI_BOOT_MODE_REG_OFFSET 0x4 +#define __data __section(".data") + +typedef int (*smc_call_handler_t)(u32 api_id, u32 arg0, u32 arg1, u32 arg2, + u32 arg3, u32 *ret_payload); + +extern smc_call_handler_t __data smc_call_handler; + #endif /* _ZYNQMP_FIRMWARE_H_ */ diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c index f0095e9dbcf..7415d685ee1 100644 --- a/lib/ecdsa/ecdsa-libcrypto.c +++ b/lib/ecdsa/ecdsa-libcrypto.c @@ -34,6 +34,112 @@ struct signer { void *signature; /* Pointer to output signature. Do not free()!*/ }; +struct ecdsa_public_key { + const char *curve_name; + const uint8_t *x; + const uint8_t *y; + int size_bits; +}; + +static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node) +{ + int x_len; + int y_len; + + key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL); + if (!key->curve_name) + return -ENOMSG; + + if (!strcmp(key->curve_name, "prime256v1")) + key->size_bits = 256; + else if (!strcmp(key->curve_name, "secp384r1")) + key->size_bits = 384; + else + return -EINVAL; + + key->x = fdt_getprop(fdt, node, "ecdsa,x-point", &x_len); + key->y = fdt_getprop(fdt, node, "ecdsa,y-point", &y_len); + + if (!key->x || !key->y) + return -EINVAL; + + if (x_len != key->size_bits / 8 || y_len != key->size_bits / 8) + return -EINVAL; + + return 0; +} + +static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node) +{ + struct ecdsa_public_key pubkey; + const EC_GROUP *group; + EC_POINT *point; + EC_KEY *ec_key; + int ret; + int nid; + int len; + + ret = fdt_get_key(&pubkey, fdt, node); + if (ret) { + fprintf(stderr, "Failed to parse ECDSA key from FDT node %d (ret=%d)\n", node, ret); + return ret; + } + + if (!strcmp(pubkey.curve_name, "prime256v1")) { + nid = NID_X9_62_prime256v1; + } else if (!strcmp(pubkey.curve_name, "secp384r1")) { + nid = NID_secp384r1; + } else { + fprintf(stderr, "Unsupported curve name: '%s'\n", pubkey.curve_name); + return -EINVAL; + } + + fprintf(stderr, "Loading ECDSA key: curve=%s, bits=%d\n", pubkey.curve_name, + pubkey.size_bits); + + ec_key = EC_KEY_new_by_curve_name(nid); + if (!ec_key) { + fprintf(stderr, "Failed to allocate EC_KEY for curve %s\n", pubkey.curve_name); + return -ENOMEM; + } + + group = EC_KEY_get0_group(ec_key); + point = EC_POINT_new(group); + if (!point) { + fprintf(stderr, "Failed to allocate EC_POINT\n"); + EC_KEY_free(ec_key); + return -ENOMEM; + } + + len = pubkey.size_bits / 8; + + uint8_t buf[1 + len * 2]; + + /* uncompressed */ + buf[0] = 0x04; + memcpy(&buf[1], pubkey.x, len); + memcpy(&buf[1 + len], pubkey.y, len); + if (!EC_POINT_oct2point(group, point, buf, sizeof(buf), NULL)) { + fprintf(stderr, "Failed to convert (x,y) point to EC_POINT\n"); + EC_POINT_free(point); + EC_KEY_free(ec_key); + return -EINVAL; + } + + if (!EC_KEY_set_public_key(ec_key, point)) { + fprintf(stderr, "Failed to set EC_POINT as public key\n"); + EC_POINT_free(point); + EC_KEY_free(ec_key); + return -EINVAL; + } + + fprintf(stderr, "Successfully loaded ECDSA key from FDT node %d\n", node); + EC_POINT_free(point); + ctx->ecdsa_key = ec_key; + + return 0; +} + static int alloc_ctx(struct signer *ctx, const struct image_sign_info *info) { memset(ctx, 0, sizeof(*ctx)); @@ -153,6 +259,72 @@ static int read_key(struct signer *ctx, const char *key_name) return (ctx->ecdsa_key) ? 0 : -EINVAL; } +static int load_key_from_fdt(struct signer *ctx, const struct image_sign_info *info) +{ + const void *fdt = info->fdt_blob; + char name[128]; + int sig_node; + int key_node; + int key_len; + int ret; + + if (!fdt) + return -EINVAL; + + ret = alloc_ctx(ctx, info); + if (ret) + return ret; + + sig_node = fdt_subnode_offset(fdt, 0, FIT_SIG_NODENAME); + if (sig_node < 0) { + fprintf(stderr, "No /signature node found\n"); + return -ENOENT; + } + + /* Case 1: explicitly specified key node */ + if (info->required_keynode >= 0) { + ret = read_key_from_fdt(ctx, fdt, info->required_keynode); + if (ret == 0) + goto check_key_len; + + fprintf(stderr, "Failed to load required keynode %d\n", info->required_keynode); + return ret; + } + + /* Case 2: use keyname hint */ + if (info->keyname) { + snprintf(name, sizeof(name), "%s", info->keyname); + key_node = fdt_subnode_offset(fdt, sig_node, name); + if (key_node >= 0) { + ret = read_key_from_fdt(ctx, fdt, key_node); + if (ret == 0) + goto check_key_len; + + fprintf(stderr, "Key hint '%s' found but failed to load\n", info->keyname); + } + } + + /* Case 3: try all subnodes */ + fdt_for_each_subnode(key_node, fdt, sig_node) { + ret = read_key_from_fdt(ctx, fdt, key_node); + if (ret == 0) + goto check_key_len; + } + + fprintf(stderr, "Failed to load any usable ECDSA key from FDT\n"); + return -EINVAL; + +check_key_len: + key_len = ecdsa_key_size_bytes(ctx->ecdsa_key); + if (key_len != info->crypto->key_len) { + fprintf(stderr, "Expected %u-bit key, got %u-bit key\n", + info->crypto->key_len * 8, key_len * 8); + return -EINVAL; + } + + return 0; +} + /* Prepare a 'signer' context that's ready to sign and verify. */ static int prepare_ctx(struct signer *ctx, const struct image_sign_info *info) { @@ -161,7 +333,9 @@ static int prepare_ctx(struct signer *ctx, const struct image_sign_info *info) memset(ctx, 0, sizeof(*ctx)); - if (info->keyfile) { + if (info->fdt_blob) { + return load_key_from_fdt(ctx, info); + } else if (info->keyfile) { snprintf(kname, sizeof(kname), "%s", info->keyfile); } else if (info->keydir && info->keyname) { snprintf(kname, sizeof(kname), "%s/%s.pem", info->keydir, diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 3dadbc54b58..077466f01f0 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -71,6 +71,15 @@ config EFI_SECURE_BOOT config EFI_SIGNATURE_SUPPORT bool +config EFI_DEBUG_SUPPORT + bool "EFI Debug Support" + default y if !HAS_BOARD_SIZE_LIMIT + help + Select this option if you want to setup the EFI Debug Support + Table and the EFI_SYSTEM_TABLE_POINTER which is used by the debug + agent or an external debugger to determine loaded image information + in a quiescent manner. + menu "UEFI services" config EFI_GET_TIME diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index cf050e5385d..bfa607c8827 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -21,6 +21,7 @@ ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) apps-y += dtbdump endif apps-$(CONFIG_BOOTEFI_TESTAPP_COMPILE) += testapp +apps-y += dbginfodump obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o obj-$(CONFIG_EFI_BOOTMGR) += efi_bootmgr.o @@ -70,6 +71,7 @@ obj-$(CONFIG_EFI_RISCV_BOOT_PROTOCOL) += efi_riscv.o obj-$(CONFIG_EFI_LOAD_FILE2_INITRD) += efi_load_initrd.o obj-$(CONFIG_EFI_SIGNATURE_SUPPORT) += efi_signature.o obj-$(CONFIG_EFI_ECPT) += efi_conformance.o +obj-$(CONFIG_EFI_DEBUG_SUPPORT) += efi_debug_support.o EFI_VAR_SEED_FILE := $(subst $\",,$(CONFIG_EFI_VAR_SEED_FILE)) $(obj)/efi_var_seed.o: $(srctree)/$(EFI_VAR_SEED_FILE) diff --git a/lib/efi_loader/dbginfodump.c b/lib/efi_loader/dbginfodump.c new file mode 100644 index 00000000000..adbbd5060cc --- /dev/null +++ b/lib/efi_loader/dbginfodump.c @@ -0,0 +1,356 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2025, Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * dbginfodump.efi prints out the content of the EFI_DEBUG_IMAGE_INFO_TABLE. + */ + +#include <efi_api.h> + +/** + * BUFFER_SIZE - size of the command line input buffer + */ +#define BUFFER_SIZE 64 + +static struct efi_simple_text_output_protocol *cerr; +static struct efi_simple_text_output_protocol *cout; +static struct efi_simple_text_input_protocol *cin; +static efi_handle_t handle; +static struct efi_system_table *systable; +static struct efi_boot_services *bs; + +static efi_guid_t guid_device_path_to_text_protocol = + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID; + +static struct efi_device_path_to_text_protocol *device_path_to_text; + +/* EFI_DEBUG_IMAGE_INFO_TABLE_GUID */ +static const efi_guid_t dbg_info_guid = + EFI_GUID(0x49152E77, 0x1ADA, 0x4764, 0xB7, 0xA2, + 0x7A, 0xFE, 0xFE, 0xD9, 0x5E, 0x8B); + +/* EFI_DEBUG_IMAGE_INFO_NORMAL */ +struct dbg_info { + u32 type; + struct efi_loaded_image *info; + efi_handle_t handle; +}; + +/* FI_DEBUG_IMAGE_INFO_TABLE_HEADER */ +struct dbg_info_header { + u32 status; + u32 size; + struct dbg_info **info; +}; + +/** + * print() - print string + * + * @string: text + */ +static void print(u16 *string) +{ + cout->output_string(cout, string); +} + +/** + * error() - print error string + * + * @string: error text + */ +static void error(u16 *string) +{ + cout->set_attribute(cout, EFI_LIGHTRED | EFI_BACKGROUND_BLACK); + print(string); + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); +} + +/** + * printu() - print unsigned + * + * @val: value to print + */ +static void printu(u32 val) +{ + u16 str[19] = u"0x"; + u16 *ptr = &str[2]; + u16 ch; + + for (ssize_t i = 8 * sizeof(u32) - 4; i >= 0; i -= 4) { + ch = (val >> i & 0xf) + '0'; + if (ch > '9') + ch += 'a' - '9' - 1; + *ptr++ = ch; + } + *ptr = 0; + print(str); +} + +/** + * printp() - print pointer + * + * @p: pointer + */ +static void printp(void *p) +{ + u16 str[19] = u"0x"; + u16 *ptr = &str[2]; + u16 ch; + + for (ssize_t i = 8 * sizeof(void *) - 4; i >= 0; i -= 4) { + ch = ((uintptr_t)p >> i & 0xf) + '0'; + if (ch > '9') + ch += 'a' - '9' - 1; + *ptr++ = ch; + } + *ptr = 0; + print(str); +} + +/** + * efi_input() - read string from console + * + * @buffer: input buffer + * @buffer_size: buffer size + * Return: status code + */ +static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size) +{ + struct efi_input_key key = {0}; + efi_uintn_t index; + efi_uintn_t pos = 0; + u16 outbuf[2] = u" "; + efi_status_t ret; + + /* Drain the console input */ + ret = cin->reset(cin, true); + *buffer = 0; + for (;;) { + ret = bs->wait_for_event(1, &cin->wait_for_key, &index); + if (ret != EFI_SUCCESS) + continue; + ret = cin->read_key_stroke(cin, &key); + if (ret != EFI_SUCCESS) + continue; + switch (key.scan_code) { + case 0x17: /* Escape */ + print(u"\r\nAborted\r\n"); + return EFI_ABORTED; + default: + break; + } + switch (key.unicode_char) { + case 0x08: /* Backspace */ + if (pos) { + buffer[pos--] = 0; + print(u"\b \b"); + } + break; + case 0x0a: /* Linefeed */ + case 0x0d: /* Carriage return */ + print(u"\r\n"); + return EFI_SUCCESS; + default: + break; + } + /* Ignore surrogate codes */ + if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF) + continue; + if (key.unicode_char >= 0x20 && + pos < buffer_size - 1) { + *outbuf = key.unicode_char; + buffer[pos++] = key.unicode_char; + buffer[pos] = 0; + print(outbuf); + } + } +} + +/** + * skip_whitespace() - skip over leading whitespace + * + * @pos: UTF-16 string + * Return: pointer to first non-whitespace + */ +static u16 *skip_whitespace(u16 *pos) +{ + for (; *pos && *pos <= 0x20; ++pos) + ; + return pos; +} + +/** + * starts_with() - check if @string starts with @keyword + * + * @string: string to search for keyword + * @keyword: keyword to be searched + * Return: true fi @string starts with the keyword + */ +static bool starts_with(u16 *string, u16 *keyword) +{ + for (; *keyword; ++string, ++keyword) { + if (*string != *keyword) + return false; + } + return true; +} + +/** + * do_help() - print help + */ +static void do_help(void) +{ + error(u"dump - print debug info table\r\n"); + error(u"exit - exit the shell\r\n"); +} + +/** + * get_dbg_info_table() - get debug info table + * + * Return: debug info table or NULL + */ +static void *get_dbg_info(void) +{ + void *dbg = NULL; + efi_uintn_t i; + + for (i = 0; i < systable->nr_tables; ++i) { + if (!memcmp(&systable->tables[i].guid, &dbg_info_guid, + sizeof(efi_guid_t))) { + dbg = systable->tables[i].table; + break; + } + } + return dbg; +} + +/** + * print_info() - print loaded image protocol + */ +static void print_info(struct efi_loaded_image *info) +{ + print(u" Address: ["); + printp(info->image_base); + print(u", "); + printp(info->image_base + info->image_size - 1); + print(u"]\r\n"); + if (device_path_to_text && info->file_path) { + u16 *string; + + string = device_path_to_text->convert_device_path_to_text( + info->file_path, true, false); + if (!string) { + error(u"ConvertDevicePathToText failed"); + } else { + print(u" File: "); + print(string); + } + print(u"\r\n"); + } +} + +/** + * do_dump() - print debug info table + */ +static efi_status_t do_dump(void) +{ + struct dbg_info_header *dbg; + u32 count; + + dbg = get_dbg_info(); + if (!dbg) { + error(u"Debug info table not found\r\n"); + return EFI_NOT_FOUND; + } + if (dbg->status & 0x01) { + error(u"Update in progress\r\n"); + return EFI_LOAD_ERROR; + } + if (dbg->status & 0x02) + print(u"Modified\r\n"); + print(u"Number of entries: "); + printu(dbg->size); + print(u"\r\n"); + + count = dbg->size; + for (u32 i = 0; count; ++i) { + struct dbg_info *info = dbg->info[i]; + + /* + * The EDK II implementation decreases the size field and + * writes a NULL value when deleting an entry which is not + * backed by the UEFI specification. + */ + if (!info) { + print(u"Deleted entry\r\n"); + continue; + } + --count; + print(u"Info type "); + printu(info->type); + print(u"\r\n"); + if (info->type != 1) + continue; + print_info(info->info); + print(u" Handle: "); + printp(info->handle); + print(u"\r\n"); + } + + return EFI_SUCCESS; +} + +/** + * efi_main() - entry point of the EFI application. + * + * @handle: handle of the loaded image + * @systab: system table + * Return: status code + */ +efi_status_t EFIAPI efi_main(efi_handle_t image_handle, + struct efi_system_table *systab) +{ + efi_status_t ret; + + handle = image_handle; + systable = systab; + cerr = systable->std_err; + cout = systable->con_out; + cin = systable->con_in; + bs = systable->boottime; + + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); + cout->clear_screen(cout); + cout->set_attribute(cout, EFI_WHITE | EFI_BACKGROUND_BLACK); + print(u"Debug Info Table Dump\r\n=====================\r\n\r\n"); + cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK); + + ret = bs->locate_protocol(&guid_device_path_to_text_protocol, + NULL, (void **)&device_path_to_text); + if (ret != EFI_SUCCESS) { + error(u"No device path to text protocol\r\n"); + device_path_to_text = NULL; + } + + for (;;) { + u16 command[BUFFER_SIZE]; + u16 *pos; + efi_uintn_t ret; + + print(u"=> "); + ret = efi_input(command, sizeof(command)); + if (ret == EFI_ABORTED) + break; + pos = skip_whitespace(command); + if (starts_with(pos, u"exit")) + break; + else if (starts_with(pos, u"dump")) + do_dump(); + else + do_help(); + } + + cout->set_attribute(cout, EFI_LIGHTGRAY | EFI_BACKGROUND_BLACK); + cout->clear_screen(cout); + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index b9437a81c64..662993fb809 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -1134,7 +1134,7 @@ efi_status_t efi_bootmgr_update_media_device_boot_option(void) { u32 i; efi_status_t ret; - efi_uintn_t count, num, total; + efi_uintn_t count, num, total = 0; efi_handle_t *handles = NULL; struct eficonfig_media_boot_option *opt = NULL; diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 754bc6a6519..ddc935d2240 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2130,6 +2130,11 @@ efi_status_t EFIAPI efi_load_image(bool boot_policy, *image_handle = NULL; free(info); } + + if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT) && *image_handle) + efi_core_new_debug_image_info_entry(EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, + info, + *image_handle); error: return EFI_EXIT(ret); } @@ -3360,6 +3365,8 @@ efi_status_t EFIAPI efi_unload_image(efi_handle_t image_handle) ret = EFI_INVALID_PARAMETER; goto out; } + if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT)) + efi_core_remove_debug_image_info_entry(image_handle); switch (efiobj->type) { case EFI_OBJECT_TYPE_STARTED_IMAGE: /* Call the unload function */ diff --git a/lib/efi_loader/efi_debug_support.c b/lib/efi_loader/efi_debug_support.c new file mode 100644 index 00000000000..186bdbce750 --- /dev/null +++ b/lib/efi_loader/efi_debug_support.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * EFI debug support + * + * Copyright (c) 2025 Ying-Chun Liu, Linaro Ltd. <paul.liu@linaro.org> + */ + +#include <efi_loader.h> +#include <linux/sizes.h> +#include <u-boot/crc.h> + +struct efi_system_table_pointer __efi_runtime_data * systab_pointer = NULL; + +struct efi_debug_image_info_table_header efi_m_debug_info_table_header = { + 0, + 0, + NULL +}; + +/* efi_m_max_table_entries is the maximum entries allocated for + * the efi_m_debug_info_table_header.efi_debug_image_info_table. + */ +static u32 efi_m_max_table_entries; + +#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof(union efi_debug_image_info *)) + +/** + * efi_initialize_system_table_pointer() - Initialize system table pointer + * + * Return: status code + */ +efi_status_t efi_initialize_system_table_pointer(void) +{ + /* Allocate efi_system_table_pointer structure with 4MB alignment. */ + systab_pointer = efi_alloc_aligned_pages(sizeof(struct efi_system_table_pointer), + EFI_RUNTIME_SERVICES_DATA, + SZ_4M); + + if (!systab_pointer) { + log_err("Installing EFI system table pointer failed\n"); + return EFI_OUT_OF_RESOURCES; + } + + systab_pointer->crc32 = 0; + + systab_pointer->signature = EFI_SYSTEM_TABLE_SIGNATURE; + systab_pointer->efi_system_table_base = (uintptr_t)&systab; + systab_pointer->crc32 = crc32(0, + (const unsigned char *)systab_pointer, + sizeof(struct efi_system_table_pointer)); + + return EFI_SUCCESS; +} + +/** + * efi_core_new_debug_image_info_entry() - Add a new efi_loaded_image structure to the + * efi_debug_image_info table. + * + * @image_info_type: type of debug image information + * @loaded_image: pointer to the loaded image protocol for the image + * being loaded + * @image_handle: image handle for the image being loaded + * + * Re-Allocates the table if it's not large enough to accommodate another + * entry. + * + * Return: status code + **/ +efi_status_t efi_core_new_debug_image_info_entry(u32 image_info_type, + struct efi_loaded_image *loaded_image, + efi_handle_t image_handle) +{ + union efi_debug_image_info **table; + u32 index; + u32 table_size; + efi_status_t ret; + + /* Set the flag indicating that we're in the process of updating + * the table. + */ + efi_m_debug_info_table_header.update_status |= + EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + + table = &efi_m_debug_info_table_header.efi_debug_image_info_table; + + if (efi_m_debug_info_table_header.table_size >= efi_m_max_table_entries) { + /* table is full, re-allocate the buffer increasing the size + * by 4 KiB. + */ + table_size = efi_m_max_table_entries * EFI_DEBUG_TABLE_ENTRY_SIZE; + + ret = efi_realloc((void **)table, table_size + EFI_PAGE_SIZE); + + if (ret != EFI_SUCCESS) { + efi_m_debug_info_table_header.update_status &= + ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + return ret; + } + + /* Enlarge the max table entries and set the first empty + * entry index to be the original max table entries. + */ + efi_m_max_table_entries += + EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE; + } + + /* We always put the next entry at the end of the currently consumed + * table (i.e. first free entry) + */ + index = efi_m_debug_info_table_header.table_size; + + /* Allocate data for new entry. */ + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, + sizeof(union efi_debug_image_info), + (void **)(&(*table)[index].normal_image)); + if (ret == EFI_SUCCESS && (*table)[index].normal_image) { + /* Update the entry. */ + (*table)[index].normal_image->image_info_type = image_info_type; + (*table)[index].normal_image->loaded_image_protocol_instance = + loaded_image; + (*table)[index].normal_image->image_handle = image_handle; + + /* Increase the number of EFI_DEBUG_IMAGE_INFO elements and + * set the efi_m_debug_info_table_header in modified status. + */ + efi_m_debug_info_table_header.table_size++; + efi_m_debug_info_table_header.update_status |= + EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; + } else { + log_err("Adding new efi_debug_image_info failed\n"); + return ret; + } + + efi_m_debug_info_table_header.update_status &= + ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + + return EFI_SUCCESS; +} + +/** + * efi_core_remove_debug_image_info_entry() - Remove an efi_debug_image_info entry. + * + * @image_handle: image handle for the image being removed + **/ +void efi_core_remove_debug_image_info_entry(efi_handle_t image_handle) +{ + union efi_debug_image_info *table; + u32 index; + + efi_m_debug_info_table_header.update_status |= + EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + + table = efi_m_debug_info_table_header.efi_debug_image_info_table; + + for (index = 0; index < efi_m_max_table_entries; index++) { + if (table[index].normal_image && + table[index].normal_image->image_handle == image_handle) { + /* Found a match. Free up the table entry. + * Move the tail of the table one slot to the front. + */ + efi_free_pool(table[index].normal_image); + + memmove(&table[index], + &table[index + 1], + (efi_m_debug_info_table_header.table_size - + index - 1) * EFI_DEBUG_TABLE_ENTRY_SIZE); + + /* Decrease the number of EFI_DEBUG_IMAGE_INFO + * elements and set the efi_m_debug_info_table_header + * in modified status. + */ + efi_m_debug_info_table_header.table_size--; + table[efi_m_debug_info_table_header.table_size].normal_image = + NULL; + efi_m_debug_info_table_header.update_status |= + EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED; + break; + } + } + + efi_m_debug_info_table_header.update_status &= + ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; +} diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 47b583cc5e1..130c4db9606 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -26,6 +26,7 @@ struct efi_system_partition efi_system_partition = { const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID; const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID; +const efi_guid_t efi_partition_info_guid = EFI_PARTITION_INFO_PROTOCOL_GUID; /** * struct efi_disk_obj - EFI disk object @@ -35,6 +36,7 @@ const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID; * @media: block I/O media information * @dp: device path to the block device * @volume: simple file system protocol of the partition + * @info: EFI partition info protocol interface */ struct efi_disk_obj { struct efi_object header; @@ -42,6 +44,7 @@ struct efi_disk_obj { struct efi_block_io_media media; struct efi_device_path *dp; struct efi_simple_file_system_protocol *volume; + struct efi_partition_info info; }; /** @@ -426,6 +429,7 @@ static efi_status_t efi_disk_add_dev( /* Fill in object data */ if (part_info) { struct efi_device_path *node = efi_dp_part_node(desc, part); + struct efi_partition_info *info = &diskobj->info; struct efi_handler *handler; void *protocol_interface; @@ -454,18 +458,48 @@ static efi_status_t efi_disk_add_dev( goto error; } + info->revision = EFI_PARTITION_INFO_PROTOCOL_REVISION; + + switch (desc->part_type) { +#if CONFIG_IS_ENABLED(EFI_PARTITION) + case PART_TYPE_EFI: + info->type = PARTITION_TYPE_GPT; + ret = part_get_gpt_pte(desc, part, &info->info.gpt); + if (ret) { + log_debug("get PTE for part %d failed %ld\n", + part, ret); + goto error; + } + break; +#endif +#if CONFIG_IS_ENABLED(DOS_PARTITION) + case PART_TYPE_DOS: + info->type = PARTITION_TYPE_MBR; + + /* TODO: implement support for MBR partition types */ + log_debug("EFI_PARTITION_INFO_PROTOCOL doesn't support MBR\n"); + break; +#endif + default: + info->type = PARTITION_TYPE_OTHER; + break; + } + diskobj->dp = efi_dp_append_node(dp_parent, node); efi_free_pool(node); diskobj->media.last_block = part_info->size - 1; - if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) + if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) { esp_guid = &efi_system_partition_guid; + info->system = 1; + } + } else { diskobj->dp = efi_dp_from_part(desc, part); diskobj->media.last_block = desc->lba - 1; } /* - * Install the device path and the block IO protocol. + * Install the device path, the block IO and partition info protocols. * * InstallMultipleProtocolInterfaces() checks if the device path is * already installed on an other handle and returns EFI_ALREADY_STARTED @@ -476,6 +510,7 @@ static efi_status_t efi_disk_add_dev( &handle, &efi_guid_device_path, diskobj->dp, &efi_block_io_guid, &diskobj->ops, + &efi_partition_info_guid, &diskobj->info, /* * esp_guid must be last entry as it * can be NULL. Its interface is NULL. diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 7d81da8f2d8..19b43c4a625 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -248,7 +248,7 @@ static struct efi_file_handle *file_open(struct file_system *fs, return &fh->base; error: - free(fh->path); + free(path); free(fh); return NULL; } diff --git a/lib/efi_loader/efi_http.c b/lib/efi_loader/efi_http.c index 189317fe2d2..9a0f2675132 100644 --- a/lib/efi_loader/efi_http.c +++ b/lib/efi_loader/efi_http.c @@ -453,7 +453,6 @@ static efi_status_t EFIAPI efi_http_service_binding_destroy_child( efi_status_t ret = EFI_SUCCESS; struct efi_http_instance *http_instance; struct efi_handler *phandler; - void *protocol_interface; if (num_instances == 0) return EFI_EXIT(EFI_NOT_FOUND); @@ -463,18 +462,18 @@ static efi_status_t EFIAPI efi_http_service_binding_destroy_child( efi_search_protocol(child_handle, &efi_http_guid, &phandler); - if (phandler) - protocol_interface = phandler->protocol_interface; + if (!phandler) + return EFI_EXIT(EFI_UNSUPPORTED); ret = efi_delete_handle(child_handle); if (ret != EFI_SUCCESS) return EFI_EXIT(ret); - http_instance = (struct efi_http_instance *)protocol_interface; + http_instance = phandler->protocol_interface; efi_free_pool(http_instance->http_load_addr); http_instance->http_load_addr = NULL; - free(protocol_interface); + free(phandler->protocol_interface); num_instances--; diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c index 0abb1f6159a..6dfc698a247 100644 --- a/lib/efi_loader/efi_memory.c +++ b/lib/efi_loader/efi_memory.c @@ -454,6 +454,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, enum efi_memory_type memory_type, efi_uintn_t pages, uint64_t *memory) { + int err; u64 efi_addr, len; uint flags; efi_status_t ret; @@ -475,17 +476,18 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, switch (type) { case EFI_ALLOCATE_ANY_PAGES: /* Any page */ - addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, - LMB_ALLOC_ANYWHERE, flags); - if (!addr) + err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, EFI_PAGE_SIZE, &addr, + len, flags); + if (err) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_MAX_ADDRESS: /* Max address */ addr = map_to_sysmem((void *)(uintptr_t)*memory); - addr = (u64)lmb_alloc_base(len, EFI_PAGE_SIZE, addr, - flags); - if (!addr) + + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, EFI_PAGE_SIZE, &addr, + len, flags); + if (err) return EFI_OUT_OF_RESOURCES; break; case EFI_ALLOCATE_ADDRESS: @@ -493,7 +495,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, return EFI_NOT_FOUND; addr = map_to_sysmem((void *)(uintptr_t)*memory); - if (lmb_alloc_addr(addr, len, flags)) + if (lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, len, flags)) return EFI_NOT_FOUND; break; default: @@ -506,7 +508,7 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type, ret = efi_update_memory_map(efi_addr, pages, memory_type, true, false); if (ret != EFI_SUCCESS) { /* Map would overlap, bail out */ - lmb_free_flags(addr, (u64)pages << EFI_PAGE_SHIFT, flags); + lmb_free(addr, (u64)pages << EFI_PAGE_SHIFT, flags); unmap_sysmem((void *)(uintptr_t)efi_addr); return EFI_OUT_OF_RESOURCES; } @@ -546,8 +548,8 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages) * been mapped with map_sysmem() from efi_allocate_pages(). Convert * it back to an address LMB understands */ - status = lmb_free_flags(map_to_sysmem((void *)(uintptr_t)memory), len, - LMB_NOOVERWRITE); + status = lmb_free(map_to_sysmem((void *)(uintptr_t)memory), len, + LMB_NOOVERWRITE); if (status) return EFI_NOT_FOUND; @@ -667,6 +669,64 @@ void *efi_alloc(size_t size) } /** + * efi_realloc() - reallocate boot services data pool memory + * + * Reallocate memory from pool for a new size and copy the data from old one. + * + * @ptr: pointer to old buffer + * @size: number of bytes to allocate + * Return: EFI status to indicate success or not + */ +efi_status_t efi_realloc(void **ptr, size_t size) +{ + efi_status_t ret; + void *new_ptr; + struct efi_pool_allocation *alloc; + u64 num_pages = efi_size_in_pages(size + + sizeof(struct efi_pool_allocation)); + size_t old_size; + + if (!*ptr) { + *ptr = efi_alloc(size); + if (*ptr) + return EFI_SUCCESS; + return EFI_OUT_OF_RESOURCES; + } + + ret = efi_check_allocated((uintptr_t)*ptr, true); + if (ret != EFI_SUCCESS) + return ret; + + alloc = container_of(*ptr, struct efi_pool_allocation, data); + + /* Check that this memory was allocated by efi_allocate_pool() */ + if (((uintptr_t)alloc & EFI_PAGE_MASK) || + alloc->checksum != checksum(alloc)) { + printf("%s: illegal realloc 0x%p\n", __func__, *ptr); + return EFI_INVALID_PARAMETER; + } + + /* Don't realloc. The actual size in pages is the same. */ + if (alloc->num_pages == num_pages) + return EFI_SUCCESS; + + old_size = alloc->num_pages * EFI_PAGE_SIZE - + sizeof(struct efi_pool_allocation); + + new_ptr = efi_alloc(size); + + /* copy old data to new alloced buffer */ + memcpy(new_ptr, *ptr, min(size, old_size)); + + /* free the old buffer */ + efi_free_pool(*ptr); + + *ptr = new_ptr; + + return EFI_SUCCESS; +} + +/** * efi_free_pool() - free memory from pool * * @buffer: start of memory to be freed diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 86f0af9538c..b8a6e08ba8e 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -1131,7 +1131,7 @@ efi_status_t efi_net_register(struct udevice *dev) struct efi_net_obj *netobj; void *transmit_buffer = NULL; uchar **receive_buffer = NULL; - size_t *receive_lengths; + size_t *receive_lengths = NULL; int i, j; if (!dev) { diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 48f91da5df7..f06cf49e443 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -18,6 +18,9 @@ efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED; +const efi_guid_t efi_debug_image_info_table_guid = + EFI_DEBUG_IMAGE_INFO_TABLE_GUID; + /* * Allow unaligned memory access. * @@ -278,6 +281,21 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + /* Initialize system table pointer */ + if (IS_ENABLED(CONFIG_EFI_DEBUG_SUPPORT)) { + efi_guid_t debug_image_info_table_guid = + efi_debug_image_info_table_guid; + + ret = efi_initialize_system_table_pointer(); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_install_configuration_table(&debug_image_info_table_guid, + &efi_m_debug_info_table_header); + if (ret != EFI_SUCCESS) + goto out; + } + if (IS_ENABLED(CONFIG_EFI_ECPT)) { ret = efi_ecpt_register(); if (ret != EFI_SUCCESS) diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index d78bf7d6191..842433f68aa 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -78,6 +78,8 @@ endif obj-$(CONFIG_EFI_ESRT) += efi_selftest_esrt.o +obj-$(CONFIG_EFI_DEBUG_SUPPORT) += efi_selftest_debug_support.o + targets += \ efi_miniapp_file_image_exception.h \ efi_miniapp_file_image_exit.h \ diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c index a367e8b89d1..f145e58a267 100644 --- a/lib/efi_selftest/efi_selftest_block_device.c +++ b/lib/efi_selftest/efi_selftest_block_device.c @@ -18,6 +18,7 @@ #include <efi_selftest.h> #include "efi_selftest_disk_image.h" #include <asm/cache.h> +#include <part_efi.h> /* Block size of compressed disk image */ #define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8 @@ -29,6 +30,7 @@ static struct efi_boot_services *boottime; static const efi_guid_t block_io_protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID; static const efi_guid_t guid_device_path = EFI_DEVICE_PATH_PROTOCOL_GUID; +static const efi_guid_t partition_info_guid = EFI_PARTITION_INFO_PROTOCOL_GUID; static const efi_guid_t guid_simple_file_system_protocol = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; static const efi_guid_t guid_file_system_info = EFI_FILE_SYSTEM_INFO_GUID; @@ -310,6 +312,7 @@ static int execute(void) struct efi_file_system_info info; u16 label[12]; } system_info; + struct efi_partition_info *part_info; efi_uintn_t buf_size; char buf[16] __aligned(ARCH_DMA_MINALIGN); u32 part1_size; @@ -375,6 +378,33 @@ static int execute(void) part1_size - 1); return EFI_ST_FAILURE; } + + /* Open the partition information protocol */ + ret = boottime->open_protocol(handle_partition, + &partition_info_guid, + (void **)&part_info, NULL, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) { + efi_st_error("Failed to open partition information protocol\n"); + return EFI_ST_FAILURE; + } + /* Check that cached partition information is the expected */ + if (part_info->revision != EFI_PARTITION_INFO_PROTOCOL_REVISION) { + efi_st_error("Partition info revision %x, expected %x\n", + part_info->revision, EFI_PARTITION_INFO_PROTOCOL_REVISION); + return EFI_ST_FAILURE; + } + if (part_info->type != PARTITION_TYPE_MBR) { + efi_st_error("Partition info type %x, expected %x\n", + part_info->type, PARTITION_TYPE_MBR); + return EFI_ST_FAILURE; + } + if (part_info->system != 0) { + efi_st_error("Partition info system %x, expected 0\n", + part_info->system); + return EFI_ST_FAILURE; + } + /* Open the simple file system protocol */ ret = boottime->open_protocol(handle_partition, &guid_simple_file_system_protocol, diff --git a/lib/efi_selftest/efi_selftest_debug_support.c b/lib/efi_selftest/efi_selftest_debug_support.c new file mode 100644 index 00000000000..9ca8b3f82f5 --- /dev/null +++ b/lib/efi_selftest/efi_selftest_debug_support.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * efi_selftest_debug_support + * + * Copyright (c) 2025 Ying-Chun Liu, Linaro Ltd. <paul.liu@linaro.org> + * + * Test the EFI_DEBUG_SUPPORT + */ + +#include <efi_loader.h> +#include <efi_selftest.h> + +/** + * efi_st_debug_support_execute() - execute test + * + * Test EFI_DEBUG_SUPPORT tables. + * + * Return: status code + */ +static int efi_st_debug_support_execute(void) +{ + struct efi_debug_image_info_table_header *efi_st_debug_info_table_header = NULL; + efi_guid_t efi_debug_image_info_table_guid = EFI_DEBUG_IMAGE_INFO_TABLE_GUID; + + /* get EFI_DEBUG_IMAGE_INFO_TABLE */ + efi_st_debug_info_table_header = efi_st_get_config_table(&efi_debug_image_info_table_guid); + + if (!efi_st_debug_info_table_header) { + efi_st_error("Missing EFI_DEBUG_IMAGE_INFO_TABLE\n"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(debug_support) = { + .name = "debug_support", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .execute = efi_st_debug_support_execute, +}; diff --git a/lib/lmb.c b/lib/lmb.c index bb6f232f6bc..45b26512a5b 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -317,8 +317,34 @@ static long _lmb_free(struct alist *lmb_rgn_lst, phys_addr_t base, rgn[i].flags); } -static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, - phys_size_t size) +/** + * lmb_overlap_checks() - perform checks to see if region can be allocated or reserved + * @lmb_rgn_lst: list of LMB regions + * @base: base address of region to be checked + * @size: size of region to be checked + * @flags: flag of the region to be checked (only for reservation requests) + * @alloc: if checks are to be done for allocation or reservation request + * + * Check if the region passed to the function overlaps with any one of + * the regions of the passed lmb region list. + * + * If the @alloc flag is set to true, this check stops as soon an + * overlapping region is found. The function can also be called to + * check if a reservation request can be satisfied, by setting + * @alloc to false. In that case, the function then iterates through + * all the regions in the list passed to ensure that the requested + * region does not overlap with any existing regions. An overlap is + * allowed only when the flag of the requested region and the existing + * region is LMB_NONE. + * + * Return: index of the overlapping region, -1 if no overlap is found + * + * When the function is called for a reservation request check, -1 will + * also be returned when there is an allowed overlap, i.e. requested + * region and existing regions have flags as LMB_NONE. + */ +static long lmb_overlap_checks(struct alist *lmb_rgn_lst, phys_addr_t base, + phys_size_t size, u32 flags, bool alloc) { unsigned long i; struct lmb_region *rgn = lmb_rgn_lst->data; @@ -326,9 +352,12 @@ static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, for (i = 0; i < lmb_rgn_lst->count; i++) { phys_addr_t rgnbase = rgn[i].base; phys_size_t rgnsize = rgn[i].size; + u32 rgnflags = rgn[i].flags; - if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) - break; + if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { + if (alloc || flags != LMB_NONE || flags != rgnflags) + break; + } } return (i < lmb_rgn_lst->count) ? i : -1; @@ -390,7 +419,8 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align) base = ALIGN_DOWN(lmbbase + lmbsize - size, align); while (base && lmbbase <= base) { - rgn = lmb_overlaps_region(&io_lmb->used_mem, base, size); + rgn = lmb_overlap_checks(&io_lmb->used_mem, base, size, + LMB_NOOVERWRITE, true); if (rgn < 0) { /* This area isn't reserved, take it */ if (lmb_add_region_flags(&io_lmb->used_mem, base, @@ -488,6 +518,21 @@ void lmb_dump_all(void) #endif } +static long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags) +{ + long ret = 0; + struct alist *lmb_rgn_lst = &lmb.used_mem; + + if (lmb_overlap_checks(lmb_rgn_lst, base, size, flags, false) != -1) + return -EEXIST; + + ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags); + if (ret) + return ret; + + return lmb_map_update_notify(base, size, LMB_MAP_OP_RESERVE, flags); +} + static void lmb_reserve_uboot_region(void) { int bank; @@ -557,40 +602,7 @@ static __maybe_unused void lmb_reserve_common_spl(void) } } -/** - * lmb_can_reserve_region() - check if the region can be reserved - * @base: base address of region to be reserved - * @size: size of region to be reserved - * @flags: flag of the region to be reserved - * - * Go through all the reserved regions and ensure that the requested - * region does not overlap with any existing regions. An overlap is - * allowed only when the flag of the request region and the existing - * region is LMB_NONE. - * - * Return: true if region can be reserved, false otherwise - */ -static bool lmb_can_reserve_region(phys_addr_t base, phys_size_t size, - u32 flags) -{ - uint i; - struct lmb_region *lmb_reserved = lmb.used_mem.data; - - for (i = 0; i < lmb.used_mem.count; i++) { - u32 rgnflags = lmb_reserved[i].flags; - phys_addr_t rgnbase = lmb_reserved[i].base; - phys_size_t rgnsize = lmb_reserved[i].size; - - if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { - if (flags != LMB_NONE || flags != rgnflags) - return false; - } - } - - return true; -} - -void lmb_add_memory(void) +static void lmb_add_memory(void) { int i; phys_addr_t bank_end; @@ -640,8 +652,7 @@ long lmb_add(phys_addr_t base, phys_size_t size) return lmb_map_update_notify(base, size, LMB_MAP_OP_ADD, LMB_NONE); } -long lmb_free_flags(phys_addr_t base, phys_size_t size, - uint flags) +long lmb_free(phys_addr_t base, phys_size_t size, u32 flags) { long ret; @@ -652,36 +663,18 @@ long lmb_free_flags(phys_addr_t base, phys_size_t size, return lmb_map_update_notify(base, size, LMB_MAP_OP_FREE, flags); } -long lmb_free(phys_addr_t base, phys_size_t size) -{ - return lmb_free_flags(base, size, LMB_NONE); -} - -long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags) -{ - long ret = 0; - struct alist *lmb_rgn_lst = &lmb.used_mem; - - if (!lmb_can_reserve_region(base, size, flags)) - return -EEXIST; - - ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags); - if (ret) - return ret; - - return lmb_map_update_notify(base, size, LMB_MAP_OP_RESERVE, flags); -} - -static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, - phys_addr_t max_addr, u32 flags) +static int _lmb_alloc_base(phys_size_t size, ulong align, + phys_addr_t *addr, u32 flags) { int ret; long i, rgn; + phys_addr_t max_addr; phys_addr_t base = 0; phys_addr_t res_base; struct lmb_region *lmb_used = lmb.used_mem.data; struct lmb_region *lmb_memory = lmb.available_mem.data; + max_addr = *addr; for (i = lmb.available_mem.count - 1; i >= 0; i--) { phys_addr_t lmbbase = lmb_memory[i].base; phys_size_t lmbsize = lmb_memory[i].size; @@ -702,7 +695,8 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, } while (base && lmbbase <= base) { - rgn = lmb_overlaps_region(&lmb.used_mem, base, size); + rgn = lmb_overlap_checks(&lmb.used_mem, base, size, + LMB_NOOVERWRITE, true); if (rgn < 0) { /* This area isn't reserved, take it */ if (lmb_add_region_flags(&lmb.used_mem, base, @@ -714,8 +708,8 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, flags); if (ret) return ret; - - return base; + *addr = base; + return 0; } res_base = lmb_used[rgn].base; @@ -728,27 +722,17 @@ static phys_addr_t _lmb_alloc_base(phys_size_t size, ulong align, log_debug("%s: Failed to allocate 0x%lx bytes below 0x%lx\n", __func__, (ulong)size, (ulong)max_addr); - return 0; -} - -phys_addr_t lmb_alloc(phys_size_t size, ulong align) -{ - return _lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE, LMB_NONE); -} - -phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, phys_addr_t max_addr, - uint flags) -{ - return _lmb_alloc_base(size, align, max_addr, flags); + return -1; } -int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) +static int _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) { long rgn; struct lmb_region *lmb_memory = lmb.available_mem.data; /* Check if the requested address is in one of the memory regions */ - rgn = lmb_overlaps_region(&lmb.available_mem, base, size); + rgn = lmb_overlap_checks(&lmb.available_mem, base, size, + LMB_NOOVERWRITE, true); if (rgn >= 0) { /* * Check if the requested end address is in the same memory @@ -756,14 +740,40 @@ int lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) */ if (lmb_addrs_overlap(lmb_memory[rgn].base, lmb_memory[rgn].size, - base + size - 1, 1)) { + base + size - 1, 1)) /* ok, reserve the memory */ - if (!lmb_reserve(base, size, flags)) - return 0; - } + return lmb_reserve(base, size, flags); } - return -1; + return -EINVAL; +} + +int lmb_alloc_mem(enum lmb_mem_type type, u64 align, phys_addr_t *addr, + phys_size_t size, u32 flags) +{ + int ret = -1; + + if (!size) + return 0; + + if (!addr) + return -EINVAL; + + switch (type) { + case LMB_MEM_ALLOC_ANY: + *addr = LMB_ALLOC_ANYWHERE; + case LMB_MEM_ALLOC_MAX: + ret = _lmb_alloc_base(size, align, addr, flags); + break; + case LMB_MEM_ALLOC_ADDR: + ret = _lmb_alloc_addr(*addr, size, flags); + break; + default: + log_debug("%s: Invalid memory allocation type requested %d\n", + __func__, type); + } + + return ret; } /* Return number of bytes from a given address that are free */ @@ -775,7 +785,8 @@ phys_size_t lmb_get_free_size(phys_addr_t addr) struct lmb_region *lmb_memory = lmb.available_mem.data; /* check if the requested address is in the memory regions */ - rgn = lmb_overlaps_region(&lmb.available_mem, addr, 1); + rgn = lmb_overlap_checks(&lmb.available_mem, addr, 1, LMB_NOOVERWRITE, + true); if (rgn >= 0) { for (i = 0; i < lmb.used_mem.count; i++) { if (addr < lmb_used[i].base) { diff --git a/lib/lwip/Makefile b/lib/lwip/Makefile index e9e8caee93a..c3f0e916f66 100644 --- a/lib/lwip/Makefile +++ b/lib/lwip/Makefile @@ -13,6 +13,7 @@ obj-y += \ lwip/src/api/sockets.o \ lwip/src/api/tcpip.o \ lwip/src/apps/http/http_client.o \ + lwip/src/apps/sntp/sntp.o \ lwip/src/apps/tftp/tftp.o \ lwip/src/core/altcp_alloc.o \ lwip/src/core/altcp.o \ diff --git a/lib/lwip/u-boot/arch/cc.h b/lib/lwip/u-boot/arch/cc.h index 6104c296f6f..f91127ac565 100644 --- a/lib/lwip/u-boot/arch/cc.h +++ b/lib/lwip/u-boot/arch/cc.h @@ -43,4 +43,8 @@ #define BYTE_ORDER BIG_ENDIAN #endif +#define SNTP_STARTUP_DELAY 0 +void sntp_set_system_time(uint32_t sec); +#define SNTP_SET_SYSTEM_TIME(sec) sntp_set_system_time(sec) + #endif /* LWIP_ARCH_CC_H */ diff --git a/lib/lwip/u-boot/lwipopts.h b/lib/lwip/u-boot/lwipopts.h index edac74ff7a2..46af91f9410 100644 --- a/lib/lwip/u-boot/lwipopts.h +++ b/lib/lwip/u-boot/lwipopts.h @@ -72,8 +72,8 @@ #define IP_FORWARD 0 #define IP_OPTIONS_ALLOWED 1 -#define IP_REASSEMBLY 0 -#define IP_FRAG 0 +#define IP_REASSEMBLY 1 +#define IP_FRAG 1 #define IP_REASS_MAXAGE 3 #define IP_REASS_MAX_PBUFS 4 #define IP_FRAG_USES_STATIC_BUF 0 @@ -162,4 +162,8 @@ #define LWIP_ALTCP_TLS_MBEDTLS 1 #endif +#if defined(CONFIG_CMD_SNTP) +#define LWIP_DHCP_GET_NTP_SRV 1 +#endif + #endif /* LWIP_UBOOT_LWIPOPTS_H */ diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c index fa9e143b4ca..92b9d7876e5 100644 --- a/lib/rsa/rsa-sign.c +++ b/lib/rsa/rsa-sign.c @@ -122,7 +122,7 @@ static int rsa_engine_get_pub_key(const char *keydir, const char *name, fprintf(stderr, "WARNING: Legacy URI specified. Please add '%s'.\n", pkcs11_schema); } - if (strstr(keydir, "object=")) + if (strstr(keydir, "object=") || strstr(keydir, "id=")) snprintf(key_id, sizeof(key_id), "%s%s;type=public", pkcs11_uri_prepend, keydir); @@ -253,7 +253,7 @@ static int rsa_engine_get_priv_key(const char *keydir, const char *name, fprintf(stderr, "WARNING: Legacy URI specified. Please add '%s'.\n", pkcs11_schema); } - if (strstr(keydir, "object=")) + if (strstr(keydir, "object=") || strstr(keydir, "id=")) snprintf(key_id, sizeof(key_id), "%s%s;type=private", pkcs11_uri_prepend, keydir); diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 4a0418a75f1..b65fbe44007 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -570,7 +570,7 @@ int rsa_verify(struct image_sign_info *info, uint8_t hash[info->crypto->key_len]; int ret; -#ifdef USE_HOSTCC +#if defined(USE_HOSTCC) && CONFIG_IS_ENABLED(LIBCRYPTO) if (!info->fdt_blob) return rsa_verify_openssl(info, region, region_count, sig, sig_len); #endif diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 9ca7933c094..5b21c57ae42 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -1141,7 +1141,7 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char *name) } printf("%s: unsupported algorithm %s\n", __func__, name); - return -EINVAL; + return TPM2_ALG_INVAL; } const char *tpm2_algorithm_name(enum tpm2_algorithms algo) diff --git a/lib/uuid.c b/lib/uuid.c index 6abbcf27b1f..a1c88b9a622 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -62,184 +62,197 @@ int uuid_str_valid(const char *uuid) return 1; } +/* + * Array of string (short and long) for known GUID of GPT partition type + * at least one string must be present, @type or @description + * + * @type : short name for the parameter 'type' of gpt command (max size UUID_STR_LEN = 36, + * no space), also used as fallback description when the next field is absent + * @description : long description associated to type GUID, used for %pUs + * @guid : known type GUID value + */ static const struct { - const char *string; + const char *type; + const char *description; efi_guid_t guid; } list_guid[] = { #ifndef USE_HOSTCC -#if defined(CONFIG_PARTITION_TYPE_GUID) || defined(CONFIG_CMD_EFIDEBUG) || \ - defined(CONFIG_EFI) - {"EFI System Partition", PARTITION_SYSTEM_GUID}, -#endif -#ifdef CONFIG_PARTITION_TYPE_GUID - {"mbr", LEGACY_MBR_PARTITION_GUID}, - {"msft", PARTITION_MSFT_RESERVED_GUID}, - {"data", PARTITION_BASIC_DATA_GUID}, - {"linux", PARTITION_LINUX_FILE_SYSTEM_DATA_GUID}, - {"raid", PARTITION_LINUX_RAID_GUID}, - {"swap", PARTITION_LINUX_SWAP_GUID}, - {"lvm", PARTITION_LINUX_LVM_GUID}, - {"u-boot-env", PARTITION_U_BOOT_ENVIRONMENT}, - {"cros-kern", PARTITION_CROS_KERNEL}, - {"cros-root", PARTITION_CROS_ROOT}, - {"cros-fw", PARTITION_CROS_FIRMWARE}, - {"cros-rsrv", PARTITION_CROS_RESERVED}, -#endif +#if CONFIG_IS_ENABLED(EFI_PARTITION) + {"mbr", NULL, LEGACY_MBR_PARTITION_GUID}, + {"msft", NULL, PARTITION_MSFT_RESERVED_GUID}, + {"data", NULL, PARTITION_BASIC_DATA_GUID}, + {"linux", NULL, PARTITION_LINUX_FILE_SYSTEM_DATA_GUID}, + {"raid", NULL, PARTITION_LINUX_RAID_GUID}, + {"swap", NULL, PARTITION_LINUX_SWAP_GUID}, + {"lvm", NULL, PARTITION_LINUX_LVM_GUID}, + {"u-boot-env", NULL, PARTITION_U_BOOT_ENVIRONMENT}, + {"cros-kern", NULL, PARTITION_CROS_KERNEL}, + {"cros-root", NULL, PARTITION_CROS_ROOT}, + {"cros-fw", NULL, PARTITION_CROS_FIRMWARE}, + {"cros-rsrv", NULL, PARTITION_CROS_RESERVED}, + { + "system", "EFI System Partition", + PARTITION_SYSTEM_GUID, + }, #if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI) { - "Device Path", + NULL, "Device Path", + PARTITION_SYSTEM_GUID, + }, + { + NULL, "Device Path", EFI_DEVICE_PATH_PROTOCOL_GUID, }, { - "Device Path To Text", + NULL, "Device Path To Text", EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID, }, { - "Device Path Utilities", + NULL, "Device Path Utilities", EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID, }, { - "Unicode Collation 2", + NULL, "Unicode Collation 2", EFI_UNICODE_COLLATION_PROTOCOL2_GUID, }, { - "Driver Binding", + NULL, "Driver Binding", EFI_DRIVER_BINDING_PROTOCOL_GUID, }, { - "Simple Text Input", + NULL, "Simple Text Input", EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID, }, { - "Simple Text Input Ex", + NULL, "Simple Text Input Ex", EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID, }, { - "Simple Text Output", + NULL, "Simple Text Output", EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID, }, { - "Block IO", + NULL, "Block IO", EFI_BLOCK_IO_PROTOCOL_GUID, }, { - "Disk IO", + NULL, "Disk IO", EFI_DISK_IO_PROTOCOL_GUID, }, { - "Simple File System", + NULL, "Simple File System", EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, }, { - "Loaded Image", + NULL, "Loaded Image", EFI_LOADED_IMAGE_PROTOCOL_GUID, }, { - "Loaded Image Device Path", + NULL, "Loaded Image Device Path", EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID, }, { - "Graphics Output", + NULL, "Graphics Output", EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, }, { - "HII String", + NULL, "HII String", EFI_HII_STRING_PROTOCOL_GUID, }, { - "HII Database", + NULL, "HII Database", EFI_HII_DATABASE_PROTOCOL_GUID, }, { - "HII Config Access", + NULL, "HII Config Access", EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID, }, { - "HII Config Routing", + NULL, "HII Config Routing", EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID, }, { - "Load File", + NULL, "Load File", EFI_LOAD_FILE_PROTOCOL_GUID, }, { - "Load File2", + NULL, "Load File2", EFI_LOAD_FILE2_PROTOCOL_GUID, }, { - "Random Number Generator", + NULL, "Random Number Generator", EFI_RNG_PROTOCOL_GUID, }, { - "Simple Network", + NULL, "Simple Network", EFI_SIMPLE_NETWORK_PROTOCOL_GUID, }, { - "PXE Base Code", + NULL, "PXE Base Code", EFI_PXE_BASE_CODE_PROTOCOL_GUID, }, { - "Device-Tree Fixup", + NULL, "Device-Tree Fixup", EFI_DT_FIXUP_PROTOCOL_GUID, }, { - "TCG2", + NULL, "TCG2", EFI_TCG2_PROTOCOL_GUID, }, { - "Firmware Management", + NULL, "Firmware Management", EFI_FIRMWARE_MANAGEMENT_PROTOCOL_GUID }, #if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL) { - "HTTP", + NULL, "HTTP", EFI_HTTP_PROTOCOL_GUID, }, { - "HTTP Service Binding", + NULL, "HTTP Service Binding", EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID, }, { - "IPv4 Config2", + NULL, "IPv4 Config2", EFI_IP4_CONFIG2_PROTOCOL_GUID, }, #endif /* Configuration table GUIDs */ { - "ACPI table", + NULL, "ACPI table", EFI_ACPI_TABLE_GUID, }, { - "EFI System Resource Table", + NULL, "EFI System Resource Table", EFI_SYSTEM_RESOURCE_TABLE_GUID, }, { - "device tree", + NULL, "device tree", EFI_FDT_GUID, }, { - "SMBIOS table", + NULL, "SMBIOS table", SMBIOS_TABLE_GUID, }, { - "SMBIOS3 table", + NULL, "SMBIOS3 table", SMBIOS3_TABLE_GUID, }, { - "Runtime properties", + NULL, "Runtime properties", EFI_RT_PROPERTIES_TABLE_GUID, }, { - "TCG2 Final Events Table", + NULL, "TCG2 Final Events Table", EFI_TCG2_FINAL_EVENTS_TABLE_GUID, }, { - "EFI Conformance Profiles Table", + NULL, "EFI Conformance Profiles Table", EFI_CONFORMANCE_PROFILES_TABLE_GUID, }, #ifdef CONFIG_EFI_RISCV_BOOT_PROTOCOL { - "RISC-V Boot", + NULL, "RISC-V Boot", RISCV_EFI_BOOT_PROTOCOL_GUID, }, #endif @@ -247,35 +260,36 @@ static const struct { #ifdef CONFIG_CMD_NVEDIT_EFI /* signature database */ { - "EFI_GLOBAL_VARIABLE_GUID", + "EFI_GLOBAL_VARIABLE_GUID", NULL, EFI_GLOBAL_VARIABLE_GUID, }, { - "EFI_IMAGE_SECURITY_DATABASE_GUID", + "EFI_IMAGE_SECURITY_DATABASE_GUID", NULL, EFI_IMAGE_SECURITY_DATABASE_GUID, }, /* certificate types */ { - "EFI_CERT_SHA256_GUID", + "EFI_CERT_SHA256_GUID", NULL, EFI_CERT_SHA256_GUID, }, { - "EFI_CERT_X509_GUID", + "EFI_CERT_X509_GUID", NULL, EFI_CERT_X509_GUID, }, { - "EFI_CERT_TYPE_PKCS7_GUID", + "EFI_CERT_TYPE_PKCS7_GUID", NULL, EFI_CERT_TYPE_PKCS7_GUID, }, #endif #if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI) - { "EFI_LZMA_COMPRESSED", EFI_LZMA_COMPRESSED }, - { "EFI_DXE_SERVICES", EFI_DXE_SERVICES }, - { "EFI_HOB_LIST", EFI_HOB_LIST }, - { "EFI_MEMORY_TYPE", EFI_MEMORY_TYPE }, - { "EFI_MEM_STATUS_CODE_REC", EFI_MEM_STATUS_CODE_REC }, - { "EFI_GUID_EFI_ACPI1", EFI_GUID_EFI_ACPI1 }, + { "EFI_LZMA_COMPRESSED", NULL, EFI_LZMA_COMPRESSED }, + { "EFI_DXE_SERVICES", NULL, EFI_DXE_SERVICES }, + { "EFI_HOB_LIST", NULL, EFI_HOB_LIST }, + { "EFI_MEMORY_TYPE", NULL, EFI_MEMORY_TYPE }, + { "EFI_MEM_STATUS_CODE_REC", NULL, EFI_MEM_STATUS_CODE_REC }, + { "EFI_GUID_EFI_ACPI1", NULL, EFI_GUID_EFI_ACPI1 }, #endif +#endif /* EFI_PARTITION */ #endif /* !USE_HOSTCC */ }; @@ -284,7 +298,8 @@ int uuid_guid_get_bin(const char *guid_str, unsigned char *guid_bin) int i; for (i = 0; i < ARRAY_SIZE(list_guid); i++) { - if (!strcmp(list_guid[i].string, guid_str)) { + if (list_guid[i].type && + !strcmp(list_guid[i].type, guid_str)) { memcpy(guid_bin, &list_guid[i].guid, 16); return 0; } @@ -298,7 +313,9 @@ const char *uuid_guid_get_str(const unsigned char *guid_bin) for (i = 0; i < ARRAY_SIZE(list_guid); i++) { if (!memcmp(list_guid[i].guid.b, guid_bin, 16)) { - return list_guid[i].string; + if (list_guid[i].description) + return list_guid[i].description; + return list_guid[i].type; } } return NULL; @@ -312,10 +329,9 @@ int uuid_str_to_bin(const char *uuid_str, unsigned char *uuid_bin, uint64_t tmp64; if (!uuid_str_valid(uuid_str)) { -#ifdef CONFIG_PARTITION_TYPE_GUID - if (!uuid_guid_get_bin(uuid_str, uuid_bin)) + if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) && + !uuid_guid_get_bin(uuid_str, uuid_bin)) return 0; -#endif return -EINVAL; } diff --git a/net/bootp.c b/net/bootp.c index f22921ed388..95d906e3b2d 100644 --- a/net/bootp.c +++ b/net/bootp.c @@ -545,14 +545,14 @@ static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip, } #endif -#ifdef CONFIG_BOOTP_PXE_CLIENTARCH - clientarch = CONFIG_BOOTP_PXE_CLIENTARCH; +#ifdef CONFIG_DHCP_PXE_CLIENTARCH + clientarch = CONFIG_DHCP_PXE_CLIENTARCH; #endif if (env_get("bootp_arch")) clientarch = env_get_ulong("bootp_arch", 16, clientarch); - if (clientarch > 0) { + if (clientarch != 0xff) { *e++ = 93; /* Client System Architecture */ *e++ = 2; *e++ = (clientarch >> 8) & 0xff; diff --git a/net/dhcpv6.c b/net/dhcpv6.c index 0c2de75ba1d..5bf935cb6a3 100644 --- a/net/dhcpv6.c +++ b/net/dhcpv6.c @@ -128,7 +128,7 @@ static int dhcp6_add_option(int option_id, uchar *pkt) break; case DHCP6_OPTION_CLIENT_ARCH_TYPE: client_arch_opt = (struct dhcp6_option_client_arch *)dhcp_option_start; - client_arch_opt->arch_type[num_client_arch++] = htons(CONFIG_DHCP6_PXE_CLIENTARCH); + client_arch_opt->arch_type[num_client_arch++] = htons(CONFIG_DHCP_PXE_CLIENTARCH); opt_len = sizeof(__be16) * num_client_arch; break; @@ -194,7 +194,7 @@ static void dhcp6_send_solicit_packet(void) pkt += dhcp6_add_option(DHCP6_OPTION_ELAPSED_TIME, pkt); pkt += dhcp6_add_option(DHCP6_OPTION_IA_NA, pkt); pkt += dhcp6_add_option(DHCP6_OPTION_ORO, pkt); - if (CONFIG_DHCP6_PXE_CLIENTARCH != 0xFF) + if (CONFIG_DHCP_PXE_CLIENTARCH != 0xFF) pkt += dhcp6_add_option(DHCP6_OPTION_CLIENT_ARCH_TYPE, pkt); pkt += dhcp6_add_option(DHCP6_OPTION_VENDOR_CLASS, pkt); pkt += dhcp6_add_option(DHCP6_OPTION_NII, pkt); @@ -244,7 +244,7 @@ static void dhcp6_send_request_packet(void) memcpy(pkt, sm_params.server_uid.uid_ptr, sm_params.server_uid.uid_size); pkt += sm_params.server_uid.uid_size; } - if (CONFIG_DHCP6_PXE_CLIENTARCH != 0xFF) + if (CONFIG_DHCP_PXE_CLIENTARCH != 0xFF) pkt += dhcp6_add_option(DHCP6_OPTION_CLIENT_ARCH_TYPE, pkt); pkt += dhcp6_add_option(DHCP6_OPTION_VENDOR_CLASS, pkt); pkt += dhcp6_add_option(DHCP6_OPTION_NII, pkt); diff --git a/net/lwip/Makefile b/net/lwip/Makefile index 5df222589b8..97299d9b542 100644 --- a/net/lwip/Makefile +++ b/net/lwip/Makefile @@ -2,8 +2,6 @@ ccflags-y += -I$(srctree)/lib/lwip/lwip/src/include -I$(srctree)/lib/lwip/u-boot obj-$(CONFIG_$(PHASE_)DM_ETH) += net-lwip.o obj-$(CONFIG_CMD_DHCP) += dhcp.o -obj-$(CONFIG_CMD_DNS) += dns.o -obj-$(CONFIG_CMD_PING) += ping.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o obj-$(CONFIG_WGET) += wget.o diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index 043d2ab6e94..4c9cb0ecaa0 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -58,7 +58,6 @@ static int dhcp_loop(struct udevice *udev) /* Wait for DHCP to complete */ do { net_lwip_rx(udev, netif); - sys_check_timeouts(); bound = dhcp_supplied_address(netif); if (bound) break; diff --git a/net/lwip/eth_internal.h b/net/lwip/eth_internal.h deleted file mode 100644 index 87561d5b214..00000000000 --- a/net/lwip/eth_internal.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2001-2015 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * Joe Hershberger, National Instruments - */ - -#ifndef __ETH_INTERNAL_H -#define __ETH_INTERNAL_H - -/* Do init that is common to driver model and legacy networking */ -void eth_common_init(void); - -/** - * eth_env_set_enetaddr_by_index() - set the MAC address environment variable - * - * This sets up an environment variable with the given MAC address (@enetaddr). - * The environment variable to be set is defined by <@base_name><@index>addr. - * If @index is 0 it is omitted. For common Ethernet this means ethaddr, - * eth1addr, etc. - * - * @base_name: Base name for variable, typically "eth" - * @index: Index of interface being updated (>=0) - * @enetaddr: Pointer to MAC address to put into the variable - * Return: 0 if OK, other value on error - */ -int eth_env_set_enetaddr_by_index(const char *base_name, int index, - uchar *enetaddr); - -int eth_mac_skip(int index); -void eth_current_changed(void); -void eth_set_dev(struct udevice *dev); -void eth_set_current_to_next(void); - -#endif diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index abc52b32049..3918d57d7e5 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -7,15 +7,19 @@ #include <dm/device.h> #include <dm/uclass.h> #include <hexdump.h> +#include <linux/kernel.h> #include <lwip/ip4_addr.h> +#include <lwip/dns.h> #include <lwip/err.h> #include <lwip/netif.h> #include <lwip/pbuf.h> #include <lwip/etharp.h> #include <lwip/init.h> #include <lwip/prot/etharp.h> +#include <lwip/timeouts.h> #include <net.h> #include <timer.h> +#include <u-boot/schedule.h> /* xx:xx:xx:xx:xx:xx\0 */ #define MAC_ADDR_STRLEN 18 @@ -139,6 +143,40 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, } /* + * Initialize DNS via env + */ +int net_lwip_dns_init(void) +{ +#if CONFIG_IS_ENABLED(CMD_DNS) + bool has_server = false; + ip_addr_t ns; + char *nsenv; + + nsenv = env_get("dnsip"); + if (nsenv && ipaddr_aton(nsenv, &ns)) { + dns_setserver(0, &ns); + has_server = true; + } + + nsenv = env_get("dnsip2"); + if (nsenv && ipaddr_aton(nsenv, &ns)) { + dns_setserver(1, &ns); + has_server = true; + } + + if (!has_server) { + log_err("No valid name server (dnsip/dnsip2)\n"); + return -EINVAL; + } + + return 0; +#else + log_err("DNS disabled\n"); + return -EINVAL; +#endif +} + +/* * Initialize the network stack if needed and start the current device if valid */ int net_lwip_eth_start(void) @@ -285,6 +323,11 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif) int len; int i; + /* lwIP timers */ + sys_check_timeouts(); + /* Other tasks and actions */ + schedule(); + if (!eth_is_active(udev)) return -EINVAL; @@ -316,6 +359,44 @@ int net_lwip_rx(struct udevice *udev, struct netif *netif) return len; } +/** + * net_lwip_dns_resolve() - find IP address from name or IP + * + * @name_or_ip: host name or IP address + * @ip: output IP address + * + * Return value: 0 on success, -1 on failure. + */ +int net_lwip_dns_resolve(char *name_or_ip, ip_addr_t *ip) +{ +#if defined(CONFIG_CMD_DNS) + char *var = "_dnsres"; + char *argv[] = { "dns", name_or_ip, var, NULL }; + int argc = ARRAY_SIZE(argv) - 1; +#endif + + if (ipaddr_aton(name_or_ip, ip)) + return 0; + +#if defined(CONFIG_CMD_DNS) + if (do_dns(NULL, 0, argc, argv) != CMD_RET_SUCCESS) + return -1; + + name_or_ip = env_get(var); + if (!name_or_ip) + return -1; + + if (!ipaddr_aton(name_or_ip, ip)) + return -1; + + env_set(var, NULL); + + return 0; +#else + return -1; +#endif +} + void net_process_received_packet(uchar *in_packet, int len) { #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER) diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index b7eb486ef77..94bacf63075 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -157,8 +157,10 @@ static void no_response(void *arg) static int tftp_loop(struct udevice *udev, ulong addr, char *fname, ip_addr_t srvip, uint16_t srvport) { + int blksize = CONFIG_TFTP_BLOCKSIZE; struct netif *netif; struct tftp_ctx ctx; + const char *ep; err_t err; if (!fname || addr == 0) @@ -187,7 +189,10 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, if (!(err == ERR_OK || err == ERR_USE)) log_err("tftp_init_client err: %d\n", err); - tftp_client_set_blksize(CONFIG_TFTP_BLOCKSIZE); + ep = env_get("tftpblocksize"); + if (ep) + blksize = simple_strtol(ep, NULL, 10); + tftp_client_set_blksize(blksize); ctx.start_time = get_timer(0); err = tftp_get(&ctx, &srvip, srvport, fname, TFTP_MODE_OCTET); @@ -201,7 +206,6 @@ static int tftp_loop(struct udevice *udev, ulong addr, char *fname, sys_timeout(NO_RSP_TIMEOUT_MS, no_response, &ctx); while (!ctx.done) { net_lwip_rx(udev, netif); - sys_check_timeouts(); if (ctrlc()) { printf("\nAbort\n"); ctx.done = ABORTED; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index f4fd9718285..55bd2b72e26 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -6,7 +6,6 @@ #include <display_options.h> #include <efi_loader.h> #include <env.h> -#include <image.h> #include <linux/kconfig.h> #include <lwip/apps/http_client.h> #include "lwip/altcp_tls.h" @@ -138,72 +137,6 @@ static int parse_url(char *url, char *host, u16 *port, char **path, return 0; } -/* - * Legacy syntax support - * Convert [<server_name_or_ip>:]filename into a URL if needed - */ -static int parse_legacy_arg(char *arg, char *nurl, size_t rem) -{ - char *p = nurl; - size_t n; - char *col = strchr(arg, ':'); - char *env; - char *server; - char *path; - - if (strstr(arg, "http") == arg) { - n = snprintf(nurl, rem, "%s", arg); - if (n < 0 || n > rem) - return -1; - return 0; - } - - n = snprintf(p, rem, "%s", "http://"); - if (n < 0 || n > rem) - return -1; - p += n; - rem -= n; - - if (col) { - n = col - arg; - server = arg; - path = col + 1; - } else { - env = env_get("httpserverip"); - if (!env) - env = env_get("serverip"); - if (!env) { - log_err("error: httpserver/serverip has to be set\n"); - return -1; - } - n = strlen(env); - server = env; - path = arg; - } - - if (rem < n) - return -1; - strncpy(p, server, n); - p += n; - rem -= n; - if (rem < 1) - return -1; - *p = '/'; - p++; - rem--; - n = strlen(path); - if (rem < n) - return -1; - strncpy(p, path, n); - p += n; - rem -= n; - if (rem < 1) - return -1; - *p = '\0'; - - return 0; -} - /** * store_block() - copy received data * @@ -338,94 +271,10 @@ static err_t httpc_headers_done_cb(httpc_state_t *connection, void *arg, struct return ERR_OK; } -#if CONFIG_IS_ENABLED(WGET_HTTPS) -enum auth_mode { - AUTH_NONE, - AUTH_OPTIONAL, - AUTH_REQUIRED, -}; - -static char *cacert; -static size_t cacert_size; -static enum auth_mode cacert_auth_mode = AUTH_OPTIONAL; -#endif #if CONFIG_IS_ENABLED(WGET_CACERT) -static int set_auth(enum auth_mode auth) -{ - cacert_auth_mode = auth; - - return CMD_RET_SUCCESS; -} #endif -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) -extern const char builtin_cacert[]; -extern const size_t builtin_cacert_size; -static bool cacert_initialized; -#endif - -#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) -static int _set_cacert(const void *addr, size_t sz) -{ - mbedtls_x509_crt crt; - void *p; - int ret; - - if (cacert) - free(cacert); - - if (!addr) { - cacert = NULL; - cacert_size = 0; - return CMD_RET_SUCCESS; - } - - p = malloc(sz); - if (!p) - return CMD_RET_FAILURE; - cacert = p; - cacert_size = sz; - - memcpy(cacert, (void *)addr, sz); - - mbedtls_x509_crt_init(&crt); - ret = mbedtls_x509_crt_parse(&crt, cacert, cacert_size); - if (ret) { - if (!wget_info->silent) - printf("Could not parse certificates (%d)\n", ret); - free(cacert); - cacert = NULL; - cacert_size = 0; - return CMD_RET_FAILURE; - } - -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) - cacert_initialized = true; -#endif - return CMD_RET_SUCCESS; -} - -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) -static int set_cacert_builtin(void) -{ - return _set_cacert(builtin_cacert, builtin_cacert_size); -} -#endif - -#if CONFIG_IS_ENABLED(WGET_CACERT) -static int set_cacert(char * const saddr, char * const ssz) -{ - ulong addr, sz; - - addr = hextoul(saddr, NULL); - sz = hextoul(ssz, NULL); - - return _set_cacert((void *)addr, sz); -} -#endif -#endif /* CONFIG_WGET_CACERT || CONFIG_WGET_BUILTIN_CACERT */ - int wget_do_request(ulong dst_addr, char *uri) { #if CONFIG_IS_ENABLED(WGET_HTTPS) @@ -461,12 +310,17 @@ int wget_do_request(ulong dst_addr, char *uri) if (!netif) return -1; + /* if URL with hostname init dns */ + if (!ipaddr_aton(ctx.server_name, NULL) && net_lwip_dns_init()) + return CMD_RET_FAILURE; + memset(&conn, 0, sizeof(conn)); #if CONFIG_IS_ENABLED(WGET_HTTPS) if (is_https) { char *ca; size_t ca_sz; +#if CONFIG_IS_ENABLED(WGET_CACERT) || CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) #if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) if (!cacert_initialized) set_cacert_builtin(); @@ -493,7 +347,7 @@ int wget_do_request(ulong dst_addr, char *uri) * with no verification if not. */ } - +#endif if (!ca && !wget_info->silent) { printf("WARNING: no CA certificates, "); printf("HTTPS connections not authenticated\n"); @@ -526,7 +380,6 @@ int wget_do_request(ulong dst_addr, char *uri) while (!ctx.done) { net_lwip_rx(udev, netif); - sys_check_timeouts(); if (ctrlc()) break; } @@ -542,54 +395,6 @@ int wget_do_request(ulong dst_addr, char *uri) return -1; } -int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) -{ - char *end; - char *url; - ulong dst_addr; - char nurl[1024]; - -#if CONFIG_IS_ENABLED(WGET_CACERT) - if (argc == 4 && !strncmp(argv[1], "cacert", strlen("cacert"))) - return set_cacert(argv[2], argv[3]); - if (argc == 3 && !strncmp(argv[1], "cacert", strlen("cacert"))) { -#if CONFIG_IS_ENABLED(WGET_BUILTIN_CACERT) - if (!strncmp(argv[2], "builtin", strlen("builtin"))) - return set_cacert_builtin(); -#endif - if (!strncmp(argv[2], "none", strlen("none"))) - return set_auth(AUTH_NONE); - if (!strncmp(argv[2], "optional", strlen("optional"))) - return set_auth(AUTH_OPTIONAL); - if (!strncmp(argv[2], "required", strlen("required"))) - return set_auth(AUTH_REQUIRED); - return CMD_RET_USAGE; - } -#endif - - if (argc < 2 || argc > 3) - return CMD_RET_USAGE; - - dst_addr = hextoul(argv[1], &end); - if (end == (argv[1] + strlen(argv[1]))) { - if (argc < 3) - return CMD_RET_USAGE; - url = argv[2]; - } else { - dst_addr = image_load_addr; - url = argv[1]; - } - - if (parse_legacy_arg(url, nurl, sizeof(nurl))) - return CMD_RET_FAILURE; - - wget_info = &default_wget_info; - if (wget_do_request(dst_addr, nurl)) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; -} - /** * wget_validate_uri() - validate the uri for wget * diff --git a/net/net-common.c b/net/net-common.c index e01b0da7d7b..b064557d524 100644 --- a/net/net-common.c +++ b/net/net-common.c @@ -1,5 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 + +#include <dm/uclass.h> #include <net-common.h> +#include <linux/time.h> +#include <rtc.h> void copy_filename(char *dst, const char *src, int size) { @@ -25,3 +29,22 @@ int wget_request(ulong dst_addr, char *uri, struct wget_http_info *info) wget_info = info ? info : &default_wget_info; return wget_do_request(dst_addr, uri); } + +void net_sntp_set_rtc(u32 seconds) +{ + struct rtc_time tm; + struct udevice *dev; + int ret; + + rtc_to_tm(seconds, &tm); + + ret = uclass_get_device(UCLASS_RTC, 0, &dev); + if (ret) + printf("SNTP: cannot find RTC: err=%d\n", ret); + else + dm_rtc_set(dev, &tm); + + printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n", + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); +} diff --git a/net/sntp.c b/net/sntp.c index 73d1d87d38b..77cee0046bd 100644 --- a/net/sntp.c +++ b/net/sntp.c @@ -57,8 +57,7 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip, unsigned src, unsigned len) { struct sntp_pkt_t *rpktp = (struct sntp_pkt_t *)pkt; - struct rtc_time tm; - ulong seconds; + u32 seconds; debug("%s\n", __func__); @@ -69,24 +68,8 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip, * As the RTC's used in U-Boot support second resolution only * we simply ignore the sub-second field. */ - memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(ulong)); - - rtc_to_tm(ntohl(seconds) - 2208988800UL + net_ntp_time_offset, &tm); -#ifdef CONFIG_DM_RTC - struct udevice *dev; - int ret; - - ret = uclass_get_device(UCLASS_RTC, 0, &dev); - if (ret) - printf("SNTP: cannot find RTC: err=%d\n", ret); - else - dm_rtc_set(dev, &tm); -#elif defined(CONFIG_CMD_DATE) - rtc_set(&tm); -#endif - printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n", - tm.tm_year, tm.tm_mon, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); + memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(seconds)); + net_sntp_set_rtc(ntohl(seconds) - 2208988800UL + net_ntp_time_offset); net_set_state(NETLOOP_SUCCESS); } diff --git a/scripts/Makefile.build b/scripts/Makefile.build index aa48d249433..998679f00a0 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -76,10 +76,12 @@ endif ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),) lib-target := $(obj)/lib.a +# Modified for U-Boot +# real-obj-y += $(obj)/lib-ksyms.o endif -ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),) -builtin-target := $(obj)/built-in.o +ifneq ($(strip $(real-obj-y) $(need-builtin)),) +builtin-target := $(obj)/built-in.a endif ifdef CONFIG_MODULES @@ -102,7 +104,11 @@ else ifeq ($(KBUILD_CHECKSRC),2) cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< endif -# Do section mismatch analysis for each module/built-in.o +ifneq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),) + cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $< +endif + +# Do section mismatch analysis for each module/built-in.a ifdef CONFIG_DEBUG_SECTION_MISMATCH cmd_secanalysis = ; scripts/mod/modpost $@ endif @@ -111,101 +117,94 @@ endif # --------------------------------------------------------------------------- # Default is built-in, unless we know otherwise +$(foreach x, i ll lst o s symtypes, $(patsubst %.o,%.$(x),$(real-obj-m))): \ + part-of-module := y + modkern_cflags = \ $(if $(part-of-module), \ $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \ $(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL)) quiet_modtag = $(if $(part-of-module),[M], ) -$(real-objs-m) : part-of-module := y -$(real-objs-m:.o=.i) : part-of-module := y -$(real-objs-m:.o=.s) : part-of-module := y -$(real-objs-m:.o=.lst): part-of-module := y - -# Default for not multi-part modules -modname = $(basetarget) - -$(multi-objs-m) : modname = $(modname-multi) -$(multi-objs-m:.o=.i) : modname = $(modname-multi) -$(multi-objs-m:.o=.s) : modname = $(modname-multi) -$(multi-objs-m:.o=.lst) : modname = $(modname-multi) -$(multi-objs-y) : modname = $(modname-multi) -$(multi-objs-y:.o=.i) : modname = $(modname-multi) -$(multi-objs-y:.o=.s) : modname = $(modname-multi) -$(multi-objs-y:.o=.lst) : modname = $(modname-multi) - quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ -cmd_cc_s_c = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< + cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) $(DISABLE_LTO) -fverbose-asm -S -o $@ $< $(obj)/%.s: $(src)/%.c FORCE $(call if_changed_dep,cc_s_c) -quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@ -cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $< +quiet_cmd_cpp_i_c = CPP $(quiet_modtag) $@ +cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(src)/%.c FORCE - $(call if_changed_dep,cc_i_c) + $(call if_changed_dep,cpp_i_c) -cmd_gensymtypes = \ +# These mirror gensymtypes_S and co below, keep them in synch. +cmd_gensymtypes_c = \ $(CPP) -D__GENKSYMS__ $(c_flags) $< | \ - scripts/genksyms/genksyms $(if $(1), -T $(2)) \ + scripts/genksyms/genksyms $(if $(1), -T $(2)) \ + $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ $(if $(KBUILD_PRESERVE),-p) \ -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ cmd_cc_symtypes_c = \ - $(call cmd_gensymtypes,true,$@) >/dev/null; \ + $(call cmd_gensymtypes_c,true,$@) >/dev/null; \ test -s $@ || rm -f $@ $(obj)/%.symtypes : $(src)/%.c FORCE $(call cmd,cc_symtypes_c) +# LLVM assembly +# Generate .ll files from .c +quiet_cmd_cc_ll_c = CC $(quiet_modtag) $@ + cmd_cc_ll_c = $(CC) $(c_flags) -emit-llvm -S -o $@ $< + +$(obj)/%.ll: $(src)/%.c FORCE + $(call if_changed_dep,cc_ll_c) + # C (.c) files # The C file is compiled and updated dependency information is generated. # (See cmd_cc_o_c + relevant part of rule_cc_o_c) quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ -cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< + cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< ifdef CONFIG_MODVERSIONS # When module versioning is enabled the following steps are executed: # o compile a <file>.o from <file>.c # o if <file>.o doesn't contain a __ksymtab version, i.e. does -# not export symbols, it's done +# not export symbols, it's done. # o otherwise, we calculate symbol versions using the good old # genksyms on the preprocessed source and postprocess them in a way # that they are usable as a linker script # o generate .tmp_<file>.o from <file>.o using the linker to # replace the unresolved symbols __crc_exported_symbol with # the actual value of the checksum generated by genksyms - # o remove .tmp_<file>.o to <file>.o -cmd_modversions = \ + +cmd_modversions_c = \ if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \ - $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ + $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ > $(@D)/.tmp_$(@F:.o=.ver); \ \ - $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ + $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ -T $(@D)/.tmp_$(@F:.o=.ver); \ mv -f $(@D)/.tmp_$(@F) $@; \ rm -f $(@D)/.tmp_$(@F:.o=.ver); \ - fi; + fi endif ifdef CONFIG_FTRACE_MCOUNT_RECORD -# gcc 5 supports generating the mcount tables directly -ifneq ($(call cc-option,-mrecord-mcount,y),y) -KBUILD_CFLAGS += -mrecord-mcount -else -# else do it all manually +ifndef CC_USING_RECORD_MCOUNT +# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl ifdef BUILD_C_RECORDMCOUNT ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") RECORDMCOUNT_FLAGS = -w endif # Due to recursion, we must skip empty.o. # The empty.o file is created in the make process in order to determine -# the target endianness and word size. It is made before all other C -# files, including recordmcount. +# the target endianness and word size. It is made before all other C +# files, including recordmcount. sub_cmd_record_mcount = \ if [ $(@) != "scripts/mod/empty.o" ]; then \ $(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \ @@ -213,17 +212,59 @@ sub_cmd_record_mcount = \ recordmcount_source := $(srctree)/scripts/recordmcount.c \ $(srctree)/scripts/recordmcount.h else -sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ +sub_cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ "$(if $(CONFIG_SYS_BIG_ENDIAN),big,little)" \ "$(if $(CONFIG_64BIT),64,32)" \ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS)" \ "$(LD) $(KBUILD_LDFLAGS)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)"; recordmcount_source := $(srctree)/scripts/recordmcount.pl +endif # BUILD_C_RECORDMCOUNT +cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \ + $(sub_cmd_record_mcount)) +endif # CC_USING_RECORD_MCOUNT +endif # CONFIG_FTRACE_MCOUNT_RECORD + +ifdef CONFIG_STACK_VALIDATION +ifneq ($(SKIP_STACK_VALIDATION),1) + +__objtool_obj := $(objtree)/tools/objtool/objtool + +objtool_args = $(if $(CONFIG_UNWINDER_ORC),orc generate,check) + +objtool_args += $(if $(part-of-module), --module,) + +ifndef CONFIG_FRAME_POINTER +objtool_args += --no-fp endif -cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \ - $(sub_cmd_record_mcount)) -endif # -record-mcount +ifdef CONFIG_GCOV_KERNEL +objtool_args += --no-unreachable +endif +ifdef CONFIG_RETPOLINE + objtool_args += --retpoline +endif + +# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory +# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file +# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file +cmd_objtool = $(if $(patsubst y%,, \ + $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ + $(__objtool_obj) $(objtool_args) $@) +objtool_obj = $(if $(patsubst y%,, \ + $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n), \ + $(__objtool_obj)) + +endif # SKIP_STACK_VALIDATION +endif # CONFIG_STACK_VALIDATION + +# Rebuild all objects when objtool changes, or is enabled/disabled. +objtool_dep = $(objtool_obj) \ + $(wildcard include/config/orc/unwinder.h \ + include/config/stack/validation.h) + +ifdef CONFIG_TRIM_UNUSED_KSYMS +cmd_gen_ksymdeps = \ + $(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd endif define rule_cc_o_c @@ -243,17 +284,25 @@ define rule_as_o_S $(call cmd,modversions_S) endef +# List module undefined symbols (or empty line if not enabled) +ifdef CONFIG_TRIM_UNUSED_KSYMS +cmd_undef_syms = $(NM) $@ | sed -n 's/^ *U //p' | xargs echo +else +cmd_undef_syms = echo +endif + # Built-in and composite module parts -$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE +$(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) # Single-part modules are special since we need to mark them in $(MODVERDIR) -$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE +$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) $(objtool_dep) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) - @{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod) + @{ echo $(@:.o=.ko); echo $@; \ + $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod) quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ @@ -268,29 +317,83 @@ $(obj)/%.lst: $(src)/%.c FORCE modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL) -$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) -$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) +$(real-obj-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) +$(real-obj-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) + +# .S file exports must have their C prototypes defined in asm/asm-prototypes.h +# or a file that it includes, in order to get versioned symbols. We build a +# dummy C file that includes asm-prototypes and the EXPORT_SYMBOL lines from +# the .S file (with trailing ';'), and run genksyms on that, to extract vers. +# +# This is convoluted. The .S file must first be preprocessed to run guards and +# expand names, then the resulting exports must be constructed into plain +# EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed +# to make the genksyms input. +# +# These mirror gensymtypes_c and co above, keep them in synch. +cmd_gensymtypes_S = \ + { echo "\#include <linux/kernel.h>" ; \ + echo "\#include <asm/asm-prototypes.h>" ; \ + $(CPP) $(a_flags) $< | \ + grep "\<___EXPORT_SYMBOL\>" | \ + sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \ + $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \ + scripts/genksyms/genksyms $(if $(1), -T $(2)) \ + $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \ + $(if $(KBUILD_PRESERVE),-p) \ + -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null)) + +quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ +cmd_cc_symtypes_S = \ + $(call cmd_gensymtypes_S,true,$@) >/dev/null; \ + test -s $@ || rm -f $@ -quiet_cmd_as_s_S = CPP $(quiet_modtag) $@ -cmd_as_s_S = $(CPP) $(a_flags) -o $@ $< +$(obj)/%.symtypes : $(src)/%.S FORCE + $(call cmd,cc_symtypes_S) + + +quiet_cmd_cpp_s_S = CPP $(quiet_modtag) $@ +cmd_cpp_s_S = $(CPP) $(a_flags) -o $@ $< $(obj)/%.s: $(src)/%.S FORCE - $(call if_changed_dep,as_s_S) + $(call if_changed_dep,cpp_s_S) quiet_cmd_as_o_S = AS $(quiet_modtag) $@ -cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< + cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< + +ifdef CONFIG_MODVERSIONS + +ASM_PROTOTYPES := $(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/asm-prototypes.h) -$(obj)/%.o: $(src)/%.S FORCE - $(call if_changed_dep,as_o_S) +ifneq ($(ASM_PROTOTYPES),) -targets += $(real-objs-y) $(real-objs-m) $(lib-y) +# versioning matches the C process described above, with difference that +# we parse asm-prototypes.h C header to get function definitions. + +cmd_modversions_S = \ + if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \ + $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ + > $(@D)/.tmp_$(@F:.o=.ver); \ + \ + $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \ + -T $(@D)/.tmp_$(@F:.o=.ver); \ + mv -f $(@D)/.tmp_$(@F) $@; \ + rm -f $(@D)/.tmp_$(@F:.o=.ver); \ + fi +endif +endif + +$(obj)/%.o: $(src)/%.S $(objtool_dep) FORCE + $(call if_changed_rule,as_o_S) + +targets += $(filter-out $(subdir-obj-y), $(real-obj-y)) $(real-obj-m) $(lib-y) targets += $(extra-y) $(MAKECMDGOALS) $(always) targets += $(real-dtb-y) $(lib-y) $(always-y) # Linker scripts preprocessor (.lds.S -> .lds) # --------------------------------------------------------------------------- quiet_cmd_cpp_lds_S = LDS $@ - cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \ + cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< $(obj)/%.lds: $(src)/%.lds.S FORCE @@ -312,17 +415,17 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/tools/asn1_compiler $(sort $(subdir-obj-y)): $(subdir-ym) ; # -# Rule to compile a set of .o files into one .o file +# Rule to compile a set of .o files into one .a file (without symbol table) # ifdef builtin-target -quiet_cmd_link_o_target = AR $@ -# If the list of objects to link is empty, just create an empty built-in.o -cmd_link_o_target = $(if $(strip $(obj-y)),\ - rm -f $@; $(AR) cDPrsT $@ $(filter $(obj-y), $^), \ - rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@) -$(builtin-target): $(obj-y) FORCE - $(call if_changed,link_o_target) +quiet_cmd_ar_builtin = AR $@ +# Modified for U-Boot, we create thin archives directly, instead of using the kernel script +# Check f49821ee32b76 and 6358d6e8b98 in kernel + cmd_ar_builtin = rm -f $@; $(AR) rcTP$(KBUILD_ARFLAGS) $@ $(real-prereqs) + +$(builtin-target): $(real-obj-y) FORCE + $(call if_changed,ar_builtin) targets += $(builtin-target) endif # builtin-target @@ -341,7 +444,7 @@ $(modorder-target): $(subdir-ym) FORCE $(Q)(cat /dev/null; $(modorder-cmds)) > $@ # -# Rule to compile a set of .o files into one .a file +# Rule to compile a set of .o files into one .a file (with symbol table) # ifdef lib-target @@ -349,25 +452,40 @@ $(lib-target): $(lib-y) FORCE $(call if_changed,ar) targets += $(lib-target) -endif -quiet_cmd_link_multi-y = AR $@ -cmd_link_multi-y = rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@ $(filter %.o,$^) +dummy-object = $(obj)/.lib_exports.o +ksyms-lds = $(dot-target).lds + +quiet_cmd_export_list = EXPORTS $@ +cmd_export_list = $(OBJDUMP) -h $< | \ + sed -ne '/___ksymtab/s/.*+\([^ ]*\).*/EXTERN(\1)/p' >$(ksyms-lds);\ + rm -f $(dummy-object);\ + echo | $(CC) $(a_flags) -c -o $(dummy-object) -x assembler -;\ + $(LD) $(ld_flags) -r -o $@ -T $(ksyms-lds) $(dummy-object);\ + rm $(dummy-object) $(ksyms-lds) + +$(obj)/lib-ksyms.o: $(lib-target) FORCE + $(call if_changed,export_list) -quiet_cmd_link_multi-m = AR [M] $@ -cmd_link_multi-m = $(cmd_link_multi-y) +targets += $(obj)/lib-ksyms.o -$(multi-used-y): FORCE - $(call if_changed,link_multi-y) -$(call multi_depend, $(multi-used-y), .o, -objs -y) +endif + +# NOTE: +# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object +# module is turned into a multi object module, $^ will contain header file +# dependencies recorded in the .*.cmd file. +quiet_cmd_link_multi-m = LD [M] $@ +cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^) $(cmd_secanalysis) $(multi-used-m): FORCE $(call if_changed,link_multi-m) - @{ echo $(@:.o=.ko); echo $(filter %.o,$^); } > $(MODVERDIR)/$(@F:.o=.mod) -$(call multi_depend, $(multi-used-m), .o, -objs -y) - -targets += $(multi-used-y) $(multi-used-m) + @{ echo $(@:.o=.ko); echo $(filter %.o,$^); \ + $(cmd_undef_syms); } > $(MODVERDIR)/$(@F:.o=.mod) +$(call multi_depend, $(multi-used-m), .o, -objs -y -m) +targets += $(multi-used-m) +targets := $(filter-out $(PHONY), $(targets)) # Add intermediate targets: # When building objects with specific suffix patterns, add intermediate @@ -375,9 +493,13 @@ targets += $(multi-used-y) $(multi-used-m) intermediate_targets = $(foreach sfx, $(2), \ $(patsubst %$(strip $(1)),%$(sfx), \ $(filter %$(strip $(1)), $(targets)))) +# %.asn1.o <- %.asn1.[ch] <- %.asn1 +# %.dtb.o <- %.dtb.S <- %.dtb <- %.dts # %.lex.o <- %.lex.c <- %.l # %.tab.o <- %.tab.[ch] <- %.y -targets += $(call intermediate_targets, .lex.o, .lex.c) \ +targets += $(call intermediate_targets, .asn1.o, .asn1.c .asn1.h) \ + $(call intermediate_targets, .dtb.o, .dtb.S .dtb) \ + $(call intermediate_targets, .lex.o, .lex.c) \ $(call intermediate_targets, .tab.o, .tab.c .tab.h) # Descending @@ -385,7 +507,7 @@ targets += $(call intermediate_targets, .lex.o, .lex.c) \ PHONY += $(subdir-ym) $(subdir-ym): - $(Q)$(MAKE) $(build)=$@ + $(Q)$(MAKE) $(build)=$@ need-builtin=$(if $(findstring $@,$(subdir-obj-y)),1) # Add FORCE to the prequisites of a target to force it to be always rebuilt. # --------------------------------------------------------------------------- diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index f687515fc79..7df62263bc4 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -67,5 +67,14 @@ ifeq ("$(strip $(warning))","") endif KBUILD_CFLAGS += $(warning) +else +ifdef CONFIG_CC_IS_CLANG +KBUILD_CFLAGS += $(call cc-disable-warning, initializer-overrides) +KBUILD_CFLAGS += $(call cc-disable-warning, unused-value) +KBUILD_CFLAGS += $(call cc-disable-warning, format) +KBUILD_CFLAGS += $(call cc-disable-warning, sign-compare) +KBUILD_CFLAGS += $(call cc-disable-warning, format-zero-length) +KBUILD_CFLAGS += $(call cc-disable-warning, uninitialized) +endif endif diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins new file mode 100644 index 00000000000..5f7df50cfe7 --- /dev/null +++ b/scripts/Makefile.gcc-plugins @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0 + +gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) += cyc_complexity_plugin.so + +gcc-plugin-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) += latent_entropy_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) \ + += -DLATENT_ENTROPY_PLUGIN +ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY + DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable +endif +export DISABLE_LATENT_ENTROPY_PLUGIN + +gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so + +gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) \ + += -fplugin-arg-structleak_plugin-verbose +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF) \ + += -fplugin-arg-structleak_plugin-byref +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \ + += -fplugin-arg-structleak_plugin-byref-all +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \ + += -DSTRUCTLEAK_PLUGIN + +gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ + += -DRANDSTRUCT_PLUGIN +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) \ + += -fplugin-arg-randomize_layout_plugin-performance-mode + +gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -DSTACKLEAK_PLUGIN +gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STACKLEAK) \ + += -fplugin-arg-stackleak_plugin-track-min-size=$(CONFIG_STACKLEAK_TRACK_MIN_SIZE) +ifdef CONFIG_GCC_PLUGIN_STACKLEAK + DISABLE_STACKLEAK_PLUGIN += -fplugin-arg-stackleak_plugin-disable +endif +export DISABLE_STACKLEAK_PLUGIN + +gcc-plugin-$(CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK) += arm_ssp_per_task_plugin.so +ifdef CONFIG_GCC_PLUGIN_ARM_SSP_PER_TASK + DISABLE_ARM_SSP_PER_TASK_PLUGIN += -fplugin-arg-arm_ssp_per_task_plugin-disable +endif +export DISABLE_ARM_SSP_PER_TASK_PLUGIN + +# All the plugin CFLAGS are collected here in case a build target needs to +# filter them out of the KBUILD_CFLAGS. +GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) +# The sancov_plugin.so is included via CFLAGS_KCOV, so it is removed here. +GCC_PLUGINS_CFLAGS := $(filter-out %/sancov_plugin.so, $(GCC_PLUGINS_CFLAGS)) +export GCC_PLUGINS_CFLAGS + +# Add the flags to the build! +KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS) + +# All enabled GCC plugins are collected here for building below. +GCC_PLUGIN := $(gcc-plugin-y) +export GCC_PLUGIN diff --git a/scripts/Makefile.kcov b/scripts/Makefile.kcov new file mode 100644 index 00000000000..3d61c4bfcbe --- /dev/null +++ b/scripts/Makefile.kcov @@ -0,0 +1,9 @@ +ifdef CONFIG_KCOV + +kcov-flags-$(CONFIG_CC_HAS_SANCOV_TRACE_PC) += -fsanitize-coverage=trace-pc +kcov-flags-$(CONFIG_KCOV_ENABLE_COMPARISONS) += -fsanitize-coverage=trace-cmp +kcov-flags-$(CONFIG_GCC_PLUGIN_SANCOV) += -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so + +export CFLAGS_KCOV := $(kcov-flags-y) + +endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 19a5be57495..5db2fbc418a 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -5,46 +5,40 @@ ccflags-y += $(EXTRA_CFLAGS) cppflags-y += $(EXTRA_CPPFLAGS) ldflags-y += $(EXTRA_LDFLAGS) -# -# flags that take effect in sub directories -export KBUILD_SUBDIR_ASFLAGS := $(KBUILD_SUBDIR_ASFLAGS) $(subdir-asflags-y) -export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y) +# flags that take effect in current and sub directories +KBUILD_AFLAGS += $(subdir-asflags-y) +KBUILD_CFLAGS += $(subdir-ccflags-y) # Figure out what we need to build from the various variables # =========================================================================== # When an object is listed to be built compiled-in and modular, # only build the compiled-in version - obj-m := $(filter-out $(obj-y),$(obj-m)) # Libraries are always collected in one lib file. # Filter out objects already built-in - lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m))) +# Determine modorder. +# Unfortunately, we don't have information about ordering between -y +# and -m subdirs. Just put -y's first. +modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko)) # Handle objects in subdirs # --------------------------------------------------------------------------- -# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o +# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.a # and add the directory to the list of dirs to descend into: $(subdir-y) # o if we encounter foo/ in $(obj-m), remove it from $(obj-m) # and add the directory to the list of dirs to descend into: $(subdir-m) - -# Determine modorder. -# Unfortunately, we don't have information about ordering between -y -# and -m subdirs. Just put -y's first. -modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko)) - __subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) subdir-y += $(__subdir-y) __subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m))) subdir-m += $(__subdir-m) -obj-y := $(patsubst %/, %/built-in.o, $(obj-y)) +obj-y := $(patsubst %/, %/built-in.a, $(obj-y)) obj-m := $(filter-out %/, $(obj-m)) # Subdirectories we need to descend into - subdir-ym := $(sort $(subdir-y) $(subdir-m)) # Expand $(foo-objs) $(foo-y) etc. by replacing their individuals @@ -54,9 +48,9 @@ multi-search = $(sort $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), # List primitive targets that are compiled from source files real-search = $(foreach m, $1, $(if $(call suffix-search, $m, $2, $3 -), $(call suffix-search, $m, $2, $3), $m)) -# if $(foo-objs) exists, foo.o is a composite object +# if $(foo-objs), $(foo-y), or $(foo-m) exists, foo.o is a composite object multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) -multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m)))) +multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))), $(m)))) multi-used := $(multi-used-y) $(multi-used-m) single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m))) @@ -74,11 +68,22 @@ base-dtb-y := $(foreach m, $(multi-dtb-y), $(firstword $(call suffix-search, $m, # $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to # tell kbuild to descend -subdir-obj-y := $(filter %/built-in.o, $(obj-y)) +subdir-obj-y := $(filter %/built-in.a, $(obj-y)) -# Replace multi-part objects by their individual parts, look at local dir only -real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y) -real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) +# Replace multi-part objects by their individual parts, +# including built-in.a from subdirectories +real-obj-y := $(foreach m, $(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) +real-obj-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m)),$(m))) + +# DTB +# If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built +extra-y += $(dtb-y) +extra-$(CONFIG_OF_ALL_DTBS) += $(dtb-) + +ifneq ($(CHECK_DTBS),) +extra-y += $(patsubst %.dtb,%.dt.yaml, $(dtb-y)) +extra-$(CONFIG_OF_ALL_DTBS) += $(patsubst %.dtb,%.dt.yaml, $(dtb-)) +endif # Add subdir path @@ -91,8 +96,8 @@ obj-y := $(addprefix $(obj)/,$(obj-y)) obj-m := $(addprefix $(obj)/,$(obj-m)) lib-y := $(addprefix $(obj)/,$(lib-y)) subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y)) -real-objs-y := $(addprefix $(obj)/,$(real-objs-y)) -real-objs-m := $(addprefix $(obj)/,$(real-objs-m)) +real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) +real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) single-used-m := $(addprefix $(obj)/,$(single-used-m)) multi-used-y := $(addprefix $(obj)/,$(multi-used-y)) multi-used-m := $(addprefix $(obj)/,$(multi-used-m)) @@ -102,22 +107,25 @@ multi-dtb-y := $(addprefix $(obj)/,$(multi-dtb-y)) real-dtb-y := $(addprefix $(obj)/,$(real-dtb-y)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) +# Finds the multi-part object the current object will be linked into. +# If the object belongs to two or more multi-part objects, all of them are +# concatenated with a colon separator. +modname-multi = $(subst $(space),:,$(sort $(foreach m,$(multi-used),\ + $(if $(filter $*.o, $($(m:.o=-objs)) $($(m:.o=-y)) $($(m:.o=-m))),$(m:.o=))))) + +modname = $(if $(modname-multi),$(modname-multi),$(basetarget)) + # These flags are needed for modversions and compiling, so we define them here -# already -# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will +# $(modname_flags) defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) -# Note: Files that end up in two or more modules are compiled without the -# KBUILD_MODNAME definition. The reason is that any made-up name would -# differ in different configs. name-fix = $(squote)$(quote)$(subst $(comma),_,$(subst -,_,$1))$(quote)$(squote) basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) -modname_flags = $(if $(filter 1,$(words $(modname))),\ - -DKBUILD_MODNAME=$(call name-fix,$(modname))) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) -orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ +orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) \ $(ccflags-y) $(CFLAGS_$(basetarget).o) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) -orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ +orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) \ $(asflags-y) $(AFLAGS_$(basetarget).o) _a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags)) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) @@ -140,7 +148,19 @@ endif ifeq ($(CONFIG_KASAN),y) _c_flags += $(if $(patsubst n%,, \ $(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \ - $(CFLAGS_KASAN)) + $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) +endif + +ifeq ($(CONFIG_UBSAN),y) +_c_flags += $(if $(patsubst n%,, \ + $(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)$(CONFIG_UBSAN_SANITIZE_ALL)), \ + $(CFLAGS_UBSAN)) +endif + +ifeq ($(CONFIG_KCOV),y) +_c_flags += $(if $(patsubst n%,, \ + $(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \ + $(CFLAGS_KCOV)) endif __c_flags = $(_c_flags) @@ -161,7 +181,6 @@ __a_flags = $(call flags,_a_flags) __cpp_flags = $(call flags,_cpp_flags) endif endif - # Modified for U-Boot: LINUXINCLUDE -> UBOOTINCLUDE c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(UBOOTINCLUDE) \ $(__c_flags) $(modkern_cflags) \ @@ -222,7 +241,6 @@ dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ # Finds the multi-part object the current object will be linked into modname-multi = $(sort $(foreach m,$(multi-used),\ $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=)))) - # Useful for describing the dependency of composite objects # Usage: # $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) @@ -278,12 +296,13 @@ $(obj)/%: $(src)/%_shipped # --------------------------------------------------------------------------- quiet_cmd_ld = LD $@ -cmd_ld = $(LD) $(ld_flags) $(filter-out FORCE,$^) -o $@ + cmd_ld = $(LD) $(ld_flags) $(real-prereqs) -o $@ # Archive # --------------------------------------------------------------------------- + quiet_cmd_ar = AR $@ -cmd_ar = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(real-prereqs) + cmd_ar = rm -f $@; $(AR) rcsTP$(KBUILD_ARFLAGS) $@ $(real-prereqs) # Objcopy # --------------------------------------------------------------------------- @@ -295,10 +314,11 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@ # --------------------------------------------------------------------------- quiet_cmd_gzip = GZIP $@ -cmd_gzip = cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@ + cmd_gzip = cat $(real-prereqs) | gzip -n -f -9 > $@ # DTC # --------------------------------------------------------------------------- +DTC ?= $(objtree)/scripts/dtc/dtc # Disable noisy checks by default ifeq ($(findstring 1,$(KBUILD_ENABLE_EXTRA_GCC_CHECKS)),) @@ -309,7 +329,6 @@ DTC_FLAGS += -Wno-unit_address_vs_reg \ -Wno-graph_child_address \ -Wno-simple_bus_reg \ -Wno-unique_unit_address \ - -Wno-simple_bus_reg \ -Wno-pci_device_reg # U-Boot specific disables @@ -567,20 +586,20 @@ printf "%08x\n" $$dec_size | \ ) quiet_cmd_bzip2 = BZIP2 $@ -cmd_bzip2 = { cat $(real-prereqs) | bzip2 -9 && $(size_append); } > $@ + cmd_bzip2 = { cat $(real-prereqs) | bzip2 -9 && $(size_append); } > $@ # Lzma # --------------------------------------------------------------------------- quiet_cmd_lzma = LZMA $@ -cmd_lzma = { cat $(real-prereqs) | lzma -9 && $(size_append); } > $@ + cmd_lzma = { cat $(real-prereqs) | lzma -9 && $(size_append); } > $@ quiet_cmd_lzo = LZO $@ -cmd_lzo = { cat $(real-prereqs) | lzop -9 && $(size_append); } > $@ + cmd_lzo = { cat $(real-prereqs) | lzop -9 && $(size_append); } > $@ quiet_cmd_lz4 = LZ4 $@ -cmd_lz4 = { cat $(real-prereqs) | lz4c -l -c1 stdin stdout && \ - $(size_append); } > $@ + cmd_lz4 = { cat $(real-prereqs) | lz4c -l -c1 stdin stdout && \ + $(size_append); } > $@ # U-Boot mkimage # --------------------------------------------------------------------------- @@ -702,12 +721,15 @@ quiet_cmd_fdt_rm_props = FDTGREP $@ # --------------------------------------------------------------------------- # Default sed regexp - multiline due to syntax constraints +# +# Use [:space:] because LLVM's integrated assembler inserts <tab> around +# the .ascii directive whereas GCC keeps the <space> as-is. define sed-offsets - "s:[[:space:]]*\.ascii[[:space:]]*\"\(.*\)\":\1:; \ + 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \ /^->/{s:->#\(.*\):/* \1 */:; \ s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ - s:->::; p;}" + s:->::; p;}' endef # Use filechk to avoid rebuilds when a header changes, but the resulting file diff --git a/scripts/Makefile.xpl b/scripts/Makefile.xpl index 43f27874f9f..03a2f151d91 100644 --- a/scripts/Makefile.xpl +++ b/scripts/Makefile.xpl @@ -135,7 +135,7 @@ head-y := $(addprefix $(obj)/,$(head-y)) libs-y := $(addprefix $(obj)/,$(libs-y)) u-boot-spl-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) -libs-y := $(patsubst %/, %/built-in.o, $(libs-y)) +libs-y := $(patsubst %/, %/built-in.a, $(libs-y)) # Add GCC lib ifeq ($(CONFIG_USE_PRIVATE_LIBGCC),y) diff --git a/scripts/dtc/pylibfdt/setup.py b/scripts/dtc/pylibfdt/setup.py index 487e669f524..0f7485de9b5 100755 --- a/scripts/dtc/pylibfdt/setup.py +++ b/scripts/dtc/pylibfdt/setup.py @@ -157,7 +157,7 @@ setup( long_description=long_description, long_description_content_type="text/plain", url="https://git.kernel.org/pub/scm/utils/dtc/dtc.git", - license="BSD", + license="GPL-2.0-or-later OR BSD-2-Clause", license_files=["Licenses/gpl-2.0.txt", "Licenses/bsd-2-clause.txt"], classifiers=[ diff --git a/test/cmd/wget.c b/test/cmd/wget.c index 445750660c2..1005392b952 100644 --- a/test/cmd/wget.c +++ b/test/cmd/wget.c @@ -241,3 +241,23 @@ static int net_test_wget(struct unit_test_state *uts) return 0; } CMD_TEST(net_test_wget, UTF_CONSOLE); + +static int net_test_wget_uri_validate(struct unit_test_state *uts) +{ + ut_asserteq(true, wget_validate_uri("http://foo.com/bar.html")); + ut_asserteq(true, wget_validate_uri("http://1.1.2.3/bar.html")); + ut_asserteq(false, wget_validate_uri("http://foo/ba r.html")); + ut_asserteq(false, wget_validate_uri("http://")); + + if (CONFIG_IS_ENABLED(WGET_HTTPS)) { + ut_asserteq(true, + wget_validate_uri("https://foo.com/bar.html")); + ut_asserteq(true, + wget_validate_uri("https://1.1.2.3/bar.html")); + ut_asserteq(false, wget_validate_uri("https://foo/ba r.html")); + ut_asserteq(false, wget_validate_uri("https://")); + } + + return 0; +} +CMD_TEST(net_test_wget_uri_validate, UTF_CONSOLE); diff --git a/test/common/print.c b/test/common/print.c index c48efc2783f..76ee851fe6a 100644 --- a/test/common/print.c +++ b/test/common/print.c @@ -45,8 +45,7 @@ static int print_guid(struct unit_test_state *uts) sprintf(str, "%pUL", guid); ut_asserteq_str("04030201-0605-0807-090A-0B0C0D0E0F10", str); sprintf(str, "%pUs", guid_esp); - if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) || - IS_ENABLED(CONFIG_CMD_EFIDEBUG) || IS_ENABLED(CONFIG_EFI)) + if (IS_ENABLED(CONFIG_EFI_PARTITION)) ut_asserteq_str("EFI System Partition", str); else ut_asserteq_str("c12a7328-f81f-11d2-ba4b-00a0c93ec93b", str); diff --git a/test/lib/Makefile b/test/lib/Makefile index ff4ff63270d..35b40b584c4 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -8,7 +8,7 @@ obj-$(CONFIG_$(PHASE_)UT_COMPRESSION) += compression.o ifeq ($(CONFIG_XPL_BUILD),) obj-y += abuf.o obj-y += alist.o -obj-$(CONFIG_EFI_LOADER) += efi_device_path.o +obj-$(CONFIG_EFI_LOADER) += efi_device_path.o efi_memory.o obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o obj-y += hexdump.o obj-$(CONFIG_SANDBOX) += kconfig.o diff --git a/test/lib/efi_memory.c b/test/lib/efi_memory.c new file mode 100644 index 00000000000..d2e1ab6b4a3 --- /dev/null +++ b/test/lib/efi_memory.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Test memory functions + * + * Copyright (c) 2025 Heinrich Schuchardt <xypron.glpk@gmx.de> + */ + +#include <efi_loader.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> + +static int lib_test_efi_alloc_aligned_pages(struct unit_test_state *uts) +{ + efi_status_t ret; + + void *addr; + unsigned long align = 0x400000; + + addr = efi_alloc_aligned_pages(4096, EFI_PERSISTENT_MEMORY_TYPE, + EFI_PAGE_SIZE); + ut_asserteq_ptr(NULL, addr); + + addr = efi_alloc_aligned_pages(4096, 0x6FFFFFFF, EFI_PAGE_SIZE); + ut_asserteq_ptr(NULL, addr); + + align = 0x200; + addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align); + ut_assertnonnull(addr); + ut_asserteq_64(0, (uintptr_t)addr & (align - 1)); + + ret = efi_free_pages((uintptr_t) addr, 1); + ut_asserteq_64(ret, EFI_SUCCESS); + + align = 0x400000; + addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align); + ut_assertnonnull(addr); + ut_asserteq_64(0, (uintptr_t)addr & (align - 1)); + + ret = efi_free_pages((uintptr_t) addr, 1); + ut_asserteq_64(ret, EFI_SUCCESS); + + return 0; +} +LIB_TEST(lib_test_efi_alloc_aligned_pages, 0); + +static int lib_test_efi_allocate_pages(struct unit_test_state *uts) +{ + efi_status_t ret; + u64 memory; + + ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, + EFI_ACPI_RECLAIM_MEMORY, + 1, &memory); + ut_asserteq_64(ret, EFI_SUCCESS); + ut_asserteq_64(0, memory & EFI_PAGE_MASK); + + ret = efi_free_pages(memory, 1); + ut_asserteq_64(ret, EFI_SUCCESS); + + return 0; +} +LIB_TEST(lib_test_efi_allocate_pages, 0); diff --git a/test/lib/lmb.c b/test/lib/lmb.c index 3bf558f7f4f..b6259bef442 100644 --- a/test/lib/lmb.c +++ b/test/lib/lmb.c @@ -71,6 +71,45 @@ static int setup_lmb_test(struct unit_test_state *uts, struct lmb *store, return 0; } +static int lmb_reserve(phys_addr_t addr, phys_size_t size, u32 flags) +{ + int err; + + err = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, size, flags); + if (err) + return err; + + return 0; +} + +static phys_addr_t lmb_alloc(phys_size_t size, ulong align) +{ + int err; + phys_addr_t addr; + + err = lmb_alloc_mem(LMB_MEM_ALLOC_ANY, align, &addr, size, LMB_NONE); + if (err) + return 0; + + return addr; +} + +static phys_addr_t lmb_alloc_base(phys_size_t size, ulong align, + phys_addr_t max_addr, u32 flags) +{ + int err; + phys_addr_t addr; + + addr = max_addr; + err = lmb_alloc_mem(LMB_MEM_ALLOC_MAX, align, &addr, size, flags); + if (err) + return 0; + + return addr; +} + +#define lmb_alloc_addr(addr, size, flags) lmb_reserve(addr, size, flags) + static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, const phys_size_t ram_size, const phys_addr_t ram0, const phys_size_t ram0_size, @@ -143,7 +182,7 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); - ret = lmb_free(a, 4); + ret = lmb_free(a, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); @@ -152,12 +191,12 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ut_asserteq(a, a2); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0); - ret = lmb_free(a2, 4); + ret = lmb_free(a2, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); - ret = lmb_free(b, 4); + ret = lmb_free(b, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, 0, 0, 3, alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, @@ -167,17 +206,17 @@ static int test_multi_alloc(struct unit_test_state *uts, const phys_addr_t ram, ut_asserteq(b, b2); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0); - ret = lmb_free(b2, 4); + ret = lmb_free(b2, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, 0, 0, 3, alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, ram_end - 8, 4); - ret = lmb_free(c, 4); + ret = lmb_free(c, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, 0, 0, 2, alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0); - ret = lmb_free(d, 4); + ret = lmb_free(d, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, 0, 0, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); @@ -281,7 +320,7 @@ static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram) ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, big_block_size + 0x10000, 0, 0, 0, 0); - ret = lmb_free(a, big_block_size); + ret = lmb_free(a, big_block_size, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_64k_addr, 0x10000, 0, 0, 0, 0); @@ -353,12 +392,12 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, - alloc_size_aligned, alloc_size, 0, 0); } /* and free them */ - ret = lmb_free(b, alloc_size); + ret = lmb_free(b, alloc_size, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + ram_size - alloc_size_aligned, alloc_size, 0, 0, 0, 0); - ret = lmb_free(a, alloc_size); + ret = lmb_free(a, alloc_size, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); @@ -369,7 +408,7 @@ static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram, ram + ram_size - alloc_size_aligned, alloc_size, 0, 0, 0, 0); /* and free it */ - ret = lmb_free(b, alloc_size); + ret = lmb_free(b, alloc_size, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); @@ -437,12 +476,12 @@ static int lib_test_lmb_at_0(struct unit_test_state *uts) ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, ram_size - 4, 0, 0, 0, 0); /* check that this was an error by freeing b */ - ret = lmb_free(b, 4); + ret = lmb_free(b, 4, LMB_NONE); ut_asserteq(ret, -1); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, a, ram_size - 4, 0, 0, 0, 0); - ret = lmb_free(a, ram_size - 4); + ret = lmb_free(a, ram_size - 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 0, 0, 0, 0, 0, 0, 0); @@ -568,20 +607,20 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); ut_asserteq(b, 0); b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); - ut_asserteq(b, -1); + ut_asserteq(b, -EEXIST); b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); ut_asserteq(b, 0); b = lmb_alloc_addr(alloc_addr_a, 0x2000, LMB_NONE); ut_asserteq(b, 0); - ret = lmb_free(alloc_addr_a, 0x2000); + ret = lmb_free(alloc_addr_a, 0x2000, LMB_NONE); ut_asserteq(ret, 0); b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); ut_asserteq(b, 0); b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NONE); - ut_asserteq(b, -1); + ut_asserteq(b, -EEXIST); b = lmb_alloc_addr(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); - ut_asserteq(b, -1); - ret = lmb_free(alloc_addr_a, 0x1000); + ut_asserteq(b, -EEXIST); + ret = lmb_free(alloc_addr_a, 0x1000, LMB_NONE); ut_asserteq(ret, 0); /* @@ -599,13 +638,13 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) alloc_addr_a + 0x4000, 0x1000, 0, 0); c = lmb_alloc_addr(alloc_addr_a + 0x1000, 0x5000, LMB_NONE); - ut_asserteq(c, -1); + ut_asserteq(c, -EEXIST); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, alloc_addr_a, 0x1000, alloc_addr_a + 0x4000, 0x1000, 0, 0); - ret = lmb_free(alloc_addr_a, 0x1000); + ret = lmb_free(alloc_addr_a, 0x1000, LMB_NONE); ut_asserteq(ret, 0); - ret = lmb_free(alloc_addr_a + 0x4000, 0x1000); + ret = lmb_free(alloc_addr_a + 0x4000, 0x1000, LMB_NOOVERWRITE); ut_asserteq(ret, 0); /* @@ -628,7 +667,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, alloc_addr_a, 0x6000, 0, 0, 0, 0); - ret = lmb_free(alloc_addr_a, 0x6000); + ret = lmb_free(alloc_addr_a, 0x6000, LMB_NONE); ut_asserteq(ret, 0); /* @@ -646,13 +685,13 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) alloc_addr_a + 0x4000, 0x1000, 0, 0); c = lmb_alloc_addr(alloc_addr_a + 0x1000, 0x5000, LMB_NOOVERWRITE); - ut_asserteq(c, -1); + ut_asserteq(c, -EEXIST); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, alloc_addr_a, 0x1000, alloc_addr_a + 0x4000, 0x1000, 0, 0); - ret = lmb_free(alloc_addr_a, 0x1000); + ret = lmb_free(alloc_addr_a, 0x1000, LMB_NOOVERWRITE); ut_asserteq(ret, 0); - ret = lmb_free(alloc_addr_a + 0x4000, 0x1000); + ret = lmb_free(alloc_addr_a + 0x4000, 0x1000, LMB_NOOVERWRITE); ut_asserteq(ret, 0); /* reserve 3 blocks */ @@ -693,7 +732,8 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) 0, 0, 0, 0); /* free thge allocation from d */ - ret = lmb_free(alloc_addr_c + 0x10000, ram_end - alloc_addr_c - 0x10000); + ret = lmb_free(alloc_addr_c + 0x10000, ram_end - alloc_addr_c - 0x10000, + LMB_NONE); ut_asserteq(ret, 0); /* allocate at 3 points in free range */ @@ -702,7 +742,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ut_asserteq(d, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000, ram_end - 4, 4, 0, 0); - ret = lmb_free(ram_end - 4, 4); + ret = lmb_free(ram_end - 4, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); @@ -711,7 +751,7 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ut_asserteq(d, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 2, ram, 0x18010000, ram_end - 128, 4, 0, 0); - ret = lmb_free(ram_end - 128, 4); + ret = lmb_free(ram_end - 128, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); @@ -720,13 +760,13 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) ut_asserteq(d, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010004, 0, 0, 0, 0); - ret = lmb_free(alloc_addr_c + 0x10000, 4); + ret = lmb_free(alloc_addr_c + 0x10000, 4, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram, 0x18010000, 0, 0, 0, 0); /* allocate at the bottom a was assigned to ram at the top */ - ret = lmb_free(ram, alloc_addr_a - ram); + ret = lmb_free(ram, alloc_addr_a - ram, LMB_NONE); ut_asserteq(ret, 0); ASSERT_LMB(mem_lst, used_lst, ram, ram_size, 1, ram + 0x8000000, 0x10010000, 0, 0, 0, 0); @@ -739,11 +779,11 @@ static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram) /* check that allocating outside memory fails */ if (ram_end != 0) { ret = lmb_alloc_addr(ram_end, 1, LMB_NONE); - ut_asserteq(ret, -1); + ut_asserteq(ret, -EINVAL); } if (ram != 0) { ret = lmb_alloc_addr(ram - 1, 1, LMB_NONE); - ut_asserteq(ret, -1); + ut_asserteq(ret, -EINVAL); } lmb_pop(&store); diff --git a/test/py/tests/test_efi_selftest.py b/test/py/tests/test_efi_selftest.py index 12cbe5caa9b..58dac72fd40 100644 --- a/test/py/tests/test_efi_selftest.py +++ b/test/py/tests/test_efi_selftest.py @@ -179,6 +179,7 @@ def test_efi_selftest_text_input_ex(ubman): @pytest.mark.buildconfigspec('cmd_bootefi_selftest') @pytest.mark.buildconfigspec('efi_tcg2_protocol') +@pytest.mark.notbuildconfigspec('sandbox') def test_efi_selftest_tcg2(ubman): """Test the EFI_TCG2 PROTOCOL diff --git a/test/py/tests/test_fit_mkimage_validate.py b/test/py/tests/test_fit_mkimage_validate.py new file mode 100644 index 00000000000..af56f08ca10 --- /dev/null +++ b/test/py/tests/test_fit_mkimage_validate.py @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2025 +# +# Test that mkimage validates image references in configurations + +import os +import subprocess +import pytest +import fit_util + +@pytest.mark.boardspec('sandbox') +@pytest.mark.requiredtool('dtc') +def test_fit_invalid_image_reference(ubman): + """Test that mkimage fails when configuration references a missing image""" + + its_fname = fit_util.make_fname(ubman, "invalid.its") + itb_fname = fit_util.make_fname(ubman, "invalid.itb") + kernel = fit_util.make_kernel(ubman, 'kernel.bin', 'kernel') + + # Write ITS with an invalid reference to a nonexistent image + its_text = ''' +/dts-v1/; + +/ { + images { + kernel@1 { + description = "Test Kernel"; + data = /incbin/("kernel.bin"); + type = "kernel"; + arch = "sandbox"; + os = "linux"; + compression = "none"; + load = <0x40000>; + entry = <0x40000>; + }; + }; + + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "notexist"; + }; + }; +}; +''' + + with open(its_fname, 'w') as f: + f.write(its_text) + + mkimage = os.path.join(ubman.config.build_dir, 'tools/mkimage') + cmd = [mkimage, '-f', its_fname, itb_fname] + + result = subprocess.run(cmd, capture_output=True, text=True) + + assert result.returncode != 0, "mkimage should fail due to missing image reference" + assert "references undefined image 'notexist'" in result.stderr + diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index cfc8f1319a9..e6d8792ac1f 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -330,6 +330,33 @@ def test_gpt_write(state_disk_image, ubman): output = ubman.run_command('gpt guid host 0') assert '375a56f7-d6c9-4e81-b5f0-09d41ca89efe' in output +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_gpt') +@pytest.mark.buildconfigspec('cmd_part') +@pytest.mark.buildconfigspec('partition_type_guid') +@pytest.mark.requiredtool('sgdisk') +def test_gpt_write_part_type(state_disk_image, ubman): + """Test the gpt command with part type uuid.""" + + output = ubman.run_command('gpt write host 0 "name=part1,type=data,size=1M;name=part2,size=512K,type=system;name=part3,size=65536,type=u-boot-env;name=part4,size=65536,type=375a56f7-d6c9-4e81-b5f0-09d41ca89efe;name=part5,size=-,type=linux"') + assert 'Writing GPT: success!' in output + output = ubman.run_command('part list host 0') + assert '1\t0x00000022\t0x00000821\t"part1"' in output + assert 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7' in output + assert '(data)' in output + assert '2\t0x00000822\t0x00000c21\t"part2"' in output + assert 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b' in output + assert '(EFI System Partition)' in output + assert '3\t0x00000c22\t0x00000ca1\t"part3"' in output + assert '3de21764-95bd-54bd-a5c3-4abe786f38a8' in output + assert '(u-boot-env)' in output + assert '4\t0x00000ca2\t0x00000d21\t"part4"' in output + assert 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7' in output + assert '(375a56f7-d6c9-4e81-b5f0-09d41ca89efe)' in output + assert '5\t0x00000d22\t0x00001fde\t"part5"' in output + assert '0fc63daf-8483-4772-8e79-3d69d8477de4' in output + assert '(linux)' in output + @pytest.mark.buildconfigspec('cmd_gpt') @pytest.mark.buildconfigspec('cmd_gpt_rename') @pytest.mark.buildconfigspec('cmd_part') diff --git a/test/py/tests/test_help.py b/test/py/tests/test_help.py index 12cb36b7b98..afb57201ba3 100644 --- a/test/py/tests/test_help.py +++ b/test/py/tests/test_help.py @@ -4,6 +4,7 @@ import pytest +@pytest.mark.buildconfigspec('cmd_help') def test_help(ubman): """Test that the "help" command can be executed.""" diff --git a/test/py/tests/test_mmc.py b/test/py/tests/test_mmc.py index e751a3bd36a..1f738ef3dcb 100644 --- a/test/py/tests/test_mmc.py +++ b/test/py/tests/test_mmc.py @@ -99,7 +99,7 @@ def test_mmc_dev(ubman): devices[x]['detected'] = 'yes' for y in mmc_modes: - output = ubman.run_command('mmc dev %d 0 %d' % x, y) + output = ubman.run_command('mmc dev %d 0 %d' % (x, y)) if 'Card did not respond to voltage select' in output: fail = 1 @@ -122,7 +122,7 @@ def test_mmcinfo(ubman): for x in range(0, controllers): if devices[x]['detected'] == 'yes': for y in mmc_modes: - ubman.run_command('mmc dev %d 0 %d' % x, y) + ubman.run_command('mmc dev %d 0 %d' % (x, y)) output = ubman.run_command('mmcinfo') if 'busy timeout' in output: pytest.skip('No SD/MMC/eMMC device present') @@ -146,7 +146,7 @@ def test_mmc_info(ubman): for x in range(0, controllers): if devices[x]['detected'] == 'yes': for y in mmc_modes: - ubman.run_command('mmc dev %d 0 %d' % x, y) + ubman.run_command('mmc dev %d 0 %d' % (x, y)) output = ubman.run_command('mmc info') assert mmc_modes_name[mmc_modes.index(y)] in output @@ -172,7 +172,7 @@ def test_mmc_rescan(ubman): for x in range(0, controllers): if devices[x]['detected'] == 'yes': for y in mmc_modes: - ubman.run_command('mmc dev %d 0 %d' % x, y) + ubman.run_command('mmc dev %d 0 %d' % (x, y)) output = ubman.run_command('mmc rescan') if output: pytest.fail('mmc rescan has something to check') @@ -210,7 +210,7 @@ def test_mmc_part(ubman): elif part_type == '83': print('ext(2/4) detected') output = ubman.run_command( - 'fstype mmc %d:%d' % x, part_id + 'fstype mmc %d:%d' % (x, part_id) ) if 'ext2' in output: part_ext2.append(part_id) @@ -246,7 +246,7 @@ def test_mmc_fatls_fatinfo(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) output = ubman.run_command( 'fatls mmc %d:%s' % (x, part)) if 'Unrecognized filesystem type' in output: @@ -288,7 +288,7 @@ def test_mmc_fatload_fatwrite(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 addr = utils.find_ram_base(ubman) devices[x]['addr_%d' % part] = addr @@ -357,7 +357,7 @@ def test_mmc_ext4ls(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) output = ubman.run_command( '%sls mmc %d:%s' % (fs, x, part) ) @@ -392,7 +392,7 @@ def test_mmc_ext4load_ext4write(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 addr = utils.find_ram_base(ubman) devices[x]['addr_%d' % part] = addr @@ -454,7 +454,7 @@ def test_mmc_ext2ls(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 output = ubman.run_command( '%sls mmc %d:%s' % (fs, x, part) @@ -491,7 +491,7 @@ def test_mmc_ext2load(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 addr = devices[x]['addr_%d' % part] size = devices[x]['size_%d' % part] @@ -534,7 +534,7 @@ def test_mmc_ls(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 output = ubman.run_command('ls mmc %d:%s' % (x, part)) if re.search(r'No \w+ table on this device', output): @@ -566,7 +566,7 @@ def test_mmc_load(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 addr = devices[x]['addr_%d' % part] size = devices[x]['size_%d' % part] @@ -609,7 +609,7 @@ def test_mmc_save(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 addr = devices[x]['addr_%d' % part] size = 0 @@ -656,7 +656,7 @@ def test_mmc_fat_read_write_files(ubman): for part in partitions: for y in mmc_modes: - ubman.run_command('mmc dev %d %d %d' % x, part, y) + ubman.run_command('mmc dev %d %d %d' % (x, part, y)) part_detect = 1 addr = utils.find_ram_base(ubman) count_f = 0 diff --git a/tools/Makefile b/tools/Makefile index 97ce1dbb17e..02297e8c93a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -63,7 +63,8 @@ HOSTCFLAGS_img2srec.o := -pedantic hostprogs-y += mkenvimage mkenvimage-objs := mkenvimage.o os_support.o generated/lib/crc32.o -hostprogs-y += dumpimage mkimage fit_info fit_check_sign +hostprogs-y += dumpimage mkimage fit_info +hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_check_sign hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += fdt_add_pubkey hostprogs-$(CONFIG_TOOLS_LIBCRYPTO) += preload_check_sign diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 84b1331df5c..392e507d449 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -1143,6 +1143,13 @@ Optional entries Some entries need to exist only if certain conditions are met. For example, an entry may want to appear in the image only if a file has a particular format. +Also, the ``optional`` property may be used to mark entries as optional:: + + tee-os { + filename = "tee.bin"; + optional; + }; + Obviously the entry must exist in the image description for it to be processed at all, so a way needs to be found to have the entry remove itself. diff --git a/tools/binman/btool/openssl.py b/tools/binman/btool/openssl.py index c6df64c5316..b26f087c447 100644 --- a/tools/binman/btool/openssl.py +++ b/tools/binman/btool/openssl.py @@ -153,7 +153,7 @@ numFirewallRegions = INTEGER:{firewall_cert_data['num_firewalls']} def x509_cert_rom(self, cert_fname, input_fname, key_fname, sw_rev, config_fname, req_dist_name_dict, cert_type, bootcore, - bootcore_opts, load_addr, sha): + bootcore_opts, load_addr, sha, debug): """Create a certificate Args: @@ -221,9 +221,13 @@ emailAddress = {req_dist_name_dict['emailAddress']} # iterationCnt = INTEGER:TEST_IMAGE_KEY_DERIVE_INDEX # salt = FORMAT:HEX,OCT:TEST_IMAGE_KEY_DERIVE_SALT + # When debugging low level boot firmware it can be useful to have ROM or TIFS + # unlock JTAG access to the misbehaving CPUs. However in a production setting + # this can lead to code modification by outside parties after it's been + # authenticated. To gain JTAG access add the 'debug' flag to the binman config [ debug ] debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000 - debugType = INTEGER:4 + debugType = INTEGER:{ "4" if debug else "0" } coreDbgEn = INTEGER:0 coreDbgSecEn = INTEGER:0 ''', file=outf) @@ -238,7 +242,7 @@ emailAddress = {req_dist_name_dict['emailAddress']} imagesize_sbl, hashval_sbl, load_addr_sysfw, imagesize_sysfw, hashval_sysfw, load_addr_sysfw_data, imagesize_sysfw_data, hashval_sysfw_data, sysfw_inner_cert_ext_boot_block, - dm_data_ext_boot_block, bootcore_opts): + dm_data_ext_boot_block, bootcore_opts, debug): """Create a certificate Args: @@ -324,9 +328,13 @@ compSize = INTEGER:{imagesize_sysfw_data} shaType = OID:{sha_type} shaValue = FORMAT:HEX,OCT:{hashval_sysfw_data} +# When debugging low level boot firmware it can be useful to have ROM or TIFS +# unlock JTAG access to the misbehaving CPUs. However in a production setting +# this can lead to code modification by outside parties after it's been +# authenticated. To gain JTAG access add the 'debug' flag to the binman config [ debug ] debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000 -debugType = INTEGER:4 +debugType = INTEGER:{ "4" if debug else "0" } coreDbgEn = INTEGER:0 coreDbgSecEn = INTEGER:0 diff --git a/tools/binman/control.py b/tools/binman/control.py index 1946656f7d3..af447d792a7 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -97,7 +97,7 @@ def _ReadMissingBlobHelp(): return tag, msg my_data = pkg_resources.resource_string(__name__, 'missing-blob-help') - re_tag = re.compile('^([-a-z0-9]+):$') + re_tag = re.compile(r"^([-\.a-z0-9]+):$") result = {} tag = None msg = '' @@ -530,6 +530,57 @@ def _RemoveTemplates(parent): for node in del_nodes: node.Delete() +def propagate_prop(node, prop): + """Propagate the provided property to all the parent nodes up the hierarchy + + Args: + node (fdt.Node): Node and all its parent nodes up to the root to + propagate the property. + prop (str): Boolean property to propagate + + Return: + True if any change was made, else False + """ + changed = False + while node: + if prop not in node.props: + node.AddEmptyProp(prop, 0) + changed = True + node = node.parent + return changed + +def scan_and_prop_bootph(node): + """Propagate bootph properties from children to parents + + The bootph schema indicates that bootph properties in children should be + implied in their parents, all the way up the hierarchy. This is expensive + to implement in U-Boot before relocation at runtime, so this function + explicitly propagates these bootph properties upwards during build time. + + This is used to set the bootph-all, bootph-some-ram property in the parent + node if the respective property is found in any of the parent's subnodes. + The other bootph-* properties are associated with the SPL stage and hence + handled by fdtgrep.c. + + Args: + node (fdt.Node): Node to scan for bootph-all and bootph-some-ram + property + + Return: + True if any change was made, else False + + """ + bootph_prop = {'bootph-all', 'bootph-some-ram'} + + changed = False + for prop in bootph_prop: + if prop in node.props: + changed |= propagate_prop(node.parent, prop) + + for subnode in node.subnodes: + changed |= scan_and_prop_bootph(subnode) + return changed + def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, indir): """Prepare the images to be processed and select the device tree @@ -589,6 +640,9 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, ind fname = tools.get_output_filename('u-boot.dtb.tmpl2') tools.write_file(fname, dtb.GetContents()) + if scan_and_prop_bootph(dtb.GetRoot()): + dtb.Sync(True) + images = _ReadImageDesc(node, use_expanded) if select_images: @@ -645,14 +699,27 @@ def CheckForProblems(image): _ShowHelpForMissingBlobs(tout.ERROR, missing_list) faked_list = [] + faked_optional_list = [] + faked_required_list = [] image.CheckFakedBlobs(faked_list) - if faked_list: + for e in faked_list: + if e.optional: + faked_optional_list.append(e) + else: + faked_required_list.append(e) + if faked_required_list: tout.warning( "Image '%s' has faked external blobs and is non-functional: %s\n" % (image.name, ' '.join([os.path.basename(e.GetDefaultFilename()) - for e in faked_list]))) + for e in faked_required_list]))) optional_list = [] + # For optional blobs, we should inform the user when the blob is not present. This will come as + # a warning since it may not be immediately apparent that something is missing otherwise. + # E.g. user thinks they supplied a blob, but there is no info of the contrary if they made an + # error. + # Faked optional blobs are not relevant for final images (as they are dropped anyway) so we + # will omit the message with default verbosity. image.CheckOptional(optional_list) if optional_list: tout.warning( @@ -660,6 +727,12 @@ def CheckForProblems(image): (image.name, ' '.join([e.name for e in optional_list]))) _ShowHelpForMissingBlobs(tout.WARNING, optional_list) + if faked_optional_list: + tout.info( + "Image '%s' has faked optional external blobs but is still functional: %s\n" % + (image.name, ' '.join([os.path.basename(e.GetDefaultFilename()) + for e in faked_optional_list]))) + missing_bintool_list = [] image.check_missing_bintools(missing_bintool_list) if missing_bintool_list: @@ -667,7 +740,7 @@ def CheckForProblems(image): "Image '%s' has missing bintools and is non-functional: %s\n" % (image.name, ' '.join([os.path.basename(bintool.name) for bintool in missing_bintool_list]))) - return any([missing_list, faked_list, missing_bintool_list]) + return any([missing_list, faked_required_list, missing_bintool_list]) def ProcessImage(image, update_fdt, write_map, get_contents=True, allow_resize=True, allow_missing=False, @@ -697,7 +770,6 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True, image.SetAllowMissing(allow_missing) image.SetAllowFakeBlob(allow_fake_blobs) image.GetEntryContents() - image.drop_absent() image.GetEntryOffsets() # We need to pack the entries to figure out where everything @@ -736,12 +808,12 @@ def ProcessImage(image, update_fdt, write_map, get_contents=True, image.Raise('Entries changed size after packing (tried %s passes)' % passes) + has_problems = CheckForProblems(image) + image.BuildImage() if write_map: image.WriteMap() - has_problems = CheckForProblems(image) - image.WriteAlternates() return has_problems diff --git a/tools/binman/entry.py b/tools/binman/entry.py index bdc60e47fca..ce7ef28e94b 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -88,6 +88,7 @@ class Entry(object): updated with a hash of the entry contents comp_bintool: Bintools used for compress and decompress data fake_fname: Fake filename, if one was created, else None + faked (bool): True if the entry is absent and faked required_props (dict of str): Properties which must be present. This can be added to by subclasses elf_fname (str): Filename of the ELF file, if this entry holds an ELF @@ -759,7 +760,7 @@ class Entry(object): self.image_pos) # pylint: disable=assignment-from-none - def GetEntries(self): + def GetEntries(self) -> None: """Return a list of entries contained by this entry Returns: @@ -1120,7 +1121,7 @@ features to produce new behaviours. if self.missing and not self.optional: missing_list.append(self) - def check_fake_fname(self, fname, size=0): + def check_fake_fname(self, fname: str, size: int = 0) -> str: """If the file is missing and the entry allows fake blobs, fake it Sets self.faked to True if faked @@ -1130,9 +1131,7 @@ features to produce new behaviours. size (int): Size of fake file to create Returns: - tuple: - fname (str): Filename of faked file - bool: True if the blob was faked, False if not + fname (str): Filename of faked file """ if self.allow_fake and not pathlib.Path(fname).is_file(): if not self.fake_fname: @@ -1142,8 +1141,8 @@ features to produce new behaviours. tout.info(f"Entry '{self._node.path}': Faked blob '{outfname}'") self.fake_fname = outfname self.faked = True - return self.fake_fname, True - return fname, False + return self.fake_fname + return fname def CheckFakedBlobs(self, faked_blobs_list): """Check if any entries in this section have faked external blobs @@ -1352,6 +1351,10 @@ features to produce new behaviours. os.mkdir(cls.fake_dir) tout.notice(f"Fake-blob dir is '{cls.fake_dir}'") + def drop_absent_optional(self) -> None: + """Entries don't have any entries, do nothing""" + pass + def ensure_props(self): """Raise an exception if properties are missing diff --git a/tools/binman/etype/blob.py b/tools/binman/etype/blob.py index 041e1122953..acd9ae34074 100644 --- a/tools/binman/etype/blob.py +++ b/tools/binman/etype/blob.py @@ -42,7 +42,7 @@ class Entry_blob(Entry): if fdt_util.GetBool(self._node, 'write-symbols'): self.auto_write_symbols = True - def ObtainContents(self, fake_size=0): + def ObtainContents(self, fake_size: int = 0) -> bool: self._filename = self.GetDefaultFilename() self._pathname = tools.get_input_filename(self._filename, self.external and (self.optional or self.section.GetAllowMissing())) @@ -50,10 +50,11 @@ class Entry_blob(Entry): if not self._pathname: if not fake_size and self.assume_size: fake_size = self.assume_size - self._pathname, faked = self.check_fake_fname(self._filename, - fake_size) + self._pathname = self.check_fake_fname(self._filename, fake_size) self.missing = True - if not faked: + if self.optional: + self.mark_absent("missing but optional") + if not self.faked: content_size = 0 if self.assume_size: # Ensure we get test coverage on next line content_size = self.assume_size diff --git a/tools/binman/etype/blob_ext_list.py b/tools/binman/etype/blob_ext_list.py index 1bfcf6733a7..a8b5a24c3a1 100644 --- a/tools/binman/etype/blob_ext_list.py +++ b/tools/binman/etype/blob_ext_list.py @@ -33,11 +33,11 @@ class Entry_blob_ext_list(Entry_blob): self._filenames = fdt_util.GetStringList(self._node, 'filenames') self._pathnames = [] - def ObtainContents(self): + def ObtainContents(self) -> bool: missing = False pathnames = [] for fname in self._filenames: - fname, _ = self.check_fake_fname(fname) + fname = self.check_fake_fname(fname) pathname = tools.get_input_filename( fname, self.external and self.section.GetAllowMissing()) # Allow the file to be missing diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py index 124fa1e4ffc..5879f377231 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -276,7 +276,8 @@ class Entry_cbfs(Entry): for entry in self._entries.values(): entry.ListEntries(entries, indent + 1) - def GetEntries(self): + def GetEntries(self) -> dict[str, Entry]: + """Returns the entries (tree children) of this section""" return self._entries def ReadData(self, decomp=True, alt_format=None): diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py index ed3cac4ee7e..db40479d30e 100644 --- a/tools/binman/etype/fit.py +++ b/tools/binman/etype/fit.py @@ -557,12 +557,15 @@ class Entry_fit(Entry_section): Raises: ValueError: Filename 'rsa2048.key' not found in input path ValueError: Multiple key paths found + ValueError: 'dir/rsa2048' is a path not a filename """ def _find_keys_dir(node): for subnode in node.subnodes: if (subnode.name.startswith('signature') or subnode.name.startswith('cipher')): hint = subnode.props['key-name-hint'].value + if '/' in hint: + self.Raise(f"'{hint}' is a path not a filename") name = tools.get_input_filename( f"{hint}.key" if subnode.name.startswith('signature') else f"{hint}.bin") diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py index 6ae5d0c8a4f..75e59c3d3a3 100644 --- a/tools/binman/etype/mkimage.py +++ b/tools/binman/etype/mkimage.py @@ -205,7 +205,7 @@ class Entry_mkimage(Entry_section): self.record_missing_bintool(self.mkimage) return data - def GetEntries(self): + def GetEntries(self) -> dict[str, Entry]: # Make a copy so we don't change the original entries = OrderedDict(self._entries) if self._imagename: diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index 1d50bb47753..03c4f7c6ec7 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -537,7 +537,7 @@ class Entry_section(Entry): for entry in self._entries.values(): entry.WriteMap(fd, indent + 1) - def GetEntries(self): + def GetEntries(self) -> dict[str, Entry]: return self._entries def GetContentsByPhandle(self, phandle, source_entry, required): @@ -772,9 +772,17 @@ class Entry_section(Entry): todo) return True - def drop_absent(self): - """Drop entries which are absent""" - self._entries = {n: e for n, e in self._entries.items() if not e.absent} + def drop_absent_optional(self) -> None: + """Drop entries which are absent. + Call for all nodes in the tree. Leaf nodes will do nothing per + definition. Sections however have _entries and should drop all children + which are absent. + """ + self._entries = {n: e for n, e in self._entries.items() if not (e.absent and e.optional)} + # Drop nodes first before traversing children to avoid superfluous calls + # to children of absent nodes. + for e in self.GetEntries().values(): + e.drop_absent_optional() def _SetEntryOffsetSize(self, name, offset, size): """Set the offset and size of an entry diff --git a/tools/binman/etype/ti_secure.py b/tools/binman/etype/ti_secure.py index 420ee263e4f..f6caa0286d9 100644 --- a/tools/binman/etype/ti_secure.py +++ b/tools/binman/etype/ti_secure.py @@ -124,6 +124,7 @@ class Entry_ti_secure(Entry_x509_cert): 'OU': 'Processors', 'CN': 'TI Support', 'emailAddress': 'support@ti.com'} + self.debug = fdt_util.GetBool(self._node, 'debug', False) def ReadFirewallNode(self): self.firewall_cert_data['certificate'] = "" diff --git a/tools/binman/etype/ti_secure_rom.py b/tools/binman/etype/ti_secure_rom.py index f6fc3f90f84..7e90c655940 100644 --- a/tools/binman/etype/ti_secure_rom.py +++ b/tools/binman/etype/ti_secure_rom.py @@ -87,6 +87,7 @@ class Entry_ti_secure_rom(Entry_x509_cert): 'OU': 'Processors', 'CN': 'TI Support', 'emailAddress': 'support@ti.com'} + self.debug = fdt_util.GetBool(self._node, 'debug', False) def NonCombinedGetCertificate(self, required): """Generate certificate for legacy boot flow diff --git a/tools/binman/etype/u_boot_spl_pubkey_dtb.py b/tools/binman/etype/u_boot_spl_pubkey_dtb.py index cb196061de2..3061c4bcdc4 100644 --- a/tools/binman/etype/u_boot_spl_pubkey_dtb.py +++ b/tools/binman/etype/u_boot_spl_pubkey_dtb.py @@ -87,6 +87,8 @@ class Entry_u_boot_spl_pubkey_dtb(Entry_blob_dtb): dir=tools.get_output_dir())\ as pubkey_tdb: tools.write_file(pubkey_tdb.name, self.GetData()) + if '/' in self._key_name_hint: + self.Raise(f"'{self._key_name_hint}' is a path not a filename") keyname = tools.get_input_filename(self._key_name_hint + ".crt") self.fdt_add_pubkey.run(pubkey_tdb.name, os.path.dirname(keyname), diff --git a/tools/binman/etype/x509_cert.py b/tools/binman/etype/x509_cert.py index 25e6808b7f9..b6e8b0b4fb0 100644 --- a/tools/binman/etype/x509_cert.py +++ b/tools/binman/etype/x509_cert.py @@ -52,6 +52,7 @@ class Entry_x509_cert(Entry_collection): self.sysfw_inner_cert_ext_boot_block = None self.dm_data_ext_boot_block = None self.firewall_cert_data = None + self.debug = False def ReadNode(self): super().ReadNode() @@ -114,7 +115,8 @@ class Entry_x509_cert(Entry_collection): bootcore=self.bootcore, bootcore_opts=self.bootcore_opts, load_addr=self.load_addr, - sha=self.sha + sha=self.sha, + debug=self.debug ) elif type == 'rom-combined': stdout = self.openssl.x509_cert_rom_combined( @@ -140,7 +142,8 @@ class Entry_x509_cert(Entry_collection): hashval_sysfw_data=self.hashval_sysfw_data, sysfw_inner_cert_ext_boot_block=self.sysfw_inner_cert_ext_boot_block, dm_data_ext_boot_block=self.dm_data_ext_boot_block, - bootcore_opts=self.bootcore_opts + bootcore_opts=self.bootcore_opts, + debug=self.debug ) if stdout is not None: data = tools.read_file(output_fname) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 4cf7dfc8216..8225216fbec 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -84,6 +84,7 @@ FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " + b"sorry you're alive\n") COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data' COMPRESS_DATA_BIG = COMPRESS_DATA * 2 +MISSING_DATA = b'missing' REFCODE_DATA = b'refcode' FSP_M_DATA = b'fsp_m' FSP_S_DATA = b'fsp_s' @@ -250,7 +251,7 @@ class TestFunctional(unittest.TestCase): # ATF and OP_TEE TestFunctional._MakeInputFile('bl31.elf', tools.read_file(cls.ElfTestFile('elf_sections'))) - TestFunctional._MakeInputFile('tee.elf', + TestFunctional.tee_elf_path = TestFunctional._MakeInputFile('tee.elf', tools.read_file(cls.ElfTestFile('elf_sections'))) # Newer OP_TEE file in v1 binary format @@ -514,9 +515,9 @@ class TestFunctional(unittest.TestCase): return dtb.GetContents() def _DoReadFileDtb(self, fname, use_real_dtb=False, use_expanded=False, - verbosity=None, map=False, update_dtb=False, - entry_args=None, reset_dtbs=True, extra_indirs=None, - threads=None): + verbosity=None, allow_fake_blobs=True, map=False, + update_dtb=False, entry_args=None, reset_dtbs=True, + extra_indirs=None, threads=None): """Run binman and return the resulting image This runs binman with a given test file and then reads the resulting @@ -534,6 +535,7 @@ class TestFunctional(unittest.TestCase): use_expanded: True to use expanded entries where available, e.g. 'u-boot-expanded' instead of 'u-boot' verbosity: Verbosity level to use (0-3, None=don't set it) + allow_fake_blobs: whether binman should fake missing ext blobs map: True to output map files for the images update_dtb: Update the offset and size of each entry in the device tree before packing it into the image @@ -571,7 +573,7 @@ class TestFunctional(unittest.TestCase): retcode = self._DoTestFile(fname, map=map, update_dtb=update_dtb, entry_args=entry_args, use_real_dtb=use_real_dtb, use_expanded=use_expanded, verbosity=verbosity, - extra_indirs=extra_indirs, + allow_fake_blobs=allow_fake_blobs, extra_indirs=extra_indirs, threads=threads) self.assertEqual(0, retcode) out_dtb_fname = tools.get_output_filename('u-boot.dtb.out') @@ -4017,7 +4019,7 @@ class TestFunctional(unittest.TestCase): self.assertEqual({ 'image-pos': 0, 'offset': 0, - 'size': 1890, + 'size': 1378, 'u-boot:image-pos': 0, 'u-boot:offset': 0, @@ -4025,7 +4027,7 @@ class TestFunctional(unittest.TestCase): 'fit:image-pos': 4, 'fit:offset': 4, - 'fit:size': 1840, + 'fit:size': 1328, 'fit/images/kernel:image-pos': 304, 'fit/images/kernel:offset': 300, @@ -4043,8 +4045,8 @@ class TestFunctional(unittest.TestCase): 'fit/images/fdt-1/u-boot-spl-dtb:offset': 0, 'fit/images/fdt-1/u-boot-spl-dtb:size': 6, - 'u-boot-nodtb:image-pos': 1844, - 'u-boot-nodtb:offset': 1844, + 'u-boot-nodtb:image-pos': 1332, + 'u-boot-nodtb:offset': 1332, 'u-boot-nodtb:size': 46, }, props) @@ -5210,13 +5212,15 @@ fdt fdtmap Extract the devicetree blob from the fdtmap def testExtblobList(self): """Test an image with an external blob list""" - data = self._DoReadFile('215_blob_ext_list.dts') - self.assertEqual(REFCODE_DATA + FSP_M_DATA, data) + data = self._DoReadFileDtb('215_blob_ext_list.dts', + allow_fake_blobs=False) + self.assertEqual(REFCODE_DATA + FSP_M_DATA, data[0]) def testExtblobListMissing(self): """Test an image with a missing external blob""" with self.assertRaises(ValueError) as e: - self._DoReadFile('216_blob_ext_list_missing.dts') + self._DoReadFileDtb('216_blob_ext_list_missing.dts', + allow_fake_blobs=False) self.assertIn("Filename 'missing-file' not found in input path", str(e.exception)) @@ -5224,7 +5228,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap """Test an image with an missing external blob that is allowed""" with terminal.capture() as (stdout, stderr): self._DoTestFile('216_blob_ext_list_missing.dts', - allow_missing=True) + allow_missing=True, allow_fake_blobs=False) err = stderr.getvalue() self.assertRegex(err, "Image 'image'.*missing.*: blob-ext") @@ -5766,10 +5770,10 @@ fdt fdtmap Extract the devicetree blob from the fdtmap def testFitSplitElfMissing(self): - """Test an split-elf FIT with a missing ELF file""" + """Test an split-elf FIT with a missing ELF file. Don't fake the file.""" if not elf.ELF_TOOLS: self.skipTest('Python elftools not available') - out, err = self.checkFitSplitElf(allow_missing=True) + out, err = self.checkFitSplitElf(allow_missing=True, allow_fake_blobs=False) self.assertRegex( err, "Image '.*' is missing external blobs and is non-functional: .*") @@ -6458,16 +6462,18 @@ fdt fdtmap Extract the devicetree blob from the fdtmap def testAbsent(self): """Check handling of absent entries""" data = self._DoReadFile('262_absent.dts') - self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data) + self.assertEqual(U_BOOT_DATA + b'aa' + U_BOOT_IMG_DATA, data) - def testPackTeeOsOptional(self): - """Test that an image with an optional TEE binary can be created""" + def testPackTeeOsElf(self): + """Test that an image with a TEE elf binary can be created""" entry_args = { 'tee-os-path': 'tee.elf', } + tee_path = self.tee_elf_path data = self._DoReadFileDtb('263_tee_os_opt.dts', entry_args=entry_args)[0] - self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data) + self.assertEqual(U_BOOT_DATA + tools.read_file(tee_path) + + U_BOOT_IMG_DATA, data) def checkFitTee(self, dts, tee_fname): """Check that a tee-os entry works and returns data @@ -6512,6 +6518,9 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertRegex( err, "Image '.*' is missing optional external blobs but is still functional: tee-os") + self.assertNotRegex( + err, + "Image '.*' has faked external blobs and is non-functional: tee-os") def testFitTeeOsOptionalFitBad(self): """Test an image with a FIT with an optional OP-TEE binary""" @@ -6537,7 +6546,15 @@ fdt fdtmap Extract the devicetree blob from the fdtmap "Node '/binman/fit/images/@tee-SEQ/tee-os': Invalid OP-TEE file: size mismatch (expected 0x4, have 0xe)", str(exc.exception)) - def testExtblobOptional(self): + def testExtblobMissingOptional(self): + """Test an image with an external blob that is optional""" + with terminal.capture() as (stdout, stderr): + data = self._DoReadFileDtb('266_blob_ext_opt.dts', + allow_fake_blobs=False)[0] + self.assertEqual(REFCODE_DATA, data) + self.assertNotIn(MISSING_DATA, data) + + def testExtblobFakedOptional(self): """Test an image with an external blob that is optional""" with terminal.capture() as (stdout, stderr): data = self._DoReadFile('266_blob_ext_opt.dts') @@ -6546,6 +6563,9 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertRegex( err, "Image '.*' is missing optional external blobs but is still functional: missing") + self.assertNotRegex( + err, + "Image '.*' has faked external blobs and is non-functional: missing") def testSectionInner(self): """Test an inner section with a size""" @@ -6726,7 +6746,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap node = dtb.GetNode('/configurations/conf-missing-tee-1') self.assertEqual('atf-1', node.props['firmware'].value) - self.assertEqual(['u-boot', 'atf-2'], + self.assertEqual(['u-boot', 'tee', 'atf-2'], fdt_util.GetStringList(node, 'loadables')) def testTooldir(self): @@ -7290,6 +7310,13 @@ fdt fdtmap Extract the devicetree blob from the fdtmap tools.to_bytes(''.join(node.props['key'].value))) self.assertNotIn('key-source', node.props) + def testKeyNameHintIsPathSplPubkeyDtb(self): + """Test that binman errors out on key-name-hint being a path""" + with self.assertRaises(ValueError) as e: + self._DoReadFile('348_key_name_hint_dir_spl_pubkey_dtb.dts') + self.assertIn( + 'Node \'/binman/u-boot-spl-pubkey-dtb\': \'keys/key\' is a path not a filename', + str(e.exception)) def testSplPubkeyDtb(self): """Test u_boot_spl_pubkey_dtb etype""" @@ -7963,6 +7990,24 @@ fdt fdtmap Extract the devicetree blob from the fdtmap entry_args=entry_args, extra_indirs=[test_subdir])[0] + def testKeyNameHintIsPathSimpleFit(self): + """Test that binman errors out on key-name-hint being a path""" + if not elf.ELF_TOOLS: + self.skipTest('Python elftools not available') + entry_args = { + 'of-list': 'test-fdt1', + 'default-dt': 'test-fdt1', + 'atf-bl31-path': 'bl31.elf', + } + test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR) + with self.assertRaises(ValueError) as e: + self._DoReadFileDtb( + '347_key_name_hint_dir_fit_signature.dts', + entry_args=entry_args, + extra_indirs=[test_subdir]) + self.assertIn( + 'Node \'/binman/fit\': \'keys/rsa2048\' is a path not a filename', + str(e.exception)) def testSimpleFitEncryptedData(self): """Test an image with a FIT containing data to be encrypted""" @@ -8020,5 +8065,29 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self._DoTestFile('346_remove_template.dts', force_missing_bintools='openssl',) + def testBootphPropagation(self): + """Test that bootph-* properties are propagated correctly to supernodes""" + _, _, _, out_dtb_fname = self._DoReadFileDtb( + '347_bootph_prop.dts', use_real_dtb=True, update_dtb=True) + dtb = fdt.Fdt(out_dtb_fname) + dtb.Scan() + root = dtb.GetRoot() + parent_node = root.FindNode('dummy-parent') + subnode1 = parent_node.FindNode('subnode-1') + subnode2 = subnode1.FindNode('subnode-2') + subnode3 = subnode1.FindNode('subnode-3') + subnode4 = subnode3.FindNode('subnode-4') + + self.assertIn('bootph-some-ram', subnode1.props, + "Child node is missing 'bootph-some-ram' property") + self.assertIn('bootph-all', subnode1.props, + "Child node is missing 'bootph-all' property") + self.assertIn('bootph-some-ram', parent_node.props, + "Parent node is missing 'bootph-some-ram' property") + self.assertIn('bootph-all', parent_node.props, + "Parent node is missing 'bootph-all' property") + self.assertEqual(len(subnode4.props), 0, + "subnode shouldn't have any properties") + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/image.py b/tools/binman/image.py index 24ce0af7c72..698cfa4148e 100644 --- a/tools/binman/image.py +++ b/tools/binman/image.py @@ -183,6 +183,8 @@ class Image(section.Entry_section): fname = tools.get_output_filename(self._filename) tout.info("Writing image to '%s'" % fname) with open(fname, 'wb') as fd: + # For final image, don't write absent blobs to file + self.drop_absent_optional() data = self.GetPaddedData() fd.write(data) tout.info("Wrote %#x bytes" % len(data)) diff --git a/tools/binman/missing-blob-help b/tools/binman/missing-blob-help index ab0023eb9fb..d2ed35bef4d 100644 --- a/tools/binman/missing-blob-help +++ b/tools/binman/missing-blob-help @@ -14,15 +14,6 @@ atf-bl31-sunxi: Please read the section on ARM Trusted Firmware (ATF) in board/sunxi/README.sunxi64 -scp-sunxi: -SCP firmware is required for system suspend, but is otherwise optional. -Please read the section on SCP firmware in board/sunxi/README.sunxi64 - -iot2050-seboot: -See the documentation for IOT2050 board. Your image is missing SEBoot -which is mandatory for board startup. Prebuilt SEBoot located at -meta-iot2050/tree/master/recipes-bsp/u-boot/files/prebuild/seboot_pg*.bin. - iot2050-otpcmd: See the documentation for IOT2050 board. Your image is missing OTP command data block which is used for provisioning the customer keys to the board. @@ -31,22 +22,62 @@ meta-iot2050/tree/master/recipes-bsp/secure-boot-otp-provisioning/files/make-otp for how to generate this binary. If you are not using secure boot or do not intend to provision the keys, disable CONFIG_IOT2050_EMBED_OTPCMD. +iot2050-seboot: +See the documentation for IOT2050 board. Your image is missing SEBoot +which is mandatory for board startup. Prebuilt SEBoot located at +meta-iot2050/tree/master/recipes-bsp/u-boot/files/prebuild/seboot_pg*.bin. + k3-rti-wdt-firmware: If CONFIG_WDT_K3_RTI_LOAD_FW is enabled, a firmware image is needed for the R5F core(s) to trigger the system reset. One possible source is https://github.com/siemens/k3-rti-wdt. +opensbi: +See the documentation for your board. The OpenSBI git repo is at +https://github.com/riscv/opensbi.git +You may need to build fw_dynamic.bin first and re-build u-boot with +OPENSBI=/path/to/fw_dynamic.bin + rockchip-tpl: An external TPL is required to initialize DRAM. Get the external TPL binary and build with ROCKCHIP_TPL=/path/to/ddr.bin. One possible source for the external TPL binary is https://github.com/rockchip-linux/rkbin. +scp-sunxi: +SCP firmware is required for system suspend, but is otherwise optional. +Please read the section on SCP firmware in board/sunxi/README.sunxi64 + +sysfw-inner-cert: +You are missing the inner certificate for TI's Foundational Security (TIFS) +firmware which is critical to authenticating the TIFS firmware during boot. +HS-FS and HS-SE parts will not boot without this certificate. + +Have a look at your board's documentation to find and include the latest +TIFS certificate blobs and how to include them in the build. + + https://docs.u-boot.org/en/latest/board/ti/k3.html + tee-os: See the documentation for your board. You may need to build Open Portable Trusted Execution Environment (OP-TEE) and build with TEE=/path/to/tee.bin -opensbi: -See the documentation for your board. The OpenSBI git repo is at -https://github.com/riscv/opensbi.git -You may need to build fw_dynamic.bin first and re-build u-boot with -OPENSBI=/path/to/fw_dynamic.bin +ti-dm: +You are missing TI's Device Management (DM) firmware which is critical to +provide resource and power management services for your board. Your board +will not boot without this firmware. + +Have a look at your board's documentation to find the latest version of +the DM firmware binary and how to include it in the build. + + https://docs.u-boot.org/en/latest/board/ti/k3.html + +ti-fs-enc.bin: +You are missing TI's Foundational Security (TIFS) firmware which is +critical to provide foundational security services like authenticated boot, +and firewall management for the SoC. Your board will not boot without +this firmware. + +Have a look at your board's documentation to find the latest version of the +TIFS firmware binary and how to include them in the build. + + https://docs.u-boot.org/en/latest/board/ti/k3.html diff --git a/tools/binman/test/170_fit_fdt.dts b/tools/binman/test/170_fit_fdt.dts index 0197ffd1597..4b1e9b41ec0 100644 --- a/tools/binman/test/170_fit_fdt.dts +++ b/tools/binman/test/170_fit_fdt.dts @@ -15,6 +15,20 @@ fit,fdt-list = "of-list"; images { + atf { + description = "atf firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; + uboot { + description = "U-Boot firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; kernel { description = "Vanilla Linux kernel"; type = "kernel"; diff --git a/tools/binman/test/220_fit_subentry_bintool.dts b/tools/binman/test/220_fit_subentry_bintool.dts index 6e29d41eeb3..b1d8fb0feae 100644 --- a/tools/binman/test/220_fit_subentry_bintool.dts +++ b/tools/binman/test/220_fit_subentry_bintool.dts @@ -12,7 +12,7 @@ #address-cells = <1>; images { - test { + kernel { description = "Something using a bintool"; type = "kernel"; arch = "arm"; diff --git a/tools/binman/test/223_fit_fdt_oper.dts b/tools/binman/test/223_fit_fdt_oper.dts index e630165acf4..cb3b31e36f6 100644 --- a/tools/binman/test/223_fit_fdt_oper.dts +++ b/tools/binman/test/223_fit_fdt_oper.dts @@ -15,6 +15,20 @@ fit,fdt-list = "of-list"; images { + atf { + description = "atf firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; + uboot { + description = "U-Boot firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; kernel { description = "Vanilla Linux kernel"; type = "kernel"; diff --git a/tools/binman/test/284_fit_fdt_list.dts b/tools/binman/test/284_fit_fdt_list.dts index 8885313f5b8..70cdb326708 100644 --- a/tools/binman/test/284_fit_fdt_list.dts +++ b/tools/binman/test/284_fit_fdt_list.dts @@ -15,6 +15,20 @@ fit,fdt-list-val = "test-fdt1", "test-fdt2"; images { + atf { + description = "atf firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; + uboot { + description = "U-Boot firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; kernel { description = "Vanilla Linux kernel"; type = "kernel"; diff --git a/tools/binman/test/333_fit_fdt_dir.dts b/tools/binman/test/333_fit_fdt_dir.dts index aa778451a4b..71971de4232 100644 --- a/tools/binman/test/333_fit_fdt_dir.dts +++ b/tools/binman/test/333_fit_fdt_dir.dts @@ -15,6 +15,20 @@ fit,fdt-list-dir = "fdts"; images { + atf { + description = "atf firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; + uboot { + description = "U-Boot firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; kernel { description = "Vanilla Linux kernel"; type = "kernel"; diff --git a/tools/binman/test/334_fit_fdt_compat.dts b/tools/binman/test/334_fit_fdt_compat.dts index 3bf45c710db..bf1b5a4a94a 100644 --- a/tools/binman/test/334_fit_fdt_compat.dts +++ b/tools/binman/test/334_fit_fdt_compat.dts @@ -15,6 +15,20 @@ fit,fdt-list = "of-list"; images { + atf { + description = "atf firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; + uboot { + description = "U-Boot firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; kernel { description = "Vanilla Linux kernel"; type = "kernel"; diff --git a/tools/binman/test/335_fit_fdt_phase.dts b/tools/binman/test/335_fit_fdt_phase.dts index f8d0740a394..c20bcad651a 100644 --- a/tools/binman/test/335_fit_fdt_phase.dts +++ b/tools/binman/test/335_fit_fdt_phase.dts @@ -15,6 +15,20 @@ fit,fdt-list = "of-list"; images { + atf { + description = "atf firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; + uboot { + description = "U-Boot firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; kernel { description = "Vanilla Linux kernel"; type = "kernel"; diff --git a/tools/binman/test/345_fit_fdt_name.dts b/tools/binman/test/345_fit_fdt_name.dts index 631a8e5f59b..0ef2e1934a0 100644 --- a/tools/binman/test/345_fit_fdt_name.dts +++ b/tools/binman/test/345_fit_fdt_name.dts @@ -15,6 +15,20 @@ fit,fdt-list = "of-list"; images { + atf { + description = "atf firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; + uboot { + description = "U-Boot firmware"; + type = "firmware"; + compression = "none"; + load = <00000000>; + entry = <00000000>; + }; kernel { description = "Vanilla Linux kernel"; type = "kernel"; diff --git a/tools/binman/test/347_bootph_prop.dts b/tools/binman/test/347_bootph_prop.dts new file mode 100644 index 00000000000..91d4e4ad600 --- /dev/null +++ b/tools/binman/test/347_bootph_prop.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; +/ { + dummy-parent { + subnode-1 { + subnode-2 { + bootph-all; + }; + subnode-3 { + bootph-some-ram; + subnode-4 { + }; + }; + }; + }; + + binman: binman { + }; +}; + diff --git a/tools/binman/test/347_key_name_hint_dir_fit_signature.dts b/tools/binman/test/347_key_name_hint_dir_fit_signature.dts new file mode 100644 index 00000000000..96e2126dadb --- /dev/null +++ b/tools/binman/test/347_key_name_hint_dir_fit_signature.dts @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + fit { + description = "test desc"; + #address-cells = <1>; + fit,fdt-list = "of-list"; + fit,sign; + + images { + u-boot { + description = "test u-boot"; + type = "standalone"; + arch = "arm64"; + os = "u-boot"; + compression = "none"; + load = <0x00000000>; + entry = <0x00000000>; + + u-boot-nodtb { + }; + + hash { + algo = "sha256"; + }; + + signature { + algo = "sha256,rsa2048"; + key-name-hint = "keys/rsa2048"; + }; + }; + @atf-SEQ { + fit,operation = "split-elf"; + description = "test tf-a"; + type = "firmware"; + arch = "arm64"; + os = "arm-trusted-firmware"; + compression = "none"; + fit,load; + fit,entry; + fit,data; + + atf-bl31 { + }; + + hash { + algo = "sha256"; + }; + + signature { + algo = "sha256,rsa2048"; + key-name-hint = "keys/rsa2048"; + }; + }; + @fdt-SEQ { + description = "test fdt"; + type = "flat_dt"; + compression = "none"; + + hash { + algo = "sha256"; + }; + + signature { + algo = "sha256,rsa2048"; + key-name-hint = "keys/rsa2048"; + }; + }; + }; + + configurations { + default = "@conf-uboot-DEFAULT-SEQ"; + @conf-uboot-SEQ { + description = "uboot config"; + fdt = "fdt-SEQ"; + fit,firmware = "u-boot"; + fit,loadables; + + hash { + algo = "sha256"; + }; + + signature { + algo = "sha256,rsa2048"; + key-name-hint = "keys/rsa2048"; + sign-images = "firmware", "loadables", "fdt"; + }; + }; + }; + }; + }; +}; diff --git a/tools/binman/test/348_key_name_hint_dir_spl_pubkey_dtb.dts b/tools/binman/test/348_key_name_hint_dir_spl_pubkey_dtb.dts new file mode 100644 index 00000000000..85ebd58b6c0 --- /dev/null +++ b/tools/binman/test/348_key_name_hint_dir_spl_pubkey_dtb.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + u-boot-spl-pubkey-dtb { + algo = "sha384,rsa4096"; + required = "conf"; + key-name-hint = "keys/key"; + }; + }; +}; diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index 6538a3d296f..9516e25e215 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -631,10 +631,13 @@ class Builder: Args: commit_upto: Commit number to use (0..self.count-1) target: Target name + + Return: + str: Output directory to use, or '' if None """ output_dir = self.get_output_dir(commit_upto) if self.work_in_output: - return output_dir + return output_dir or '' return os.path.join(output_dir, target) def get_done_file(self, commit_upto, target): @@ -1683,7 +1686,7 @@ class Builder: """ thread_dir = self.get_thread_dir(thread_num) builderthread.mkdir(thread_dir) - git_dir = os.path.join(thread_dir, '.git') + git_dir = os.path.join(thread_dir, '.git') if thread_dir else None # Create a worktree or a git repo clone for this thread if it # doesn't already exist diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index b4cb66397bb..371708c8a98 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -31,12 +31,14 @@ def mkdir(dirname, parents=False): """Make a directory if it doesn't already exist. Args: - dirname (str): Directory to create + dirname (str): Directory to create, or None to do nothing parents (bool): True to also make parent directories Raises: OSError: File already exists """ + if not dirname or os.path.exists(dirname): + return try: if parents: os.makedirs(dirname) @@ -45,8 +47,8 @@ def mkdir(dirname, parents=False): except OSError as err: if err.errno == errno.EEXIST: if os.path.realpath('.') == os.path.realpath(dirname): - print(f"Cannot create the current working directory '{dirname}'!") - sys.exit(1) + raise ValueError( + f"Cannot create the current working directory '{dirname}'!") else: raise @@ -55,7 +57,7 @@ def _remove_old_outputs(out_dir): """Remove any old output-target files Args: - out_dir (str): Output directory for the build + out_dir (str): Output directory for the build, or None for current dir Since we use a build directory that was previously used by another board, it may have produced an SPL image. If we don't remove it (i.e. @@ -63,7 +65,7 @@ def _remove_old_outputs(out_dir): output of this build, even if it does not produce SPL images. """ for elf in BASE_ELF_FILENAMES: - fname = os.path.join(out_dir, elf) + fname = os.path.join(out_dir or '', elf) if os.path.exists(fname): os.remove(fname) @@ -191,9 +193,11 @@ class BuilderThread(threading.Thread): Args: brd (Board): Board to create arguments for - out_dir (str): Path to output directory containing the files + out_dir (str): Path to output directory containing the files, or + or None to not use a separate output directory out_rel_dir (str): Output directory relative to the current dir - work_dir (str): Directory to which the source will be checked out + work_dir (str): Directory to which the source will be checked out, + or None to use current directory commit_upto (int): Commit number to build (0...n-1) Returns: @@ -204,22 +208,22 @@ class BuilderThread(threading.Thread): """ args = [] cwd = work_dir - src_dir = os.path.realpath(work_dir) - if not self.builder.in_tree: - if commit_upto is None: - # In this case we are building in the original source directory - # (i.e. the current directory where buildman is invoked. The - # output directory is set to this thread's selected work - # directory. - # - # Symlinks can confuse U-Boot's Makefile since we may use '..' - # in our path, so remove them. + src_dir = os.path.realpath(work_dir) if work_dir else os.getcwd() + if commit_upto is None: + # In this case we are building in the original source directory + # (i.e. the current directory where buildman is invoked. The + # output directory is set to this thread's selected work + # directory. + # + # Symlinks can confuse U-Boot's Makefile since we may use '..' + # in our path, so remove them. + if out_dir: real_dir = os.path.realpath(out_dir) args.append(f'O={real_dir}') - cwd = None - src_dir = os.getcwd() - else: - args.append(f'O={out_rel_dir}') + cwd = None + src_dir = os.getcwd() + elif out_rel_dir: + args.append(f'O={out_rel_dir}') if self.builder.verbose_build: args.append('V=1') else: @@ -397,7 +401,8 @@ class BuilderThread(threading.Thread): config_only (bool): Only configure the source, do not build it adjust_cfg (list of str): See the cfgutil module and run_commit() commit (Commit): Commit only being built - out_dir (str): Output directory for the build + out_dir (str): Output directory for the build, or None to use + current out_rel_dir (str): Output directory relatie to the current dir result (CommandResult): Previous result @@ -409,7 +414,8 @@ class BuilderThread(threading.Thread): """ # Set up the environment and command line env = self.builder.make_environment(self.toolchain) - mkdir(out_dir) + if out_dir and not os.path.exists(out_dir): + mkdir(out_dir) args, cwd, src_dir = self._build_args(brd, out_dir, out_rel_dir, work_dir, commit_upto) @@ -419,7 +425,7 @@ class BuilderThread(threading.Thread): _remove_old_outputs(out_dir) # If we need to reconfigure, do that now - cfg_file = os.path.join(out_dir, '.config') + cfg_file = os.path.join(out_dir or '', '.config') cmd_list = [] if do_config or adjust_cfg: result = self._reconfigure( @@ -627,7 +633,7 @@ class BuilderThread(threading.Thread): # Extract the environment from U-Boot and dump it out cmd = [f'{self.toolchain.cross}objcopy', '-O', 'binary', '-j', '.rodata.default_environment', - 'env/built-in.o', 'uboot.env'] + 'env/built-in.a', 'uboot.env'] command.run_one(*cmd, capture=True, capture_stderr=True, cwd=result.out_dir, raise_on_error=False, env=env) if not work_in_output: diff --git a/tools/buildman/buildman.rst b/tools/buildman/buildman.rst index 5fa7b277cb8..8c45a841024 100644 --- a/tools/buildman/buildman.rst +++ b/tools/buildman/buildman.rst @@ -1333,6 +1333,14 @@ To build a particular target, rather than the default U-Boot target, use the `--target` option. This is unlikely to be useful unless you are building a single board. +Buildman normally builds out-of-tree, meaning that the source directory is not +disturbed by the build. Use `-i` to do an in-tree build instead. Note that this +does not affect the source directory, since buildman creates a separate git +'worktree' for each board. This means that it is possible to do an in-tree +build of an entire branch, or even a 'current source' build for multiple boards. +As a special case, you can use `-wi` to do an in-tree build in the current +directory. + Build summary ------------- diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 4c9489126c1..4dedd333551 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -390,7 +390,7 @@ def get_boards_obj(output_dir, regen_board_list, maintainer_check, full_check, read it in. Args: - output_dir (str): Output directory to use + output_dir (str): Output directory to use, or None to use current dir regen_board_list (bool): True to just regenerate the board list maintainer_check (bool): True to just run a maintainer check full_check (bool): True to just run a full check of Kconfig and @@ -414,9 +414,9 @@ def get_boards_obj(output_dir, regen_board_list, maintainer_check, full_check, return 2 return 0 - if not os.path.exists(output_dir): + if output_dir and not os.path.exists(output_dir): os.makedirs(output_dir) - board_file = os.path.join(output_dir, 'boards.cfg') + board_file = os.path.join(output_dir or '', 'boards.cfg') if regen_board_list and regen_board_list != '-': board_file = regen_board_list @@ -501,7 +501,7 @@ def adjust_args(args, series, selected): def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col, - clean_dir): + in_tree, clean_dir): """Set up the output directory Args: @@ -509,6 +509,7 @@ def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col, work_in_output (bool): True to work in the output directory branch (str): Name of branch to build, or None if none no_subdirs (bool): True to put the output in the top-level output dir + in_tree (bool): True if doing an in-tree build clean_dir: Used for tests only, indicates that the existing output_dir should be removed before starting the build @@ -516,9 +517,11 @@ def setup_output_dir(output_dir, work_in_output, branch, no_subdirs, col, str: Updated output directory pathname """ if not output_dir: - if work_in_output: - sys.exit(col.build(col.RED, '-w requires that you specify -o')) output_dir = '..' + if work_in_output: + if not in_tree: + sys.exit(col.build(col.RED, '-w requires that you specify -o')) + output_dir = None if branch and not no_subdirs: # As a special case allow the board directory to be placed in the # output directory itself rather than any subdirectory. @@ -751,7 +754,7 @@ def do_buildman(args, toolchains=None, make_func=None, brds=None, output_dir = setup_output_dir( args.output_dir, args.work_in_output, args.branch, - args.no_subdirs, col, clean_dir) + args.no_subdirs, col, args.in_tree, clean_dir) # Work out what subset of the boards we are building if not brds: diff --git a/tools/fit_image.c b/tools/fit_image.c index caed8d5f901..8717dc9a3b1 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -24,6 +24,65 @@ static struct legacy_img_hdr header; +static int fit_estimate_hash_sig_size(struct image_tool_params *params, const char *fname) +{ + bool signing = IMAGE_ENABLE_SIGN && (params->keydir || params->keyfile); + struct stat sbuf; + void *fdt; + int fd; + int estimate = 0; + int depth, noffset; + const char *name; + + fd = mmap_fdt(params->cmdname, fname, 0, &fdt, &sbuf, false, true); + if (fd < 0) + return -EIO; + + /* + * Walk the FIT image, looking for nodes named hash* and + * signature*. Since the interesting nodes are subnodes of an + * image or configuration node, we are only interested in + * those at depth exactly 3. + * + * The estimate for a hash node is based on a sha512 digest + * being 64 bytes, with another 64 bytes added to account for + * fdt structure overhead (the tags and the name of the + * "value" property). + * + * The estimate for a signature node is based on an rsa4096 + * signature being 512 bytes, with another 512 bytes to + * account for fdt overhead and the various other properties + * (hashed-nodes etc.) that will also be filled in. + * + * One could try to be more precise in the estimates by + * looking at the "algo" property and, in the case of + * configuration signatures, the sign-images property. Also, + * when signing an already created FIT image, the hash nodes + * already have properly sized value properties, so one could + * also take pre-existence of "value" properties in hash nodes + * into account. But this rather simple approach should work + * well enough in practice. + */ + for (depth = 0, noffset = fdt_next_node(fdt, 0, &depth); + noffset >= 0 && depth > 0; + noffset = fdt_next_node(fdt, noffset, &depth)) { + if (depth != 3) + continue; + + name = fdt_get_name(fdt, noffset, NULL); + if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) + estimate += 128; + + if (signing && !strncmp(name, FIT_SIG_NODENAME, strlen(FIT_SIG_NODENAME))) + estimate += 1024; + } + + munmap(fdt, sbuf.st_size); + close(fd); + + return estimate; +} + static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, const char *tmpfile) { @@ -627,6 +686,7 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) struct stat sbuf; int ret; int images; + int confs; int node; fd = mmap_fdt(params->cmdname, fname, 0, &old_fdt, &sbuf, false, false); @@ -695,6 +755,43 @@ static int fit_import_data(struct image_tool_params *params, const char *fname) } } + confs = fdt_path_offset(fdt, FIT_CONFS_PATH); + static const char * const props[] = { FIT_KERNEL_PROP, + FIT_RAMDISK_PROP, + FIT_FDT_PROP, + FIT_LOADABLE_PROP, + FIT_FPGA_PROP, + FIT_FIRMWARE_PROP, + FIT_SCRIPT_PROP}; + + fdt_for_each_subnode(node, fdt, confs) { + const char *conf_name = fdt_get_name(fdt, node, NULL); + + for (int i = 0; i < ARRAY_SIZE(props); i++) { + int count = fdt_stringlist_count(fdt, node, props[i]); + + if (count < 0) + continue; + + for (int j = 0; j < count; j++) { + const char *img_name = + fdt_stringlist_get(fdt, node, props[i], j, NULL); + if (!img_name || !*img_name) + continue; + + int img = fdt_subnode_offset(fdt, images, img_name); + + if (img < 0) { + fprintf(stderr, + "Error: configuration '%s' references undefined image '%s' in property '%s'\n", + conf_name, img_name, props[i]); + ret = FDT_ERR_NOTFOUND; + goto err_munmap; + } + } + } + } + munmap(old_fdt, sbuf.st_size); /* Close the old fd so we can re-use it. */ @@ -750,7 +847,7 @@ static int fit_handle_file(struct image_tool_params *params) char bakfile[MKIMAGE_MAX_TMPFILE_LEN + 4] = {0}; char cmd[MKIMAGE_MAX_DTC_CMDLINE_LEN]; size_t size_inc; - int ret; + int ret = EXIT_FAILURE; /* Flattened Image Tree (FIT) format handling */ debug ("FIT format handling\n"); @@ -806,16 +903,16 @@ static int fit_handle_file(struct image_tool_params *params) rename(tmpfile, bakfile); /* - * Set hashes for images in the blob. Unfortunately we may need more - * space in either FDT, so keep trying until we succeed. - * - * Note: this is pretty inefficient for signing, since we must - * calculate the signature every time. It would be better to calculate - * all the data and then store it in a separate step. However, this - * would be considerably more complex to implement. Generally a few - * steps of this loop is enough to sign with several keys. + * Set hashes for images in the blob and compute + * signatures. We do an attempt at estimating the expected + * extra size, but just in case that is not sufficient, keep + * trying adding 1K, with a reasonable upper bound of 64K + * total, until we succeed. */ - for (size_inc = 0; size_inc < 64 * 1024; size_inc += 1024) { + size_inc = fit_estimate_hash_sig_size(params, bakfile); + if (size_inc < 0) + goto err_system; + do { if (copyfile(bakfile, tmpfile) < 0) { printf("Can't copy %s to %s\n", bakfile, tmpfile); ret = -EIO; @@ -824,7 +921,8 @@ static int fit_handle_file(struct image_tool_params *params) ret = fit_add_file_data(params, size_inc, tmpfile); if (!ret || ret != -ENOSPC) break; - } + size_inc += 1024; + } while (size_inc < 64 * 1024); if (ret) { fprintf(stderr, "%s Can't add hashes to FIT blob: %d\n", @@ -854,7 +952,7 @@ static int fit_handle_file(struct image_tool_params *params) err_system: unlink(tmpfile); unlink(bakfile); - return -1; + return ret; } /** diff --git a/tools/image-host.c b/tools/image-host.c index a9b86902763..21dd7f2d922 100644 --- a/tools/image-host.c +++ b/tools/image-host.c @@ -19,7 +19,7 @@ #include <openssl/evp.h> #endif -#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD) +#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD) && CONFIG_IS_ENABLED(LIBCRYPTO) #include <openssl/rsa.h> #include <openssl/err.h> #endif @@ -1416,7 +1416,7 @@ int fit_check_sign(const void *fit, const void *key, } #endif -#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD) +#if CONFIG_IS_ENABLED(IMAGE_PRE_LOAD) && CONFIG_IS_ENABLED(LIBCRYPTO) /** * rsa_verify_openssl() - Verify a signature against some data with openssl API * diff --git a/tools/imx8image.c b/tools/imx8image.c index a333ded46e2..cad55fd3cf2 100644 --- a/tools/imx8image.c +++ b/tools/imx8image.c @@ -1146,7 +1146,7 @@ int imx8image_copy_image(int outfd, struct image_tool_params *mparams) fprintf(stdout, "CONTAINER SW VERSION:\t0x%04x\n", sw_version); build_container(soc, sector_size, emmc_fastboot, - img_sp, false, fuse_version, sw_version, outfd); + img_sp, dcd_skip, fuse_version, sw_version, outfd); return 0; } diff --git a/tools/mkimage.c b/tools/mkimage.c index 2954626a283..361711c53b2 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -519,8 +519,13 @@ int main(int argc, char **argv) */ retval = tparams->fflag_handle(¶ms); - if (retval != EXIT_SUCCESS) + if (retval != EXIT_SUCCESS) { + if (retval == FDT_ERR_NOTFOUND) { + // Already printed error, exit cleanly + exit(EXIT_FAILURE); + } usage("Bad parameters for FIT image type"); + } } if (params.lflag || params.fflag) { diff --git a/tools/rmboard.py b/tools/rmboard.py index 594fd89b8d7..21d68c57261 100755 --- a/tools/rmboard.py +++ b/tools/rmboard.py @@ -112,8 +112,7 @@ def rm_board(board): rm_kconfig_include(fname) # Remove unwanted files - cmd = ['git', 'rm', '-r'] + real - stdout = command.output(*cmd, capture=True) + stdout = command.output('git', 'rm', '-r', *real) ## Change the messages as needed msg = '''arm: Remove %s board @@ -130,7 +129,8 @@ Remove it. # Check if the board is mentioned anywhere else. The user will need to deal # with this - print(command.output('git', 'grep', '-il', board, raise_on_error=False)) + cmd = ['git', 'grep', '-il', board] + print(command.output(*cmd, raise_on_error=False)) print(' '.join(cmd)) for board in sys.argv[1:]: diff --git a/tools/termios_linux.h b/tools/termios_linux.h index 0806a91180a..0e5a5c475b5 100644 --- a/tools/termios_linux.h +++ b/tools/termios_linux.h @@ -32,13 +32,13 @@ #include <asm/ioctls.h> #include <asm/termbits.h> -#if defined(BOTHER) && defined(TCGETS2) +#if defined(BOTHER) && defined(TCGETS2) && !defined(__powerpc64__) #define termios termios2 #endif static inline int tcgetattr(int fd, struct termios *t) { -#if defined(BOTHER) && defined(TCGETS2) +#if defined(BOTHER) && defined(TCGETS2) && !defined(__powerpc64__) return ioctl(fd, TCGETS2, t); #else return ioctl(fd, TCGETS, t); @@ -50,7 +50,7 @@ static inline int tcsetattr(int fd, int a, const struct termios *t) int cmd; switch (a) { -#if defined(BOTHER) && defined(TCGETS2) +#if defined(BOTHER) && defined(TCGETS2) && !defined(__powerpc64__) case TCSANOW: cmd = TCSETS2; break; |