Skip to content

Commit 63d6d61

Browse files
committed
More peer review fixes and attempt to resolve CI build errors.
1 parent a49ec95 commit 63d6d61

8 files changed

Lines changed: 71 additions & 22 deletions

File tree

arch.mk

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -563,13 +563,23 @@ endif
563563
## RISCV (32-bit)
564564
ifeq ($(ARCH),RISCV)
565565
CROSS_COMPILE?=riscv32-unknown-elf-
566-
# GCC 12-14 split CSR/fence.i into separate extensions (zicsr, zifencei)
567-
# and require them explicitly. GCC 15+ re-implies them, and adding them
568-
# explicitly can cause multilib lookup failures. Detect by testing if a
569-
# CSR/fence.i instruction assembles WITHOUT the extension flag. If it
570-
# fails, add the extension.
571-
RISCV32_ZICSR := $(shell echo "void f(void){__asm__ volatile(\"csrr a0,mhartid\");}" | $(CROSS_COMPILE)gcc -march=rv32imac -mabi=ilp32 -x c -c - -o /dev/null 2>/dev/null || echo _zicsr)
572-
RISCV32_ZIFENCEI := $(shell echo "void f(void){__asm__ volatile(\"fence.i\");}" | $(CROSS_COMPILE)gcc -march=rv32imac -mabi=ilp32 -x c -c - -o /dev/null 2>/dev/null || echo _zifencei)
566+
# Detect zicsr/zifencei support: GCC 12+ may require these extensions
567+
# explicitly. However, GCC 15 decomposes arch strings (m→zmmul,
568+
# a→zaamo+zalrsc, c→zca) which can break multilib lookup.
569+
# Verify with a link test, not just compile, to catch multilib mismatches.
570+
RISCV32_ZICSR := $(shell echo "void _start(void){}" | \
571+
$(CROSS_COMPILE)gcc -march=rv32imac_zicsr -mabi=ilp32 -c -x c - -o /dev/null 2>/dev/null && echo _zicsr)
572+
RISCV32_ZIFENCEI := $(shell echo "void _start(void){}" | \
573+
$(CROSS_COMPILE)gcc -march=rv32imac_zifencei -mabi=ilp32 -c -x c - -o /dev/null 2>/dev/null && echo _zifencei)
574+
ifneq ($(RISCV32_ZICSR)$(RISCV32_ZIFENCEI),)
575+
RISCV32_EXT_LINK_OK := $(shell echo "void _start(void){}" | \
576+
$(CROSS_COMPILE)gcc -march=rv32imac$(RISCV32_ZICSR)$(RISCV32_ZIFENCEI) \
577+
-mabi=ilp32 -nostartfiles -x c - -o /dev/null 2>/dev/null && echo ok)
578+
ifneq ($(RISCV32_EXT_LINK_OK),ok)
579+
RISCV32_ZICSR :=
580+
RISCV32_ZIFENCEI :=
581+
endif
582+
endif
573583
ARCH_FLAGS=-march=rv32imac$(RISCV32_ZICSR)$(RISCV32_ZIFENCEI) -mabi=ilp32 -mcmodel=medany
574584
CFLAGS+=-fno-builtin-printf -DUSE_M_TIME -g -nostartfiles -DARCH_RISCV
575585
CFLAGS+=$(ARCH_FLAGS)
@@ -619,13 +629,20 @@ ifeq ($(ARCH),RISCV64)
619629
UPDATE_OBJS?=src/update_ram.o
620630
endif
621631

