Skip to content

Commit aec3ce3

Browse files
committed
Clean up Agilex 5 shared platform helpers
1 parent cc18259 commit aec3ce3

17 files changed

Lines changed: 105 additions & 198 deletions

File tree

‎.github/workflows/test-build-agilex5.yml‎

Lines changed: 0 additions & 28 deletions
This file was deleted.

‎arch.mk‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ ifeq ($(ARCH),AARCH64)
176176
CFLAGS+=-DWOLFBOOT_DUALBOOT -DWOLFBOOT_UBOOT_LEGACY
177177
# BL31 owns GICv3 and secondary-core/PSCI setup. Do not touch RVBAR.
178178
CFLAGS+=-DSKIP_RVBAR=1 -DSKIP_GIC_INIT=1
179+
ifeq ($(DEBUG_UART),1)
180+
OBJS+=hal/uart/ns16550.o
181+
endif
179182
# Full SDHCI host reset: SPL leaves the Cadence host in UHS-I 1.8V/SDR104,
180183
# which mutes CMD8 against the 3.3V re-powered card (hardware-verified).
181184
endif

‎config/examples/agilex5_013b_sdcard.config‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ CFLAGS_EXTRA+=-DLINUX_BOOTARGS_ROOT=\"/dev/mmcblk0p4\"
5252
# Board settings, see docs/Agilex5.md. Defaults match the 013B dev kit.
5353
#CFLAGS_EXTRA+=-DDEBUG_UART_NUM=1
5454
#CFLAGS_EXTRA+=-DAGILEX5_DDR_SIZE=0x70000000
55-
CFLAGS_EXTRA+=-DAGILEX5_FDT_DISABLE_PATHS=\"/leds\"
55+
CFLAGS_EXTRA+=-DWOLFBOOT_FDT_DISABLE_PATHS=\"/leds\"
5656

5757
# SD6HC uses SDMA for cache-coherent multi-block transfers.
5858
CFLAGS_EXTRA+=-DSDHCI_FORCE_CARD_DETECT

‎docs/Agilex5.md‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ make clean
2222
make -j"$(nproc)"
2323
```
2424

25-
The hosted build is also covered by the `Agilex 5 wolfBoot build` GitHub
26-
Actions workflow. It installs the same freestanding AArch64 toolchain used by
27-
the other Cortex-A ports and builds this configuration on every relevant
28-
pull request; hardware is required only for the SD-card and Linux handoff
29-
steps below.
25+
The hosted build is covered by the Agilex 5 job in the `Test Example Configs`
26+
GitHub Actions workflow. It installs the same freestanding AArch64 toolchain
27+
used by the other Cortex-A ports and builds this configuration on every pull
28+
request; hardware is required only for the SD-card and Linux handoff steps
29+
below.
3030

3131
The default RSA-4096/SHA3-384 key is for development only. Production builds
3232
must supply controlled signing keys and keep them separate from both the SDM
@@ -43,10 +43,10 @@ their config:
4343

4444
| Setting | Default | Purpose |
4545
|---|---|---|
46-
| `CFLAGS_EXTRA+=-DDEBUG_UART_NUM=1` | UART0 (`0x10C02000`) | console UART for wolfBoot and Linux `earlycon` |
46+
| `CFLAGS_EXTRA+=-DDEBUG_UART_NUM=<0\|1>` | UART0 (`0x10C02000`) | select UART0 or UART1 (`0x10C02100`) for wolfBoot and Linux `earlycon` |
4747
| `CFLAGS_EXTRA+=-DDEBUG_UART_BASE=<addr>` | unset | any other console UART; write the address without a `UL` suffix |
4848
| `CFLAGS_EXTRA+=-DAGILEX5_DDR_SIZE=<bytes>` | `0x70000000` (1792 MiB) | DDR size written to the DTB memory node |
49-
| `CFLAGS_EXTRA+=-DAGILEX5_FDT_DISABLE_PATHS=\"/leds\"` | unset | comma-separated DTB node paths to mark `disabled`, for hardware behind the unprogrammed FPGA |
49+
| `CFLAGS_EXTRA+=-DWOLFBOOT_FDT_DISABLE_PATHS=\"/leds\"` | unset | comma-separated DTB node paths to mark `disabled`, for hardware behind the unprogrammed FPGA |
5050

