[PATCH v1 0/8] U-boot: arm: Refine the booting on Total Compute

This patch series is to refine the booting on Arm Total Compuate platform.
It changes to use the info passed in DTB for initialization DRAM info, and dynamically initializes the booting envoironment variables.
Another big change is to use an envoironment file for boot commands, based on it, the series extends to support multiple block devices (MMC and virtio). And the env file is extended for booting Debian.
The last commit is to update memory mapping info based on the DRAM info passed via DT binding.
Boyan Karatotev (5): arm: total_compute: depend on TF-A for hardware description arm: total_compute: Initialize environment variables arm: total_compute: Remove unused bootm_size arm: total_compute: move the boot command to an env file arm: total_compute: Minor improvement for boot arguments
Leo Yan (3): arm: total_compute: Dynamically detect block device arm: total_compute: Support Debian boot arm: total_compute: Update memory mapping info
arch/arm/Kconfig | 2 + board/armltd/total_compute/Makefile | 1 + board/armltd/total_compute/lowlevel_init.S | 12 +++ board/armltd/total_compute/total_compute.c | 102 ++++++++++++++----- board/armltd/total_compute/total_compute.env | 39 +++++++ configs/total_compute_defconfig | 2 +- include/configs/total_compute.h | 31 ------ 7 files changed, 130 insertions(+), 59 deletions(-) create mode 100644 board/armltd/total_compute/lowlevel_init.S create mode 100644 board/armltd/total_compute/total_compute.env