622-
# GCC 12-14 split CSR/fence.i into separate extensions (zicsr, zifencei)
623-
# and require them explicitly. GCC 15+ re-implies them, and adding them
624-
# explicitly can cause multilib lookup failures. Detect by testing if a
625-
# CSR/fence.i instruction assembles WITHOUT the extension flag. If it
626-
# fails, add the extension.
627-
RISCV64_ZICSR := $(shell echo "void f(void){__asm__ volatile(\"csrr a0,mhartid\");}" | $(CROSS_COMPILE)gcc -march=rv64imac -mabi=lp64 -x c -c - -o /dev/null 2>/dev/null || echo _zicsr)
628-
RISCV64_ZIFENCEI := $(shell echo "void f(void){__asm__ volatile(\"fence.i\");}" | $(CROSS_COMPILE)gcc -march=rv64imac -mabi=lp64 -x c -c - -o /dev/null 2>/dev/null || echo _zifencei)
632+
# Detect zicsr/zifencei support with link verification (see RV32 comment)
633+
RISCV64_ZICSR := $(shell echo "void _start(void){}" | \
634+
$(CROSS_COMPILE)gcc -march=rv64imafd_zicsr -mabi=lp64d -c -x c - -o /dev/null 2>/dev/null && echo _zicsr)
635+
RISCV64_ZIFENCEI := $(shell echo "void _start(void){}" | \
636+
$(CROSS_COMPILE)gcc -march=rv64imafd_zifencei -mabi=lp64d -c -x c - -o /dev/null 2>/dev/null && echo _zifencei)
637+
ifneq ($(RISCV64_ZICSR)$(RISCV64_ZIFENCEI),)
638+
RISCV64_EXT_LINK_OK := $(shell echo "void _start(void){}" | \
639+
$(CROSS_COMPILE)gcc -march=rv64imafd$(RISCV64_ZICSR)$(RISCV64_ZIFENCEI) \
640+
-mabi=lp64d -nostartfiles -x c - -o /dev/null 2>/dev/null && echo ok)
641+
ifneq ($(RISCV64_EXT_LINK_OK),ok)
642+
RISCV64_ZICSR :=
643+
RISCV64_ZIFENCEI :=
644+
endif
645+
endif
629646

630647
ifeq ($(RISCV_MMODE),1)
631648
# E51 core: rv64imac (no FPU, no crypto extensions)

config/examples/polarfire_mpfs250_m_qspi.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# PolarFire SoC MPFS250T M-Mode (Machine Mode) with SC QSPI Flash
22
#
33
# This configuration runs wolfBoot directly from eNVM in M-mode (Machine Mode),
4-
# and boots a test application from SC QSPI flash to on-chip LIM (no DDR).
4+
# and boots a test application from SC QSPI flash to L2 Scratchpad (no DDR).
55
#
66
# Boot flow:
77
# 1. eNVM (0x20220100) -> L2_SCRATCH (0x0A000000) - wolfBoot starts

docs/Targets.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1507,7 +1507,7 @@ $SC_INSTALL_DIR/eclipse/jre/bin/java -jar \
15071507
2. **L2 SRAM Execution** (0x0A000000): wolfBoot runs from scratchpad
15081508
3. **Hardware Init**: L2 cache configuration, UART setup
15091509
4. **QSPI Init**: SC QSPI controller (0x37020100), JEDEC ID read, 4-byte address mode
1510-
5. **Image Load**: Read signed image from QSPI flash (0x20000) to LIM (0x08000200)
1510+
5. **Image Load**: Read signed image from QSPI flash (0x20000) to L2 Scratchpad (0x0A010200)
15111511
6. **Verify & Boot**: SHA384 integrity check, ECC384 signature verification, jump to app
15121512
15131513
#### M-Mode QSPI Partition Layout

