diff --git a/config/examples/polarfire_mpfs250.config b/config/examples/polarfire_mpfs250.config index f7dd8922..2b05d8e2 100644 --- a/config/examples/polarfire_mpfs250.config +++ b/config/examples/polarfire_mpfs250.config @@ -9,7 +9,7 @@ DEBUG?=0 DEBUG_SYMBOLS?=1 DEBUG_UART?=1 VTOR?=1 -EXT_FLASH?=1 +EXT_FLASH?=0 SPI_FLASH?=0 NO_XIP?=1 NVM_FLASH_WRITEONCE?=0 @@ -39,7 +39,7 @@ NO_ARM_ASM?=0 WOLFBOOT_SECTOR_SIZE?=0x1000 # Load Partition to RAM Address -WOLFBOOT_LOAD_ADDRESS?=0x80200000 +WOLFBOOT_LOAD_ADDRESS?=0x8E000000 # Partition layout for PolarFire SoC MPFS250T # Using update_disk loader we just need to specify the partition number or A/B @@ -48,9 +48,12 @@ CFLAGS_EXTRA+=-DBOOT_PART_A=1 CFLAGS_EXTRA+=-DBOOT_PART_B=2 # DTS (Device Tree) -WOLFBOOT_LOAD_DTS_ADDRESS?=0x8a000000 +WOLFBOOT_LOAD_DTS_ADDRESS?=0x8A000000 +# Optional EMMC_SD debugging logs #CFLAGS_EXTRA+=-DDEBUG_MMC +# Optional disk debugging logs +#CFLAGS_EXTRA+=-DDEBUG_DISK # Used by test-application for ELF WOLFBOOT_PARTITION_BOOT_ADDRESS=0x80200000 diff --git a/docs/Targets.md b/docs/Targets.md index 9b77ed17..b44ca7bb 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -792,6 +792,15 @@ The PolarFire SoC is a 64-bit RISC-V SoC featuring a five-core CPU cluster (1× * Low power consumption * External flash support +### PolarFire SoC Files + +`hal/mpfs250.c` - Hardware abstraction layer implementation (UART and uSD) +`hal/mpfs250.h` - Register definitions and hardware interfaces +`hal/mpfs250.ld` - Linker script for the platform +`hal/mpfs.dts` / `hal/mpfs.dtb` - Device tree source and binary +`hal/mpfs.yaml` - HSS payload generator configuration +`hal/mpfs250.its` - For creating new FIT images with Kernel and DTB + ### Building PolarFire SoC All build settings come from .config file. For this platform use `TARGET=mpfs250` and `ARCH=RISCV64`. @@ -837,18 +846,20 @@ The HSS MMC boot source looks for GPT with GUID "21686148-6449-6E6F-744E-6565644 The resulting image from `hss-payload-generator` can be directly placed into GPT BIOS partition. The HSS tinyCLI supports the `USBDMSC` command to mount the eMMC or SD card as a USB device. You can then use "dd" to copy the boot image to the BOOT partition 2. Example: -``` -sudo dd if=wolfboot.bin of=/dev/sdc2 bs=512 +```sh +sudo dd if=wolfboot.bin of=/dev/sdc1 bs=512 && sudo cmp wolfboot.bin /dev/sdc1 ``` ### PolarFire testing This section describes how to build the test-application, create a custom uSD with required partitions and copying signing test-application to uSD partitions. -To use your own application (Linux FIT Image, ELF, etc) just replace test-app/image.elf with your own filename. +To use your own application (Linux FIT Image, ELF, etc) just replace test-app/image.elf with your own file (example "fitImage"). 1) Partition uSD card (replace /dev/sdc with your actual media, find using `lsblk`): +Note: adjust +64M for larger OFP A/B + ```sh sudo fdisk /dev/sdc < kernel.bin +$ mkimage -f hal/mpfs250.its fitImageNew +FIT description: PolarFire SoC MPFS250T +Created: Mon Dec 22 15:29:32 2025 + Image 0 (kernel-1) + Description: Kernel Image + Created: Mon Dec 22 15:29:32 2025 + Type: Kernel Image + Compression: uncompressed + Data Size: 19745280 Bytes = 19282.50 KiB = 18.83 MiB + Architecture: RISC-V + OS: Linux + Load Address: 0x80200000 + Entry Point: 0x80200000 + Hash algo: sha256 + Hash value: 800ce147fa91f367ec620936a59a1035c49971ed4b9080c96bdc547471e80487 + Image 1 (fdt-1) + Description: Flattened Device Tree blob + Created: Mon Dec 22 15:29:32 2025 + Type: Flat Device Tree + Compression: uncompressed + Data Size: 19897 Bytes = 19.43 KiB = 0.02 MiB + Architecture: RISC-V + Load Address: 0x8a000000 + Hash algo: sha256 + Hash value: 0b4efca8c0607c9a8f4f9a00ccb7691936e019f3181aab45e6d52dae91975039 + Default Configuration: 'conf@1' + Configuration 0 (conf@1) + Description: PolarFire SoC MPFS250T + Kernel: kernel-1 + FDT: fdt-1 + Hash algo: sha256 + Hash value: unavailable +``` ### Debugging PolarFire Soc @@ -946,117 +1016,66 @@ set architecture riscv:rv64 ### PolarFire Example Boot Output ``` -wolfBoot Version: 2.7.0 (Dec 17 2025 17:03:55) -mmc_set_timeout: timeout_val 500000 (12) -mmc_set_clock: requested khz: 400, actual khz: 400 -mmc_send_cmd: cmd_index: 0, cmd_arg: 00000000, resp_type: 0 -mmc_send_cmd: cmd_index: 8, cmd_arg: 00000100, resp_type: 9 -mmc_init: xpc:0, si8r:1, max_ma (3.3v:128 1.8v:128) -mmc_send_cmd: cmd_index: 55, cmd_arg: 00000000, resp_type: 1 -mmc_send_cmd: cmd_index: 41, cmd_arg: 00000000, resp_type: 4 -ocr_reg: 0x40FF8000 -mmc_init: sending OCR arg: 0x41200000 -mmc_send_cmd: cmd_index: 55, cmd_arg: 00000000, resp_type: 1 -mmc_send_cmd: cmd_index: 41, cmd_arg: 41200000, resp_type: 4 -ocr_reg: 0x40FF8000 -mmc_send_cmd: cmd_index: 55, cmd_arg: 00000000, resp_type: 1 -mmc_send_cmd: cmd_index: 41, cmd_arg: 41200000, resp_type: 4 -ocr_reg: 0xC1FF8000 -mmc_send_cmd: cmd_index: 2, cmd_arg: 00000000, resp_type: 3 -mmc_send_cmd: cmd_index: 3, cmd_arg: 00000000, resp_type: 8 -mmc_init: rca: 43690 -mmc_send_cmd: cmd_index: 9, cmd_arg: AAAA0000, resp_type: 3 -mmc_init: sector size: 512 -mmc_init: sector count: 62333952 -mmc_send_cmd: cmd_index: 7, cmd_arg: AAAA0000, resp_type: 2 -mmc_send_cmd: cmd_index: 55, cmd_arg: AAAA0000, resp_type: 1 -mmc_send_cmd: cmd_index: 6, cmd_arg: 00000002, resp_type: 1 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_send_cmd: cmd_index: 16, cmd_arg: 00000008, resp_type: 1 -mmc_send_cmd: cmd_index: 55, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 51, block_addr: 00000000, dst 0x801FFCD0, sz: 8 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 6, block_addr: 00000001, dst 0x801FFC38, sz: 64 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 6, block_addr: 80000001, dst 0x801FFC38, sz: 64 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -mmc_set_clock: requested khz: 50000, actual khz: 50000 +wolfBoot Version: 2.7.0 (Dec 22 2025 14:14:37) Reading MBR... -disk_read: drv:0, start:0, count:512, dst:0x801FF918 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00000000, dst 0x801FF918, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 Found GPT PTE at sector 1 Found valid boot signature in MBR -disk_read: drv:0, start:512, count:512, dst:0x801FF918 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00000001, dst 0x801FF918, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 Valid GPT partition table Current LBA: 0x1 Backup LBA: 0x3B723FF Max number of partitions: 128 Software limited: only allowing up to 16 partitions per disk. -Disk size: 1850178048 -disk_read: drv:0, start:1024, count:128, dst:0x801FF818 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00000002, dst 0x801FF588, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -disk0.p0 (0_3FFFE00h@ 0_400000) -disk_read: drv:0, start:1152, count:128, dst:0x801FF818 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00000002, dst 0x801FF588, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -disk0.p1 (0_3FFFE00h@ 0_400000) -disk_read: drv:0, start:1280, count:128, dst:0x801FF818 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00000002, dst 0x801FF588, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -disk0.p2 (0_3FFFE00h@ 0_400000) -disk_read: drv:0, start:1408, count:128, dst:0x801FF818 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00000002, dst 0x801FF588, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -disk0.p3 (0_3FFFE00h@ 0_400000) -disk_read: drv:0, start:1536, count:128, dst:0x801FF818 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00000003, dst 0x801FF588, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 +Disk size: 1849146880 +disk0.p0 (0_7FFE00h@ 0_100000) +disk0.p1 (0_3FFFE00h@ 0_900000) +disk0.p2 (0_3FFFE00h@ 0_4900000) +disk0.p3 (7_65AFFE00h@ 0_8900000) Total partitions on disk0: 4 Checking primary OS image in 0,1... -disk_read: drv:0, start:4194304, count:512, dst:0x801FFDA0 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00002000, dst 0x801FFDA0, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 Checking secondary OS image in 0,2... -disk_read: drv:0, start:4194304, count:512, dst:0x801FFDA0 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: cmd_index: 17, block_addr: 00002000, dst 0x801FFDA0, sz: 512 -mmc_send_cmd: cmd_index: 13, cmd_arg: AAAA0000, resp_type: 1 -mmc_read: status: 0 -No valid OS image found in either partition 1 or 2 -wolfBoot: PANIC! +Versions, A:1 B:1 +Load address 0x8E000000 +Attempting boot from P:A +Boot partition: 0x801FFDA0 (sz 19767000, ver 0x1, type 0x601) +Loading image from disk...done. +Boot partition: 0x8E000000 (sz 19767000, ver 0x1, type 0x601) +Checking image integrity...done. +Verifying image signature...done. +Firmware Valid. +Flattened uImage Tree: Version 17, Size 19767000 +Loading Image kernel-1: 0x8E0002C8 -> 0x80200000 (19745280 bytes) +Image kernel-1: 0x80200000 (19745280 bytes) +Loading Image fdt-1: 0x8F2D4DCC -> 0x8A000000 (19897 bytes) +Image fdt-1: 0x8A000000 (19897 bytes) +Loading DTS: 0x8A000000 -> 0x8A000000 (19897 bytes) +Loading elf at 0x80200000 +Invalid elf, falling back to raw binary +Booting at 80200000 +[ 0.000000] Linux version 6.12.22-linux4microchip+fpga-2025.07-g032a7095303a (oe-user@oe-host) (riscv64-oe-linux-gcc (GCC) 13.3.0, GNU ld (GNU Binutils) 2.42.0.20240723) #1 SMP Tue Jul 22 10:04:20 UTC 2025 +[ 0.000000] Machine model: Microchip PolarFire-SoC VIDEO Kit +[ 0.000000] SBI specification v1.0 detected +[ 0.000000] SBI implementation ID=0x8 Version=0x10002 +[ 0.000000] SBI TIME extension detected +[ 0.000000] SBI IPI extension detected +[ 0.000000] SBI RFENCE extension detected +[ 0.000000] SBI SRST extension detected +[ 0.000000] earlycon: ns16550a0 at MMIO32 0x0000000020100000 (options '115200n8') +... ``` ### PolarFire TODO -1) Add support for full HSS replacement using wolfboot. -2) Add support for eMMC and QSPI NOR flash - +* Add eMMC/SD features: + - Multi-block read (CMD18 support) + - DMA read support + - Write support + - eMMC support (not just SD) +* Add support for reading serial number and modifying ethernet MAC in device tree +* Add support for QSPI NOR flash +* Add support for full HSS replacement using wolfboot + - Machine level assembly startup + - DDR driver ## STM32F7 diff --git a/hal/mpfs.yaml b/hal/mpfs.yaml index ab397c94..3f29d1d1 100644 --- a/hal/mpfs.yaml +++ b/hal/mpfs.yaml @@ -4,14 +4,13 @@ set-name: 'PolarFire-SoC-HSS::wolfBoot' hart-entry-points: { - u54_1: '0x80200000', - u54_2: '0x80200000', - u54_3: '0x80200000', - u54_4: '0x80200000' + u54_1: '0x80000000', + u54_2: '0x80000000', + u54_3: '0x80000000', + u54_4: '0x80000000' } payloads: wolfboot.elf: { - exec-addr: '0x80200000', owner-hart: u54_1, secondary-hart: u54_2, secondary-hart: u54_3, diff --git a/hal/mpfs250.its b/hal/mpfs250.its new file mode 100644 index 00000000..f7465bba --- /dev/null +++ b/hal/mpfs250.its @@ -0,0 +1,44 @@ +/dts-v1/; + +/ { + description = "PolarFire SoC MPFS250T"; + #address-cells = <1>; + + images { + kernel-1 { + description = "Kernel Image"; + data = /incbin/("../kernel.bin"); + type = "kernel"; + arch = "riscv"; + os = "linux"; + compression = "none"; + load = <0x80200000>; + entry = <0x80200000>; + hash { + algo = "sha256"; + }; + }; + fdt-1 { + description = "Flattened Device Tree blob"; + data = /incbin/("mpfs.dtb"); + type = "flat_dt"; + arch = "riscv"; + compression = "none"; + load = <0x8a000000>; + hash { + algo = "sha256"; + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + description = "PolarFire SoC MPFS250T"; + kernel = "kernel-1"; + fdt = "fdt-1"; + hash { + algo = "sha256"; + }; + }; + }; +}; \ No newline at end of file diff --git a/hal/mpfs250.ld b/hal/mpfs250.ld index 1542d663..49d1e640 100644 --- a/hal/mpfs250.ld +++ b/hal/mpfs250.ld @@ -9,7 +9,7 @@ MEMORY { /* The first 0x100 bytes of eNVM are used for boot ROM secure boot meta information */ FLASH_ENVM (rx) : ORIGIN = 0x20220100, LENGTH = 128k - 0x100 - DDR (rx) : ORIGIN = 0x80200000, LENGTH = 1028k + DDR (rx) : ORIGIN = 0x80000000, LENGTH = 1028k L2_SCRATCH (rwx) : ORIGIN = 0x0A000000, LENGTH = 256k } diff --git a/hal/zynq.c b/hal/zynq.c index 0585b647..2a0f3e18 100644 --- a/hal/zynq.c +++ b/hal/zynq.c @@ -200,7 +200,7 @@ typedef struct pmu_aes { /* requires PMU built with -DENABLE_EFUSE_ACCESS=1 */ #define PM_EFUSE_ACCESS 0x35 typedef struct pmu_efuse { - uint64_t src; /* adress of data buffer */ + uint64_t src; /* address of data buffer */ uint32_t size; /* size in words */ uint32_t offset; /* offset */ uint32_t flag; /* 0: to read efuse, 1: to write efuse */ diff --git a/src/disk.c b/src/disk.c index 951febe0..692e865e 100644 --- a/src/disk.c +++ b/src/disk.c @@ -226,7 +226,12 @@ int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf) if (len < 0) { return -1; } + ret = disk_read(drv, p->start + off, len, buf); +#ifdef DEBUG_DISK + wolfBoot_printf("disk_part_read: drv: %d, part: %d, off: %llu, sz: %llu, " + "buf: %p, ret %d\r\n", drv, part, p->start + off, len, buf, ret); +#endif if (ret == 0) { ret = len; /* success expects to return the number of bytes read */ } @@ -262,6 +267,10 @@ int disk_part_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t return -1; } ret = disk_write(drv, p->start + off, len, buf); +#ifdef DEBUG_DISK + wolfBoot_printf("disk_part_write: drv: %d, part: %d, off: %llu, sz: %llu, " + "buf: %p, ret %d\r\n", drv, part, p->start + off, sz, buf, ret); +#endif if (ret == 0) { ret = len; /* success expects to return the number of bytes written */ } diff --git a/src/fdt.c b/src/fdt.c index 85259591..a6889742 100644 --- a/src/fdt.c +++ b/src/fdt.c @@ -836,7 +836,7 @@ void* fit_load_image(void* fdt, const char* image, int* lenp) image, data, load, len); memcpy(load, data, len); - /* load should always have entry, but if not use load adress */ + /* load should always have entry, but if not use load address */ data = (entry != NULL) ? entry : load; } wolfBoot_printf("Image %s: %p (%d bytes)\n", image, data, len); diff --git a/test-app/Makefile b/test-app/Makefile index 3927f0d5..0a63829f 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -132,6 +132,10 @@ ifeq ($(ARCH),RISCV) APP_OBJS+=startup_riscv.o vector_riscv.o endif +ifeq ($(ARCH),RISCV64) + APP_OBJS+=startup_riscv.o vector_riscv.o +endif + ifeq ($(ARCH),ARM) APP_OBJS+=startup_arm.o endif diff --git a/test-app/RISCV64-mpfs250.ld b/test-app/RISCV64-mpfs250.ld index 975a44e6..7c6d6104 100644 --- a/test-app/RISCV64-mpfs250.ld +++ b/test-app/RISCV64-mpfs250.ld @@ -6,6 +6,10 @@ _Min_Heap_Size = 0x00002000; /* required amount of heap */ _Min_Stack_Size = 0x00002000; /* required amount of stack */ +OUTPUT_ARCH( "riscv" ) + +ENTRY( _reset ) + /* Memory areas */ MEMORY { @@ -24,6 +28,7 @@ SECTIONS { . = ALIGN(8); KEEP(*(.isr_vector)) /* Startup code */ + _start_vector = .; . = ALIGN(8); } >IRAM diff --git a/test-app/app_mpfs250.c b/test-app/app_mpfs250.c index 49513c17..57d219b8 100644 --- a/test-app/app_mpfs250.c +++ b/test-app/app_mpfs250.c @@ -36,6 +36,7 @@ void main(void) { + uart_init(); hal_init(); wolfBoot_printf("========================\r\n");