From: Boyan Karatotev boyan.karatotev@arm.com
On Total Compute, TF-A passes the info via DT binding for the hardware description - includes the serial, memory, and arm_ffa nodes.
This commit initializes the fdt base address based on the passed the register x1.
The similar implementation has already been done for the raspberry pi, so borrow a lot of it.
Co-developed-by: Jackson Cooper-Driver jackson.cooper-driver@arm.com Signed-off-by: Jackson Cooper-Driver jackson.cooper-driver@arm.com Signed-off-by: Boyan Karatotev boyan.karatotev@arm.com Signed-off-by: Leo Yan leo.yan@arm.com --- arch/arm/Kconfig | 1 + board/armltd/total_compute/Makefile | 1 + board/armltd/total_compute/lowlevel_init.S | 12 +++++++ board/armltd/total_compute/total_compute.c | 41 +++++++++++----------- include/configs/total_compute.h | 18 ---------- 5 files changed, 35 insertions(+), 38 deletions(-) create mode 100644 board/armltd/total_compute/lowlevel_init.S
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 060636e9e2..d0127418ee 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1390,6 +1390,7 @@ config TARGET_TOTAL_COMPUTE select DM_SERIAL select DM_MMC select DM_GPIO + imply OF_HAS_PRIOR_STAGE
config TARGET_LS2080A_EMU bool "Support ls2080a_emu" diff --git a/board/armltd/total_compute/Makefile b/board/armltd/total_compute/Makefile index 8b10458431..f1ef5a0c39 100644 --- a/board/armltd/total_compute/Makefile +++ b/board/armltd/total_compute/Makefile @@ -4,3 +4,4 @@ # Usama Arif usama.arif@arm.com
obj-y := total_compute.o +obj-y += lowlevel_init.o diff --git a/board/armltd/total_compute/lowlevel_init.S b/board/armltd/total_compute/lowlevel_init.S new file mode 100644 index 0000000000..3c06937966 --- /dev/null +++ b/board/armltd/total_compute/lowlevel_init.S @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2024 Arm Limited + */ + +.global save_boot_params +save_boot_params: + /* The firmware provided FDT address via x1 */ + adr x8, fw_dtb_pointer + str x1, [x8] + + b save_boot_params_ret diff --git a/board/armltd/total_compute/total_compute.c b/board/armltd/total_compute/total_compute.c index e1b4f49d04..571a075145 100644 --- a/board/armltd/total_compute/total_compute.c +++ b/board/armltd/total_compute/total_compute.c @@ -7,19 +7,10 @@ #include <config.h> #include <dm.h> #include <dm/platform_data/serial_pl01x.h> +#include <env.h> #include <asm/armv8/mmu.h> #include <asm/global_data.h> - -static const struct pl01x_serial_plat serial_plat = { - .base = UART0_BASE, - .type = TYPE_PL011, - .clock = CFG_PL011_CLOCK, -}; - -U_BOOT_DRVINFO(total_compute_serials) = { - .name = "serial_pl01x", - .plat = &serial_plat, -}; +#include <asm/system.h>
static struct mm_region total_compute_mem_map[] = { { @@ -43,6 +34,23 @@ static struct mm_region total_compute_mem_map[] = {
struct mm_region *mem_map = total_compute_mem_map;
+/* + * Push the variable into the .data section so that it + * does not get cleared later. + */ +unsigned long __section(".data") fw_dtb_pointer; + +void *board_fdt_blob_setup(int *err) +{ + *err = 0; + if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) { + *err = -ENXIO; + return NULL; + } + + return (void *)fw_dtb_pointer; +} + int board_init(void) { return 0; @@ -50,19 +58,12 @@ int board_init(void)
int dram_init(void) { - gd->ram_size = PHYS_SDRAM_1_SIZE; - return 0; + return fdtdec_setup_mem_size_base(); }
int dram_init_banksize(void) { - gd->bd->bi_dram[0].start = PHYS_SDRAM_1; - gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; - - gd->bd->bi_dram[1].start = PHYS_SDRAM_2; - gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; - - return 0; + return fdtdec_setup_memory_banksize(); }
/* Nothing to be done here as handled by PSCI interface */ diff --git a/include/configs/total_compute.h b/include/configs/total_compute.h index a8bd8e259c..205e6a6278 100644 --- a/include/configs/total_compute.h +++ b/include/configs/total_compute.h @@ -11,24 +11,6 @@
/* Link Definitions */
-/* AP non-secure UART base address */ -#define UART0_BASE 0x2A400000 - -/* PL011 Serial Configuration */ -#define CFG_PL011_CLOCK 7372800 - -/* Miscellaneous configurable options */ - -/* Physical Memory Map */ -#define PHYS_SDRAM_1 0x80000000 -/* Top 48MB reserved for secure world use */ -#define DRAM_SEC_SIZE 0x03000000 -#define PHYS_SDRAM_1_SIZE 0x80000000 - DRAM_SEC_SIZE -#define CFG_SYS_SDRAM_BASE PHYS_SDRAM_1 - -#define PHYS_SDRAM_2 0x8080000000 -#define PHYS_SDRAM_2_SIZE 0x180000000 - #define CFG_EXTRA_ENV_SETTINGS \ "bootm_size=0x20000000\0" \ "load_addr=0xa0000000\0" \

From: Boyan Karatotev boyan.karatotev@arm.com
Initialize the environment variables 'fdt_addr_r' and 'kernel_addr_r' during the misc init phase. The static configurations are not needed, remove them.
Signed-off-by: Boyan Karatotev boyan.karatotev@arm.com Signed-off-by: Leo Yan leo.yan@arm.com --- arch/arm/Kconfig | 1 + board/armltd/total_compute/total_compute.c | 23 ++++++++++++++++++++++ include/configs/total_compute.h | 4 +--- 3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d0127418ee..f4ce884e37 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1391,6 +1391,7 @@ config TARGET_TOTAL_COMPUTE select DM_MMC select DM_GPIO imply OF_HAS_PRIOR_STAGE + imply MISC_INIT_R
config TARGET_LS2080A_EMU bool "Support ls2080a_emu" diff --git a/board/armltd/total_compute/total_compute.c b/board/armltd/total_compute/total_compute.c index 571a075145..02bb648ce7 100644 --- a/board/armltd/total_compute/total_compute.c +++ b/board/armltd/total_compute/total_compute.c @@ -8,6 +8,8 @@ #include <dm.h> #include <dm/platform_data/serial_pl01x.h> #include <env.h> +#include <linux/sizes.h> + #include <asm/armv8/mmu.h> #include <asm/global_data.h> #include <asm/system.h> @@ -51,6 +53,27 @@ void *board_fdt_blob_setup(int *err) return (void *)fw_dtb_pointer; }
+int misc_init_r(void) +{ + size_t base; + + if (!env_get("fdt_addr_r")) + env_set_hex("fdt_addr_r", fw_dtb_pointer); + + if (!env_get("kernel_addr_r")) { + /* + * The kernel has to be 2M aligned and the first 64K at the + * start of SDRAM is reserved for DTB. + */ + base = gd->ram_base + SZ_2M; + assert(IS_ALIGNED(base, SZ_2M)); + + env_set_hex("kernel_addr_r", base); + } + + return 0; +} + int board_init(void) { return 0; diff --git a/include/configs/total_compute.h b/include/configs/total_compute.h index 205e6a6278..8053dca315 100644 --- a/include/configs/total_compute.h +++ b/include/configs/total_compute.h @@ -14,9 +14,7 @@ #define CFG_EXTRA_ENV_SETTINGS \ "bootm_size=0x20000000\0" \ "load_addr=0xa0000000\0" \ - "kernel_addr_r=0x80080000\0" \ - "initrd_addr_r=0x88000000\0" \ - "fdt_addr_r=0x83000000\0" + "initrd_addr_r=0x88000000\0" /* * If vbmeta partition is present, boot Android with verification using AVB. * Else if system partition is present (no vbmeta partition), boot Android

From: Boyan Karatotev boyan.karatotev@arm.com
The whole DRAM bank is used for loading and U-boot can detect the overlap between the kernel and initramfs. So it is safe to drop bootm_size.
Signed-off-by: Boyan Karatotev boyan.karatotev@arm.com Signed-off-by: Leo Yan leo.yan@arm.com --- include/configs/total_compute.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/include/configs/total_compute.h b/include/configs/total_compute.h index 8053dca315..4c966ce4bf 100644 --- a/include/configs/total_compute.h +++ b/include/configs/total_compute.h @@ -12,7 +12,6 @@ /* Link Definitions */
#define CFG_EXTRA_ENV_SETTINGS \ - "bootm_size=0x20000000\0" \ "load_addr=0xa0000000\0" \ "initrd_addr_r=0x88000000\0" /*

From: Boyan Karatotev boyan.karatotev@arm.com
The boot command for Total Compute has many aspects and changes from time to time. So move it to an .env file where it can be a proper script.
Signed-off-by: Boyan Karatotev boyan.karatotev@arm.com Signed-off-by: Leo Yan leo.yan@arm.com --- board/armltd/total_compute/total_compute.env | 28 ++++++++++++++++++++ configs/total_compute_defconfig | 2 +- include/configs/total_compute.h | 10 ------- 3 files changed, 29 insertions(+), 11 deletions(-) create mode 100644 board/armltd/total_compute/total_compute.env
diff --git a/board/armltd/total_compute/total_compute.env b/board/armltd/total_compute/total_compute.env new file mode 100644 index 0000000000..8975a86fd2 --- /dev/null +++ b/board/armltd/total_compute/total_compute.env @@ -0,0 +1,28 @@ +/* DRAM1 + 0x2000_0000 */ +load_addr=0xa0000000 +/* DRAM1 + 0x0800_0000 */ +initrd_addr_r=0x88000000 + +bootcmd= + if part number mmc 0 vbmeta is_avb; then + echo 'MMC with vbmeta partition detected.'; + echo 'Starting Android Verified boot...'; + avb init 0; + if avb verify; then + set bootargs $bootargs $avb_bootargs; + part start mmc 0 boot boot_start; + part size mmc 0 boot boot_size; + mmc read ${load_addr} ${boot_start} ${boot_size}; + bootm ${load_addr} ${load_addr} ${fdt_addr_r}; + else; + echo 'AVB verification failed.'; + exit; + fi; + elif part number mmc 0 system is_non_avb_android; then + echo 'Booting Android non-AVB...'; + booti ${kernel_addr_r} ${initrd_addr_r} ${fdt_addr_r}; + elif iminfo ${load_addr}; then + echo 'Booting FIT image...'; + bootm ${load_addr} ${load_addr} ${fdt_addr_r}; + fi; + echo 'ERROR: No valid image to boot the system. Aborting boot sequence.'; diff --git a/configs/total_compute_defconfig b/configs/total_compute_defconfig index 5f21d2e367..291083d8b6 100644 --- a/configs/total_compute_defconfig +++ b/configs/total_compute_defconfig @@ -18,7 +18,6 @@ CONFIG_FIT_SIGNATURE=y CONFIG_LEGACY_IMAGE_FORMAT=y CONFIG_DISTRO_DEFAULTS=y CONFIG_BOOTDELAY=5 -CONFIG_BOOTCOMMAND="if part number mmc 0 vbmeta is_avb; then echo MMC with vbmeta partition detected.; echo starting Android Verified boot.; avb init 0; if avb verify; then set bootargs $bootargs $avb_bootargs; part start mmc 0 boot boot_start; part size mmc 0 boot boot_size; mmc read ${load_addr} ${boot_start} ${boot_size}; bootm ${load_addr} ${load_addr} ${fdt_addr_r}; else; echo AVB verification failed.; exit; fi; elif part number mmc 0 system is_non_avb_android; then booti ${kernel_addr_r} ${initrd_addr_r} ${fdt_addr_r};else; echo Booting FIT image.; bootm ${load_addr} ${load_addr} ${fdt_addr_r}; fi;" CONFIG_SYS_CBSIZE=512 CONFIG_SYS_PBSIZE=544 # CONFIG_DISPLAY_CPUINFO is not set @@ -60,3 +59,4 @@ CONFIG_SYS_FLASH_CFI=y CONFIG_SYS_MAX_FLASH_SECT=256 # CONFIG_RANDOM_UUID is not set CONFIG_LIBAVB=y +CONFIG_ENV_SOURCE_FILE=total_compute diff --git a/include/configs/total_compute.h b/include/configs/total_compute.h index 4c966ce4bf..5cc0166f19 100644 --- a/include/configs/total_compute.h +++ b/include/configs/total_compute.h @@ -11,16 +11,6 @@
/* Link Definitions */
-#define CFG_EXTRA_ENV_SETTINGS \ - "load_addr=0xa0000000\0" \ - "initrd_addr_r=0x88000000\0" -/* - * If vbmeta partition is present, boot Android with verification using AVB. - * Else if system partition is present (no vbmeta partition), boot Android - * without verification (for development purposes). - * Else boot FIT image. - */ - #define CFG_SYS_FLASH_BASE 0x0C000000
#endif /* __TOTAL_COMPUTE_H */

From: Boyan Karatotev boyan.karatotev@arm.com
Tell the AVB command that is loading from MMC.
Signed-off-by: Boyan Karatotev boyan.karatotev@arm.com Signed-off-by: Leo Yan leo.yan@arm.com --- board/armltd/total_compute/total_compute.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/board/armltd/total_compute/total_compute.env b/board/armltd/total_compute/total_compute.env index 8975a86fd2..9dd50819ea 100644 --- a/board/armltd/total_compute/total_compute.env +++ b/board/armltd/total_compute/total_compute.env @@ -7,7 +7,7 @@ bootcmd= if part number mmc 0 vbmeta is_avb; then echo 'MMC with vbmeta partition detected.'; echo 'Starting Android Verified boot...'; - avb init 0; + avb init mmc 0; if avb verify; then set bootargs $bootargs $avb_bootargs; part start mmc 0 boot boot_start;

Dynamically detect block device in the boot command, this allows to support both MMC and virtio block devices.
Signed-off-by: Leo Yan leo.yan@arm.com --- board/armltd/total_compute/total_compute.env | 21 +++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/board/armltd/total_compute/total_compute.env b/board/armltd/total_compute/total_compute.env index 9dd50819ea..93460aa5dc 100644 --- a/board/armltd/total_compute/total_compute.env +++ b/board/armltd/total_compute/total_compute.env @@ -4,21 +4,28 @@ load_addr=0xa0000000 initrd_addr_r=0x88000000
bootcmd= - if part number mmc 0 vbmeta is_avb; then - echo 'MMC with vbmeta partition detected.'; + virtio scan; + if virtio info; then + blk_dev=virtio; + else; + blk_dev=mmc; + fi; + echo block device is ${blk_dev}; + if part number ${blk_dev} 0 vbmeta is_avb; then + echo '${blk_dev} with vbmeta partition detected.'; echo 'Starting Android Verified boot...'; - avb init mmc 0; + avb init ${blk_dev} 0; if avb verify; then set bootargs $bootargs $avb_bootargs; - part start mmc 0 boot boot_start; - part size mmc 0 boot boot_size; - mmc read ${load_addr} ${boot_start} ${boot_size}; + part start ${blk_dev} 0 boot boot_start; + part size ${blk_dev} 0 boot boot_size; + ${blk_dev} read ${load_addr} ${boot_start} ${boot_size}; bootm ${load_addr} ${load_addr} ${fdt_addr_r}; else; echo 'AVB verification failed.'; exit; fi; - elif part number mmc 0 system is_non_avb_android; then + elif part number ${blk_dev} 0 system is_non_avb_android; then echo 'Booting Android non-AVB...'; booti ${kernel_addr_r} ${initrd_addr_r} ${fdt_addr_r}; elif iminfo ${load_addr}; then

Add booting option for Debian system.
Signed-off-by: Leo Yan leo.yan@arm.com --- board/armltd/total_compute/total_compute.env | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/board/armltd/total_compute/total_compute.env b/board/armltd/total_compute/total_compute.env index 93460aa5dc..7924632678 100644 --- a/board/armltd/total_compute/total_compute.env +++ b/board/armltd/total_compute/total_compute.env @@ -31,5 +31,9 @@ bootcmd= elif iminfo ${load_addr}; then echo 'Booting FIT image...'; bootm ${load_addr} ${load_addr} ${fdt_addr_r}; + else; + echo 'Booting Debian...'; + set bootargs $bootargs root=/dev/mmcblk0p1 rw; + booti ${kernel_addr_r} - ${fdt_addr_r}; fi; echo 'ERROR: No valid image to boot the system. Aborting boot sequence.';

This commit introduces build_mem_map() function for updating the mem_map structure with copying info from gd->bd->bi_dram, so that it can keep the consistence for DRAM info passed via DT.
The page table size is calculated prior to mem_map is ready, introduce the get_page_table_size() function for a predefined table size.
Signed-off-by: Leo Yan leo.yan@arm.com --- board/armltd/total_compute/total_compute.c | 44 +++++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-)
diff --git a/board/armltd/total_compute/total_compute.c b/board/armltd/total_compute/total_compute.c index 02bb648ce7..4101816317 100644 --- a/board/armltd/total_compute/total_compute.c +++ b/board/armltd/total_compute/total_compute.c @@ -14,7 +14,10 @@ #include <asm/global_data.h> #include <asm/system.h>
-static struct mm_region total_compute_mem_map[] = { +/* +1 is end of list which needs to be empty */ +#define TC_MEM_MAP_MAX (1 + CONFIG_NR_DRAM_BANKS + 1) + +static struct mm_region total_compute_mem_map[TC_MEM_MAP_MAX] = { { .virt = 0x0UL, .phys = 0x0UL, @@ -22,15 +25,6 @@ static struct mm_region total_compute_mem_map[] = { .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - .virt = 0x80000000UL, - .phys = 0x80000000UL, - .size = 0xff80000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, { - /* List terminator */ - 0, } };
@@ -89,6 +83,36 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); }
+void build_mem_map(void) +{ + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + /* + * The first node is for I/O device, start from node 1 for + * updating DRAM info. + */ + mem_map[i + 1].virt = gd->bd->bi_dram[i].start; + mem_map[i + 1].phys = gd->bd->bi_dram[i].start; + mem_map[i + 1].size = gd->bd->bi_dram[i].size; + mem_map[i + 1].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + } +} + +void enable_caches(void) +{ + build_mem_map(); + + icache_enable(); + dcache_enable(); +} + +u64 get_page_table_size(void) +{ + return SZ_256K; +} + /* Nothing to be done here as handled by PSCI interface */ void reset_cpu(void) {

On Fri, 25 Oct 2024 18:18:13 +0100, Leo Yan wrote:
This patch series is to refine the booting on Arm Total Compuate platform.
It changes to use the info passed in DTB for initialization DRAM info, and dynamically initializes the booting envoironment variables.
Another big change is to use an envoironment file for boot commands, based on it, the series extends to support multiple block devices (MMC and virtio). And the env file is extended for booting Debian.
[...]
Applied to u-boot/master, thanks!
participants (2)
-
Leo Yan
-
Tom Rini