Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/test-configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,15 @@ jobs:
config-file: ./config/examples/zynqmp.config
make-args: CFLAGS_EXTRA=-DWOLFBOOT_ZYNQMP_PHY_INIT

zynqmp_phy_delay_test:
uses: ./.github/workflows/test-build-aarch64.yml
with:
arch: aarch64
config-file: ./config/examples/zynqmp.config
# Exercise a custom step list using every op (GPIO, WR, RD, DELAY)
# plus BOOT_BENCHMARK's hal_get_timer_us dependency.
make-args: BOOT_BENCHMARK=1 CFLAGS_EXTRA="-DWOLFBOOT_ZYNQMP_PHY_INIT -DZYNQMP_PHY_INIT_STEPS={ZYNQMP_PHY_OP_GPIO,0,1},{ZYNQMP_PHY_OP_DELAY,0,10},{ZYNQMP_PHY_OP_WR,0x1E,0x0819},{ZYNQMP_PHY_OP_RD,0x1F,0}"

zynq7000_test:
uses: ./.github/workflows/test-build.yml
with:
Expand Down
41 changes: 27 additions & 14 deletions hal/zynq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1998,13 +1998,21 @@ void hal_delay_ms(uint64_t ms)
}
}

/* Fallback if CNTFRQ_EL0 is unset (no ATF/BL31); ZynqMP counter is 100 MHz */
#ifndef ZYNQMP_TIMER_CLK_FREQ
#define ZYNQMP_TIMER_CLK_FREQ 100000000ULL
#endif

uint64_t hal_timer_ms(void)
{
uint64_t val;
unsigned long cntfrq;
unsigned long cntpct;
asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq));
asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
/* AArch64 UDIV by 0 yields 0, which would hang hal_delay_ms() */
if (cntfrq == 0)
cntfrq = ZYNQMP_TIMER_CLK_FREQ;
val = cntpct * 1000;
val /= cntfrq;
return val;
Expand Down Expand Up @@ -2169,6 +2177,9 @@ static void zynq_phy_init(void)
(int)steps[i].arg0, (int)rval);
}
break;
case ZYNQMP_PHY_OP_DELAY:
hal_delay_ms(steps[i].arg1);
break;
default:
break;
}
Expand Down Expand Up @@ -2573,17 +2584,11 @@ void RAMFUNCTION ext_flash_unlock(void)

}

/* The following helpers (hal_get_timer_us, hal_get_dts_address, hal_dts_fixup)
* are only compiled into the wolfBoot binary. The test-app build also links
* hal/zynq.o but must not pull in FDT/MMU-specific code, so __WOLFBOOT gates
* these symbols out of that build. */
#if defined(MMU) && defined(__WOLFBOOT)
/* Fallback timer frequency if CNTFRQ_EL0 is not configured (e.g. boot path
* that did not run ATF/BL31). ZynqMP system counter is 100 MHz. */
#ifndef ZYNQMP_TIMER_CLK_FREQ
#define ZYNQMP_TIMER_CLK_FREQ 100000000ULL
#endif

/* hal_get_timer_us serves the BENCHMARK_* macros and update_disk
* (include/hal.h); the extra gate terms keep it available to every build
* variant that can reference it, including the test-app link. */
#if (defined(MMU) && defined(__WOLFBOOT)) || \
defined(WOLFBOOT_UPDATE_DISK) || defined(BOOT_BENCHMARK)
/* Get current time in microseconds using ARMv8 generic timer */
uint64_t hal_get_timer_us(void)
{
Expand All @@ -2595,10 +2600,18 @@ uint64_t hal_get_timer_us(void)
* (matches hal/versal.c). */
if (freq == 0)
freq = ZYNQMP_TIMER_CLK_FREQ;
/* Use __uint128_t to avoid overflow of (count * 1e6) at long uptimes
* (would overflow uint64_t after ~51h at 100MHz). */
return (uint64_t)(((__uint128_t)count * 1000000ULL) / freq);
/* Split divide: no (count * 1e6) uint64 overflow at long uptimes and
* no libgcc 128-bit helper (__udivti3) in links without one */
return (count / freq) * 1000000ULL +
((count % freq) * 1000000ULL) / freq;
}
#endif /* (MMU && __WOLFBOOT) || WOLFBOOT_UPDATE_DISK || BOOT_BENCHMARK */

/* The following helpers (hal_get_dts_address, hal_dts_fixup) are only
* compiled into the wolfBoot binary. The test-app build also links
* hal/zynq.o but must not pull in FDT/MMU-specific code, so __WOLFBOOT gates
* these symbols out of that build. */
#if defined(MMU) && defined(__WOLFBOOT)

void* hal_get_dts_address(void)
{
Expand Down
2 changes: 2 additions & 0 deletions hal/zynq.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,8 @@
#define ZYNQMP_PHY_OP_GPIO 0 /* write arg1 to ZYNQMP_PHY_GPIO_ADDR */
#define ZYNQMP_PHY_OP_WR 1 /* MDIO write: reg=arg0, val=arg1 */
#define ZYNQMP_PHY_OP_RD 2 /* MDIO read: reg=arg0 (arg1 ignored) */
#define ZYNQMP_PHY_OP_DELAY 3 /* delay arg1 ms, max 65535 (arg0
* ignored); e.g. PHY reset settle */

/* Default sequence: read the PHY ID registers (2, 3) as a diagnostic. With
* DEBUG_UART=1 this prints the ID and confirms MDIO reached the PHY. Override
Expand Down
Loading