5151
wolfBoot does not read the DDR size from the DTB, because without U-Boot the
5252
memory node holds whatever the DTB author wrote rather than the fitted size.

‎hal/agilex5.c‎

Lines changed: 23 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "fdt.h"
2828
#include "hal.h"
2929
#include "hal/agilex5.h"
30+
#include "aarch64_arch.h"
3031
#include "image.h"
3132
#include "printf.h"
3233

@@ -46,70 +47,36 @@
4647
#endif
4748

4849
#ifdef DEBUG_UART
49-
#define UART_RBR 0U
50-
#define UART_THR 0U
51-
#define UART_LSR 5U
52-
#define UART_LSR_THRE (1U << 5)
53-
#define UART_LSR_TEMT (1U << 6)
54-
#define UART_TIMEOUT 1000000U
55-
#define UART_REG(_n) \
56-
(*(volatile uint32_t *)((uintptr_t)DEBUG_UART_BASE + \
57-
((uintptr_t)(_n) << 2)))
50+
#include "ns16550.h"
51+
52+
static struct ns16550_dev uart_console;
5853

5954
void uart_init(void)
6055
{
61-
/* SPL configured the DesignWare APB UART, its clock and pinmux. */
56+
uart_console.base = (uintptr_t)DEBUG_UART_BASE;
57+
uart_console.reg_shift = 2;
58+
uart_console.reg_off = 0;
59+
uart_console.clk_hz = 0;
60+
uart_console.io_width = 4;
61+
uart_console.crlf = 1;
62+
/* Keep the baud, clock and pinmux settings inherited from SPL. */
6263
}
6364

6465
void uart_write(const char *buf, uint32_t len)
6566
{
66-
uint32_t i;
67-
68-
for (i = 0; i < len; i++) {
69-
uint32_t timeout = UART_TIMEOUT;
70-
if (buf[i] == '\n') {
71-
while (((UART_REG(UART_LSR) & UART_LSR_THRE) == 0U) &&
72-
(--timeout != 0U)) {}
73-
if (timeout != 0U)
74-
UART_REG(UART_THR) = '\r';
75-
timeout = UART_TIMEOUT;
76-
}
77-
while (((UART_REG(UART_LSR) & UART_LSR_THRE) == 0U) &&
78-
(--timeout != 0U)) {}
79-
if (timeout != 0U)
80-
UART_REG(UART_THR) = (uint32_t)(uint8_t)buf[i];
81-
}
67+
(void)ns16550_write(&uart_console, buf, len);
8268
}
8369
#else
8470
#define uart_init() do {} while (0)
8571
#endif
8672

