From e00ba92ca41f0712dc2ca198c78ff763cae196d4 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 17 Sep 2026 17:00:37 -0700 Subject: [PATCH] versal: support DDR apertures above 1 TB in the translation table --- config/examples/versal_vmk180.config | 13 +++++++++ docs/Targets.md | 1 + hal/versal.h | 18 ++++++++++++- hal/versal.ld | 6 +++-- src/boot_aarch64_start.S | 40 ++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 3 deletions(-) diff --git a/config/examples/versal_vmk180.config b/config/examples/versal_vmk180.config index a6c328ef4a..70366c2c24 100644 --- a/config/examples/versal_vmk180.config +++ b/config/examples/versal_vmk180.config @@ -105,6 +105,19 @@ WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x6000000 # DTS (Device Tree) - matches addresses from BOOT.BIN analysis WOLFBOOT_LOAD_DTS_ADDRESS?=0x1000 + +# High DDR aperture: for designs whose DDR lives above the default address map +# (e.g. DDR at 0x400_0000_0000). These must stay BELOW the defaults above and +# use '=' so they override them. Base and size are 512 GB aligned with no +# UL/ULL suffix (the assembler consumes them); the FIT ITS must then use +# #address-cells = <2> with two-cell load/entry values, and the bootgen BIF +# and BL31 BL33 entry must match WOLFBOOT_ORIGIN. +#WOLFBOOT_ORIGIN=0x40000800000 +#WOLFBOOT_LOAD_ADDRESS=0x40010000000 +#WOLFBOOT_LOAD_DTS_ADDRESS=0x40000001000 +#CFLAGS_EXTRA+=-DVERSAL_DDR_HIGH_BASE=0x40000000000 +#CFLAGS_EXTRA+=-DVERSAL_DDR_HIGH_SIZE=0x10000000000 +#CFLAGS_EXTRA+=-DVERSAL_NO_DDR_LOW WOLFBOOT_DTS_BOOT_ADDRESS?=0x7B0000 WOLFBOOT_DTS_UPDATE_ADDRESS?=0x39B0000 diff --git a/docs/Targets.md b/docs/Targets.md index 3289930bcb..30efc621f5 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -4925,6 +4925,7 @@ Note: If using QSPI there are bootgen issues with 2025.1+, so recommend 2024.1 o ### Common Notes - Debugging with OCRAM (OCM): set `WOLFBOOT_ORIGIN=0xFFFC0000` (OCM is 256KB at `0xFFFC0000 - 0xFFFFFFFF`). +- **High DDR apertures**: designs whose DDR window lives above the default map (for example DDR at `0x400_0000_0000`) add `CFLAGS_EXTRA+=-DVERSAL_DDR_HIGH_BASE=...` and `-DVERSAL_DDR_HIGH_SIZE=...` (512 GB aligned, plain hex literals with no `UL` suffix) to map the window in the translation table, plus `-DVERSAL_NO_DDR_LOW` when nothing remains at `0x0`. Move `WOLFBOOT_ORIGIN`, `WOLFBOOT_LOAD_ADDRESS` and `WOLFBOOT_LOAD_DTS_ADDRESS` into the window (`hal/versal.ld` follows `WOLFBOOT_ORIGIN` from the config), update the bootgen BIF load/exec and the BL31 BL33 entry to match, and switch the FIT ITS to `#address-cells = <2>` with two-cell `load`/`entry` values since 32-bit cells cannot hold addresses above 4 GB. A commented recipe is in `config/examples/versal_vmk180.config`; the DDR aperture itself must be routed to the APU by the design's PDI. - Test application uses generic `boot_arm64_start.S` and `AARCH64.ld` and prints EL + version. - Entry point: `_start` (in `boot_arm64_start.S`) which sets up stack, clears BSS, and calls `main()` diff --git a/hal/versal.h b/hal/versal.h index bce990ace9..eddd6d5885 100644 --- a/hal/versal.h +++ b/hal/versal.h @@ -122,9 +122,25 @@ /* DDR defines for MMU table setup (used by boot_aarch64_start.S) * These macros enable proper DDR mapping in the page tables. - * Without these, the MMU tables would have DDR_0_REG=0 and no DDR mapped! */ + * Without these, the MMU tables would have DDR_0_REG=0 and no DDR mapped! + * VERSAL_NO_DDR_LOW leaves the low window (0x0-0x7FFFFFFF) unmapped, for + * designs whose DDR aperture lives entirely above 4 GB; pair it with + * VERSAL_DDR_HIGH_BASE/VERSAL_DDR_HIGH_SIZE (512 GB aligned, plain hex + * literals with no UL/ULL suffix - they are consumed by the assembler), + * which map an additional Normal-memory window in the translation table. */ +#if defined(VERSAL_DDR_HIGH_BASE) && !defined(VERSAL_DDR_HIGH_SIZE) +#error "VERSAL_DDR_HIGH_BASE requires VERSAL_DDR_HIGH_SIZE" +#endif +#if defined(VERSAL_DDR_HIGH_SIZE) && !defined(VERSAL_DDR_HIGH_BASE) +#error "VERSAL_DDR_HIGH_SIZE requires VERSAL_DDR_HIGH_BASE" +#endif +#if defined(VERSAL_NO_DDR_LOW) && !defined(VERSAL_DDR_HIGH_BASE) +#error "VERSAL_NO_DDR_LOW without VERSAL_DDR_HIGH_BASE maps no DDR at all" +#endif +#ifndef VERSAL_NO_DDR_LOW #define XPAR_PSU_DDR_0_S_AXI_BASEADDR VERSAL_DDR_0_BASE #define XPAR_PSU_DDR_0_S_AXI_HIGHADDR VERSAL_DDR_0_HIGH +#endif /* ============================================================================ diff --git a/hal/versal.ld b/hal/versal.ld index 1688158c44..a09b1c97ba 100644 --- a/hal/versal.ld +++ b/hal/versal.ld @@ -6,7 +6,9 @@ * This script is for production boot where: * - PLM/PSM have initialized DDR * - BL31 runs at EL3 and transitions to EL2 - * - wolfBoot runs at EL2 from DDR at 0x8000000 (replacing U-Boot) + * - wolfBoot runs at EL2 from DDR (replacing U-Boot). The DDR region + * ORIGIN below follows WOLFBOOT_ORIGIN from the .config, which defaults + * to 0x8000000; a high-DDR design sets it into its own aperture. * * Memory Map: * 0x00000000 - 0x07FFFFFF : Reserved / Low DDR @@ -36,7 +38,7 @@ _EL2_STACK_SIZE = DEFINED(_EL2_STACK_SIZE) ? _EL2_STACK_SIZE : 0x8000; /* Prima */ MEMORY { - DDR (rwx) : ORIGIN = 0x8000000, LENGTH = 0x200000 + DDR (rwx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = 0x200000 } /* Sections */ diff --git a/src/boot_aarch64_start.S b/src/boot_aarch64_start.S index 3334d6e553..3ad3b0d30f 100644 --- a/src/boot_aarch64_start.S +++ b/src/boot_aarch64_start.S @@ -606,6 +606,35 @@ MMUTableL0: .set SECT, MMUTableL1+0x1000 /* 0x80_0000_0000 - 0xFF_FFFF_FFFF */ .8byte SECT + 0x3 +#if defined(TARGET_versal) && defined(VERSAL_DDR_HIGH_BASE) +/* Optional high DDR window (designs whose DDR aperture sits above 1 TB). + * One L0 descriptor per 512 GB, pointing at MMUTableL1_HI pages below. + * Base and size must be 512 GB aligned and end within the 44-bit space. */ +.if (VERSAL_DDR_HIGH_BASE % 0x8000000000) != 0 +.error "VERSAL_DDR_HIGH_BASE must be 512GB aligned" +.endif +.if VERSAL_DDR_HIGH_SIZE < 0x8000000000 +.error "VERSAL_DDR_HIGH_SIZE must be at least 512GB (one L0 granule)" +.endif +.if (VERSAL_DDR_HIGH_SIZE % 0x8000000000) != 0 +.error "VERSAL_DDR_HIGH_SIZE must be a multiple of 512GB" +.endif +.if (VERSAL_DDR_HIGH_BASE + VERSAL_DDR_HIGH_SIZE) > 0x100000000000 +.error "VERSAL_DDR_HIGH window exceeds the 44-bit address space" +.endif +.if VERSAL_DDR_HIGH_BASE < 0x10000000000 +.error "VERSAL_DDR_HIGH_BASE must be at least 1TB (the first two L0 entries are fixed)" +.endif +.rept ((VERSAL_DDR_HIGH_BASE / 0x8000000000) - 2) +.8byte 0 /* invalid up to the high window */ +.endr +.set SECT, MMUTableL1_HI +.rept (VERSAL_DDR_HIGH_SIZE / 0x8000000000) +.8byte SECT + 0x3 +.set SECT, SECT + 0x1000 +.endr +#endif /* TARGET_versal && VERSAL_DDR_HIGH_BASE */ + .section .mmu_tbl1,"a" MMUTableL1: @@ -674,6 +703,17 @@ MMUTableL1: .endr +#if defined(TARGET_versal) && defined(VERSAL_DDR_HIGH_BASE) +/* 1 GB Normal-memory blocks covering the high DDR window. */ +.balign 4096 +MMUTableL1_HI: +.set SECT, VERSAL_DDR_HIGH_BASE +.rept (VERSAL_DDR_HIGH_SIZE / 0x40000000) +.8byte SECT + Memory +.set SECT, SECT + 0x40000000 +.endr +#endif /* TARGET_versal && VERSAL_DDR_HIGH_BASE */ + .section .mmu_tbl2,"a" MMUTableL2: