Skip to content

Commit e0234b6

Browse files
committed
Peer review fixes
1 parent ee943dd commit e0234b6

6 files changed

Lines changed: 286 additions & 237 deletions

File tree

config/examples/zynqmp_sdcard.config

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@ CFLAGS_EXTRA+=-DBOOT_PART_A=1
8484
CFLAGS_EXTRA+=-DBOOT_PART_B=2
8585

8686
# Disk read chunk size for firmware loading (update_disk.c). 512KB gives the
87-
# best throughput (~1.4s for 32MB). The SDMA engine handles boundary crossings
88-
# every 4KB (SDHCI_DMA_THRESHOLD default) within each 512KB chunk.
87+
# best throughput (~1.4s for 32MB). The SDMA engine handles SDMA buffer
88+
# boundary crossings within each 512KB chunk; this boundary is 4KB by default
89+
# (auto-derived from SDHCI_DMA_THRESHOLD). To reduce boundary IRQs, override
90+
# SDHCI_DMA_BUFF_BOUNDARY independently, e.g.:
91+
# CFLAGS_EXTRA+=-DSDHCI_DMA_BUFF_BOUNDARY=SDHCI_SRS01_DMA_BUFF_512KB
8992
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000
9093

9194
# Linux rootfs is on partition 4. Device naming depends on whether both

docs/Targets.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,7 +2599,7 @@ qemu-system-aarch64 -machine xlnx-zcu102 -cpu cortex-a53 -serial stdio -display
25992599

26002600
Use `config/examples/zynqmp_sdcard.config`. This uses the Arasan SDHCI controller (SD1 - external SD card slot on ZCU102) and an **MBR** partitioned SD card.
26012601

2602-
wolfBoot unconditionally flushes the EL2 D-cache/I-cache and disables the EL2 MMU before handoff (see `el2_flush_and_disable_mmu` in `src/boot_aarch64_start.S`), satisfying the ARM64 Linux boot protocol with no extra config flag required.
2602+
On the direct-jump handoff path, wolfBoot flushes the EL2 D-cache/I-cache and disables the EL2 MMU via `el2_flush_and_disable_mmu` in `src/boot_aarch64_start.S` when `BOOT_EL1` is not enabled and the current exception level is EL2. The ERET-to-EL1 handoff path is different, so this cleanup is not unconditional.
26032603

26042604
**Partition layout**
26052605
| Partition | Name | Size | Type | Contents |
@@ -2705,8 +2705,11 @@ The ZynqMP uses an Arasan SDHCI v3.0 controller. Key considerations:
27052705
level. `SDHCI_FORCE_CARD_DETECT` is set in the config since FSBL already booted from
27062706
the same SD card.
27072707
- **`DISK_BLOCK_SIZE`**: Controls the firmware read chunk size in `update_disk.c` (default
2708-
64KB). This determines the per-read size passed to the SDHCI driver. Must be less than
2709-
the SDMA buffer boundary (4KB with the default threshold).
2708+
64KB). This determines the per-read size passed to the SDHCI driver. It does not need
2709+
to be smaller than `SDHCI_DMA_BUFF_BOUNDARY`; if a read crosses one or more SDMA buffer
2710+
boundaries, the SDHCI driver handles that via the normal SDMA boundary interrupt path.
2711+
In practice, this setting is a tradeoff: larger reads may trigger boundary IRQs more
2712+
often, while smaller reads reduce crossings but increase request overhead.
27102713

27112714
**Debug**
27122715

