diff options
100 files changed, 1925 insertions, 344 deletions
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ae91252a00b..772810460c5 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,6 @@ Please do not submit a Pull Request via github. Our project makes use of mailing lists for patch submission and review. For more details please -see https://www.denx.de/wiki/U-Boot/Patches +see https://u-boot.readthedocs.io/en/latest/develop/sending_patches.html The only exception to this is in order to trigger a CI loop on Azure prior to posting of patches. @@ -3,7 +3,7 @@ VERSION = 2022 PATCHLEVEL = 10 SUBLEVEL = -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = # *DOCUMENTATION* @@ -1001,18 +1001,12 @@ ifeq ($(CONFIG_MPC85xx)$(CONFIG_OF_SEPARATE),yy) INPUTS-y += u-boot-with-dtb.bin endif -ifeq ($(CONFIG_ARCH_ROCKCHIP),y) -# On ARM64 this target is produced by binman so we don't need this dep +ifeq ($(CONFIG_ARCH_ROCKCHIP)$(CONFIG_SPL),yy) +# Binman image dependencies ifeq ($(CONFIG_ARM64),y) -ifeq ($(CONFIG_SPL),y) -# TODO: Get binman to generate this too -INPUTS-y += u-boot-rockchip.bin -endif +INPUTS-y += u-boot.itb else -ifeq ($(CONFIG_SPL),y) -# Generate these inputs for binman which will create the output files -INPUTS-y += idbloader.img u-boot.img -endif +INPUTS-y += u-boot.img endif endif @@ -1498,29 +1492,6 @@ OBJCOPYFLAGS_u-boot-with-spl.bin = -I binary -O binary \ u-boot-with-spl.bin: $(SPL_IMAGE) $(SPL_PAYLOAD) FORCE $(call if_changed,pad_cat) -ifeq ($(CONFIG_ARCH_ROCKCHIP),y) - -# TPL + SPL -ifeq ($(CONFIG_SPL)$(CONFIG_TPL),yy) -MKIMAGEFLAGS_u-boot-tpl-rockchip.bin = -n $(CONFIG_SYS_SOC) -T rksd -tpl/u-boot-tpl-rockchip.bin: tpl/u-boot-tpl.bin FORCE - $(call if_changed,mkimage) -idbloader.img: tpl/u-boot-tpl-rockchip.bin spl/u-boot-spl.bin FORCE - $(call if_changed,cat) -else -MKIMAGEFLAGS_idbloader.img = -n $(CONFIG_SYS_SOC) -T rksd -idbloader.img: spl/u-boot-spl.bin FORCE - $(call if_changed,mkimage) -endif - -ifeq ($(CONFIG_ARM64),y) -OBJCOPYFLAGS_u-boot-rockchip.bin = -I binary -O binary \ - --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff -u-boot-rockchip.bin: idbloader.img u-boot.itb FORCE - $(call if_changed,pad_cat) -endif # CONFIG_ARM64 - -endif # CONFIG_ARCH_ROCKCHIP ifeq ($(CONFIG_ARCH_LPC32XX)$(CONFIG_SPL),yy) MKIMAGEFLAGS_lpc32xx-spl.img = -T lpc32xximage -a $(CONFIG_SPL_TEXT_BASE) @@ -2225,7 +2196,9 @@ CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h \ lpc32xx-* bl31.c bl31.elf bl31_*.bin image.map tispl.bin* \ idbloader.img flash.bin flash.log defconfig keep-syms-lto.c \ mkimage-out.spl.mkimage mkimage.spl.mkimage imx-boot.map \ - itb.fit.fit itb.fit.itb itb.map spl.map + itb.fit.fit itb.fit.itb itb.map spl.map mkimage-out.rom.mkimage \ + mkimage.rom.mkimage rom.map simple-bin.map simple-bin-spi.map \ + idbloader-spi.img # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config include/generated spl tpl \ diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0b72e4f6503..82cd456f51f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1974,7 +1974,7 @@ config ARCH_STM32MP config ARCH_ROCKCHIP bool "Support Rockchip SoCs" select BLK - select BINMAN if SPL_OPTEE || (SPL && !ARM64) + select BINMAN if SPL_OPTEE || SPL select DM select DM_GPIO select DM_I2C diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index 5f09ef0a4af..3a4b665f244 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -67,11 +67,24 @@ void spl_board_init(void) #endif } +void tzpc_init(void) +{ + /* + * Mark the whole OCRAM as non-secure, otherwise DMA devices cannot + * access it. This is for example necessary for MMC boot. + */ +#ifdef TZPCR0SIZE_BASE + out_le32(TZPCR0SIZE_BASE, 0); +#endif +} + void board_init_f(ulong dummy) { int ret; icache_enable(); + tzpc_init(); + /* Clear global data */ memset((void *)gd, 0, sizeof(gd_t)); if (IS_ENABLED(CONFIG_DEBUG_UART)) diff --git a/arch/arm/dts/px30-u-boot.dtsi b/arch/arm/dts/px30-u-boot.dtsi index f102b2aef42..462eaf68f82 100644 --- a/arch/arm/dts/px30-u-boot.dtsi +++ b/arch/arm/dts/px30-u-boot.dtsi @@ -3,6 +3,8 @@ * (C) Copyright 2019 Rockchip Electronics Co., Ltd */ +#include "rockchip-u-boot.dtsi" + / { aliases { mmc0 = &emmc; diff --git a/arch/arm/dts/r7s72100-gr-peach-u-boot.dts b/arch/arm/dts/r7s72100-gr-peach-u-boot.dts index f48121a9a81..5b176a9acd7 100644 --- a/arch/arm/dts/r7s72100-gr-peach-u-boot.dts +++ b/arch/arm/dts/r7s72100-gr-peach-u-boot.dts @@ -46,8 +46,8 @@ }; - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r7s72100", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r7s72100-rpc-if"; reg = <0x3fefa000 0x100>, <0x18000000 0x08000000>; bank-width = <2>; num-cs = <1>; diff --git a/arch/arm/dts/r8a774c0-u-boot.dtsi b/arch/arm/dts/r8a774c0-u-boot.dtsi index af1c86171b6..d29610676ca 100644 --- a/arch/arm/dts/r8a774c0-u-boot.dtsi +++ b/arch/arm/dts/r8a774c0-u-boot.dtsi @@ -10,8 +10,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rcar-gen3-rpc", "renesas,rpc-r8a774c0"; + rpc: spi@ee200000 { + compatible = "renesas,r8a774c0-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0x04000000>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77950-u-boot.dtsi b/arch/arm/dts/r8a77950-u-boot.dtsi index 5a116514646..2306c7bab84 100644 --- a/arch/arm/dts/r8a77950-u-boot.dtsi +++ b/arch/arm/dts/r8a77950-u-boot.dtsi @@ -13,8 +13,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r8a7795", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r8a7795-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77960-u-boot.dtsi b/arch/arm/dts/r8a77960-u-boot.dtsi index f1cae1c3593..f64e5a416b0 100644 --- a/arch/arm/dts/r8a77960-u-boot.dtsi +++ b/arch/arm/dts/r8a77960-u-boot.dtsi @@ -13,8 +13,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r8a7796", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r8a7796-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77965-u-boot.dtsi b/arch/arm/dts/r8a77965-u-boot.dtsi index 9cc6f205375..c4abcc5a9b7 100644 --- a/arch/arm/dts/r8a77965-u-boot.dtsi +++ b/arch/arm/dts/r8a77965-u-boot.dtsi @@ -13,8 +13,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r8a77965", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r8a77965-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77970-u-boot.dtsi b/arch/arm/dts/r8a77970-u-boot.dtsi index ac3c6be4adb..614caa9e9c2 100644 --- a/arch/arm/dts/r8a77970-u-boot.dtsi +++ b/arch/arm/dts/r8a77970-u-boot.dtsi @@ -13,8 +13,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r8a77970", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r8a77970-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77980-u-boot.dtsi b/arch/arm/dts/r8a77980-u-boot.dtsi index 365d40ac49b..54f01c926dc 100644 --- a/arch/arm/dts/r8a77980-u-boot.dtsi +++ b/arch/arm/dts/r8a77980-u-boot.dtsi @@ -13,8 +13,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r8a77980", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r8a77980-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77990-u-boot.dtsi b/arch/arm/dts/r8a77990-u-boot.dtsi index 6655abe8752..50bbbe18647 100644 --- a/arch/arm/dts/r8a77990-u-boot.dtsi +++ b/arch/arm/dts/r8a77990-u-boot.dtsi @@ -9,8 +9,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r8a77990", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r8a77990-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a77995-u-boot.dtsi b/arch/arm/dts/r8a77995-u-boot.dtsi index 0917a80f096..347b59ac42c 100644 --- a/arch/arm/dts/r8a77995-u-boot.dtsi +++ b/arch/arm/dts/r8a77995-u-boot.dtsi @@ -9,8 +9,8 @@ / { soc { - rpc: rpc@ee200000 { - compatible = "renesas,rpc-r8a77995", "renesas,rpc"; + rpc: spi@ee200000 { + compatible = "renesas,r8a77995-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x100>, <0 0x08000000 0 0>; clocks = <&cpg CPG_MOD 917>; bank-width = <2>; diff --git a/arch/arm/dts/r8a779a0-u-boot.dtsi b/arch/arm/dts/r8a779a0-u-boot.dtsi index 83dbe3f20ef..9f2772a9485 100644 --- a/arch/arm/dts/r8a779a0-u-boot.dtsi +++ b/arch/arm/dts/r8a779a0-u-boot.dtsi @@ -10,7 +10,7 @@ / { soc { rpc: spi@ee200000 { - compatible = "renesas,rpc-r8a779a0", "renesas,rcar-gen3-rpc"; + compatible = "renesas,r8a779a0-rpc-if", "renesas,rcar-gen3-rpc-if"; reg = <0 0xee200000 0 0x200>, <0 0x08000000 0 0x04000000>; clocks = <&cpg CPG_MOD 629>; bank-width = <2>; diff --git a/arch/arm/dts/rk3288-u-boot.dtsi b/arch/arm/dts/rk3288-u-boot.dtsi index 9eb696b1411..e411445ed69 100644 --- a/arch/arm/dts/rk3288-u-boot.dtsi +++ b/arch/arm/dts/rk3288-u-boot.dtsi @@ -56,7 +56,7 @@ }; }; -#ifdef CONFIG_ROCKCHIP_SPI_IMAGE +#if defined(CONFIG_ROCKCHIP_SPI_IMAGE) && defined(CONFIG_HAS_ROM) &binman { rom { filename = "u-boot.rom"; diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi index 9fb6d86bc1d..53ee760b989 100644 --- a/arch/arm/dts/rk3288.dtsi +++ b/arch/arm/dts/rk3288.dtsi @@ -109,48 +109,48 @@ ports = <&vopl_out>, <&vopb_out>; }; - sdmmc: dwmmc@ff0c0000 { + sdmmc: mmc@ff0c0000 { compatible = "rockchip,rk3288-dw-mshc"; max-frequency = <150000000>; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; - clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; reg = <0xff0c0000 0x4000>; status = "disabled"; }; - sdio0: dwmmc@ff0d0000 { + sdio0: mmc@ff0d0000 { compatible = "rockchip,rk3288-dw-mshc"; max-frequency = <150000000>; clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>, <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>; - clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; reg = <0xff0d0000 0x4000>; status = "disabled"; }; - sdio1: dwmmc@ff0e0000 { + sdio1: mmc@ff0e0000 { compatible = "rockchip,rk3288-dw-mshc"; max-frequency = <150000000>; clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>, <&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>; - clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; reg = <0xff0e0000 0x4000>; status = "disabled"; }; - emmc: dwmmc@ff0f0000 { + emmc: mmc@ff0f0000 { compatible = "rockchip,rk3288-dw-mshc"; max-frequency = <150000000>; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; - clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; reg = <0xff0f0000 0x4000>; diff --git a/arch/arm/dts/rk3308-u-boot.dtsi b/arch/arm/dts/rk3308-u-boot.dtsi index 4bfad31fbab..ab5bfc2ce93 100644 --- a/arch/arm/dts/rk3308-u-boot.dtsi +++ b/arch/arm/dts/rk3308-u-boot.dtsi @@ -3,6 +3,8 @@ *(C) Copyright 2019 Rockchip Electronics Co., Ltd */ +#include "rockchip-u-boot.dtsi" + / { aliases { mmc0 = &emmc; diff --git a/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi b/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi index 95f26524948..16c33735eb2 100644 --- a/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi +++ b/arch/arm/dts/rk3326-odroid-go2-u-boot.dtsi @@ -3,6 +3,8 @@ * Copyright (c) 2020 Theobroma Systems Design und Consulting GmbH */ +#include "rockchip-u-boot.dtsi" + / { chosen { u-boot,spl-boot-order = &sdmmc; diff --git a/arch/arm/dts/rk3328-u-boot.dtsi b/arch/arm/dts/rk3328-u-boot.dtsi index 16335582642..d4a7540a92c 100644 --- a/arch/arm/dts/rk3328-u-boot.dtsi +++ b/arch/arm/dts/rk3328-u-boot.dtsi @@ -3,6 +3,8 @@ * (C) Copyright 2019 Rockchip Electronics Co., Ltd */ +#include "rockchip-u-boot.dtsi" + / { aliases { mmc0 = &emmc; diff --git a/arch/arm/dts/rk3368-u-boot.dtsi b/arch/arm/dts/rk3368-u-boot.dtsi index 2767c2678db..811d59ac346 100644 --- a/arch/arm/dts/rk3368-u-boot.dtsi +++ b/arch/arm/dts/rk3368-u-boot.dtsi @@ -4,6 +4,7 @@ */ #include <dt-bindings/memory/rk3368-dmc.h> +#include "rockchip-u-boot.dtsi" / { dmc: dmc@ff610000 { diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi index 716b9a433a1..3c1a15fe51b 100644 --- a/arch/arm/dts/rk3399-u-boot.dtsi +++ b/arch/arm/dts/rk3399-u-boot.dtsi @@ -60,7 +60,7 @@ }; -#ifdef CONFIG_ROCKCHIP_SPI_IMAGE +#if defined(CONFIG_ROCKCHIP_SPI_IMAGE) && defined(CONFIG_HAS_ROM) &binman { rom { filename = "u-boot.rom"; diff --git a/arch/arm/dts/rk3568-u-boot.dtsi b/arch/arm/dts/rk3568-u-boot.dtsi index 5a80dda275b..fa9b6ae23b9 100644 --- a/arch/arm/dts/rk3568-u-boot.dtsi +++ b/arch/arm/dts/rk3568-u-boot.dtsi @@ -3,6 +3,8 @@ * (C) Copyright 2021 Rockchip Electronics Co., Ltd */ +#include "rockchip-u-boot.dtsi" + / { aliases { mmc0 = &sdhci; diff --git a/arch/arm/dts/rockchip-u-boot.dtsi b/arch/arm/dts/rockchip-u-boot.dtsi index eae3ee715da..584f21eb5bf 100644 --- a/arch/arm/dts/rockchip-u-boot.dtsi +++ b/arch/arm/dts/rockchip-u-boot.dtsi @@ -17,13 +17,57 @@ filename = "u-boot-rockchip.bin"; pad-byte = <0xff>; - blob { + mkimage { filename = "idbloader.img"; + args = "-n", CONFIG_SYS_SOC, "-T", "rksd"; +#ifdef CONFIG_TPL + multiple-data-files; + + u-boot-tpl { + }; +#endif + u-boot-spl { + }; }; +#ifdef CONFIG_ARM64 + blob { + filename = "u-boot.itb"; +#else u-boot-img { +#endif offset = <CONFIG_SPL_PAD_TO>; }; }; + +#ifdef CONFIG_ROCKCHIP_SPI_IMAGE + simple-bin-spi { + filename = "u-boot-rockchip-spi.bin"; + pad-byte = <0xff>; + + mkimage { + filename = "idbloader-spi.img"; + args = "-n", CONFIG_SYS_SOC, "-T", "rkspi"; +#ifdef CONFIG_TPL + multiple-data-files; + + u-boot-tpl { + }; +#endif + u-boot-spl { + }; + }; + +#ifdef CONFIG_ARM64 + blob { + filename = "u-boot.itb"; +#else + u-boot-img { +#endif + /* Sync with u-boot,spl-payload-offset if present */ + offset = <CONFIG_SYS_SPI_U_BOOT_OFFS>; + }; + }; +#endif }; #endif diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index c561a77e6a1..b46cea2f91c 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -425,12 +425,10 @@ config SPL_MMC config ROCKCHIP_SPI_IMAGE bool "Build a SPI image for rockchip" - depends on HAS_ROM help Some Rockchip SoCs support booting from SPI flash. Enable this - option to produce a 4MB SPI-flash image (called u-boot.rom) - containing U-Boot. The image is built by binman. U-Boot sits near - the start of the image. + option to produce a SPI-flash image containing U-Boot. The image + is built by binman. U-Boot sits near the start of the image. config LNX_KRNL_IMG_TEXT_OFFSET_BASE default SYS_TEXT_BASE diff --git a/arch/arm/mach-rockchip/rk3308/rk3308.c b/arch/arm/mach-rockchip/rk3308/rk3308.c index 70fe0d0ac35..dd9109b7c3d 100644 --- a/arch/arm/mach-rockchip/rk3308/rk3308.c +++ b/arch/arm/mach-rockchip/rk3308/rk3308.c @@ -8,6 +8,7 @@ #include <asm/global_data.h> #include <asm/io.h> #include <asm/arch/grf_rk3308.h> +#include <asm/arch-rockchip/bootrom.h> #include <asm/arch-rockchip/hardware.h> #include <asm/gpio.h> #include <debug_uart.h> @@ -142,6 +143,11 @@ enum { #define GPIO0_A4 4 +const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { + [BROM_BOOTSOURCE_EMMC] = "/mmc@ff490000", + [BROM_BOOTSOURCE_SD] = "/mmc@ff480000", +}; + int rk_board_init(void) { static struct rk3308_grf * const grf = (void *)GRF_BASE; diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c index 01a05599cd0..21db03b961c 100644 --- a/arch/arm/mach-rockchip/rk3399/rk3399.c +++ b/arch/arm/mach-rockchip/rk3399/rk3399.c @@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR; #define GRF_BASE 0xff770000 const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { - [BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000", + [BROM_BOOTSOURCE_EMMC] = "/mmc@fe330000", [BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000/flash@0", [BROM_BOOTSOURCE_SD] = "/mmc@fe320000", }; @@ -180,9 +180,9 @@ const char *spl_decode_boot_device(u32 boot_device) u32 boot_device; const char *ofpath; } spl_boot_devices_tbl[] = { - { BOOT_DEVICE_MMC1, "/mmc@fe320000" }, - { BOOT_DEVICE_MMC2, "/sdhci@fe330000" }, - { BOOT_DEVICE_SPI, "/spi@ff1d0000" }, + { BOOT_DEVICE_MMC2, "/mmc@fe320000" }, + { BOOT_DEVICE_MMC1, "/mmc@fe330000" }, + { BOOT_DEVICE_SPI, "/spi@ff1d0000/flash@0" }, }; for (i = 0; i < ARRAY_SIZE(spl_boot_devices_tbl); ++i) diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 1b6cdc4df02..14d5c560bf8 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -44,7 +44,9 @@ __board_reset(void) { /* Do nothing */ } +void board_reset_prepare(void) __attribute__((weak, alias("__board_reset"))); void board_reset(void) __attribute__((weak, alias("__board_reset"))); +void board_reset_last(void) __attribute__((weak, alias("__board_reset"))); int checkcpu (void) { @@ -319,12 +321,18 @@ int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) #else volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + /* Call board-specific preparation for reset */ + board_reset_prepare(); + /* Attempt board-specific reset */ board_reset(); /* Next try asserting HRESET_REQ */ out_be32(&gur->rstcr, 0x2); udelay(100); + + /* Attempt last-stage board-specific reset */ + board_reset_last(); #endif return 1; diff --git a/arch/riscv/dts/fu740-c000-u-boot.dtsi b/arch/riscv/dts/fu740-c000-u-boot.dtsi index a6f7a0873ee..917e9bf1634 100644 --- a/arch/riscv/dts/fu740-c000-u-boot.dtsi +++ b/arch/riscv/dts/fu740-c000-u-boot.dtsi @@ -7,11 +7,11 @@ / { cpus { - assigned-clocks = <&prci PRCI_CLK_COREPLL>; + assigned-clocks = <&prci FU740_PRCI_CLK_COREPLL>; assigned-clock-rates = <1200000000>; u-boot,dm-spl; cpu0: cpu@0 { - clocks = <&prci PRCI_CLK_COREPLL>; + clocks = <&prci FU740_PRCI_CLK_COREPLL>; u-boot,dm-spl; status = "okay"; cpu0_intc: interrupt-controller { @@ -19,28 +19,28 @@ }; }; cpu1: cpu@1 { - clocks = <&prci PRCI_CLK_COREPLL>; + clocks = <&prci FU740_PRCI_CLK_COREPLL>; u-boot,dm-spl; cpu1_intc: interrupt-controller { u-boot,dm-spl; }; }; cpu2: cpu@2 { - clocks = <&prci PRCI_CLK_COREPLL>; + clocks = <&prci FU740_PRCI_CLK_COREPLL>; u-boot,dm-spl; cpu2_intc: interrupt-controller { u-boot,dm-spl; }; }; cpu3: cpu@3 { - clocks = <&prci PRCI_CLK_COREPLL>; + clocks = <&prci FU740_PRCI_CLK_COREPLL>; u-boot,dm-spl; cpu3_intc: interrupt-controller { u-boot,dm-spl; }; }; cpu4: cpu@4 { - clocks = <&prci PRCI_CLK_COREPLL>; + clocks = <&prci FU740_PRCI_CLK_COREPLL>; u-boot,dm-spl; cpu4_intc: interrupt-controller { u-boot,dm-spl; @@ -76,7 +76,7 @@ reg = <0x0 0x100b0000 0x0 0x0800 0x0 0x100b2000 0x0 0x2000 0x0 0x100b8000 0x0 0x1000>; - clocks = <&prci PRCI_CLK_DDRPLL>; + clocks = <&prci FU740_PRCI_CLK_DDRPLL>; clock-frequency = <933333324>; u-boot,dm-spl; }; @@ -100,7 +100,7 @@ }; ð0 { - assigned-clocks = <&prci PRCI_CLK_GEMGXLPLL>; + assigned-clocks = <&prci FU740_PRCI_CLK_GEMGXLPLL>; assigned-clock-rates = <125125000>; }; diff --git a/arch/riscv/dts/fu740-c000.dtsi b/arch/riscv/dts/fu740-c000.dtsi index 649efe400ac..7b77c13496d 100644 --- a/arch/riscv/dts/fu740-c000.dtsi +++ b/arch/riscv/dts/fu740-c000.dtsi @@ -1,10 +1,9 @@ // SPDX-License-Identifier: (GPL-2.0 OR MIT) -/* Copyright (c) 2020-2021 SiFive, Inc */ +/* Copyright (c) 2020 SiFive, Inc */ /dts-v1/; #include <dt-bindings/clock/sifive-fu740-prci.h> -#include <dt-bindings/reset/sifive-fu740-prci.h> / { #address-cells = <2>; @@ -139,20 +138,21 @@ soc { #address-cells = <2>; #size-cells = <2>; - compatible = "sifive,fu740-c000", "sifive,fu740", "simple-bus"; + compatible = "simple-bus"; ranges; plic0: interrupt-controller@c000000 { #interrupt-cells = <1>; - compatible = "sifive,plic-1.0.0"; + #address-cells = <0>; + compatible = "sifive,fu540-c000-plic", "sifive,plic-1.0.0"; reg = <0x0 0xc000000 0x0 0x4000000>; riscv,ndev = <69>; interrupt-controller; - interrupts-extended = < - &cpu0_intc 0xffffffff - &cpu1_intc 0xffffffff &cpu1_intc 9 - &cpu2_intc 0xffffffff &cpu2_intc 9 - &cpu3_intc 0xffffffff &cpu3_intc 9 - &cpu4_intc 0xffffffff &cpu4_intc 9>; + interrupts-extended = + <&cpu0_intc 0xffffffff>, + <&cpu1_intc 0xffffffff>, <&cpu1_intc 9>, + <&cpu2_intc 0xffffffff>, <&cpu2_intc 9>, + <&cpu3_intc 0xffffffff>, <&cpu3_intc 9>, + <&cpu4_intc 0xffffffff>, <&cpu4_intc 9>; }; prci: clock-controller@10000000 { compatible = "sifive,fu740-c000-prci"; @@ -166,7 +166,7 @@ reg = <0x0 0x10010000 0x0 0x1000>; interrupt-parent = <&plic0>; interrupts = <39>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; status = "disabled"; }; uart1: serial@10011000 { @@ -174,7 +174,7 @@ reg = <0x0 0x10011000 0x0 0x1000>; interrupt-parent = <&plic0>; interrupts = <40>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; status = "disabled"; }; i2c0: i2c@10030000 { @@ -182,7 +182,7 @@ reg = <0x0 0x10030000 0x0 0x1000>; interrupt-parent = <&plic0>; interrupts = <52>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; reg-shift = <2>; reg-io-width = <1>; #address-cells = <1>; @@ -194,7 +194,7 @@ reg = <0x0 0x10031000 0x0 0x1000>; interrupt-parent = <&plic0>; interrupts = <53>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; reg-shift = <2>; reg-io-width = <1>; #address-cells = <1>; @@ -203,22 +203,22 @@ }; qspi0: spi@10040000 { compatible = "sifive,fu740-c000-spi", "sifive,spi0"; - reg = <0x0 0x10040000 0x0 0x1000 - 0x0 0x20000000 0x0 0x10000000>; + reg = <0x0 0x10040000 0x0 0x1000>, + <0x0 0x20000000 0x0 0x10000000>; interrupt-parent = <&plic0>; interrupts = <41>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; }; qspi1: spi@10041000 { compatible = "sifive,fu740-c000-spi", "sifive,spi0"; - reg = <0x0 0x10041000 0x0 0x1000 - 0x0 0x30000000 0x0 0x10000000>; + reg = <0x0 0x10041000 0x0 0x1000>, + <0x0 0x30000000 0x0 0x10000000>; interrupt-parent = <&plic0>; interrupts = <42>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -228,7 +228,7 @@ reg = <0x0 0x10050000 0x0 0x1000>; interrupt-parent = <&plic0>; interrupts = <43>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -237,12 +237,12 @@ compatible = "sifive,fu540-c000-gem"; interrupt-parent = <&plic0>; interrupts = <55>; - reg = <0x0 0x10090000 0x0 0x2000 - 0x0 0x100a0000 0x0 0x1000>; + reg = <0x0 0x10090000 0x0 0x2000>, + <0x0 0x100a0000 0x0 0x1000>; local-mac-address = [00 00 00 00 00 00]; clock-names = "pclk", "hclk"; - clocks = <&prci PRCI_CLK_GEMGXLPLL>, - <&prci PRCI_CLK_GEMGXLPLL>; + clocks = <&prci FU740_PRCI_CLK_GEMGXLPLL>, + <&prci FU740_PRCI_CLK_GEMGXLPLL>; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -251,8 +251,8 @@ compatible = "sifive,fu740-c000-pwm", "sifive,pwm0"; reg = <0x0 0x10020000 0x0 0x1000>; interrupt-parent = <&plic0>; - interrupts = <44 45 46 47>; - clocks = <&prci PRCI_CLK_PCLK>; + interrupts = <44>, <45>, <46>, <47>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; #pwm-cells = <3>; status = "disabled"; }; @@ -260,8 +260,8 @@ compatible = "sifive,fu740-c000-pwm", "sifive,pwm0"; reg = <0x0 0x10021000 0x0 0x1000>; interrupt-parent = <&plic0>; - interrupts = <48 49 50 51>; - clocks = <&prci PRCI_CLK_PCLK>; + interrupts = <48>, <49>, <50>, <51>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; #pwm-cells = <3>; status = "disabled"; }; @@ -273,7 +273,7 @@ cache-size = <2097152>; cache-unified; interrupt-parent = <&plic0>; - interrupts = <19 21 22 20>; + interrupts = <19>, <21>, <22>, <20>; reg = <0x0 0x2010000 0x0 0x1000>; }; gpio: gpio@10060000 { @@ -287,28 +287,27 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; - clocks = <&prci PRCI_CLK_PCLK>; + clocks = <&prci FU740_PRCI_CLK_PCLK>; status = "disabled"; }; pcie@e00000000 { + compatible = "sifive,fu740-pcie"; #address-cells = <3>; - #interrupt-cells = <1>; - #num-lanes = <8>; #size-cells = <2>; - compatible = "sifive,fu740-pcie"; - reg = <0xe 0x00000000 0x1 0x0 - 0xd 0xf0000000 0x0 0x10000000 - 0x0 0x100d0000 0x0 0x1000>; + #interrupt-cells = <1>; + reg = <0xe 0x00000000 0x0 0x80000000>, + <0xd 0xf0000000 0x0 0x10000000>, + <0x0 0x100d0000 0x0 0x1000>; reg-names = "dbi", "config", "mgmt"; device_type = "pci"; dma-coherent; bus-range = <0x0 0xff>; - ranges = <0x81000000 0x0 0x60080000 0x0 0x60080000 0x0 0x10000 - 0x82000000 0x0 0x60090000 0x0 0x60090000 0x0 0xff70000 - 0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x1000000 - 0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>; + ranges = <0x81000000 0x0 0x60080000 0x0 0x60080000 0x0 0x10000>, /* I/O */ + <0x82000000 0x0 0x60090000 0x0 0x60090000 0x0 0xff70000>, /* mem */ + <0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x1000000>, /* mem */ + <0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>; /* mem prefetchable */ num-lanes = <0x8>; - interrupts = <56 57 58 59 60 61 62 63 64>; + interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>; interrupt-names = "msi", "inta", "intb", "intc", "intd"; interrupt-parent = <&plic0>; interrupt-map-mask = <0x0 0x0 0x0 0x7>; @@ -316,13 +315,11 @@ <0x0 0x0 0x0 0x2 &plic0 58>, <0x0 0x0 0x0 0x3 &plic0 59>, <0x0 0x0 0x0 0x4 &plic0 60>; + clock-names = "pcie_aux"; + clocks = <&prci FU740_PRCI_CLK_PCIE_AUX>; pwren-gpios = <&gpio 5 0>; reset-gpios = <&gpio 8 0>; - clocks = <&prci PRCI_CLK_PCIEAUX>; - clock-names = "pcieaux"; - resets = <&prci PRCI_RST_PCIE_POWER_UP_N>; - reset-names = "rst_n"; - + resets = <&prci 4>; status = "okay"; }; }; diff --git a/arch/riscv/dts/hifive-unmatched-a00.dts b/arch/riscv/dts/hifive-unmatched-a00.dts index b44e8c160db..c4ed9efdff0 100644 --- a/arch/riscv/dts/hifive-unmatched-a00.dts +++ b/arch/riscv/dts/hifive-unmatched-a00.dts @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* Copyright (c) 2019-2021 SiFive, Inc */ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2020 SiFive, Inc */ #include "fu740-c000.dtsi" #include <dt-bindings/gpio/gpio.h> @@ -9,8 +9,6 @@ #define RTCCLK_FREQ 1000000 / { - #address-cells = <2>; - #size-cells = <2>; model = "SiFive HiFive Unmatched A00"; compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000", "sifive,fu740"; @@ -28,9 +26,6 @@ reg = <0x0 0x80000000 0x4 0x00000000>; }; - soc { - }; - hfclk: hfclk { #clock-cells = <0>; compatible = "fixed-clock"; @@ -65,10 +60,21 @@ temperature-sensor@4c { compatible = "ti,tmp451"; reg = <0x4c>; + vcc-supply = <&vdd_bpro>; interrupt-parent = <&gpio>; interrupts = <6 IRQ_TYPE_LEVEL_LOW>; }; + eeprom@54 { + compatible = "microchip,24c02", "atmel,24c02"; + reg = <0x54>; + vcc-supply = <&vdd_bpro>; + label = "board-id"; + pagesize = <16>; + read-only; + size = <256>; + }; + pmic@58 { compatible = "dlg,da9063"; reg = <0x58>; @@ -76,48 +82,44 @@ interrupts = <1 IRQ_TYPE_LEVEL_LOW>; interrupt-controller; - regulators { - vdd_bcore1: bcore1 { - regulator-min-microvolt = <1050000>; - regulator-max-microvolt = <1050000>; - regulator-min-microamp = <5000000>; - regulator-max-microamp = <5000000>; - regulator-always-on; - }; + onkey { + compatible = "dlg,da9063-onkey"; + }; + + rtc { + compatible = "dlg,da9063-rtc"; + }; + + wdt { + compatible = "dlg,da9063-watchdog"; + }; - vdd_bcore2: bcore2 { + regulators { + vdd_bcore: bcores-merged { regulator-min-microvolt = <1050000>; regulator-max-microvolt = <1050000>; - regulator-min-microamp = <5000000>; - regulator-max-microamp = <5000000>; + regulator-min-microamp = <4800000>; + regulator-max-microamp = <4800000>; regulator-always-on; }; vdd_bpro: bpro { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; - regulator-min-microamp = <2500000>; - regulator-max-microamp = <2500000>; + regulator-min-microamp = <2400000>; + regulator-max-microamp = <2400000>; regulator-always-on; }; vdd_bperi: bperi { - regulator-min-microvolt = <1050000>; - regulator-max-microvolt = <1050000>; + regulator-min-microvolt = <1060000>; + regulator-max-microvolt = <1060000>; regulator-min-microamp = <1500000>; regulator-max-microamp = <1500000>; regulator-always-on; }; - vdd_bmem: bmem { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-min-microamp = <3000000>; - regulator-max-microamp = <3000000>; - regulator-always-on; - }; - - vdd_bio: bio { + vdd_bmem_bio: bmem-bio-merged { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-min-microamp = <3000000>; @@ -128,86 +130,66 @@ vdd_ldo1: ldo1 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; - regulator-min-microamp = <100000>; - regulator-max-microamp = <100000>; regulator-always-on; }; vdd_ldo2: ldo2 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; - regulator-min-microamp = <200000>; - regulator-max-microamp = <200000>; regulator-always-on; }; vdd_ldo3: ldo3 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-min-microamp = <200000>; - regulator-max-microamp = <200000>; regulator-always-on; }; vdd_ldo4: ldo4 { regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; - regulator-min-microamp = <200000>; - regulator-max-microamp = <200000>; regulator-always-on; }; vdd_ldo5: ldo5 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-min-microamp = <100000>; - regulator-max-microamp = <100000>; regulator-always-on; }; vdd_ldo6: ldo6 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; - regulator-min-microamp = <200000>; - regulator-max-microamp = <200000>; regulator-always-on; }; vdd_ldo7: ldo7 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-min-microamp = <200000>; - regulator-max-microamp = <200000>; regulator-always-on; }; vdd_ldo8: ldo8 { regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-min-microamp = <200000>; - regulator-max-microamp = <200000>; regulator-always-on; }; vdd_ld09: ldo9 { regulator-min-microvolt = <1050000>; regulator-max-microvolt = <1050000>; - regulator-min-microamp = <200000>; - regulator-max-microamp = <200000>; + regulator-always-on; }; vdd_ldo10: ldo10 { regulator-min-microvolt = <1000000>; regulator-max-microvolt = <1000000>; - regulator-min-microamp = <300000>; - regulator-max-microamp = <300000>; + regulator-always-on; }; vdd_ldo11: ldo11 { regulator-min-microvolt = <2500000>; regulator-max-microvolt = <2500000>; - regulator-min-microamp = <300000>; - regulator-max-microamp = <300000>; regulator-always-on; }; }; @@ -217,7 +199,7 @@ &qspi0 { status = "okay"; flash@0 { - compatible = "issi,is25wp256", "jedec,spi-nor"; + compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; m25p,fast-read; @@ -234,6 +216,7 @@ spi-max-frequency = <20000000>; voltage-ranges = <3300 3300>; disable-wp; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; }; }; @@ -256,4 +239,8 @@ &gpio { status = "okay"; + gpio-line-names = "J29.1", "PMICNTB", "PMICSHDN", "J8.1", "J8.3", + "PCIe_PWREN", "THERM", "UBRDG_RSTN", "PCIe_PERSTN", + "ULPI_RSTN", "J8.2", "UHUB_RSTN", "GEMGXL_RST", "J8.4", + "EN_VDD_SD", "SD_CD"; }; diff --git a/board/firefly/firefly-rk3308/roc_cc_rk3308.c b/board/firefly/firefly-rk3308/roc_cc_rk3308.c index 28dcc2a6903..bdf3cc03dc5 100644 --- a/board/firefly/firefly-rk3308/roc_cc_rk3308.c +++ b/board/firefly/firefly-rk3308/roc_cc_rk3308.c @@ -70,7 +70,7 @@ int rockchip_dnl_key_pressed(void) { unsigned int val; - if (adc_channel_single_shot("saradc", 1, &val)) { + if (adc_channel_single_shot("saradc@ff1e0000", 1, &val)) { printf("%s read adc key val failed\n", __func__); return false; } diff --git a/board/freescale/ls1043ardb/ddr.c b/board/freescale/ls1043ardb/ddr.c index 08b43ff5e4c..4d2fce38412 100644 --- a/board/freescale/ls1043ardb/ddr.c +++ b/board/freescale/ls1043ardb/ddr.c @@ -114,7 +114,7 @@ dimm_params_t ddr_raw_timing = { .mirrored_dimm = 0, .n_row_addr = 15, .n_col_addr = 10, - .bank_addr_bits = 0, + .bank_addr_bits = 2, .bank_group_bits = 2, .edc_config = 0, .burst_lengths_bitmask = 0x0c, diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c index a71952dcf39..25906d3fc01 100644 --- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c +++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c @@ -83,7 +83,19 @@ struct cpld_data { #define CPLD_FXS_LED 0x0F #define CPLD_SYS_RST 0x00 -void board_reset(void) +void board_reset_prepare(void) +{ + /* + * During reset preparation, turn off external watchdog. + * This ensures that external watchdog does not trigger + * another reset or possible infinite reset loop. + */ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + out_8(&cpld_data->wd_cfg, CPLD_WD_CFG); + in_8(&cpld_data->wd_cfg); /* Read back to sync write */ +} + +void board_reset_last(void) { struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); out_8(&cpld_data->system_rst, 1); @@ -92,12 +104,46 @@ void board_reset(void) void board_cpld_init(void) { struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + u8 prev_wd_cfg = in_8(&cpld_data->wd_cfg); out_8(&cpld_data->wd_cfg, CPLD_WD_CFG); out_8(&cpld_data->status_led, CPLD_STATUS_LED); out_8(&cpld_data->fxo_led, CPLD_FXO_LED); out_8(&cpld_data->fxs_led, CPLD_FXS_LED); + + /* + * CPLD's system reset register on P1/P2 RDB boards is not autocleared + * after flipping it. If this register is set to one then CPLD triggers + * reset of CPU in few ms. + * + * CPLD does not trigger reset of CPU for 100ms after the last reset. + * + * This means that trying to reset board via CPLD system reset register + * cause reboot loop. To prevent this reboot loop, the only workaround + * is to try to clear CPLD's system reset register as early as possible + * and it has to be done in 100ms since the last start of reset. + */ out_8(&cpld_data->system_rst, CPLD_SYS_RST); + + /* + * If watchdog timer was already set to non-disabled value then it means + * that watchdog timer was already activated, has already expired and + * caused CPU reset. If this happened then due to CPLD firmware bug, + * writing to wd_cfg register has no effect and therefore it is not + * possible to reactivate watchdog timer again. Also if CPU was reset + * via watchdog then some peripherals like i2c do not work. Watchdog and + * i2c start working again after CPU reset via non-watchdog method. + * + * So in case watchdog timer register in CPLD was already enabled then + * disable it in CPLD and reset CPU which cause new boot. Watchdog timer + * is disabled few lines above, after reading CPLD previous value. + * This logic (disabling timer before reset) prevents reboot loop. + */ + if (prev_wd_cfg != CPLD_WD_CFG) { + eieio(); + do_reset(NULL, 0, 0, NULL); + while (1); /* do_reset() does not occur immediately */ + } } void board_gpio_init(void) diff --git a/board/freescale/p1_p2_rdb_pc/spl.c b/board/freescale/p1_p2_rdb_pc/spl.c index b60027ebd9a..eda84bf2b1f 100644 --- a/board/freescale/p1_p2_rdb_pc/spl.c +++ b/board/freescale/p1_p2_rdb_pc/spl.c @@ -31,6 +31,12 @@ void board_init_f(ulong bootflag) u32 plat_ratio, bus_clk; ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + /* + * Call board_early_init_f() as early as possible as it workarounds + * reboot loop due to broken CPLD state machine for reset line. + */ + board_early_init_f(); + console_init_f(); /* Set pmuxcr to allow both i2c1 and i2c2 */ diff --git a/board/freescale/p1_p2_rdb_pc/tlb.c b/board/freescale/p1_p2_rdb_pc/tlb.c index 105d9e38aac..65cedd42a0d 100644 --- a/board/freescale/p1_p2_rdb_pc/tlb.c +++ b/board/freescale/p1_p2_rdb_pc/tlb.c @@ -61,11 +61,11 @@ struct fsl_e_tlb_entry tlb_table[] = { MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 5, BOOKE_PAGESZ_1M, 1), #endif +#endif /* not SPL */ SET_TLB_ENTRY(1, CONFIG_SYS_CPLD_BASE, CONFIG_SYS_CPLD_BASE_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, 0, 6, BOOKE_PAGESZ_1M, 1), -#endif /* not SPL */ #ifdef CONFIG_SYS_NAND_BASE /* *I*G - NAND */ diff --git a/board/kontron/sl28/common.c b/board/kontron/sl28/common.c index 33c6843c3f7..331de29baee 100644 --- a/board/kontron/sl28/common.c +++ b/board/kontron/sl28/common.c @@ -2,6 +2,9 @@ #include <common.h> #include <asm/global_data.h> +#include <asm/io.h> + +#include "sl28.h" DECLARE_GLOBAL_DATA_PTR; @@ -9,3 +12,22 @@ u32 get_lpuart_clk(void) { return gd->bus_clk / CONFIG_SYS_FSL_LPUART_CLK_DIV; } + +enum boot_source sl28_boot_source(void) +{ + u32 rcw_src = in_le32(DCFG_BASE + DCFG_PORSR1) & DCFG_PORSR1_RCW_SRC; + + switch (rcw_src) { + case DCFG_PORSR1_RCW_SRC_SDHC1: + return BOOT_SOURCE_SDHC; + case DCFG_PORSR1_RCW_SRC_SDHC2: + return BOOT_SOURCE_MMC; + case DCFG_PORSR1_RCW_SRC_I2C: + return BOOT_SOURCE_I2C; + case DCFG_PORSR1_RCW_SRC_FSPI_NOR: + return BOOT_SOURCE_SPI; + default: + debug("unknown bootsource (%08x)\n", rcw_src); + return BOOT_SOURCE_UNKNOWN; + } +} diff --git a/board/kontron/sl28/sl28.c b/board/kontron/sl28/sl28.c index 32e9694b77c..0576b3eae48 100644 --- a/board/kontron/sl28/sl28.c +++ b/board/kontron/sl28/sl28.c @@ -24,6 +24,8 @@ #include <fdtdec.h> #include <miiphy.h> +#include "sl28.h" + DECLARE_GLOBAL_DATA_PTR; #if CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) @@ -60,6 +62,27 @@ int board_eth_init(struct bd_info *bis) return pci_eth_init(bis); } +enum env_location env_get_location(enum env_operation op, int prio) +{ + enum boot_source src = sl28_boot_source(); + + if (prio) + return ENVL_UNKNOWN; + + if (!CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH)) + return ENVL_NOWHERE; + + /* write and erase always operate on the environment */ + if (op == ENVOP_SAVE || op == ENVOP_ERASE) + return ENVL_SPI_FLASH; + + /* failsafe boot will always use the compiled-in default environment */ + if (src == BOOT_SOURCE_SPI) + return ENVL_NOWHERE; + + return ENVL_SPI_FLASH; +} + static int __sl28cpld_read(uint reg) { struct udevice *dev; @@ -103,8 +126,28 @@ static void stop_recovery_watchdog(void) wdt_stop(dev); } +static void sl28_set_prompt(void) +{ + enum boot_source src = sl28_boot_source(); + + switch (src) { + case BOOT_SOURCE_SPI: + env_set("PS1", "[FAILSAFE] => "); + break; + case BOOT_SOURCE_SDHC: + env_set("PS1", "[SDHC] => "); + break; + default: + env_set("PS1", NULL); + break; + } +} + int fsl_board_late_init(void) { + if (IS_ENABLED(CONFIG_CMDLINE_PS_SUPPORT)) + sl28_set_prompt(); + /* * Usually, the after a board reset, the watchdog is enabled by * default. This is to supervise the bootloader boot-up. Therefore, diff --git a/board/kontron/sl28/sl28.h b/board/kontron/sl28/sl28.h new file mode 100644 index 00000000000..7f0105049cb --- /dev/null +++ b/board/kontron/sl28/sl28.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __SL28_H +#define __SL28_H + +enum boot_source { + BOOT_SOURCE_UNKNOWN, + BOOT_SOURCE_SDHC, + BOOT_SOURCE_MMC, + BOOT_SOURCE_I2C, + BOOT_SOURCE_SPI, +}; + +enum boot_source sl28_boot_source(void); + +#endif diff --git a/board/kontron/sl28/spl.c b/board/kontron/sl28/spl.c index 0e6ad5f37e1..ffaf517a8bb 100644 --- a/board/kontron/sl28/spl.c +++ b/board/kontron/sl28/spl.c @@ -5,6 +5,9 @@ #include <asm/spl.h> #include <asm/arch-fsl-layerscape/fsl_serdes.h> #include <asm/arch-fsl-layerscape/soc.h> +#include <spi_flash.h> + +#include "sl28.h" #define DCFG_RCWSR25 0x160 #define GPINFO_HW_VARIANT_MASK 0xff @@ -58,7 +61,56 @@ int board_fit_config_name_match(const char *name) void board_boot_order(u32 *spl_boot_list) { - spl_boot_list[0] = BOOT_DEVICE_SPI; + enum boot_source src = sl28_boot_source(); + + switch (src) { + case BOOT_SOURCE_SDHC: + spl_boot_list[0] = BOOT_DEVICE_MMC2; + break; + case BOOT_SOURCE_SPI: + case BOOT_SOURCE_I2C: + spl_boot_list[0] = BOOT_DEVICE_SPI; + break; + case BOOT_SOURCE_MMC: + spl_boot_list[0] = BOOT_DEVICE_MMC1; + break; + default: + panic("unexpected bootsource (%d)\n", src); + break; + } +} + +unsigned int spl_spi_get_uboot_offs(struct spi_flash *flash) +{ + enum boot_source src = sl28_boot_source(); + + switch (src) { + case BOOT_SOURCE_SPI: + return 0x000000; + case BOOT_SOURCE_I2C: + return 0x230000; + default: + panic("unexpected bootsource (%d)\n", src); + break; + } +} + +const char *spl_board_loader_name(u32 boot_device) +{ + enum boot_source src = sl28_boot_source(); + + switch (src) { + case BOOT_SOURCE_SDHC: + return "SD card (Test mode)"; + case BOOT_SOURCE_SPI: + return "Failsafe SPI flash"; + case BOOT_SOURCE_I2C: + return "SPI flash"; + case BOOT_SOURCE_MMC: + return "eMMC"; + default: + return "(unknown)"; + } } int board_early_init_f(void) diff --git a/board/renesas/rcar-common/common.c b/board/renesas/rcar-common/common.c index 0352d341e75..daa1beb14f8 100644 --- a/board/renesas/rcar-common/common.c +++ b/board/renesas/rcar-common/common.c @@ -9,6 +9,7 @@ #include <common.h> #include <dm.h> +#include <fdt_support.h> #include <init.h> #include <asm/global_data.h> #include <dm/uclass-internal.h> @@ -19,9 +20,11 @@ DECLARE_GLOBAL_DATA_PTR; -/* If the firmware passed a device tree use it for U-Boot DRAM setup. */ +/* If the firmware passed a device tree use it for e.g. U-Boot DRAM setup. */ extern u64 rcar_atf_boot_args[]; +#define FDT_RPC_PATH "/soc/spi@ee200000" + int fdtdec_board_setup(const void *fdt_blob) { void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]); @@ -81,7 +84,7 @@ static int is_mem_overlap(void *blob, int first_mem_node, int curr_mem_node) return 0; } -int ft_board_setup(void *blob, struct bd_info *bd) +static void scrub_duplicate_memory(void *blob) { /* * Scrub duplicate /memory@* node entries here. Some R-Car DTs might @@ -119,6 +122,45 @@ int ft_board_setup(void *blob, struct bd_info *bd) first_mem_node = 0; mem = 0; } +} + +static void update_rpc_status(void *blob) +{ + void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]); + int offset, enabled; + + /* + * Check if the DT fragment received from TF-A had its RPC-IF device node + * enabled. + */ + if (fdt_magic(atf_fdt_blob) != FDT_MAGIC) + return; + + offset = fdt_path_offset(atf_fdt_blob, FDT_RPC_PATH); + if (offset < 0) + return; + + enabled = fdtdec_get_is_enabled(atf_fdt_blob, offset); + if (!enabled) + return; + + /* + * Find the RPC-IF device node, and enable it if it has a flash subnode. + */ + offset = fdt_path_offset(blob, FDT_RPC_PATH); + if (offset < 0) + return; + + if (fdt_subnode_offset(blob, offset, "flash") < 0) + return; + + fdt_status_okay(blob, offset); +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + scrub_duplicate_memory(blob); + update_rpc_status(blob); return 0; } diff --git a/cmd/riscv/sbi.c b/cmd/riscv/sbi.c index ee11e0f88e4..522f502435b 100644 --- a/cmd/riscv/sbi.c +++ b/cmd/riscv/sbi.c @@ -68,11 +68,21 @@ static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc, ret = sbi_get_impl_version(&vers); if (ret < 0) break; - if (impl_id == 1) + switch (impl_id) { + case 1: /* OpenSBI */ printf("%ld.%ld", vers >> 16, vers & 0xffff); - else + break; + case 3: /* KVM */ + printf("%ld.%ld.%ld", + vers >> 16, + (vers >> 8) & 0xff, + vers & 0xff); + break; + default: printf("0x%lx", vers); + break; + } break; } } diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c index 47adaffd184..d0c63cadf41 100644 --- a/cmd/tpm-common.c +++ b/cmd/tpm-common.c @@ -333,6 +333,26 @@ int do_tpm_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return 0; } +int do_tpm_report_state(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct udevice *dev; + char buf[80]; + int rc; + + rc = get_tpm(&dev); + if (rc) + return rc; + rc = tpm_report_state(dev, buf, sizeof(buf)); + if (rc < 0) { + printf("Couldn't get TPM state (%d)\n", rc); + return CMD_RET_FAILURE; + } + printf("%s\n", buf); + + return 0; +} + int do_tpm_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { struct udevice *dev; diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h index 358ddff5761..de4a934aab6 100644 --- a/cmd/tpm-user-utils.h +++ b/cmd/tpm-user-utils.h @@ -21,6 +21,8 @@ int do_tpm_device(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_tpm_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_tpm_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); +int do_tpm_report_state(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]); int do_tpm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); #endif /* __TPM_USER_UTILS_H */ diff --git a/cmd/tpm-v1.c b/cmd/tpm-v1.c index bf238a9f2e3..0efb079b0a9 100644 --- a/cmd/tpm-v1.c +++ b/cmd/tpm-v1.c @@ -131,7 +131,8 @@ static int do_tpm_extend(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_FAILURE; } - rc = tpm_pcr_extend(dev, index, in_digest, out_digest); + rc = tpm_pcr_extend(dev, index, in_digest, sizeof(in_digest), + out_digest, "cmd"); if (!rc) { puts("PCR value after execution of the command:\n"); print_byte_string(out_digest, sizeof(out_digest)); diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index 4ea5f9f094f..d93b83ada93 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -359,6 +359,7 @@ static int do_tpm_pcr_setauthvalue(struct cmd_tbl *cmdtp, int flag, static struct cmd_tbl tpm2_commands[] = { U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""), U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""), + U_BOOT_CMD_MKENT(state, 0, 1, do_tpm_report_state, "", ""), U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""), U_BOOT_CMD_MKENT(startup, 0, 1, do_tpm2_startup, "", ""), U_BOOT_CMD_MKENT(self_test, 0, 1, do_tpm2_self_test, "", ""), @@ -389,6 +390,8 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command", " Show all devices or set the specified device\n" "info\n" " Show information about the TPM.\n" +"state\n" +" Show internal state from the TPM (if available)\n" "init\n" " Initialize the software stack. Always the first command to issue.\n" "startup <mode>\n" diff --git a/cmd/tpm_test.c b/cmd/tpm_test.c index a3ccb12f53a..b35eae81dc3 100644 --- a/cmd/tpm_test.c +++ b/cmd/tpm_test.c @@ -91,7 +91,8 @@ static int test_early_extend(struct udevice *dev) tpm_init(dev); TPM_CHECK(tpm_startup(dev, TPM_ST_CLEAR)); TPM_CHECK(tpm_continue_self_test(dev)); - TPM_CHECK(tpm_pcr_extend(dev, 1, value_in, value_out)); + TPM_CHECK(tpm_pcr_extend(dev, 1, value_in, sizeof(value_in), value_out, + "test")); printf("done\n"); return 0; } @@ -438,7 +439,7 @@ static int test_timing(struct udevice *dev) 100); TTPM_CHECK(tpm_nv_read_value(dev, INDEX0, (uint8_t *)&x, sizeof(x)), 100); - TTPM_CHECK(tpm_pcr_extend(dev, 0, in, out), 200); + TTPM_CHECK(tpm_pcr_extend(dev, 0, in, sizeof(in), out, "test"), 200); TTPM_CHECK(tpm_set_global_lock(dev), 50); TTPM_CHECK(tpm_tsc_physical_presence(dev, PHYS_PRESENCE), 100); printf("done\n"); diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig index b0b5fb11ca7..fc1c6079275 100644 --- a/configs/kontron_sl28_defconfig +++ b/configs/kontron_sl28_defconfig @@ -12,6 +12,7 @@ CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1028a-kontron-sl28" CONFIG_SPL_TEXT_BASE=0x18010000 CONFIG_SYS_FSL_SDHC_CLK_DIV=1 +CONFIG_SPL_MMC=y CONFIG_SPL_SERIAL=y CONFIG_SPL_SIZE_LIMIT=0x20000 CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0 @@ -46,12 +47,15 @@ CONFIG_SPL_BOARD_INIT=y # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set CONFIG_SPL_STACK=0x18009ff0 CONFIG_SYS_SPL_MALLOC=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x900 CONFIG_SPL_MPC8XXX_INIT_DDR=y CONFIG_SPL_SPI_LOAD=y -CONFIG_SYS_SPI_U_BOOT_OFFS=0x230000 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x800000 +CONFIG_CMDLINE_PS_SUPPORT=y CONFIG_CMD_ASKENV=y CONFIG_CMD_GREPENV=y CONFIG_CMD_NVEDIT_EFI=y diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig index e9cc632696d..cfccfdcfc40 100644 --- a/configs/lschlv2_defconfig +++ b/configs/lschlv2_defconfig @@ -60,7 +60,6 @@ CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_SPEED=25000000 CONFIG_SPI_FLASH_STMICRO=y -CONFIG_DM_ETH=y CONFIG_DM_MDIO=y CONFIG_MVGBE=y CONFIG_MII=y diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig index b83a072b04d..1945b72450c 100644 --- a/configs/lsxhl_defconfig +++ b/configs/lsxhl_defconfig @@ -61,7 +61,6 @@ CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_SPEED=25000000 CONFIG_SPI_FLASH_STMICRO=y -CONFIG_DM_ETH=y CONFIG_DM_MDIO=y CONFIG_MVGBE=y CONFIG_MII=y diff --git a/doc/develop/index.rst b/doc/develop/index.rst index f7ee09db246..72332f7da6d 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -11,6 +11,7 @@ General codingstyle designprinciples + patman process release_cycle system_configuration diff --git a/doc/develop/process.rst b/doc/develop/process.rst index 388945cf9bb..0fa0143bf37 100644 --- a/doc/develop/process.rst +++ b/doc/develop/process.rst @@ -108,6 +108,8 @@ Differences to the Linux Development Process In U-Boot, ``"-rc1"`` will only be released after all (or at least most of the) patches that were submitted during the merge window have been applied. +.. _custodians: + Custodians ---------- @@ -127,31 +129,88 @@ patch, these should leave no doubt if they were just comments and the patch will be accepted anyway, or if the patch should be reworked/resubmitted, or if it was rejected. -Work flow of a Custodian +Review Process, Git Tags ------------------------ -The normal flow of work in the U-Boot development process will look -like this: +There are a number of *git tags* that are used to document the origin and the +processing of patches on their way into the mainline U-Boot code. The following +is an attempt to document how these are usually handled in the U-Boot project. + +In general, we try to follow the established procedures from other projects, +especially the Linux kernel, but there may be smaller differences. For +reference, see the Linux kernel's `Submitting patches +<https://www.kernel.org/doc/html/latest/process/submitting-patches.html>`_ +document. + +.. _dco: + +* Signed-off-by: the *Signed-off-by:* is a line at the end of the commit + message by which the signer certifies that they were involved in the development + of the patch and that they accept the `Developer Certificate of Origin + <https://developercertificate.org/>`_. Following this and adding a + ``Signed-off-by:`` line that contains the developer's name and email address + is required. -#. A developer submits a patch via e-mail to the u-boot mailing list. In - U-Boot, we make use of the `Developer Certificate of Origin - <https://developercertificate.org/>`_ that is common in other projects such - as the Linux kernel. Following this and adding a ``Signed-off-by:`` line - that contains the developer's name and email address is required. + * Please note that in U-Boot, we do not add a ``Signed-off-by`` tag if we + just pass on a patch without any changes. * Please note that when importing code from other projects you must say where it comes from, and what revision you are importing. You must not however copy ``Signed-off-by`` or other tags. -#. Everybody who can is invited to review and test the changes. Typically, we - follow the same guidelines as the Linux kernel for `Acked-by - <https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by>`_ - as well as `Reviewed-by - <https://www.kernel.org/doc/html/latest/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes>`_ - and similar additional tags. +* Everybody who can is invited to review and test the changes. Typically, we + follow the same guidelines as the Linux kernel for `Acked-by + <https://www.kernel.org/doc/html/latest/process/submitting-patches.html#when-to-use-acked-by-cc-and-co-developed-by>`_ + as well as `Reviewed-by + <https://www.kernel.org/doc/html/latest/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes>`_ + and similar additional tags. + +* Reviewed-by: The patch has been reviewed and found acceptible according to + the `Reveiwer's statement of oversight + <https://www.kernel.org/doc/html/latest/process/submitting-patches.html#reviewer-s-statement-of-oversight>`_. + A *Reviewed-by:* tag is a statement of opinion that the patch is an + appropriate modification of the code without any remaining serious technical + issues. Any interested reviewer (who has done the work) can offer a + *Reviewed-by:* tag for a patch. + +* Acked-by: If a person was not directly involved in the preparation or + handling of a patch but wishes to signify and record their approval of it + then they can arrange to have an *Acked-by:* line added to the patch's + changelog. + +* Tested-by: A *Tested-by:* tag indicates that the patch has been successfully + tested (in some environment) by the person named. Andrew Morton: "I think + it's very useful information to have. For a start, it tells you who has the + hardware and knows how to build a kernel. So if you're making a change to a + driver and want it tested, you can troll the file's changelog looking for + people who might be able to help." + +* Reported-by: If this patch fixes a problem reported by somebody else, + consider adding a *Reported-by:* tag to credit the reporter for their + contribution. Please note that this tag should not be added without the + reporter's permission, especially if the problem was not reported in a public + forum. + +* Cc: If a person should have the opportunity to comment on a patch, you may + optionally add a *Cc:* tag to the patch. Git tools (git send-email) will then + automatically arrange that they receives a copy of the patch when you submit it + to the mainling list. This is the only tag which might be added without an + explicit action by the person it names. This tag documents that potentially + interested parties have been included in the discussion. + For example, when your change affects a specific board or driver, then makes + a lot of sense to put the respective maintainer of this code on Cc: + +Work flow of a Custodian +------------------------ + +The normal flow of work in the U-Boot development process will look +like this: #. The responsible custodian inspects this patch, especially for: + #. The commit message is useful, descriptive and makes correct and + appropraite usage of required *git tags*. + #. :doc:`codingstyle` #. Basic logic: diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst index b75576cb570..db3a445372c 100644 --- a/doc/develop/release_cycle.rst +++ b/doc/develop/release_cycle.rst @@ -68,7 +68,7 @@ For the next scheduled release, release candidates were made on:: * U-Boot v2022.10-rc3 was released on Mon 22 August 2022. -.. * U-Boot v2022.10-rc4 was released on Mon 05 September 2022. +* U-Boot v2022.10-rc4 was released on Mon 05 September 2022. .. * U-Boot v2022.10-rc5 was released on Mon 19 September 2022. diff --git a/doc/develop/sending_patches.rst b/doc/develop/sending_patches.rst index 0542adeaed9..173075687e9 100644 --- a/doc/develop/sending_patches.rst +++ b/doc/develop/sending_patches.rst @@ -3,14 +3,452 @@ Sending patches =============== -.. toctree:: - :maxdepth: 2 +*Before you begin* to implement any new ideas or concepts it is always a good +idea to present your plans on the `U-Boot mailing list +<https://lists.denx.de/listinfo/u-boot>`_. U-Boot supports a huge amount of +very different systems, and it is often impossible for the individual developer +to oversee the consequences of a specific change to all architectures. +Discussing concepts early can help you to avoid spending effort on code which, +when submitted as a patch, might be rejected and/or will need lots of rework +because it does not fit for some reason. Early peer review is an important +resource - use it. Being familiar with the :doc:`process` is also important. - patman +A good introduction how to prepare for submitting patches can be found in the +LWN article `How to Get Your Change Into the Linux Kernel +<http://lwn.net/Articles/139918/>`_ as the same rules apply to U-Boot, too. +Using patman +------------ You can use a tool called patman to prepare, check and sent patches. It creates change logs, cover letters and patch notes. It also simplified the process of sending multiple versions of a series. See more details at :doc:`patman`. + +General Patch Submission Rules +------------------------------ + +* All patches must be sent to the `u-boot@lists.denx.de + <https://lists.denx.de/listinfo/u-boot>`_ mailing list. + +* If your patch affects the code maintained by one of the :ref:`custodians`, CC + them when emailing your patch. The easiest way to make sure you don't forget + this even when you resubmit the patch later is to add a ``Cc: name + <address>`` line after your ``Signed-off-by:`` line (see the example below). + +* Take a look at the commit logs of the files you are modifying. Authors of + past commits might have input to your change, so also CC them if you think + they may have feedback. + +* Patches should always contain exactly one complete logical change, i. e. + + * Changes that contain different, unrelated modifications shall be submitted + as *separate* patches, one patch per changeset. + + * If one logical set of modifications affects or creates several files, all + these changes shall be submitted in a *single* patch. + +* Non-functional changes, i.e. whitespace and reformatting changes, should be + done in separate patches marked as ``cosmetic``. This separation of functional + and cosmetic changes greatly facilitates the review process. + +* Some comments on running :doc:`checkpatch.pl <checkpatch>`: + + * Checkpatch is a tool that can help you find some style problems, but is + imperfect, and the things it complains about are of varying importance. + So use common sense in interpreting the results. + + * Warnings that clearly only make sense in the Linux kernel can be ignored. + This includes ``Use #include <linux/$file> instead of <asm/$file>`` for + example. + + * If you encounter warnings for existing code, not modified by your patch, + consider submitting a separate, cosmetic-only patch -- clearly described + as such -- that *precedes* your substantive patch. + + * For minor modifications (e.g. changed arguments of a function call), + adhere to the present codingstyle of the module. Relating checkpatch + warnings can be ignored in this case. A respective note in the commit or + cover letter why they are ignored is desired. + +* Send your patches as plain text messages: no HTML, no MIME, no links, no + compression, no attachments. Just plain text. The best way the generate + patches is by using the ``git format-patch`` command. Please use the + ``master`` branch of the mainline U-Boot git repository + (``https://source.denx.de/u-boot/u-boot.git``) as reference, unless (usually + late in a release cycle) there has been an announcement to use the ``next`` + branch of this repository instead. + +* Make sure that your mailer does not mangle the patch by automatic changes + like wrapping of longer lines etc. + The best way to send patches is by not using your regular mail tool, but by + using either ``git send-email`` or the ``git imap-send`` command instead. + If you believe you need to use a mailing list for testing (instead of any + regular mail address you own), we have a special test list for such purposes. + It would be best to subscribe to the list for the duration of your tests to + avoid repeated moderation - see https://lists.denx.de/listinfo/test + +* Choose a meaningful Subject: - keep in mind that the Subject will also be + visible as headline of your commit message. Make sure the subject does not + exceed 60 characters or so. + +* The start of the subject should be a meaningfull tag (arm:, ppc:, tegra:, + net:, ext2:, etc) + +* Include the string "PATCH" in the Subject: line of your message, e. g. + "[PATCH] Add support for feature X". ``git format-patch`` should automatically + do this. + +* If you are sending a patch series composed of multiple patches, make sure + their titles clearly state the patch order and total number of patches (``git + format-patch -n``). Also, often times an introductory email describing what + the patchset does is useful (``git format-patch -n --cover-letter``). As an + example:: + + [PATCH 0/3] Add support for new SuperCPU2000 + (This email does not contain a patch, just a description) + [PATCH 1/3] Add core support for SuperCPU2000 + [PATCH 2/3] Add support for SuperCPU2000's on-chip I2C controller + [PATCH 3/3] Add support for SuperCPU2000's on-chip UART + +* In the message body, include a description of your changes. + + * For bug fixes: a description of the bug and how your patch fixes this bug. + Please try to include a way of demonstrating that the patch actually fixes + something. + + * For new features: a description of the feature and your implementation. + +* Additional comments which you don't want included in U-Boot's history can be + included below the first "---" in the message body. + +* If your description gets too long, that's a strong indication that you should + split up your patch. + +* Remember that there is a size limit of 100 kB on the mailing list. In most + cases, you did something wrong if your patch exceeds this limit. Think again + if you should not split it into separate logical parts. + +Attributing Code, Copyrights, Signing +------------------------------------- + +* Sign your changes, i. e. add a *Signed-off-by:* line to the message body. + This can be automated by using ``git commit -s``. Please see the + :ref:`Developer Certificate of Origin <dco>` section for more details here. + +* If you change or add *significant* parts to a file, then please make sure to + add your copyright to that file, for example like this:: + + (C) Copyright 2010 Joe Hacker <jh@hackers.paradise.com> + + Please do *not* include a detailed description of your + changes. We use the *git* commit messages for this purpose. + +* If you add new files, please always make sure that these contain your + copyright note and a GPLv2+ SPDX-License-Identifier, for example like this:: + + (C) Copyright 2010 Joe Hacker <jh@hackers.paradise.com> + + SPDX-License-Identifier:<TAB>GPL-2.0+ + +* If you are copying or adapting code from other projects, like the Linux + kernel, or BusyBox, or similar, please make sure to state clearly where you + copied the code from, and provide terse but precise information which exact + version or even commit ID was used. Follow the ideas of this note from the + Linux "SubmittingPatches" document:: + + Special note to back-porters: It seems to be a common and useful practice + to insert an indication of the origin of a patch at the top of the commit + message (just after the subject line) to facilitate tracking. For instance, + here's what we see in 2.6-stable : + + Date: Tue May 13 19:10:30 2008 +0000 + + SCSI: libiscsi regression in 2.6.25: fix nop timer handling + + commit 4cf1043593db6a337f10e006c23c69e5fc93e722 upstream + + And here's what appears in 2.4 : + + Date: Tue May 13 22:12:27 2008 +0200 + + wireless, airo: waitbusy() won't delay + + [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a] + +Whatever the format, this information provides a valuable help to people +tracking your trees, and to people trying to trouble-shoot bugs in your +tree. + +Commit message conventions +-------------------------- + +Please adhere to the following conventions when writing your commit +log messages. + +* The first line of the log message is the summary line. Keep this less than 70 + characters long. + +* Don't use periods to end the summary line (e.g., don't do "Add support for + X.") + +* Use the present tense in your summary line (e.g., "Add support for X" rather + than "Added support for X"). Furthermore, use the present tense in your log + message to describe what the patch is doing. This isn't a strict rule -- it's + OK to use the past tense for describing things that were happening in the old + code for example. + +* Use the imperative tense in your summary line (e.g., "Add support for X" + rather than "Adds support for X"). In general, you can think of the summary + line as "this commit is meant to 'Add support for X'" + +* If applicable, prefix the summary line with a word describing what area of + code is being affected followed by a colon. This is a standard adopted by + both U-Boot and Linux. For example, if your change affects all mpc85xx + boards, prefix your summary line with "mpc85xx:". If your change affects the + PCI common code, prefix your summary line with "pci:". The best thing to do + is look at the "git log <file>" output to see what others have done so you + don't break conventions. + +* Insert a blank line after the summary line + +* For bug fixes, it's good practice to briefly describe how things behaved + before this commit + +* Put a detailed description after the summary and blank line. If the summary + line is sufficient to describe the change (e.g. it is a trivial spelling + correction or whitespace update), you can omit the blank line and detailed + description. + +* End your log message with S.O.B. (Signed-off-by) line. This is done + automatically when you use ``git commit -s``. Please see the + :ref:`Developer Certificate of Origin <dco>` section for more details here. + +* Keep EVERY line under 72 characters. That is, your message should be + line-wrapped with line-feeds. However, don't get carried away and wrap it too + short either since this also looks funny. + +* Detail level: The audience of the commit log message that you should cater to + is those familiar with the underlying source code you are modifying, but who + are _not_ familiar with the patch you are submitting. They should be able to + determine what is being changed and why. Avoid excessive low-level detail. + Before submitting, re-read your commit log message with this audience in mind + and adjust as needed. + +Sending updated patch versions +------------------------------ + +It is pretty normal that the first version of a patch you are submitting does +not get accepted as is, and that you are asked to submit another, improved +version. + +When re-posting such a new version of your patch(es), please always make sure +to observe the following rules. + +* Make an appropriate note that this is a re-submission in the subject line, + eg. "[PATCH v2] Add support for feature X". ``git format-patch + --subject-prefix="PATCH v2"`` can be used in this case (see the example + below). + +* Please make sure to keep a "change log", i. e. a description of what you have + changed compared to previous versions of this patch. This change log should + be added below the "---" line in the patch, which starts the "comment + section", i. e. which contains text that does not get included into the + actual commit message. + Note: it is *not* sufficient to provide a change log in some cover letter + that gets sent as a separate message with the patch series. The reason is + that such cover letters are not as easily reviewed in our `patchwork queue + <http://patchwork.ozlabs.org/project/uboot/list/>`_ so they are not helpful + to any reviewers using this tool. Example:: + + From: Joe Hacker <jh@hackers.paradise.com> + Date: Thu, 1 Jan 2222 12:21:22 +0200 + Subject: [PATCH 1/2 v3] FOO: add timewarp-support + + This patch adds timewarp-support for the FOO family of processors. + + adapted for the current kernel structures. + + Signed-off-by: Joe Hacker <jh@hackers.paradise.com> + Cc: Tom Maintainer <tm@u-boot.custodians.org> + --- + Changes for v2: + - Coding Style cleanup + - fixed miscalculation of time-space discontinuities + Changes for v3: + - fixed compiler warnings observed with GCC-17.3.5 + - worked around integer overflow in warp driver + + arch/foo/cpu/spacetime.c | 8 + + drivers/warp/Kconfig | 7 + + drivers/warp/Makefile | 42 +++ + drivers/warp/warp-core.c | 255 +++++++++++++++++++++++++ + +* Make sure that your mailer adds or keeps correct ``In-reply-to:`` and + ``References:`` headers, so threading of messages is working and everybody + can see that the new message refers to some older posting of the same topic. + +Uncommented and un-threaded repostings are extremely annoying and +time-consuming, as we have to try to remember if anything similar has been +posted before, look up the old threads, and then manually compare if anything +has been changed, or what. + +If you have problems with your e-mail client, for example because it mangles +white space or wraps long lines, then please read this article about `Email +Clients and Patches <http://kerneltrap.org/Linux/Email_Clients_and_Patches>`_. + +Notes +----- + +1. U-Boot is Free Software that can redistributed and/or modified under the + terms of the `GNU General Public License + <http://www.fsf.org/licensing/licenses/gpl.html>`_ (GPL). Currently (August + 2022) version 2 of the GPL applies. Please see :download:`Licensing + <../../Licenses/README>` for details. To allow that later versions of U-Boot + may be released under a later version of the GPL, all new code that gets + added to U-Boot shall use a "GPL-2.0+" SPDX-License-Identifier. + +2. All code must follow the :doc:`codingstyle` requirements. + +3. Before sending the patch, you *must* run some form of local testing. + Submitting a patch that does not build or function correct is a mistake. For + non-trivial patches, either building a number of platforms locally or making + use of :doc:`ci_testing` is strongly encouraged in order to avoid problems + that can be found when attempting to merge the patch. + +4. If you modify existing code, make sure that your new code does not add to + the memory footprint of the code. Remember: Small is beautiful! When adding + new features follow the guidelines laid out in :doc:`system_configuration`. + +Patch Tracking +-------------- + +Like some other projects, U-Boot uses `Patchwork <http://patchwork.ozlabs.org/>`_ +to track the state of patches. This is one of the reasons why it is mandatory +to submit all patches to the U-Boot mailing list - only then they will be +picked up by patchwork. + +At http://patchwork.ozlabs.org/project/uboot/list/ you can find the list of +open U-Boot patches. By using the "Filters" link (Note: requires JavaScript) +you can also select other views, for example, to include old patches that have, +for example, already been applied or rejected. + +Note that Patchwork automatically tracks and collects a number of git tags from +follow-up mails, so it is usually better to apply a patch through the Patchwork +commandline interface than just manually applying it from a posting on the +mailing list (in which case you have to do all the tracking and adding of git +tags yourself). This also obviates the need of a developer to resubmit a patch +only in order to collect these tags. + +A Custodian has additional privileges and can: + +* **Delegate** a patch + +* **Change the state** of a patch. The following states exist: + + * New + + * Under Review + + * Accepted + + * Rejected + + * RFC + + * Not Applicable + + * Changes Requested + + * Awaiting Upstream + + * Superseeded + + * Deferred + + * Archived + +Patchwork work-flow +^^^^^^^^^^^^^^^^^^^ + +The following are a "rule of thumb" as to how the states are used in patchwork +today. Not all states are used by all custodians. + +* New: Patch has been submitted to the list, and none of the maintainers has + changed it's state since. + +* Under Review: A custodian is reviewing the patch currently. + +* Accepted: When a patch has been applied to a custodian repository that gets + used for pulling from into upstream, they are put into "accepted" state. + +* Rejected: Rejected means we just don't want to do what the patch does. + +* RFC: The patch is not intended to be applied to any of the mainline + repositories, but merely for discussing or testing some idea or new feature. + +* Not Applicable: The patch either was not intended to be applied, as it was + a debugging or discussion aide that patchwork picked up, or was cross-posted + to our list but intended for another project entirely. + +* Changes Requested: The patch looks mostly OK, but requires some rework before + it will be accepted for mainline. + +* Awaiting Upstream: A custodian may have applied this to the ``next`` branch + and has not merged yet to master, or has queued the patch up to be submitted + to be merged, but has not yet. + +* Superseeded: Patches are marked as 'superseeded' when the poster submits a + new version of these patches. + +* Deferred: Deferred usually means the patch depends on something else that + isn't upstream, such as patches that only apply against some specific other + repository. This is also used when a patch has been in patchwork for over a + year and it is unlikely to be applied as-is. + +* Archived: Archiving puts the patch away somewhere where it doesn't appear in + the normal pages and needs extra effort to get to. + +Apply patches +^^^^^^^^^^^^^ + +To apply a patch from the `patchwork queue +<http://patchwork.ozlabs.org/project/uboot/list/>`_ using ``git``, download the +mbox file and apply it using:: + + git am file + +The `openembedded wiki <http://wiki.openembedded.net/>`_ also provides a script +named `pw-am.sh +<http://cgit.openembedded.org/cgit.cgi/openembedded/tree/contrib/patchwork/pw-am.sh>`_ +which can be used to fetch an 'mbox' patch from patchwork and git am it:: + + usage: pw-am.sh <number> + example: 'pw-am.sh 71002' will get and apply the patch from http://patchwork.ozlabs.org/patch/71002/ + +Update the state of patches +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You have to register to be able to update the state of patches. You can use the +Web interface, `pwclient`, or `pwparser`. + +pwclient +^^^^^^^^ + +The `pwclient` command line tool can be used for example to retrieve patches, +search the queue or update the state. + +All necessary information for `pwclient` is linked from the bottom of +http://patchwork.ozlabs.org/project/uboot/ + +Use:: + + pwclient help + +for an overview on how to use it. + +pwparser +^^^^^^^^ + +See http://www.mail-archive.com/patchwork@lists.ozlabs.org/msg00057.html diff --git a/doc/device-tree-bindings/firmware/fwu-mdata-mtd.yaml b/doc/device-tree-bindings/firmware/fwu-mdata-mtd.yaml new file mode 100644 index 00000000000..4f5404f9991 --- /dev/null +++ b/doc/device-tree-bindings/firmware/fwu-mdata-mtd.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/firmware/u-boot,fwu-mdata-sf.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: FWU metadata on MTD device without GPT + +maintainers: + - Masami Hiramatsu <masami.hiramatsu@linaro.org> + +properties: + compatible: + items: + - const: u-boot,fwu-mdata-mtd + + fwu-mdata-store: + maxItems: 1 + description: Phandle of the MTD device which contains the FWU medatata. + + mdata-offsets: + minItems: 2 + description: Offsets of the primary and secondary FWU metadata in the NOR flash. + +required: + - compatible + - fwu-mdata-store + - mdata-offsets + +additionalProperties: false + +examples: + - | + fwu-mdata { + compatible = "u-boot,fwu-mdata-mtd"; + fwu-mdata-store = <&spi-flash>; + mdata-offsets = <0x500000 0x530000>; + }; diff --git a/doc/usage/cmd/gpio.rst b/doc/usage/cmd/gpio.rst index f6a5668388c..ee902138f16 100644 --- a/doc/usage/cmd/gpio.rst +++ b/doc/usage/cmd/gpio.rst @@ -45,6 +45,31 @@ gpio status Display the status of one or multiple GPIOs. By default only claimed GPIOs are displayed. +gpio status command output fields are:: + + <name>: <function>: <value> [x] <label> + +*function* can take the following values: + +output + pin configured in gpio output, *value* indicates the pin's level + +input + pin configured in gpio input, *value* indicates the pin's level + +func + pin configured in alternate function, followed by *label* + which shows pinmuxing label. + +unused + pin not configured + +*[x]* or *[ ]* indicate respectively if the gpio is used or not. + +*label* shows the gpio label. + +Parameters +---------- -a Display GPIOs irrespective of being claimed. @@ -77,6 +102,23 @@ Switch the status of a GPIO:: => echo $myvar 0 +Show the GPIO status:: + + => gpio status + Bank GPIOA: + GPIOA1: func rgmii-0 + GPIOA2: func rgmii-0 + GPIOA7: func rgmii-0 + GPIOA10: output: 0 [x] hdmi-transmitter@39.reset-gpios + GPIOA13: output: 1 [x] red.gpios + + Bank GPIOB: + GPIOB0: func rgmii-0 + GPIOB1: func rgmii-0 + GPIOB2: func uart4-0 + GPIOB7: input: 0 [x] mmc@58005000.cd-gpios + GPIOB11: func rgmii-0 + Configuration ------------- diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 7d31a9f22a8..97bf1c6e15b 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -728,6 +728,12 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id) u32 div, con; switch (clk_id) { + case HCLK_SDIO: + case SCLK_SDIO: + con = readl(&cru->clksel_con[15]); + /* dwmmc controller have internal div 2 */ + div = 2; + break; case HCLK_SDMMC: case SCLK_SDMMC: con = readl(&cru->clksel_con[16]); @@ -750,37 +756,46 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id) return DIV_TO_RATE(GPLL_HZ, div); } +static void rk3399_dwmmc_set_clk(struct rockchip_cru *cru, + unsigned int con, ulong set_rate) +{ + /* Select clk_sdmmc source from GPLL by default */ + /* mmc clock defaulg div 2 internal, provide double in cru */ + int src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); + + if (src_clk_div > 128) { + /* use 24MHz source for 400KHz clock */ + src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); + assert(src_clk_div - 1 < 128); + rk_clrsetreg(&cru->clksel_con[con], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + } else { + rk_clrsetreg(&cru->clksel_con[con], + CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | + (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); + } +} + static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru, ulong clk_id, ulong set_rate) { - int src_clk_div; - int aclk_emmc = 198 * MHz; - switch (clk_id) { + case HCLK_SDIO: + case SCLK_SDIO: + rk3399_dwmmc_set_clk(cru, 15, set_rate); + break; case HCLK_SDMMC: case SCLK_SDMMC: - /* Select clk_sdmmc source from GPLL by default */ - /* mmc clock defaulg div 2 internal, provide double in cru */ - src_clk_div = DIV_ROUND_UP(GPLL_HZ / 2, set_rate); - - if (src_clk_div > 128) { - /* use 24MHz source for 400KHz clock */ - src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate); - assert(src_clk_div - 1 < 128); - rk_clrsetreg(&cru->clksel_con[16], - CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, - CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | - (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); - } else { - rk_clrsetreg(&cru->clksel_con[16], - CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, - CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | - (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); - } + rk3399_dwmmc_set_clk(cru, 16, set_rate); break; - case SCLK_EMMC: + case SCLK_EMMC: { + int aclk_emmc = 198 * MHz; /* Select aclk_emmc source from GPLL */ - src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc); + int src_clk_div = DIV_ROUND_UP(GPLL_HZ, aclk_emmc); + assert(src_clk_div - 1 < 32); rk_clrsetreg(&cru->clksel_con[21], @@ -797,6 +812,7 @@ static ulong rk3399_mmc_set_clk(struct rockchip_cru *cru, CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); break; + } default: return -EINVAL; } @@ -918,6 +934,8 @@ static ulong rk3399_clk_get_rate(struct clk *clk) switch (clk->id) { case 0 ... 63: return 0; + case HCLK_SDIO: + case SCLK_SDIO: case HCLK_SDMMC: case SCLK_SDMMC: case SCLK_EMMC: @@ -992,6 +1010,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate) case PCLK_PERILP1: return 0; + case HCLK_SDIO: + case SCLK_SDIO: case HCLK_SDMMC: case SCLK_SDMMC: case SCLK_EMMC: diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c index b025050e224..5edc864e4bd 100644 --- a/drivers/clk/sifive/fu740-prci.c +++ b/drivers/clk/sifive/fu740-prci.c @@ -103,53 +103,53 @@ static const struct __prci_clock_ops sifive_fu740_prci_pcieaux_clk_ops = { /* List of clock controls provided by the PRCI */ struct __prci_clock __prci_init_clocks_fu740[] = { - [PRCI_CLK_COREPLL] = { + [FU740_PRCI_CLK_COREPLL] = { .name = "corepll", .parent_name = "hfclk", .ops = &sifive_fu740_prci_wrpll_clk_ops, .pwd = &__prci_corepll_data, }, - [PRCI_CLK_DDRPLL] = { + [FU740_PRCI_CLK_DDRPLL] = { .name = "ddrpll", .parent_name = "hfclk", .ops = &sifive_fu740_prci_wrpll_clk_ops, .pwd = &__prci_ddrpll_data, }, - [PRCI_CLK_GEMGXLPLL] = { + [FU740_PRCI_CLK_GEMGXLPLL] = { .name = "gemgxlpll", .parent_name = "hfclk", .ops = &sifive_fu740_prci_wrpll_clk_ops, .pwd = &__prci_gemgxlpll_data, }, - [PRCI_CLK_DVFSCOREPLL] = { + [FU740_PRCI_CLK_DVFSCOREPLL] = { .name = "dvfscorepll", .parent_name = "hfclk", .ops = &sifive_fu740_prci_wrpll_clk_ops, .pwd = &__prci_dvfscorepll_data, }, - [PRCI_CLK_HFPCLKPLL] = { + [FU740_PRCI_CLK_HFPCLKPLL] = { .name = "hfpclkpll", .parent_name = "hfclk", .ops = &sifive_fu740_prci_wrpll_clk_ops, .pwd = &__prci_hfpclkpll_data, }, - [PRCI_CLK_CLTXPLL] = { + [FU740_PRCI_CLK_CLTXPLL] = { .name = "cltxpll", .parent_name = "hfclk", .ops = &sifive_fu740_prci_wrpll_clk_ops, .pwd = &__prci_cltxpll_data, }, - [PRCI_CLK_TLCLK] = { + [FU740_PRCI_CLK_TLCLK] = { .name = "tlclk", .parent_name = "corepll", .ops = &sifive_fu740_prci_tlclksel_clk_ops, }, - [PRCI_CLK_PCLK] = { + [FU740_PRCI_CLK_PCLK] = { .name = "pclk", .parent_name = "hfpclkpll", .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops, }, - [PRCI_CLK_PCIEAUX] { + [FU740_PRCI_CLK_PCIE_AUX] { .name = "pcieaux", .parent_name = "", .ops = &sifive_fu740_prci_pcieaux_clk_ops, diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c index 52ae268e0c8..c8fb6002907 100644 --- a/drivers/clk/sifive/sifive-prci.c +++ b/drivers/clk/sifive/sifive-prci.c @@ -685,14 +685,14 @@ static int sifive_prci_probe(struct udevice *dev) * case the design uses hfpclk to drive * Chiplink */ - pc = &data->clks[PRCI_CLK_HFPCLKPLL]; + pc = &data->clks[FU740_PRCI_CLK_HFPCLKPLL]; parent_rate = sifive_prci_parent_rate(pc, data); sifive_prci_wrpll_set_rate(pc, 260000000, parent_rate); pc->ops->enable_clk(pc, 1); } else if (prci_pll_reg & PRCI_PRCIPLL_CLTXPLL) { /* CLTX pll init */ - pc = &data->clks[PRCI_CLK_CLTXPLL]; + pc = &data->clks[FU740_PRCI_CLK_CLTXPLL]; parent_rate = sifive_prci_parent_rate(pc, data); sifive_prci_wrpll_set_rate(pc, 260000000, parent_rate); diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index b5122d1a1c3..0b0b4e5cb7e 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -214,7 +214,7 @@ static void set_csn_config(int dimm_number, int i, fsl_ddr_cfg_regs_t *ddr, odt_rd_cfg = popts->cs_local_opts[i].odt_rd_cfg; odt_wr_cfg = popts->cs_local_opts[i].odt_wr_cfg; #ifdef CONFIG_SYS_FSL_DDR4 - ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits; + ba_bits_cs_n = dimm_params[dimm_number].bank_addr_bits - 2; bg_bits_cs_n = dimm_params[dimm_number].bank_group_bits; #else n_banks_per_sdram_device diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index e2bdc12ef2c..ea791622628 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -246,7 +246,7 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num, /* SDRAM device parameters */ pdimm->n_row_addr = ((spd->addressing >> 3) & 0x7) + 12; pdimm->n_col_addr = (spd->addressing & 0x7) + 9; - pdimm->bank_addr_bits = (spd->density_banks >> 4) & 0x3; + pdimm->bank_addr_bits = ((spd->density_banks >> 4) & 0x3) + 2; pdimm->bank_group_bits = (spd->density_banks >> 6) & 0x3; /* diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index 2f76beb2dbe..eb2f06e8300 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -27,9 +27,9 @@ /* Option parameter Structures */ struct options_string { const char *option_name; - size_t offset; - unsigned int size; - const char printhex; + u32 offset : 9; + u32 size : 4; + u32 printhex : 1; }; static unsigned int picos_to_mhz(unsigned int picos) diff --git a/drivers/mtd/renesas_rpc_hf.c b/drivers/mtd/renesas_rpc_hf.c index 2c61ce7b6e6..aca7a6cdd25 100644 --- a/drivers/mtd/renesas_rpc_hf.c +++ b/drivers/mtd/renesas_rpc_hf.c @@ -388,7 +388,8 @@ static int rpc_hf_probe(struct udevice *dev) } static const struct udevice_id rpc_hf_ids[] = { - { .compatible = "renesas,rpc" }, + { .compatible = "renesas,r7s72100-rpc-if" }, + { .compatible = "renesas,rcar-gen3-rpc-if" }, {} }; diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index cd4c2c29a65..835e5bd8bd5 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -22,6 +22,8 @@ #define ENETC_DRIVER_NAME "enetc_eth" +static int enetc_remove(struct udevice *dev); + /* * sets the MAC address in IERB registers, this setting is persistent and * carried over to Linux. @@ -319,6 +321,7 @@ static int enetc_config_phy(struct udevice *dev) static int enetc_probe(struct udevice *dev) { struct enetc_priv *priv = dev_get_priv(dev); + int res; if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_available(dev_ofnode(dev))) { enetc_dbg(dev, "interface disabled\n"); @@ -350,7 +353,10 @@ static int enetc_probe(struct udevice *dev) enetc_start_pcs(dev); - return enetc_config_phy(dev); + res = enetc_config_phy(dev); + if(res) + enetc_remove(dev); + return res; } /* diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c index c0a06dcaed0..cbf502bd0e9 100644 --- a/drivers/ram/rockchip/sdram_rk3399.c +++ b/drivers/ram/rockchip/sdram_rk3399.c @@ -85,7 +85,7 @@ struct sdram_rk3399_ops { int (*data_training_first)(struct dram_info *dram, u32 channel, u8 rank, struct rk3399_sdram_params *sdram); int (*set_rate_index)(struct dram_info *dram, - struct rk3399_sdram_params *params); + struct rk3399_sdram_params *params, u32 ctl_fn); void (*modify_param)(const struct chan_info *chan, struct rk3399_sdram_params *params); struct rk3399_sdram_params * @@ -1644,7 +1644,8 @@ static int data_training_first(struct dram_info *dram, u32 channel, u8 rank, } static int switch_to_phy_index1(struct dram_info *dram, - struct rk3399_sdram_params *params) + struct rk3399_sdram_params *params, + u32 unused) { u32 channel; u32 *denali_phy; @@ -2539,26 +2540,25 @@ static int lpddr4_set_ctl(struct dram_info *dram, } static int lpddr4_set_rate(struct dram_info *dram, - struct rk3399_sdram_params *params) + struct rk3399_sdram_params *params, + u32 ctl_fn) { - u32 ctl_fn; u32 phy_fn; - for (ctl_fn = 0; ctl_fn < 2; ctl_fn++) { - phy_fn = lpddr4_get_phy_fn(params, ctl_fn); + phy_fn = lpddr4_get_phy_fn(params, ctl_fn); - lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]); - lpddr4_set_ctl(dram, params, ctl_fn, - dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq); + lpddr4_set_phy(dram, params, phy_fn, &dfs_cfgs_lpddr4[ctl_fn]); + lpddr4_set_ctl(dram, params, ctl_fn, + dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq); - if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) - printf("%s: change freq to %d mhz %d, %d\n", __func__, - dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq, - ctl_fn, phy_fn); - } + if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) + printf("%s: change freq to %dMHz %d, %d\n", __func__, + dfs_cfgs_lpddr4[ctl_fn].base.ddr_freq / MHz, + ctl_fn, phy_fn); return 0; } + #endif /* CONFIG_RAM_RK3399_LPDDR4 */ /* CS0,n=1 @@ -2955,6 +2955,12 @@ static int sdram_init(struct dram_info *dram, params->ch[ch].cap_info.rank = rank; } +#if defined(CONFIG_RAM_RK3399_LPDDR4) + /* LPDDR4 needs to be trained at 400MHz */ + lpddr4_set_rate(dram, params, 0); + params->base.ddr_freq = dfs_cfgs_lpddr4[0].base.ddr_freq / MHz; +#endif + params->base.num_channels = 0; for (channel = 0; channel < 2; channel++) { const struct chan_info *chan = &dram->chan[channel]; @@ -2964,8 +2970,6 @@ static int sdram_init(struct dram_info *dram, if (cap_info->rank == 0) { clear_channel_params(params, 1); continue; - } else { - params->base.num_channels++; } if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) { @@ -2991,6 +2995,8 @@ static int sdram_init(struct dram_info *dram, printf("no ddrconfig find, Cap not support!\n"); continue; } + + params->base.num_channels++; set_ddrconfig(chan, params, channel, cap_info->ddrconfig); set_cap_relate_config(chan, params, channel); } @@ -3005,7 +3011,9 @@ static int sdram_init(struct dram_info *dram, params->base.stride = calculate_stride(params); dram_all_config(dram, params); - dram->ops->set_rate_index(dram, params); + ret = dram->ops->set_rate_index(dram, params, 1); + if (ret) + return ret; debug("Finish SDRAM initialization...\n"); return 0; diff --git a/drivers/spi/renesas_rpc_spi.c b/drivers/spi/renesas_rpc_spi.c index 26b6aa85c92..cb2b8fb64de 100644 --- a/drivers/spi/renesas_rpc_spi.c +++ b/drivers/spi/renesas_rpc_spi.c @@ -449,13 +449,8 @@ static const struct dm_spi_ops rpc_spi_ops = { }; static const struct udevice_id rpc_spi_ids[] = { - { .compatible = "renesas,rpc-r7s72100" }, - { .compatible = "renesas,rpc-r8a7795" }, - { .compatible = "renesas,rpc-r8a7796" }, - { .compatible = "renesas,rpc-r8a77965" }, - { .compatible = "renesas,rpc-r8a77970" }, - { .compatible = "renesas,rpc-r8a77995" }, - { .compatible = "renesas,rcar-gen3-rpc" }, + { .compatible = "renesas,r7s72100-rpc-if" }, + { .compatible = "renesas,rcar-gen3-rpc-if" }, { } }; diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index a0acffa4b07..03f7fdd5978 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -113,6 +113,7 @@ config SYSRESET_PSCI config SYSRESET_SBI bool "Enable support for SBI System Reset" depends on RISCV_SMODE && SBI_V02 + default y select SYSRESET_CMD_POWEROFF if CMD_POWEROFF help Enable system reset and poweroff via the SBI system reset extension. diff --git a/drivers/tpm/cr50_i2c.c b/drivers/tpm/cr50_i2c.c index f8c30878947..acf4c7859a9 100644 --- a/drivers/tpm/cr50_i2c.c +++ b/drivers/tpm/cr50_i2c.c @@ -13,11 +13,13 @@ #include <irq.h> #include <log.h> #include <spl.h> +#include <tpm-common.h> #include <tpm-v2.h> #include <acpi/acpigen.h> #include <acpi/acpi_device.h> #include <asm/gpio.h> #include <asm/io.h> +#include <asm/unaligned.h> #include <linux/delay.h> #include <dm/acpi.h> @@ -37,6 +39,50 @@ enum { CR50_MAX_BUF_SIZE = 63, }; +/* + * Operations specific to the Cr50 TPM used on Chromium OS and Android devices + * + * FIXME: below is not enough to differentiate between vendors commands + * of numerous devices. However, the current tpm2 APIs aren't very amenable + * to extending generically because the marshaling code is assuming all + * knowledge of all commands. + */ +#define TPM2_CC_VENDOR_BIT_MASK 0x20000000 + +#define TPM2_CR50_VENDOR_COMMAND (TPM2_CC_VENDOR_BIT_MASK | 0) +#define TPM2_CR50_SUB_CMD_IMMEDIATE_RESET 19 +#define TPM2_CR50_SUB_CMD_NVMEM_ENABLE_COMMITS 21 +#define TPM2_CR50_SUB_CMD_REPORT_TPM_STATE 23 +#define TPM2_CR50_SUB_CMD_TURN_UPDATE_ON 24 +#define TPM2_CR50_SUB_CMD_GET_REC_BTN 29 +#define TPM2_CR50_SUB_CMD_TPM_MODE 40 +#define TPM2_CR50_SUB_CMD_GET_BOOT_MODE 52 +#define TPM2_CR50_SUB_CMD_RESET_EC 53 + +/* Cr50 vendor-specific error codes. */ +#define VENDOR_RC_ERR 0x00000500 +enum cr50_vendor_rc { + VENDOR_RC_INTERNAL_ERROR = (VENDOR_RC_ERR | 6), + VENDOR_RC_NO_SUCH_SUBCOMMAND = (VENDOR_RC_ERR | 8), + VENDOR_RC_NO_SUCH_COMMAND = (VENDOR_RC_ERR | 127), +}; + +enum cr50_tpm_mode { + /* + * Default state: TPM is enabled, and may be set to either + * TPM_MODE_ENABLED or TPM_MODE_DISABLED. + */ + TPM_MODE_ENABLED_TENTATIVE = 0, + + /* TPM is enabled, and mode may not be changed. */ + TPM_MODE_ENABLED = 1, + + /* TPM is disabled, and mode may not be changed. */ + TPM_MODE_DISABLED = 2, + + TPM_MODE_INVALID, +}; + /** * struct cr50_priv - Private driver data * @@ -54,6 +100,41 @@ struct cr50_priv { bool use_irq; }; +/* + * The below structure represents the body of the response to the 'report tpm + * state' vendor command. + * + * It is transferred over the wire, so it needs to be serialized/deserialized, + * and it is likely to change, so its contents must be versioned. + */ +#define TPM_STATE_VERSION 1 +struct tpm_vendor_state { + u32 version; + /* + * The following three fields are set by the TPM in case of an assert. + * There is no other processing than setting the source code line + * number, error code and the first 4 characters of the function name. + * + * We don't expect this happening, but it is included in the report + * just in case. + */ + u32 fail_line; /* s_failLIne */ + u32 fail_code; /* s_failCode */ + char func_name[4]; /* s_failFunction, limited to 4 chars */ + + /* + * The following two fields are the current time filtered value of the + * 'failed tries' TPM counter, and the maximum allowed value of the + * counter. + * + * failed_tries == max_tries is the definition of the TPM lockout + * condition. + */ + u32 failed_tries; /* gp.failedTries */ + u32 max_tries; /* gp.maxTries */ + /* The below fields are present in version 2 and above */ +}; + /* Wait for interrupt to indicate TPM is ready */ static int cr50_i2c_wait_tpm_ready(struct udevice *dev) { @@ -573,6 +654,87 @@ static int cr50_i2c_get_desc(struct udevice *dev, char *buf, int size) return len; } +static int stringify_state(char *buf, int len, char *str, size_t max_size) +{ + struct tpm_vendor_state state; + size_t text_size = 0; + + state.version = get_unaligned_be32(buf + + offsetof(struct tpm_vendor_state, version)); + state.fail_line = get_unaligned_be32(buf + + offsetof(struct tpm_vendor_state, fail_line)); + state.fail_code = get_unaligned_be32(buf + + offsetof(struct tpm_vendor_state, fail_code)); + memcpy(state.func_name, + buf + offsetof(struct tpm_vendor_state, func_name), + sizeof(state.func_name)); + state.failed_tries = get_unaligned_be32(buf + + offsetof(struct tpm_vendor_state, failed_tries)); + state.max_tries = get_unaligned_be32(buf + + offsetof(struct tpm_vendor_state, max_tries)); + + text_size += snprintf(str + text_size, max_size - text_size, + "v=%d", state.version); + if (text_size >= max_size) + return -ENOSPC; + + if (state.version > TPM_STATE_VERSION) + text_size += snprintf(str + text_size, + max_size - text_size, + " not fully supported\n"); + if (text_size >= max_size) + return -ENOSPC; + + if (state.version == 0) + return -EINVAL; /* This should never happen */ + + text_size += snprintf(str + text_size, + max_size - text_size, + " failed_tries=%d max_tries=%d\n", + state.failed_tries, state.max_tries); + if (text_size >= max_size) + return -ENOSPC; + + if (state.fail_line) { + /* make sure function name is zero terminated. */ + char func_name[sizeof(state.func_name) + 1]; + + memcpy(func_name, state.func_name, sizeof(state.func_name)); + func_name[sizeof(state.func_name)] = '\0'; + + text_size += snprintf(str + text_size, + max_size - text_size, + "tpm failed: f %s line %d code %d", + func_name, + state.fail_line, + state.fail_code); + if (text_size >= max_size) + return -ENOSPC; + } + + return 0; +} + +static int cr50_i2c_report_state(struct udevice *dev, char *str, int str_max) +{ + char buf[50]; + size_t buf_size = sizeof(buf); + int ret; + + ret = tpm2_report_state(dev, TPM2_CR50_VENDOR_COMMAND, + TPM2_CR50_SUB_CMD_REPORT_TPM_STATE, + buf, &buf_size); + if (ret) + return ret; + + /* TPM responded as expected */ + ret = stringify_state(buf, buf_size, str, str_max); + if (ret) + return ret; + + return 0; +} + static int cr50_i2c_open(struct udevice *dev) { char buf[80]; @@ -730,6 +892,7 @@ struct acpi_ops cr50_acpi_ops = { static const struct tpm_ops cr50_i2c_ops = { .open = cr50_i2c_open, .get_desc = cr50_i2c_get_desc, + .report_state = cr50_i2c_report_state, .send = cr50_i2c_send, .recv = cr50_i2c_recv, .cleanup = cr50_i2c_cleanup, diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c index 0eb35f50c4e..5ff0cd3958c 100644 --- a/drivers/tpm/tpm-uclass.c +++ b/drivers/tpm/tpm-uclass.c @@ -49,6 +49,16 @@ int tpm_get_desc(struct udevice *dev, char *buf, int size) return ops->get_desc(dev, buf, size); } +int tpm_report_state(struct udevice *dev, char *buf, int size) +{ + struct tpm_ops *ops = tpm_get_ops(dev); + + if (!ops->report_state) + return -ENOSYS; + + return ops->report_state(dev, buf, size); +} + /* Returns max number of milliseconds to wait */ static ulong tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip_priv *priv, u32 ordinal) diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c index ac6eb143539..dd94bdc31fb 100644 --- a/drivers/tpm/tpm2_tis_sandbox.c +++ b/drivers/tpm/tpm2_tis_sandbox.c @@ -366,8 +366,10 @@ static int sandbox_tpm2_check_readyness(struct udevice *dev, int command) break; default: - if (!tpm->tests_done) - return TPM2_RC_NEEDS_TEST; + /* Skip this, since the startup may have happened in SPL + * if (!tpm->tests_done) + * return TPM2_RC_NEEDS_TEST; + */ break; } @@ -793,6 +795,16 @@ static int sandbox_tpm2_get_desc(struct udevice *dev, char *buf, int size) return snprintf(buf, size, "Sandbox TPM2.x"); } +static int sandbox_tpm2_report_state(struct udevice *dev, char *buf, int size) +{ + struct sandbox_tpm2 *priv = dev_get_priv(dev); + + if (size < 40) + return -ENOSPC; + + return snprintf(buf, size, "init_done=%d", priv->init_done); +} + static int sandbox_tpm2_open(struct udevice *dev) { struct sandbox_tpm2 *tpm = dev_get_priv(dev); @@ -832,6 +844,7 @@ static const struct tpm_ops sandbox_tpm2_ops = { .open = sandbox_tpm2_open, .close = sandbox_tpm2_close, .get_desc = sandbox_tpm2_get_desc, + .report_state = sandbox_tpm2_report_state, .xfer = sandbox_tpm2_xfer, }; diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 8ba55aab9f8..d0e92c7a071 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -119,6 +119,7 @@ static struct usb_descriptor_header *fb_fs_function[] = { (struct usb_descriptor_header *)&interface_desc, (struct usb_descriptor_header *)&fs_ep_in, (struct usb_descriptor_header *)&fs_ep_out, + NULL, }; static struct usb_descriptor_header *fb_hs_function[] = { diff --git a/include/configs/kontron_sl28.h b/include/configs/kontron_sl28.h index 38063ba4842..df46e586f35 100644 --- a/include/configs/kontron_sl28.h +++ b/include/configs/kontron_sl28.h @@ -37,8 +37,6 @@ /* serial port */ #define CONFIG_SYS_NS16550_CLK (get_bus_freq(0) / 2) -#define COUNTER_FREQUENCY_REAL (get_board_sys_clk() / 4) - /* SPL */ #define CONFIG_SYS_MONITOR_LEN (1024 * 1024) diff --git a/include/dt-bindings/clock/sifive-fu740-prci.h b/include/dt-bindings/clock/sifive-fu740-prci.h index c1224783c08..672bdadbf6c 100644 --- a/include/dt-bindings/clock/sifive-fu740-prci.h +++ b/include/dt-bindings/clock/sifive-fu740-prci.h @@ -1,10 +1,9 @@ -/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ /* - * Copyright (C) 2020-2021 SiFive, Inc. + * Copyright (C) 2019 SiFive, Inc. * Wesley Terpstra * Paul Walmsley * Zong Li - * Pragnesh Patel */ #ifndef __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H @@ -12,14 +11,14 @@ /* Clock indexes for use by Device Tree data and the PRCI driver */ -#define PRCI_CLK_COREPLL 0 -#define PRCI_CLK_DDRPLL 1 -#define PRCI_CLK_GEMGXLPLL 2 -#define PRCI_CLK_DVFSCOREPLL 3 -#define PRCI_CLK_HFPCLKPLL 4 -#define PRCI_CLK_CLTXPLL 5 -#define PRCI_CLK_TLCLK 6 -#define PRCI_CLK_PCLK 7 -#define PRCI_CLK_PCIEAUX 8 +#define FU740_PRCI_CLK_COREPLL 0 +#define FU740_PRCI_CLK_DDRPLL 1 +#define FU740_PRCI_CLK_GEMGXLPLL 2 +#define FU740_PRCI_CLK_DVFSCOREPLL 3 +#define FU740_PRCI_CLK_HFPCLKPLL 4 +#define FU740_PRCI_CLK_CLTXPLL 5 +#define FU740_PRCI_CLK_TLCLK 6 +#define FU740_PRCI_CLK_PCLK 7 +#define FU740_PRCI_CLK_PCIE_AUX 8 -#endif +#endif /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */ diff --git a/include/efi_api.h b/include/efi_api.h index 83c01085fde..9bb0d44ac8d 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -226,6 +226,22 @@ enum efi_reset_type { EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \ 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a) +#define EFI_CONFORMANCE_PROFILES_TABLE_GUID \ + EFI_GUID(0x36122546, 0xf7ef, 0x4c8f, 0xbd, 0x9b, \ + 0xeb, 0x85, 0x25, 0xb5, 0x0c, 0x0b) + +#define EFI_CONFORMANCE_PROFILES_TABLE_VERSION 1 + +#define EFI_CONFORMANCE_PROFILE_EBBR_2_0_GUID \ + EFI_GUID(0xcce33c35, 0x74ac, 0x4087, 0xbc, 0xe7, \ + 0x8b, 0x29, 0xb0, 0x2e, 0xeb, 0x27) + +struct efi_conformance_profiles_table { + u16 version; + u16 number_of_profiles; + efi_guid_t conformance_profiles[]; +} __packed; + struct efi_capsule_header { efi_guid_t capsule_guid; u32 header_size; diff --git a/include/efi_loader.h b/include/efi_loader.h index b0d6fff67c5..545ba06d946 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -531,8 +531,10 @@ void efi_carve_out_dt_rsv(void *fdt); void efi_try_purge_kaslr_seed(void *fdt); /* Called by bootefi to make console interface available */ efi_status_t efi_console_register(void); -/* Called by efi_init_obj_list() to initialize efi_disks */ +/* Called by efi_init_early() to add block devices when probed */ efi_status_t efi_disk_init(void); +/* Called by efi_init_obj_list() to proble all block devices */ +efi_status_t efi_disks_register(void); /* Called by efi_init_obj_list() to install EFI_RNG_PROTOCOL */ efi_status_t efi_rng_register(void); /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ @@ -1051,6 +1053,13 @@ extern u8 num_image_type_guids; efi_status_t efi_esrt_register(void); /** + * efi_ecpt_register() - Install the ECPT system table. + * + * Return: status code + */ +efi_status_t efi_ecpt_register(void); + +/** * efi_esrt_populate() - Populates the ESRT entries from the FMP instances * present in the system. * If an ESRT already exists, the old ESRT is replaced in the system table. diff --git a/include/tpm-common.h b/include/tpm-common.h index a28629e7013..b2c5404430f 100644 --- a/include/tpm-common.h +++ b/include/tpm-common.h @@ -120,6 +120,16 @@ struct tpm_ops { int (*get_desc)(struct udevice *dev, char *buf, int size); /** + * report_state() - Collect information about the current TPM state + * + * @dev: Device to check + * @buf: Buffer to put the string + * @size: Maximum size of buffer + * Return: return code of the operation (0 = success) + */ + int (*report_state)(struct udevice *dev, char *buf, int size); + + /** * send() - send data to the TPM * * @dev: Device to talk to @@ -235,6 +245,16 @@ u32 tpm_clear_and_reenable(struct udevice *dev); int tpm_get_desc(struct udevice *dev, char *buf, int size); /** + * tpm_report_state() - Collect information about the current TPM state + * + * @dev: Device to check + * @buf: Buffer to put the string + * @size: Maximum size of buffer + * Return: return code of the operation (0 = success) + */ +int tpm_report_state(struct udevice *dev, char *buf, int size); + +/** * tpm_xfer() - send data to the TPM and get response * * This first uses the device's send() method to send the bytes. Then it calls diff --git a/include/tpm-v2.h b/include/tpm-v2.h index e79c90b9395..737e57551d7 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -658,4 +658,34 @@ u32 tpm2_disable_platform_hierarchy(struct udevice *dev); u32 tpm2_submit_command(struct udevice *dev, const u8 *sendbuf, u8 *recvbuf, size_t *recv_size); +/** + * tpm_cr50_report_state() - Report the Cr50 internal state + * + * @dev: TPM device + * @vendor_cmd: Vendor command number to send + * @vendor_subcmd: Vendor sub-command number to send + * @recvbuf: Buffer to save the response to + * @recv_size: Pointer to the size of the response buffer + * Return: result of the operation + */ +u32 tpm2_report_state(struct udevice *dev, uint vendor_cmd, uint vendor_subcmd, + u8 *recvbuf, size_t *recv_size); + +/** + * tpm2_enable_nvcommits() - Tell TPM to commit NV data immediately + * + * For Chromium OS verified boot, we may reboot or reset at different times, + * possibly leaving non-volatile data unwritten by the TPM. + * + * This vendor command is used to indicate that non-volatile data should be + * written to its store immediately. + * + * @dev TPM device + * @vendor_cmd: Vendor command number to send + * @vendor_subcmd: Vendor sub-command number to send + * Return: result of the operation + */ +u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd, + uint vendor_subcmd); + #endif /* __TPM_V2_H */ diff --git a/include/tpm_api.h b/include/tpm_api.h index 11aa14eb793..8979d9d6df7 100644 --- a/include/tpm_api.h +++ b/include/tpm_api.h @@ -81,14 +81,16 @@ u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data, * * @param dev TPM device * @param index index of the PCR - * @param in_digest 160-bit value representing the event to be + * @param in_digest 160/256-bit value representing the event to be * recorded - * @param out_digest 160-bit PCR value after execution of the + * @param size size of digest in bytes + * @param out_digest 160/256-bit PCR value after execution of the * command + * @param name digest source, used for log output * Return: return code of the operation */ u32 tpm_pcr_extend(struct udevice *dev, u32 index, const void *in_digest, - void *out_digest); + uint size, void *out_digest, const char *name); /** * Issue a TPM_PCRRead command. diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 5cfff8c56bc..b8fb2701a74 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -385,6 +385,23 @@ config EFI_ESRT help Enabling this option creates the ESRT UEFI system table. +config EFI_ECPT + bool "Enable the UEFI ECPT generation" + default y + help + Enabling this option created the ECPT UEFI table. + +config EFI_EBBR_2_0_CONFORMANCE + bool "Add the EBBRv2.0 conformance entry to the ECPT table" + depends on EFI_ECPT + depends on EFI_LOADER_HII + depends on EFI_RISCV_BOOT_PROTOCOL || !RISCV + depends on EFI_RNG_PROTOCOL || !DM_RNG + depends on EFI_UNICODE_COLLATION_PROTOCOL2 + default y + help + Enabling this option adds the EBBRv2.0 conformance entry to the ECPT UEFI table. + config EFI_RISCV_BOOT_PROTOCOL bool "RISCV_EFI_BOOT_PROTOCOL support" default y diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index f54c244c326..e187d2a914f 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -76,6 +76,7 @@ obj-$(CONFIG_EFI_TCG2_PROTOCOL) += efi_tcg2.o 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 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/efi_conformance.c b/lib/efi_loader/efi_conformance.c new file mode 100644 index 00000000000..a49aae92497 --- /dev/null +++ b/lib/efi_loader/efi_conformance.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * EFI conformance profile table + * + * Copyright (C) 2022 Arm Ltd. + */ + +#include <common.h> +#include <efi_loader.h> +#include <log.h> +#include <efi_api.h> +#include <malloc.h> + +static const efi_guid_t efi_ecpt_guid = EFI_CONFORMANCE_PROFILES_TABLE_GUID; +static const efi_guid_t efi_ebbr_2_0_guid = + EFI_CONFORMANCE_PROFILE_EBBR_2_0_GUID; + +/** + * efi_ecpt_register() - Install the ECPT system table. + * + * Return: status code + */ +efi_status_t efi_ecpt_register(void) +{ + int num_entries = 0; + struct efi_conformance_profiles_table *ecpt; + efi_status_t ret; + size_t ecpt_size; + + ecpt_size = num_entries * sizeof(efi_guid_t) + + sizeof(struct efi_conformance_profiles_table); + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, ecpt_size, + (void **)&ecpt); + + if (ret != EFI_SUCCESS) { + log_err("Out of memory\n"); + + return ret; + } + + if (CONFIG_IS_ENABLED(EFI_EBBR_2_0_CONFORMANCE)) + guidcpy(&ecpt->conformance_profiles[num_entries++], + &efi_ebbr_2_0_guid); + + ecpt->version = EFI_CONFORMANCE_PROFILES_TABLE_VERSION; + ecpt->number_of_profiles = num_entries; + + /* Install the ECPT in the system configuration table. */ + ret = efi_install_configuration_table(&efi_ecpt_guid, (void *)ecpt); + if (ret != EFI_SUCCESS) { + log_err("Failed to install ECPT\n"); + efi_free_pool(ecpt); + + return ret; + } + + log_debug("ECPT created\n"); + + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 3164fd484e2..ee9dc6bbd82 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -987,12 +987,14 @@ static efi_status_t EFIAPI efi_cin_read_key_stroke_ex( efi_cin_check(); if (!key_available) { + memset(key_data, 0, sizeof(struct efi_key_data)); ret = EFI_NOT_READY; goto out; } /* * CTRL+A - CTRL+Z have to be signaled as a - z. * SHIFT+CTRL+A - SHIFT+CTRL+Z have to be signaled as A - Z. + * CTRL+\ - CTRL+_ have to be signaled as \ - _. */ switch (next_key.key.unicode_char) { case 0x01 ... 0x07: @@ -1005,6 +1007,9 @@ static efi_status_t EFIAPI efi_cin_read_key_stroke_ex( next_key.key.unicode_char += 0x40; else next_key.key.unicode_char += 0x60; + break; + case 0x1c ... 0x1f: + next_key.key.unicode_char += 0x40; } *key_data = next_key; key_available = false; diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index 6c428ee061f..9062058ac22 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -190,13 +190,14 @@ static char *dp_msging(char *s, struct efi_device_path *dp) struct efi_device_path_nvme *ndp = (struct efi_device_path_nvme *)dp; u32 ns_id; - int i; memcpy(&ns_id, &ndp->ns_id, sizeof(ns_id)); s += sprintf(s, "NVMe(0x%x,", ns_id); - for (i = 0; i < sizeof(ndp->eui64); ++i) + + /* Display byte 7 first, byte 0 last */ + for (int i = 0; i < 8; ++i) s += sprintf(s, "%s%02x", i ? "-" : "", - ndp->eui64[i]); + ndp->eui64[i ^ 7]); s += sprintf(s, ")"); break; diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index f269abf1354..5feeb52ccb4 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -760,3 +760,20 @@ efi_status_t efi_disk_init(void) return EFI_SUCCESS; } + +/** + * efi_disks_register() - ensure all block devices are available in UEFI + * + * The function probes all block devices. As we store UEFI variables on the + * EFI system partition this function has to be called before enabling + * variable services. + */ +efi_status_t efi_disks_register(void) +{ + struct udevice *dev; + + uclass_foreach_dev_probe(UCLASS_BLK, dev) { + } + + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 751beda5902..c633fcd91e3 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -246,6 +246,14 @@ efi_status_t efi_init_obj_list(void) /* Set up console modes */ efi_setup_console_size(); + /* + * Probe block devices to find the ESP. + * efi_disks_register() must be called before efi_init_variables(). + */ + ret = efi_disks_register(); + if (ret != EFI_SUCCESS) + goto out; + /* Initialize variable services */ ret = efi_init_variables(); if (ret != EFI_SUCCESS) @@ -266,6 +274,12 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + if (IS_ENABLED(CONFIG_EFI_ECPT)) { + ret = efi_ecpt_register(); + if (ret != EFI_SUCCESS) + goto out; + } + if (IS_ENABLED(CONFIG_EFI_ESRT)) { ret = efi_esrt_register(); if (ret != EFI_SUCCESS) diff --git a/lib/efi_loader/helloworld.c b/lib/efi_loader/helloworld.c index 10666dc0f22..d565f327457 100644 --- a/lib/efi_loader/helloworld.c +++ b/lib/efi_loader/helloworld.c @@ -29,24 +29,66 @@ static struct efi_system_table *systable; static struct efi_boot_services *boottime; static struct efi_simple_text_output_protocol *con_out; +/* + * Print an unsigned 32bit value as decimal number to an u16 string + * + * @value: value to be printed + * @buf: pointer to buffer address + * on return position of terminating zero word + */ +static void uint2dec(u32 value, u16 **buf) +{ + u16 *pos = *buf; + int i; + u16 c; + u64 f; + + /* + * Increment by .5 and multiply with + * (2 << 60) / 1,000,000,000 = 0x44B82FA0.9B5A52CC + * to move the first digit to bit 60-63. + */ + f = 0x225C17D0; + f += (0x9B5A52DULL * value) >> 28; + f += 0x44B82FA0ULL * value; + + for (i = 0; i < 10; ++i) { + /* Write current digit */ + c = f >> 60; + if (c || pos != *buf) + *pos++ = c + '0'; + /* Eliminate current digit */ + f &= 0xfffffffffffffff; + /* Get next digit */ + f *= 0xaULL; + } + if (pos == *buf) + *pos++ = '0'; + *pos = 0; + *buf = pos; +} + /** * print_uefi_revision() - print UEFI revision number */ static void print_uefi_revision(void) { - u16 rev[] = u"0.0.0"; - - rev[0] = (systable->hdr.revision >> 16) + '0'; - rev[4] = systable->hdr.revision & 0xffff; - for (; rev[4] >= 10;) { - rev[4] -= 10; - ++rev[2]; + u16 rev[13] = {0}; + u16 *buf = rev; + u16 digit; + + uint2dec(systable->hdr.revision >> 16, &buf); + *buf++ = '.'; + uint2dec(systable->hdr.revision & 0xffff, &buf); + + /* Minor revision is only to be shown if non-zero */ + digit = *--buf; + if (digit == '0') { + *buf = 0; + } else { + *buf++ = '.'; + *buf = digit; } - /* Third digit is only to be shown if non-zero */ - if (rev[4]) - rev[4] += '0'; - else - rev[3] = 0; con_out->output_string(con_out, u"Running on UEFI "); con_out->output_string(con_out, rev); diff --git a/lib/efi_selftest/efi_selftest_miniapp_exception.c b/lib/efi_selftest/efi_selftest_miniapp_exception.c index 79f9a67859b..a9ad381001f 100644 --- a/lib/efi_selftest/efi_selftest_miniapp_exception.c +++ b/lib/efi_selftest/efi_selftest_miniapp_exception.c @@ -9,6 +9,7 @@ #include <common.h> #include <efi_api.h> +#include <host_arch.h> /* * Entry point of the EFI application. @@ -33,11 +34,17 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle, asm volatile (".word 0xe7f7defb\n"); #elif defined(CONFIG_RISCV) asm volatile (".word 0xffffffff\n"); +#elif defined(CONFIG_X86) + asm volatile (".word 0xffff\n"); #elif defined(CONFIG_SANDBOX) +#if (HOST_ARCH == HOST_ARCH_ARM || HOST_ARCH == HOST_ARCH_AARCH64) + asm volatile (".word 0xe7f7defb\n"); +#elif (HOST_ARCH == HOST_ARCH_RISCV32 || HOST_ARCH == HOST_ARCH_RISCV64) asm volatile (".word 0xffffffff\n"); -#elif defined(CONFIG_X86) +#elif (HOST_ARCH == HOST_ARCH_X86 || HOST_ARCH == HOST_ARCH_X86_64) asm volatile (".word 0xffff\n"); #endif +#endif con_out->output_string(con_out, u"Exception not triggered.\n"); return EFI_ABORTED; } diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c index 22a769c5874..d0e3ab1b21d 100644 --- a/lib/tpm-v1.c +++ b/lib/tpm-v1.c @@ -456,12 +456,13 @@ u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm) 0x0, 0x0, 0x0, 0x4, }; const size_t index_offset = 18; - const size_t perm_offset = 60; + const size_t perm_offset = 74; u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); u32 err; - if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command), + if (pack_byte_string(buf, sizeof(buf), "sd", + 0, command, sizeof(command), index_offset, index)) return TPM_LIB_ERROR; err = tpm_sendrecv_command(dev, buf, response, &response_length); diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 1bf627853af..697b982e079 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -89,14 +89,18 @@ u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index, * Calculate the offset of the nv_policy piece by adding each of the * chunks below. */ - uint offset = 10 + 8 + 13 + 14; + const int platform_len = sizeof(u32); + const int session_hdr_len = 13; + const int message_len = 14; + uint offset = TPM2_HDR_LEN + platform_len + session_hdr_len + + message_len; u8 command_v2[COMMAND_BUFFER_SIZE] = { /* header 10 bytes */ tpm_u16(TPM2_ST_SESSIONS), /* TAG */ - tpm_u32(offset + nv_policy_size),/* Length */ + tpm_u32(offset + nv_policy_size + 2),/* Length */ tpm_u32(TPM2_CC_NV_DEFINE_SPACE),/* Command code */ - /* handles 8 bytes */ + /* handles 4 bytes */ tpm_u32(TPM2_RH_PLATFORM), /* Primary platform seed */ /* session header 13 bytes */ @@ -107,12 +111,15 @@ u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index, tpm_u16(0), /* auth_size */ /* message 14 bytes + policy */ - tpm_u16(12 + nv_policy_size), /* size */ + tpm_u16(message_len + nv_policy_size), /* size */ tpm_u32(space_index), tpm_u16(TPM2_ALG_SHA256), tpm_u32(nv_attributes), tpm_u16(nv_policy_size), - /* nv_policy */ + /* + * nv_policy + * space_size + */ }; int ret; @@ -120,8 +127,9 @@ u32 tpm2_nv_define_space(struct udevice *dev, u32 space_index, * Fill the command structure starting from the first buffer: * - the password (if any) */ - ret = pack_byte_string(command_v2, sizeof(command_v2), "s", - offset, nv_policy, nv_policy_size); + ret = pack_byte_string(command_v2, sizeof(command_v2), "sw", + offset, nv_policy, nv_policy_size, + offset + nv_policy_size, space_size); if (ret) return TPM_LIB_ERROR; @@ -157,6 +165,8 @@ u32 tpm2_pcr_extend(struct udevice *dev, u32 index, u32 algorithm, }; int ret; + if (!digest) + return -EINVAL; /* * Fill the command structure starting from the first buffer: * - the digest @@ -669,3 +679,49 @@ u32 tpm2_submit_command(struct udevice *dev, const u8 *sendbuf, { return tpm_sendrecv_command(dev, sendbuf, recvbuf, recv_size); } + +u32 tpm2_report_state(struct udevice *dev, uint vendor_cmd, uint vendor_subcmd, + u8 *recvbuf, size_t *recv_size) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + /* header 10 bytes */ + tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ + tpm_u32(10 + 2), /* Length */ + tpm_u32(vendor_cmd), /* Command code */ + + tpm_u16(vendor_subcmd), + }; + int ret; + + ret = tpm_sendrecv_command(dev, command_v2, recvbuf, recv_size); + log_debug("ret=%s, %x\n", dev->name, ret); + if (ret) + return ret; + if (*recv_size < 12) + return -ENODATA; + *recv_size -= 12; + memcpy(recvbuf, recvbuf + 12, *recv_size); + + return 0; +} + +u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd, + uint vendor_subcmd) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + /* header 10 bytes */ + tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ + tpm_u32(10 + 2), /* Length */ + tpm_u32(vendor_cmd), /* Command code */ + + tpm_u16(vendor_subcmd), + }; + int ret; + + ret = tpm_sendrecv_command(dev, command_v2, NULL, NULL); + log_debug("ret=%s, %x\n", dev->name, ret); + if (ret) + return ret; + + return 0; +} diff --git a/lib/tpm_api.c b/lib/tpm_api.c index 032f383ca04..7e8df8795ef 100644 --- a/lib/tpm_api.c +++ b/lib/tpm_api.c @@ -140,15 +140,17 @@ u32 tpm_write_lock(struct udevice *dev, u32 index) } u32 tpm_pcr_extend(struct udevice *dev, u32 index, const void *in_digest, - void *out_digest) + uint size, void *out_digest, const char *name) { - if (tpm_is_v1(dev)) + if (tpm_is_v1(dev)) { return tpm1_extend(dev, index, in_digest, out_digest); - else if (tpm_is_v2(dev)) + } else if (tpm_is_v2(dev)) { return tpm2_pcr_extend(dev, index, TPM2_ALG_SHA256, in_digest, TPM2_DIGEST_LEN); - else + /* @name is ignored as we do not support the TPM log here */ + } else { return -ENOSYS; + } } u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count) diff --git a/lib/uuid.c b/lib/uuid.c index 284f8113ff8..465e1ac38f5 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -220,6 +220,10 @@ static const struct { "TCG2 Final Events Table", EFI_TCG2_FINAL_EVENTS_TABLE_GUID, }, + { + "EFI Conformance Profiles Table", + EFI_CONFORMANCE_PROFILES_TABLE_GUID, + }, #ifdef CONFIG_EFI_RISCV_BOOT_PROTOCOL { "RISC-V Boot", diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index c5e8942a76a..f505722f6b0 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -654,12 +654,7 @@ CONFIG_SYS_FM1_DTSEC4_RISER_PHY_ADDR CONFIG_SYS_FM1_DTSEC5_PHY_ADDR CONFIG_SYS_FM1_QSGMII11_PHY_ADDR CONFIG_SYS_FM1_QSGMII21_PHY_ADDR -CONFIG_SYS_FM2_10GEC1_PHY_ADDR CONFIG_SYS_FM2_CLK -CONFIG_SYS_FM2_DTSEC1_PHY_ADDR -CONFIG_SYS_FM2_DTSEC2_PHY_ADDR -CONFIG_SYS_FM2_DTSEC3_PHY_ADDR -CONFIG_SYS_FM2_DTSEC4_PHY_ADDR CONFIG_SYS_FM_MURAM_SIZE CONFIG_SYS_FPGAREG_DIPSW CONFIG_SYS_FPGAREG_FREQ diff --git a/test/dm/Makefile b/test/dm/Makefile index 52fe178a828..7543df8823c 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -107,6 +107,7 @@ obj-$(CONFIG_SYSINFO_GPIO) += sysinfo-gpio.o obj-$(CONFIG_UT_DM) += tag.o obj-$(CONFIG_TEE) += tee.o obj-$(CONFIG_TIMER) += timer.o +obj-$(CONFIG_TPM_V2) += tpm.o obj-$(CONFIG_DM_USB) += usb.o obj-$(CONFIG_DM_VIDEO) += video.o ifeq ($(CONFIG_VIRTIO_SANDBOX),y) diff --git a/test/dm/tpm.c b/test/dm/tpm.c new file mode 100644 index 00000000000..0b46f799591 --- /dev/null +++ b/test/dm/tpm.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <common.h> +#include <dm.h> +#include <tpm_api.h> +#include <dm/test.h> +#include <test/test.h> +#include <test/ut.h> + +/* Basic test of the TPM uclass */ +static int dm_test_tpm(struct unit_test_state *uts) +{ + struct udevice *dev; + char buf[50]; + + /* check probe success */ + ut_assertok(uclass_first_device_err(UCLASS_TPM, &dev)); + ut_assert(tpm_is_v2(dev)); + + ut_assert(tpm_report_state(dev, buf, sizeof(buf))); + ut_asserteq_str("init_done=0", buf); + + ut_assertok(tpm_init(dev)); + + ut_assert(tpm_report_state(dev, buf, sizeof(buf))); + ut_asserteq_str("init_done=1", buf); + + return 0; +} +DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT); diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst index b3613d7cbd0..18bd328c5cd 100644 --- a/tools/binman/entries.rst +++ b/tools/binman/entries.rst @@ -1175,6 +1175,9 @@ Properties / Entry arguments: - args: Arguments to pass - data-to-imagename: Indicates that the -d data should be passed in as the image name also (-n) + - multiple-data-files: boolean to tell binman to pass all files as + datafiles to mkimage instead of creating a temporary file the result + of datafiles concatenation The data passed to mkimage via the -d flag is collected from subnodes of the mkimage node, e.g.:: @@ -1205,6 +1208,25 @@ a section, or just multiple subnodes like this:: }; }; +To pass all datafiles untouched to mkimage:: + + mkimage { + args = "-n rk3399 -T rkspi"; + multiple-data-files; + + u-boot-tpl { + }; + + u-boot-spl { + }; + }; + +This calls mkimage to create a Rockchip RK3399-specific first stage +bootloader, made of TPL+SPL. Since this first stage bootloader requires to +align the TPL and SPL but also some weird hacks that is handled by mkimage +directly, binman is told to not perform the concatenation of datafiles prior +to passing the data to mkimage. + To use CONFIG options in the arguments, use a string list instead, as in this example which also produces four arguments:: diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py index ddbd9cec658..c2288c48eef 100644 --- a/tools/binman/etype/mkimage.py +++ b/tools/binman/etype/mkimage.py @@ -18,11 +18,16 @@ class Entry_mkimage(Entry): - args: Arguments to pass - data-to-imagename: Indicates that the -d data should be passed in as the image name also (-n) + - multiple-data-files: boolean to tell binman to pass all files as + datafiles to mkimage instead of creating a temporary file the result + of datafiles concatenation + - filename: filename of output binary generated by mkimage The data passed to mkimage via the -d flag is collected from subnodes of the mkimage node, e.g.:: mkimage { + filename = "imximage.bin"; args = "-n test -T imximage"; u-boot-spl { @@ -35,8 +40,9 @@ class Entry_mkimage(Entry): mkimage -d <data_file> -n test -T imximage <output_file> The output from mkimage then becomes part of the image produced by - binman. If you need to put multiple things in the data file, you can use - a section, or just multiple subnodes like this:: + binman but also is written into `imximage.bin` file. If you need to put + multiple things in the data file, you can use a section, or just multiple + subnodes like this:: mkimage { args = "-n test -T imximage"; @@ -51,6 +57,25 @@ class Entry_mkimage(Entry): Note that binman places the contents (here SPL and TPL) into a single file and passes that to mkimage using the -d option. + To pass all datafiles untouched to mkimage:: + + mkimage { + args = "-n rk3399 -T rkspi"; + multiple-data-files; + + u-boot-tpl { + }; + + u-boot-spl { + }; + }; + + This calls mkimage to create a Rockchip RK3399-specific first stage + bootloader, made of TPL+SPL. Since this first stage bootloader requires to + align the TPL and SPL but also some weird hacks that is handled by mkimage + directly, binman is told to not perform the concatenation of datafiles prior + to passing the data to mkimage. + To use CONFIG options in the arguments, use a string list instead, as in this example which also produces four arguments:: @@ -96,8 +121,10 @@ class Entry_mkimage(Entry): """ def __init__(self, section, etype, node): super().__init__(section, etype, node) + self._multiple_data_files = fdt_util.GetBool(self._node, 'multiple-data-files') self._mkimage_entries = OrderedDict() self._imagename = None + self._filename = fdt_util.GetString(self._node, 'filename') self.align_default = None def ReadNode(self): @@ -122,16 +149,27 @@ class Entry_mkimage(Entry): def ObtainContents(self): # Use a non-zero size for any fake files to keep mkimage happy # Note that testMkimageImagename() relies on this 'mkimage' parameter - data, input_fname, uniq = self.collect_contents_to_file( - self._mkimage_entries.values(), 'mkimage', 1024) - if data is None: - return False + fake_size = 1024 + if self._multiple_data_files: + fnames = [] + uniq = self.GetUniqueName() + for entry in self._mkimage_entries.values(): + if not entry.ObtainContents(fake_size=fake_size): + return False + fnames.append(tools.get_input_filename(entry.GetDefaultFilename())) + input_fname = ":".join(fnames) + else: + data, input_fname, uniq = self.collect_contents_to_file( + self._mkimage_entries.values(), 'mkimage', fake_size) + if data is None: + return False if self._imagename: image_data, imagename_fname, _ = self.collect_contents_to_file( [self._imagename], 'mkimage-n', 1024) if image_data is None: return False - output_fname = tools.get_output_filename('mkimage-out.%s' % uniq) + outfile = self._filename if self._filename else 'mkimage-out.%s' % uniq + output_fname = tools.get_output_filename(outfile) args = ['-d', input_fname] if self._data_to_imagename: diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 5422940e07e..3ced14b7e98 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -5898,6 +5898,36 @@ fdt fdtmap Extract the devicetree blob from the fdtmap self.assertIn("Node '/binman/u-boot-dtb': The zstd compression " "requires a length header", str(e.exception)) + def testMkimageMultipleDataFiles(self): + """Test passing multiple files to mkimage in a mkimage entry""" + data = self._DoReadFile('252_mkimage_mult_data.dts') + # Size of files are packed in their 4B big-endian format + expect = struct.pack('>I', len(U_BOOT_TPL_DATA)) + expect += struct.pack('>I', len(U_BOOT_SPL_DATA)) + # Size info is always followed by a 4B zero value. + expect += tools.get_bytes(0, 4) + expect += U_BOOT_TPL_DATA + # All but last files are 4B-aligned + align_pad = len(U_BOOT_TPL_DATA) % 4 + if align_pad: + expect += tools.get_bytes(0, align_pad) + expect += U_BOOT_SPL_DATA + self.assertEqual(expect, data[-len(expect):]) + + def testMkimageMultipleNoContent(self): + """Test passing multiple data files to mkimage with one data file having no content""" + with self.assertRaises(ValueError) as exc: + self._DoReadFile('253_mkimage_mult_no_content.dts') + self.assertIn('Could not complete processing of contents', + str(exc.exception)) + + def testMkimageFilename(self): + """Test using mkimage to build a binary with a filename""" + retcode = self._DoTestFile('254_mkimage_filename.dts') + self.assertEqual(0, retcode) + fname = tools.get_output_filename('mkimage-test.bin') + self.assertTrue(os.path.exists(fname)) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/252_mkimage_mult_data.dts b/tools/binman/test/252_mkimage_mult_data.dts new file mode 100644 index 00000000000..a092bc39bf3 --- /dev/null +++ b/tools/binman/test/252_mkimage_mult_data.dts @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + mkimage { + args = "-T script"; + multiple-data-files; + + u-boot-tpl { + }; + + u-boot-spl { + }; + }; + }; +}; diff --git a/tools/binman/test/253_mkimage_mult_no_content.dts b/tools/binman/test/253_mkimage_mult_no_content.dts new file mode 100644 index 00000000000..dd65666c62e --- /dev/null +++ b/tools/binman/test/253_mkimage_mult_no_content.dts @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + mkimage { + args = "-T script"; + multiple-data-files; + + _testing { + return-unknown-contents; + }; + + u-boot-spl { + }; + }; + }; +}; diff --git a/tools/binman/test/254_mkimage_filename.dts b/tools/binman/test/254_mkimage_filename.dts new file mode 100644 index 00000000000..4483790ae86 --- /dev/null +++ b/tools/binman/test/254_mkimage_filename.dts @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + mkimage { + filename = "mkimage-test.bin"; + args = "-T script"; + + u-boot-spl { + }; + }; + }; +}; |