87-
static uint64_t timer_count(void)
88-
{
89-
uint64_t count;
90-
__asm__ volatile("mrs %0, cntpct_el0" : "=r"(count));
91-
return count;
92-
}
93-
94-
static uint64_t timer_frequency(void)
95-
{
96-
uint64_t frequency;
97-
__asm__ volatile("mrs %0, cntfrq_el0" : "=r"(frequency));
98-
return frequency;
99-
}
100-
10173
uint64_t hal_get_timer_us(void)
10274
{
103-
uint64_t frequency = timer_frequency();
104-
uint64_t count = timer_count();
75+
uint64_t frequency = timer_get_freq();
76+
uint64_t count = timer_get_count();
10577
uint64_t whole;
10678
uint64_t rem;
10779

108-
/* BL31 normally programs CNTFRQ_EL0. Keep delay loops live even when a
109-
* non-conforming handoff leaves it clear.
110-
*/
111-
if (frequency == 0U)
112-
frequency = 100000000U;
11380
/* Split the conversion so it stays in 64-bit math: a __uint128_t divide
11481
* pulls in libgcc's __udivti3, which the bare-metal link has no runtime
11582
* for. The whole and remainder parts are exact and cannot overflow. */
@@ -129,11 +96,6 @@ void hal_init(void)
12996

13097
void hal_prepare_boot(void)
13198
{
132-
#ifdef DEBUG_UART
133-
uint32_t timeout = UART_TIMEOUT;
134-
while (((UART_REG(UART_LSR) & UART_LSR_TEMT) == 0U) &&
135-
(--timeout != 0U)) {}
136-
#endif
13799
__asm__ volatile("dsb sy" : : : "memory");
138100
__asm__ volatile("ic iallu" : : : "memory");
139101
__asm__ volatile("dsb sy" : : : "memory");
@@ -156,16 +118,16 @@ void *hal_get_dts_update_address(void)
156118
}
157119

158120
#ifdef __WOLFBOOT
159-
#ifdef AGILEX5_FDT_DISABLE_PATHS
160-
static const char* const agilex5_fdt_disable[] = { AGILEX5_FDT_DISABLE_PATHS };
121+
#ifdef WOLFBOOT_FDT_DISABLE_PATHS
122+
static const char* const fdt_disable_paths[] = { WOLFBOOT_FDT_DISABLE_PATHS };
161123
#endif
162124

163125
int hal_dts_fixup(void *dts_addr, uint32_t capacity)
164126
{
165127
fdt_ctx ctx;
166128
int off;
167129
int ret;
168-
#ifdef AGILEX5_FDT_DISABLE_PATHS
130+
#ifdef WOLFBOOT_FDT_DISABLE_PATHS
169131
unsigned int i;
170132
#endif
171133

@@ -203,17 +165,17 @@ int hal_dts_fixup(void *dts_addr, uint32_t capacity)
203165

204166
/* wolfBoot does not program the fabric, so the board config lists the
205167
* nodes whose hardware sits behind the unprogrammed FPGA. */
206-
#ifdef AGILEX5_FDT_DISABLE_PATHS
207-
for (i = 0; i < sizeof(agilex5_fdt_disable) /
208-
sizeof(agilex5_fdt_disable[0]); i++) {
209-
off = fdt_path_offset(&ctx, agilex5_fdt_disable[i]);
168+
#ifdef WOLFBOOT_FDT_DISABLE_PATHS
169+
for (i = 0; i < sizeof(fdt_disable_paths) /
170+
sizeof(fdt_disable_paths[0]); i++) {
171+
off = fdt_path_offset(&ctx, fdt_disable_paths[i]);
210172
if (off < 0)
211173
continue;
212-
ret = fdt_fixup_str(&ctx, off, agilex5_fdt_disable[i], "status",
174+
ret = fdt_fixup_str(&ctx, off, fdt_disable_paths[i], "status",
213175
"disabled");
214176
if (ret != 0) {
215177
wolfBoot_printf("FDT: failed to disable %s (%d)\n",
216-
agilex5_fdt_disable[i], ret);
178+
fdt_disable_paths[i], ret);
217179
return ret;
218180
}
219181
}
@@ -251,22 +213,6 @@ int RAMFUNCTION hal_flash_erase(uintptr_t address, int len)
251213
#if defined(DISK_SDCARD) || defined(DISK_EMMC)
252214
#include "sdhci.h"
253215

254-
#define AGILEX5_SDHCI_HRS05 0x014U
255-
#define AGILEX5_SDHCI_HRS07 0x01CU
256-
#define AGILEX5_SDHCI_HRS09 0x024U
257-
#define AGILEX5_SDHCI_HRS10 0x028U
258-
#define AGILEX5_SDHCI_HRS16 0x040U
259-
260-
#define AGILEX5_SDHCI_PHY_DQ_TIMING 0x2000U
261-
#define AGILEX5_SDHCI_PHY_DQS_TIMING 0x2004U
262-
#define AGILEX5_SDHCI_PHY_GATE_LPBK_CTRL 0x2008U
263-
#define AGILEX5_SDHCI_PHY_DLL_MASTER_CTRL 0x200CU
264-
#define AGILEX5_SDHCI_PHY_DLL_SLAVE_CTRL 0x2010U
265-
266-
#define AGILEX5_SDHCI_PHY_INIT_COMPLETE (1U << 1)
267-
#define AGILEX5_SDHCI_PHY_SW_RESET (1U << 0)
268-
#define AGILEX5_SDHCI_PHY_INIT_TIMEOUT 1000000U
269-
270216
static void agilex5_sdhci_write_phy(uint32_t address, uint32_t value)
271217
{
272218
sdhci_reg_write(SDHCI_HRS04, address);

‎hal/agilex5.h‎

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,54 @@
5151
#endif
5252

5353
#define AGILEX5_DDR_BASE 0x80000000UL
54-
/* U-Boot normally writes the measured DDR size into the DTB; wolfBoot hands
55-
* the DTB straight to Linux, so the board config supplies it. Default is the
56-
* DK-A5E013BM16AEA's 1792 MiB. */
54+
/* The GSRD U-Boot device tree starts HPS DDR at 0x80000000. U-Boot normally
55+
* writes the measured size into the DTB; wolfBoot supplies the 013B's
56+
* 1792 MiB because it hands the DTB directly to Linux. */
5757
#ifndef AGILEX5_DDR_SIZE
5858
#define AGILEX5_DDR_SIZE 0x70000000UL
5959
#endif
6060

61-
/* No UL suffix: the base is also stringified into the earlycon argument. */
61+
/* Agilex 5 HPS UART0 and UART1 MMIO bases. The GSRD device tree maps these as
62+
* serial@10c02000 and serial@10c02100. The selected value is also emitted in
63+
* Linux's earlycon argument, so keep the address macros free of a C suffix. */
64+
#define AGILEX5_UART0_BASE 0x10C02000
65+
#define AGILEX5_UART1_BASE 0x10C02100
6266
#ifndef DEBUG_UART_BASE
6367
#if defined(DEBUG_UART_NUM) && DEBUG_UART_NUM == 1
64-
#define DEBUG_UART_BASE 0x10C02100
68+
#define DEBUG_UART_BASE AGILEX5_UART1_BASE
6569
#else
66-
#define DEBUG_UART_BASE 0x10C02000
70+
#define DEBUG_UART_BASE AGILEX5_UART0_BASE
6771
#endif
6872
#endif
73+
74+
/* HPS SDMMC controller base from the Agilex 5 HPS memory map. */
6975
#define AGILEX5_SDHCI_BASE 0x10808000UL
76+
/* The Cortex-A55 data cache uses 64-byte lines. */
7077
#define CACHE_LINE_SIZE 64UL
7178

72-
#ifndef __ASSEMBLER__
73-
unsigned int current_el(void);
79+
/* TF-A programs the architectural counter to 100 MHz on the GSRD boot path. */
80+
#ifndef TIMER_CLK_FREQ
81+
#define TIMER_CLK_FREQ 100000000UL
7482
#endif
7583

84+
/* Cadence SD6HC host and PHY register offsets from the GSRD U-Boot driver. */
85+
#define AGILEX5_SDHCI_HRS05 0x014U
86+
#define AGILEX5_SDHCI_HRS07 0x01CU
87+
#define AGILEX5_SDHCI_HRS09 0x024U
88+
#define AGILEX5_SDHCI_HRS10 0x028U
89+
#define AGILEX5_SDHCI_HRS16 0x040U
90+
#define AGILEX5_SDHCI_PHY_DQ_TIMING 0x2000U
91+
#define AGILEX5_SDHCI_PHY_DQS_TIMING 0x2004U
92+
#define AGILEX5_SDHCI_PHY_GATE_LPBK_CTRL 0x2008U
93+
#define AGILEX5_SDHCI_PHY_DLL_MASTER_CTRL 0x200CU
94+
#define AGILEX5_SDHCI_PHY_DLL_SLAVE_CTRL 0x2010U
95+
#define AGILEX5_SDHCI_PHY_INIT_COMPLETE (1U << 1)
96+
#define AGILEX5_SDHCI_PHY_SW_RESET (1U << 0)
97+
#define AGILEX5_SDHCI_PHY_INIT_TIMEOUT 1000000U
98+
99+
/* wolfBoot occupies the GSRD BL33 region at 0x80200000. The DTB is staged at
100+
* 0x8f000000, matching agilex5.its, and the signed image uses the next
101+
* 256 MiB at 0x90000000 so neither buffer overlaps wolfBoot or the DTB. */
76102
#ifndef WOLFBOOT_LOAD_ADDRESS
77103
#define WOLFBOOT_LOAD_ADDRESS 0x90000000UL
78104
#endif

‎hal/versal.h‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -598,14 +598,6 @@
598598
*/
599599
#ifndef __ASSEMBLER__
600600

601-
/* Get current exception level */
602-
static inline unsigned int current_el(void)
603-
{
604-
unsigned long el;
605-
__asm__ volatile("mrs %0, CurrentEL" : "=r" (el));
606-
return (unsigned int)((el >> 2) & 0x3);
607-
}
608-
609601
/* Memory barrier */
610602
static inline void dmb(void)
611603
{

‎hal/zynq.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#endif
3535

3636
#include <target.h>
37+
#include "aarch64_arch.h"
3738
#include "image.h"
3839
#include "printf.h"
3940
#include "hal_fpga.h"
@@ -113,7 +114,6 @@ static int test_ext_flash(QspiDev_t* dev);
113114

114115
/* asm function */
115116
extern void flush_dcache_range(unsigned long start, unsigned long stop);
116-
extern unsigned int current_el(void);
117117

118118
void hal_delay_ms(uint64_t ms);
119119
uint64_t hal_timer_ms(void);

‎include/aarch64_arch.h‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,28 @@
1919
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
2020
*/
2121

22-
/* Architectural AArch64 helpers that carry no SoC-specific state: the generic
23-
* timer and set/way data-cache maintenance. Several HALs each grew their own
24-
* copy of these; this is the shared home for them. Inline, so including it
25-
* changes nothing for a HAL that does not call them.
22+
/* Architectural AArch64 helpers that carry no SoC-specific state: exception
23+
* level access, the generic timer and set/way data-cache maintenance. Several
24+
* HALs each grew their own copy of these; this is the shared home for them.
25+
* Inline, so including it changes nothing for a HAL that does not call them.
2626
*
27-
* Define TIMER_CLK_FREQ before including for the rate to assume when firmware
28-
* left CNTFRQ_EL0 unprogrammed. */
27+
* Define TIMER_CLK_FREQ before including to expose the timer helpers and set
28+
* the rate to assume when firmware left CNTFRQ_EL0 unprogrammed. */
2929

3030
#ifndef _AARCH64_ARCH_H_
3131
#define _AARCH64_ARCH_H_
3232

3333
#include <stdint.h>
3434

35-
#ifndef TIMER_CLK_FREQ
36-
#error "TIMER_CLK_FREQ must be defined before including aarch64_arch.h"
37-
#endif
35+
static inline unsigned int current_el(void)
36+
{
37+
unsigned long el;
3838

39+
__asm__ volatile("mrs %0, CurrentEL" : "=r"(el) : : "cc");
40+
return (unsigned int)((el >> 2) & 0x3U);
41+
}
42+
43+
#ifdef TIMER_CLK_FREQ
3944
/* CNTPCT_EL0, the architectural counter. */
4045
static inline uint64_t timer_get_count(void)
4146
{
@@ -68,6 +73,7 @@ static inline int timer_expired(uint64_t deadline)
6873
{
6974
return timer_get_count() > deadline;
7075
}
76+
#endif
7177

7278
/* Data-cache maintenance by set/way over every level to the point of
7379
* coherency. clean != 0 -> clean+invalidate, else invalidate only. */

‎include/sdhci.h‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,6 @@ void sdhci_platform_init(void);
483483
* to the card clock and return that, keeping the internal divider ~1. */
484484
uint32_t sdhci_platform_set_clock(uint32_t clock_khz, uint32_t base_clk_khz);
485485

486-
/* Optional controller settle time in microseconds after each init command.
487-
* Opt in with -DSDHCI_WAIT_AFTER_CMD_US=<us>. */
488-
489486
/* Platform interrupt setup (PLIC/NVIC/GIC/etc.) */
490487
void sdhci_platform_irq_init(void);
491488

0 commit comments

Comments
 (0)