hal/zynq.c

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,6 @@ static int csu_dma_config(int ch, int doSwap)
504504
int csu_aes(int enc, const uint8_t* iv, const uint8_t* in, uint8_t* out, uint32_t sz)
505505
{
506506
int ret;
507-
uint32_t reg;
508507

509508
/* Flush data cache for variables used */
510509
flush_dcache_range((unsigned long)iv, (unsigned long)iv + AES_GCM_TAG_SZ);
@@ -601,7 +600,6 @@ int csu_init(void)
601600
#endif
602601
uint32_t reg1 = pmu_mmio_read(CSU_IDCODE);
603602
uint32_t reg2 = pmu_mmio_read(CSU_VERSION);
604-
uint64_t ms;
605603

606604
wolfBoot_printf("CSU ID 0x%08x, Ver 0x%08x\n",
607605
reg1, reg2 & CSU_VERSION_MASK);
@@ -1444,13 +1442,29 @@ void qspi_init(void)
14441442
#if (GQSPI_CLK_REF / (2 << GQSPI_CLK_DIV)) <= 40000000 /* 40MHz */
14451443
/* At <40 MHz, the Quad-SPI controller should be in non-loopback mode with
14461444
* the clock and data tap delays bypassed. */
1447-
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
1445+
/* IOU_TAPDLY_BYPASS is not writable from EL2/EL1 without going through PMU. */
1446+
if (current_el() <= 2) {
1447+
pmu_request(PM_MMIO_WRITE, IOU_TAPDLY_BYPASS_ADDR,
1448+
IOU_TAPDLY_BYPASS_LQSPI_RX, IOU_TAPDLY_BYPASS_LQSPI_RX,
1449+
0, NULL);
1450+
}
1451+
else {
1452+
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
1453+
}
14481454
GQSPI_LPBK_DLY_ADJ = 0;
14491455
GQSPI_DATA_DLY_ADJ = 0;
14501456
#elif (GQSPI_CLK_REF / (2 << GQSPI_CLK_DIV)) <= 100000000 /* 100MHz */
14511457
/* At <100 MHz, the Quad-SPI controller should be in clock loopback mode
14521458
* with the clock tap delay bypassed, but the data tap delay enabled. */
1453-
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
1459+
/* IOU_TAPDLY_BYPASS is not writable from EL2/EL1 without going through PMU. */
1460+
if (current_el() <= 2) {
1461+
pmu_request(PM_MMIO_WRITE, IOU_TAPDLY_BYPASS_ADDR,
1462+
IOU_TAPDLY_BYPASS_LQSPI_RX, IOU_TAPDLY_BYPASS_LQSPI_RX,
1463+
0, NULL);
1464+
}
1465+
else {
1466+
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
1467+
}
14541468
GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK;
14551469
GQSPI_DATA_DLY_ADJ = (GQSPI_DATA_DLY_ADJ_USE_DATA_DLY |
14561470
GQSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(2));
@@ -1810,14 +1824,23 @@ void RAMFUNCTION ext_flash_unlock(void)
18101824
}
18111825

18121826
#if defined(MMU) && defined(__WOLFBOOT)
1827+
/* Fallback timer frequency if CNTFRQ_EL0 is not configured (e.g. boot path
1828+
* that did not run ATF/BL31). ZynqMP system counter is 100 MHz. */
1829+
#ifndef ZYNQMP_TIMER_CLK_FREQ
1830+
#define ZYNQMP_TIMER_CLK_FREQ 100000000ULL
1831+
#endif
1832+
18131833
/* Get current time in microseconds using ARMv8 generic timer */
18141834
uint64_t hal_get_timer_us(void)
18151835
{
18161836
uint64_t count, freq;
18171837
__asm__ volatile("mrs %0, CNTPCT_EL0" : "=r"(count));
18181838
__asm__ volatile("mrs %0, CNTFRQ_EL0" : "=r"(freq));
1839+
/* Fall back to a known frequency rather than returning 0, so udelay()
1840+
* callers that spin on hal_get_timer_us() advancing remain monotonic
1841+
* (matches hal/versal.c). */
18191842
if (freq == 0)
1820-
return 0;
1843+
freq = ZYNQMP_TIMER_CLK_FREQ;
18211844
/* Use __uint128_t to avoid overflow of (count * 1e6) at long uptimes
18221845
* (would overflow uint64_t after ~51h at 100MHz). */
18231846
return (uint64_t)(((__uint128_t)count * 1000000ULL) / freq);

include/sdhci.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@
5757
#define DISK_TEST_BLOCK_ADDR 149504 /* ~76MB offset */
5858
#endif
5959

60-
/* Auto-select DMA buffer boundary based on threshold */
60+
/* DMA buffer boundary: how often the SDMA engine pauses to refresh its
61+
* address pointer (handled by sdhci_irq_handler() via SDHCI_SRS12_DMAINT).
62+
* This is a throughput knob and is independent of SDHCI_DMA_THRESHOLD
63+
* (which controls when to switch from PIO to SDMA). Override in target
64+
* .config to match the largest expected single transfer for fewer
65+
* boundary IRQs; otherwise auto-select based on the threshold. */
66+
#ifndef SDHCI_DMA_BUFF_BOUNDARY
6167
#if (SDHCI_DMA_THRESHOLD > (256U * 1024U))
6268
#define SDHCI_DMA_BUFF_BOUNDARY SDHCI_SRS01_DMA_BUFF_512KB
6369
#if (SDHCI_DMA_THRESHOLD != (512U * 1024U))
@@ -99,6 +105,7 @@
99105
#warning "SDHCI_DMA_THRESHOLD rounded up to 4KB (minimum)"
100106
#endif
101107
#endif
108+
#endif /* !SDHCI_DMA_BUFF_BOUNDARY */
102109

103110
/* Timeouts */
104111
#ifndef SDHCI_INIT_TIMEOUT_US

src/boot_aarch64.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include "hal/versal.h"
3535
#elif defined(TARGET_zynq)
3636
#include "hal/zynq.h"
37-
#elif defined(TARGET_ls1028a)
37+
#elif defined(TARGET_nxp_ls1028a)
3838
#include "hal/nxp_ls1028a.h"
3939
#endif
4040

0 commit comments

Comments
 (0)