hal/mpfs250.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static void mpfs_signal_main_hart_started(void)
182182
* 2. Send IPI to wake the hart
183183
* 3. Wait for hart to acknowledge wake-up
184184
*
185-
* Returns: Number of harts successfully woken
185+
* Returns: Number of harts where wake was attempted
186186
*/
187187
int mpfs_wake_secondary_harts(void)
188188
{
@@ -1099,8 +1099,16 @@ static void qspi_uart_program(void)
10991099
wolfBoot_printf("QSPI-PROG: Erasing %u sector(s) at 0x%x...\r\n",
11001100
n_sectors, addr);
11011101
ext_flash_unlock();
1102-
for (s = 0; s < n_sectors; s++)
1103-
ext_flash_erase(addr + s * FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE);
1102+
for (s = 0; s < n_sectors; s++) {
1103+
int ret = ext_flash_erase(addr + s * FLASH_SECTOR_SIZE,
1104+
FLASH_SECTOR_SIZE);
1105+
if (ret < 0) {
1106+
wolfBoot_printf("QSPI-PROG: Erase failed at 0x%x (ret %d)\r\n",
1107+
addr + s * FLASH_SECTOR_SIZE, ret);
1108+
ext_flash_lock();
1109+
return;
1110+
}
1111+
}
11041112

11051113
/* "ERASED\r\n" must be the last bytes before the first ACK (0x06).
11061114
* Do not insert any wolfBoot_printf between here and the transfer loop. */
@@ -1109,6 +1117,7 @@ static void qspi_uart_program(void)
11091117
/* Chunk transfer: wolfBoot requests each 256-byte block with ACK 0x06 */
11101118
written = 0;
11111119
while (written < size) {
1120+
int ret;
11121121
uint32_t chunk_len = size - written;
11131122
if (chunk_len > QSPI_PROG_CHUNK)
11141123
chunk_len = QSPI_PROG_CHUNK;
@@ -1118,7 +1127,13 @@ static void qspi_uart_program(void)
11181127
for (i = 0; i < chunk_len; i++)
11191128
chunk[i] = uart_qspi_rx();
11201129

1121-
ext_flash_write(addr + written, chunk, (int)chunk_len);
1130+
ret = ext_flash_write(addr + written, chunk, (int)chunk_len);
1131+
if (ret < 0) {
1132+
wolfBoot_printf("QSPI-PROG: Write failed at 0x%x (ret %d)\r\n",
1133+
addr + written, ret);
1134+
ext_flash_lock();
1135+
return;
1136+
}
11221137
written += chunk_len;
11231138
}
11241139
ext_flash_lock();
@@ -1240,7 +1255,14 @@ int ext_flash_erase(uintptr_t address, int len)
12401255
#if defined(MMU) && !defined(WOLFBOOT_NO_PARTITIONS)
12411256
void* hal_get_dts_address(void)
12421257
{
1258+
#if defined(EXT_FLASH) && defined(NO_XIP)
1259+
/* Flash is not memory-mapped when using NO_XIP with external flash
1260+
* (e.g. SC SPI). DTS must be loaded via ext_flash_read, not direct
1261+
* dereference. Return NULL so the caller skips the direct-access path. */
1262+
return NULL;
1263+
#else
12431264
return (void*)WOLFBOOT_DTS_BOOT_ADDRESS;
1265+
#endif
12441266
}
12451267
#endif
12461268

src/boot_riscv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ void do_boot(const uint32_t *app_offset)
504504
* Note: -march=rv64imac does not define __riscv_zifencei, so
505505
* riscv_icache_sync() in elf.c is a no-op. We emit fence.i manually. */
506506
asm volatile("fence" ::: "memory");
507-
asm volatile(".word 0x0000100f" ::: "memory"); /* fence.i */
507+
asm volatile("fence.i" ::: "memory");
508508
asm volatile("jr %0" : : "r"(app_offset));
509509
__builtin_unreachable();
510510
#endif /* WOLFBOOT_MMODE_SMODE_BOOT */

src/boot_riscv_start.S

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ _reset:
186186
* Jump to main initialization code in L2 SRAM
187187
* From here on, we execute from L2 SRAM (faster than eNVM)
188188
*/
189-
la t0, .L_sram_entry
189+
lui t0, %hi(.L_sram_entry)
190+
addi t0, t0, %lo(.L_sram_entry)
190191
jr t0
191192

192193
/*

test-app/startup_riscv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ void __attribute__((naked)) isr_synctrap(void)
8181
{
8282
#ifdef WOLFBOOT_RISCV_MMODE
8383
asm volatile("csrr %0, mcause" : "=r"(synctrap_cause));
84+
asm volatile("mret");
8485
#else
8586
asm volatile("csrr %0, scause" : "=r"(synctrap_cause));
87+
asm volatile("sret");
8688
#endif
8789
}
8890

tools/scripts/mpfs_qspi_prog.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ def main():
8585
with open(bin_path, "rb") as f:
8686
data = f.read()
8787

88+
# Device-side rejects images > 2 MiB; fail fast here to avoid
89+
# waiting through prompt/erase only to have the target abort.
90+
MAX_IMAGE_SIZE = 0x200000 # 2 MiB, matches device-side check
91+
if len(data) > MAX_IMAGE_SIZE:
92+
print(f"Error: image too large ({len(data):,} bytes, max {MAX_IMAGE_SIZE:,})")
93+
sys.exit(1)
94+
8895
print(f"wolfBoot QSPI programmer for PolarFire SoC MPFS250")
8996
print(f" Port : {port_name} @ {BAUD_RATE} baud")
9097
print(f" Binary : {bin_path} ({len(data):,} bytes)")

0 commit comments

Comments
 (0)