From f08c8211904ac9feb2598aa354b0b7bddc245bfe Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 Jul 2026 21:30:42 +0700 Subject: [PATCH] address #3787 Codex round 2: board-gate PHY resets, session robustness The board-specific PHY-reset nets move behind a board.h opt-in (TRACE_ETM_QUIET_ENET_PHY on same70_xplained and mimxrt1170_evkb) so other boards of those families cannot inherit a foreign GPIO write; the chip-level trace pin muxes stay family-wide by design (same pattern as stm32h7). same70 reference: width 1 is the validated default until the J403.16 rework, and the hooks now wait (bounded) for PCKRDY3 before Ozone arms trace. ra8m1 reference caches the boot ROM in AfterTargetConnect so --attach sessions decode ROM execution too. etm_capture rejects an unexpanded CMake JLINK_DEVICE with a clear error; PIO-USB + TRACE_ETM on RP2350 is now a compile error (48 MHz trace clock is too slow for PIO-USB and a runtime switch would desync the stream); etm_profile keeps same-named statics from different modules as distinct rows. Build-verified: same70_xplained, mimxrt1170_evkb, raspberry_pi_pico2. --- .claude/skills/etm-trace/scripts/etm_capture.py | 4 ++++ .claude/skills/etm-trace/scripts/etm_profile.py | 4 ++++ hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h | 5 +++++ hw/bsp/imxrt/family.c | 7 +++++-- hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug | 8 +++++--- hw/bsp/rp2040/family.c | 3 +++ hw/bsp/same7x/boards/same70_xplained/board.h | 4 ++++ .../boards/same70_xplained/ozone/same70.jdebug | 12 ++++++++++++ hw/bsp/same7x/family.c | 5 ++++- 9 files changed, 46 insertions(+), 6 deletions(-) diff --git a/.claude/skills/etm-trace/scripts/etm_capture.py b/.claude/skills/etm-trace/scripts/etm_capture.py index af6c1ec68..ccde886f2 100644 --- a/.claude/skills/etm-trace/scripts/etm_capture.py +++ b/.claude/skills/etm-trace/scripts/etm_capture.py @@ -160,6 +160,10 @@ def resolve_board(board): for path in glob.glob(f"{REPO_ROOT}/hw/bsp/*/boards/{board}/board.cmake"): m = re.search(r'JLINK_DEVICE\s+([^\s)]+)\s*\)', open(path).read()) if m: + if "${" in m.group(1): + sys.exit(f"error: {path} defines JLINK_DEVICE via an " + f"unexpanded CMake variable ({m.group(1)}) - pass " + f"--device explicitly for this board") cfg["device"] = m.group(1) cfg["ref"] = path break diff --git a/.claude/skills/etm-trace/scripts/etm_profile.py b/.claude/skills/etm-trace/scripts/etm_profile.py index b00f6f1d2..b859328ca 100644 --- a/.claude/skills/etm-trace/scripts/etm_profile.py +++ b/.claude/skills/etm-trace/scripts/etm_profile.py @@ -61,6 +61,10 @@ def parse_profile(path): totals["run"], totals["fetch"] = run, fetch elif name == "[Unaccounted]": totals["unaccounted"] = fetch + elif name in funcs and funcs[name]["module"] != module: + # same-named static from another module: keep both rows distinct + funcs[f"{name} [{module}]"] = {"module": module, "run": run, + "fetch": fetch} else: funcs[name] = {"module": module, "run": run, "fetch": fetch} for module, name, cells in rows(lines[cov_start:prof_start]): diff --git a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h index a6332d896..c041fd47b 100644 --- a/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h +++ b/hw/bsp/imxrt/boards/mimxrt1170_evkb/board.h @@ -35,6 +35,11 @@ // required since iMXRT MCUX-SDK include this file for board size #define BOARD_FLASH_SIZE (0x1000000U) +// TRACE_ETM: this board wires the 100M PHY reset (ENET_RST_B) to +// GPIO_LPSR_04; the family trace init holds it in reset (RMII lines share +// the trace pads) +#define TRACE_ETM_QUIET_ENET_PHY 1 + // LED: IOMUXC_GPIO_AD_04_GPIO9_IO03 #define LED_PORT BOARD_INITPINS_USER_LED_PERIPHERAL #define LED_PIN BOARD_INITPINS_USER_LED_CHANNEL diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c index 1b1a1f1d8..4bd7993f0 100644 --- a/hw/bsp/imxrt/family.c +++ b/hw/bsp/imxrt/family.c @@ -131,12 +131,15 @@ static void trace_etm_init(void) { // breaks ETM trace - switch the pad to GPIO (MIMXRT1170-EVKB HUG 3.2) IOMUXC_SetPinMux(IOMUXC_GPIO_LPSR_10_GPIO12_IO10, 0U); +#ifdef TRACE_ETM_QUIET_ENET_PHY // Hold the 100M Ethernet PHY (RTL8201) in reset: its RMII lines are - // hardwired to the trace pads and drive against the stream at speed - // (ENET_RST_B = GPIO_LPSR_04) + // hardwired to the trace pads and drive against the stream at speed. The + // reset net is a BOARD property (mimxrt1170_evkb: ENET_RST_B = + // GPIO_LPSR_04), hence the board.h gate. IOMUXC_SetPinMux(IOMUXC_GPIO_LPSR_04_GPIO12_IO04, 0U); GPIO12->GDIR |= (1U << 4); GPIO12->DR &= ~(1U << 4); +#endif // TRACE0-3 + TRACE_CLK on GPIO_DISP_B2_02..06, fast slew + high drive IOMUXC_SetPinMux(IOMUXC_GPIO_DISP_B2_02_ARM_TRACE00, 0U); diff --git a/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug b/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug index 927eeda72..02d568240 100644 --- a/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug +++ b/hw/bsp/ra/boards/ra8m1_ek/ozone/ra8m1.jdebug @@ -41,12 +41,14 @@ void BeforeTargetConnect (void) { * AfterTargetConnect * * Function description -* Event handler routine. Optional. +* Cache the boot-ROM range for the trace decoder on --attach sessions +* too (the download hook that normally does this is skipped on attach). * ********************************************************************** */ -//void AfterTargetConnect (void) { -//} +void AfterTargetConnect (void) { + Exec.Command("ReadIntoTraceCache 0x0 0x10000"); +} /********************************************************************* * diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c index f0d6ba245..e12f51b14 100644 --- a/hw/bsp/rp2040/family.c +++ b/hw/bsp/rp2040/family.c @@ -180,6 +180,9 @@ void board_init(void) #if (CFG_TUH_ENABLED && CFG_TUH_RPI_PIO_USB) || (CFG_TUD_ENABLED && CFG_TUD_RPI_PIO_USB) // Set the system clock to a multiple of 12mhz for bit-banging USB with pico-usb #if defined(PICO_RP2350) && PICO_RP2350 == 1 + #ifdef TRACE_ETM + #error "TRACE_ETM pins clk_sys to 48 MHz (board.cmake) - too slow for PIO-USB, and a runtime clock switch desyncs the trace stream" + #endif set_sys_clock_khz(156000, true); // rp2350 default is 150Mhz #else set_sys_clock_khz(120000, true); // rp2040 default is 125Mhz diff --git a/hw/bsp/same7x/boards/same70_xplained/board.h b/hw/bsp/same7x/boards/same70_xplained/board.h index 85e23deb8..86edf606f 100644 --- a/hw/bsp/same7x/boards/same70_xplained/board.h +++ b/hw/bsp/same7x/boards/same70_xplained/board.h @@ -52,6 +52,10 @@ extern "C" { #define UART_PORT_CLOCK ID_USART1 #define BOARD_USART USART1 +// TRACE_ETM: this board wires the KSZ8081 PHY reset to PC10; the family +// trace init holds it in reset (RMII rx lines share the trace pads) +#define TRACE_ETM_QUIET_ENET_PHY 1 + static inline void board_vbus_set(uint8_t rhport, bool state) { (void) rhport; (void) state; diff --git a/hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug b/hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug index 0fde09716..f024f0ceb 100644 --- a/hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug +++ b/hw/bsp/same7x/boards/same70_xplained/ozone/same70.jdebug @@ -64,6 +64,12 @@ void AfterTargetReset (void) { // in the post-reset/post-download hooks, not AfterTargetConnect. Target.WriteU32 (0x400E064C, 0x00000014); // PMC_PCK3: CSS=MCK, PRESS=/2 Target.WriteU32 (0x400E0600, 0x00000800); // PMC_SCER: PCK3 on + // wait for PCKRDY3 (bounded) before Ozone arms the trace components + int i; + i = 0; + while (((Target.ReadU32 (0x400E0668) & 0x00000800) == 0) && (i < 100)) { + i = i + 1; + } } /********************************************************************* @@ -100,4 +106,10 @@ void AfterTargetDownload (void) { // in the post-reset/post-download hooks, not AfterTargetConnect. Target.WriteU32 (0x400E064C, 0x00000014); // PMC_PCK3: CSS=MCK, PRESS=/2 Target.WriteU32 (0x400E0600, 0x00000800); // PMC_SCER: PCK3 on + // wait for PCKRDY3 (bounded) before Ozone arms the trace components + int i; + i = 0; + while (((Target.ReadU32 (0x400E0668) & 0x00000800) == 0) && (i < 100)) { + i = i + 1; + } } diff --git a/hw/bsp/same7x/family.c b/hw/bsp/same7x/family.c index d99c17efb..8ec6a708b 100644 --- a/hw/bsp/same7x/family.c +++ b/hw/bsp/same7x/family.c @@ -65,13 +65,16 @@ void board_init(void) { #if defined(TRACE_ETM) // same70_xplained J403 (Cortex Debug+ETM footprint, bottom side) carries // 4-bit trace: TRACECLK=PD8 (peripheral D), TRACED0-3=PD4-7 (peripheral C). +#ifdef TRACE_ETM_QUIET_ENET_PHY // The trace pins double as the Ethernet PHY's RMII receive lines // (PD4=CRS_DV, PD5/6=RXD0/1, PD7=RXER - PHY OUTPUTS): hold the KSZ8081 in - // reset (PHY_RESET=PC10 low) or it drives against the trace stream. + // reset or it drives against the trace stream. The reset net is a BOARD + // property (same70_xplained: PHY_RESET=PC10), hence the board.h gate. _pmc_enable_periph_clock(ID_PIOC); gpio_set_pin_level(GPIO(GPIO_PORTC, 10), false); gpio_set_pin_direction(GPIO(GPIO_PORTC, 10), GPIO_DIRECTION_OUT); gpio_set_pin_function(GPIO(GPIO_PORTC, 10), GPIO_PIN_FUNCTION_OFF); +#endif // The TPIU is clocked from PCK3 (datasheet 16.7.4) - run it from MCK. // skip if the debugger already started PCK3 (reprogramming glitches the