Cleanups and improvements

pull/655/head
David Garske 2025-12-19 15:41:19 -08:00 committed by Daniele Lacamera
parent 0292da582b
commit 3317fba381
8 changed files with 131 additions and 102 deletions

View File

@ -22,6 +22,8 @@ DUALBANK_SWAP?=0
PKA?=0
ENCRYPT=0
WOLFTPM?=0
ELF?=1
#DEBUG_ELF?=1
# Optionally allow downgrade to older valid version in update partition
ALLOW_DOWNGRADE?=0

View File

@ -831,63 +831,92 @@ Example one-shot command:
cp ./config/examples/polarfire_mpfs250.config .config && make clean && make wolfboot.elf && size wolfboot.elf && hss-payload-generator -vvv -c ./hal/mpfs.yaml wolfboot.bin && file wolfboot.bin && ls -la wolfboot.bin
```
#### Build PolarFire test-application, sign it and apply to uSD
```sh
# make test-app
make test-app/image.elf
# assemble GPT image
dd if=/dev/zero of=app.bin bs=1M count=64
/sbin/fdisk app.bin <<EOF
g
n
1
+16M
n
+16M
x
n
1
OFP_A
n
2
OFP_B
r
w
EOF
cp test-app/image.elf image.bin
tools/keytools/sign $SIGN $HASH image.bin wolfboot_signing_private_key.der 1
tools/keytools/sign $SIGN $HASH image.bin wolfboot_signing_private_key.der 2
dd if=image_v1_signed.bin of=app.bin bs=512 seek=2048 conv=notrunc
dd if=image_v2_signed.bin of=app.bin bs=512 seek=34816 conv=notrunc
```
### Flashing PolarFire SoC
The HSS MMC boot source looks for GPT with GUID "21686148-6449-6E6F-744E-656564454649" or sector "0" if no GPT found. That GUID is the default "BIOS" boot partition.
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/sde2 bs=1024
sudo dd if=wolfboot.bin of=/dev/sdc2 bs=512
```
Flashing to eNVM:
### PolarFire testing
The boot rom expects a 0x100 byte secure boot header added. It also requires the .ld is offset by 0x100 to leave room for this. The mpfsBootmodeProgrammer adds 0x100 of meta information for secure boot.
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.
```sh
$SC_INSTALL_DIR/eclipse/jre/bin/java -jar \
$SC_INSTALL_DIR/extras/mpfs/mpfsBootmodeProgrammer.jar \
--bootmode 1 --die MPFS250T --package FCVG484 --workdir $PWD wolfboot.elf
# make test-app
make test-app/image.elf
```
Note: wolfBoot does not support running from eNVM in machine mode yet.
```sh
# Partition uSD card
sudo fdisk /dev/sdc <<EOF
g
n
1
+8M
n
2
+64M
n
3
+64M
n
4
t
1
4
x
n
2
OFP_A
n
3
OFP_B
r
p
w
EOF
```
Result should look like:
```
Disk /dev/sdc: 29.72 GiB, 31914983424 bytes, 62333952 sectors
Disk model: MassStorageClass
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 9A5E3FBC-AAB2-483E-941C-7797802BD173
Device Start End Sectors Size Type
/dev/sdc1 2048 18431 16384 8M BIOS boot
/dev/sdc2 18432 149503 131072 64M Linux filesystem
/dev/sdc3 149504 280575 131072 64M Linux filesystem
/dev/sdc4 280576 62332927 62052352 29.6G Linux filesystem
```
```sh
# Sign image with version 1
./tools/keytools/sign --ecc384 --sha384 test-app/image.elf wolfboot_signing_private_key.der 1
# Copy signed image to both OFP partitions
sudo dd if=image_v1_signed.bin of=/dev/sdc2 bs=512
sudo dd if=image_v1_signed.bin of=/dev/sdc2 bs=512
# Copy wolfBoot to BIOS boot partition
sudo dd if=wolfboot.bin of=/dev/sdc1 bs=512
```
### Debugging PolarFire Soc

View File

@ -46,7 +46,6 @@
#define DEBUG_MMC
/* Placeholder functions - to be implemented */
void hal_init(void)
{
wolfBoot_printf("wolfBoot Version: %s (%s %s)\n",
@ -269,7 +268,7 @@ uint32_t mmc_set_clock(uint32_t clock_khz)
base_clk_khz = (reg & EMMC_SD_SRS16_BCSDCLK_MASK) >> EMMC_SD_SRS16_BCSDCLK_SHIFT;
if (base_clk_khz == 0) {
/* error getting base clock */
return 0;
return -1;
}
base_clk_khz *= 1000; /* convert MHz to kHz */
@ -427,14 +426,13 @@ int mmc_power_init_seq(uint32_t voltage)
if (status == 0) {
/* send CMD0 (go idle) to reset card */
status = mmc_send_cmd(MMC_CMD0_GO_IDLE, 0, EMMC_SD_RESP_NONE);
}
if (status == 0) {
mmc_delay(DEFAULT_DELAY);
if (status == 0) {
mmc_delay(DEFAULT_DELAY);
/* send the operating conditions command */
status = mmc_send_cmd(SD_CMD8_SEND_IF_COND, IF_COND_27V_33V,
EMMC_SD_RESP_R7);
}
/* send the operating conditions command */
status = mmc_send_cmd(SD_CMD8_SEND_IF_COND, IF_COND_27V_33V,
EMMC_SD_RESP_R7);
}
return status;
}
@ -553,6 +551,7 @@ int mmc_set_bus_width(uint32_t bus_width)
return status;
}
/* helper to get bits from the response registers */
static uint32_t get_srs_bits(int from, int count)
{
volatile uint32_t *resp = ((volatile uint32_t*)(EMMC_SD_BASE + 0x210));
@ -564,8 +563,8 @@ static uint32_t get_srs_bits(int from, int count)
off = from / 32;
shft = from & 31;
ret = resp[off] >> shft;
if (from + shft > 32) {
ret |= resp[off + 1] << (32 - shft) % 32;
if ((from + shft) > 32) {
ret |= resp[off + 1] << ((32 - shft) % 32);
}
return ret & mask;
}
@ -806,34 +805,29 @@ int mmc_init(void)
if (status == 0) {
/* Get sector size and count */
uint32_t csd_struct;
uint32_t c_size = 0;
#define SECT_SIZE_CSD_MASK 0x03C000
#define SECT_SIZE_CSD_SHIFT 14
c_size = (EMMC_SD_SRS04 & SECT_SIZE_CSD_MASK) >> SECT_SIZE_CSD_SHIFT;
if (c_size < 32) {
g_sector_size = (1U << c_size);
#ifdef DEBUG_MMC
wolfBoot_printf("mmc_init: sector size: %d\n", g_sector_size);
#endif
}
uint32_t bl_len, c_size, c_size_mult;
bl_len = get_srs_bits(22, 4);
g_sector_size = (1U << bl_len);
csd_struct = get_srs_bits(126, 2);
switch (csd_struct) {
case 0:
c_size = get_srs_bits(62, 12);
g_sector_count = (c_size + 1) << (get_srs_bits(47, 3) + 2);
c_size_mult = get_srs_bits(47, 3);
g_sector_count = (c_size + 1) << (c_size_mult + 2);
break;
case 1:
c_size = get_srs_bits(48, 22);
g_sector_count = (c_size + 1) << 10;
break;
default:
/* invalid CSR structure */
/* invalid CSD structure */
status = -1;
break;
}
#ifdef DEBUG_MMC
wolfBoot_printf("mmc_init: sector count: %d\n", g_sector_count);
wolfBoot_printf("mmc_init: csd_version: %d, sector: size %d count %d\n",
csd_struct, g_sector_size, g_sector_count);
#endif
}
if (status == 0) {
@ -890,11 +884,10 @@ int mmc_init(void)
}
/* returns number of bytes read on success or negative on error */
int disk_read(int drv, uint64_t start, uint32_t count, uint32_t *buf)
int disk_read(int drv, uint64_t start, uint32_t count, uint8_t *buf)
{
int status = 0;
uint32_t read_sz, block_addr;
uint8_t* p_buf = (uint8_t*)buf;
uint32_t tmp_block[EMMC_SD_BLOCK_SIZE/sizeof(uint32_t)];
(void)drv; /* only one drive supported */
@ -906,33 +899,34 @@ int disk_read(int drv, uint64_t start, uint32_t count, uint32_t *buf)
while (count > 0) {
block_addr = (start / EMMC_SD_BLOCK_SIZE);
read_sz = count;
if (read_sz < EMMC_SD_BLOCK_SIZE) {
/* last partial block read */
if (read_sz > EMMC_SD_BLOCK_SIZE) {
read_sz = EMMC_SD_BLOCK_SIZE;
}
if (read_sz < EMMC_SD_BLOCK_SIZE || ((uintptr_t)buf % 4) != 0) {
/* partial or unaligned block read */
status = mmc_read(MMC_CMD17_READ_SINGLE, block_addr,
tmp_block, EMMC_SD_BLOCK_SIZE);
if (status == 0) {
memcpy(p_buf, tmp_block, read_sz);
break; /* last partial block read */
memcpy(buf, tmp_block, read_sz);
}
}
else {
/* full block read */
read_sz = EMMC_SD_BLOCK_SIZE;
status = mmc_read(MMC_CMD17_READ_SINGLE, block_addr,
(uint32_t*)p_buf, read_sz);
(uint32_t*)buf, read_sz);
}
if (status != 0) {
break;
}
start += read_sz;
p_buf += read_sz;
buf += read_sz;
count -= read_sz;
}
return status;
}
int disk_write(int drv, uint64_t start, uint32_t count, const uint32_t *buf)
int disk_write(int drv, uint64_t start, uint32_t count, const uint8_t *buf)
{
/* not supported */
(void)drv;

View File

@ -836,8 +836,7 @@
#define MMC_CMD0_GO_IDLE 0 /* Reset card to idle state */
#define MMC_CMD1_SEND_OP_COND 1 /* MMC: Send operating conditions */
#define MMC_CMD2_ALL_SEND_CID 2 /* Get card identification */
#define MMC_CMD3_SET_REL_ADDR 3 /* MMC: Set relative address */
#define SD_CMD3_SEND_REL_ADDR 3 /* SD: Get relative address */
#define MMC_CMD3_SET_REL_ADDR 3 /* Set relative address */
#define MMC_CMD_4_SET_DSR 4
#define SD_CMD_6_SWITCH_FUNC 6 /* SD: Switch function */
#define MMC_CMD7_SELECT_CARD 7 /* Select/deselect card */
@ -873,11 +872,11 @@
#define MAX_CURRENT_MA 150 /* mA */
#define SD_RCA_SHIFT 16
#define SD_RCA_SHIFT 16 /* relative card address */
#define SD_RCA_MASK (0xFFFFU << SD_RCA_SHIFT) /* relative card address mask */
#define SCR_REG_DATA_SIZE 8
/* Switch Function Command Arguments */
#define SDCARD_SWITCH_FUNC_MODE_SWITCH (0x1u << 31) /* Set function mode */
#define SDCARD_SWITCH_FUNC_MODE_CHECK (0x0u << 31) /* Check mode */

View File

@ -1,4 +1,4 @@
/* fsp_tgl.c
/* x86_fsp_tgl.c
*
* Copyright (C) 2025 wolfSSL Inc.
*
@ -70,18 +70,19 @@ void disk_close(int drv)
{
#ifdef WOLFBOOT_FSP
sata_disable(sata_bar);
sata_bar = 0;
#endif
(void)drv;
}
int disk_read(int drv, uint64_t start, uint32_t count, uint32_t *buf)
int disk_read(int drv, uint64_t start, uint32_t count, uint8_t *buf)
{
return ata_drive_read(drv, start, count, (uint8_t*)buf);
return ata_drive_read(drv, start, count, buf);
}
int disk_write(int drv, uint64_t start, uint32_t count, const uint32_t *buf)
int disk_write(int drv, uint64_t start, uint32_t count, const uint8_t *buf)
{
return ata_drive_write(drv, start, count, (const uint8_t*)buf);
return ata_drive_write(drv, start, count, buf);
}
/*!

View File

@ -58,14 +58,14 @@ struct disk_drive {
/* user supplied functions */
int disk_init(int drv);
int disk_read(int drv, uint64_t start, uint32_t count, uint32_t *buf);
int disk_write(int drv, uint64_t start, uint32_t count, const uint32_t *buf);
int disk_read(int drv, uint64_t start, uint32_t count, uint8_t *buf);
int disk_write(int drv, uint64_t start, uint32_t count, const uint8_t *buf);
void disk_close(int drv);
/* standard functions */
int disk_open(int drv);
int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint32_t *buf);
int disk_part_write(int drv, int part, uint64_t off, uint64_t sz, const uint32_t *buf);
int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf);
int disk_part_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t *buf);
int disk_find_partition_by_label(int drv, const char *label);
#endif /* _WOLFBOOT_DISK_H */

View File

@ -33,6 +33,7 @@
#include <stdint.h>
#include <string.h>
#include "wolfboot/wolfboot.h"
#include "disk.h"
#include "printf.h"
@ -61,7 +62,7 @@ int disk_open(int drv)
uint32_t n_parts = 0;
uint32_t gpt_lba = 0;
struct guid_ptable ptable;
uint32_t sector[GPT_SECTOR_SIZE/sizeof(uint32_t)];
uint8_t sector[GPT_SECTOR_SIZE] XALIGNED(4);
if ((drv < 0) || (drv > MAX_DISKS)) {
wolfBoot_printf("Attempting to access invalid drive %d\r\n", drv);
@ -119,9 +120,9 @@ int disk_open(int drv)
/* Read and parse partition entries */
for (i = 0; i < n_parts; i++) {
struct gpt_part_info part_info;
uint64_t address = ptable.start_array * GPT_SECTOR_SIZE +
i * ptable.array_sz;
uint32_t entry_buf[GPT_PART_ENTRY_SIZE/sizeof(uint32_t)]; /* Max partition entry size */
uint64_t address = (ptable.start_array * GPT_SECTOR_SIZE) +
(i * ptable.array_sz);
uint8_t entry_buf[GPT_PART_ENTRY_SIZE] XALIGNED(4); /* Max partition entry size */
if (ptable.array_sz > sizeof(entry_buf)) {
wolfBoot_printf("Partition entry size too large\r\n");
@ -211,7 +212,7 @@ static struct disk_partition *open_part(int drv, int part)
*
* @return The number of bytes read into the buffer on success, or -1 if an error occurs.
*/
int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint32_t *buf)
int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf)
{
struct disk_partition *p = open_part(drv, part);
int len = sz;
@ -227,7 +228,7 @@ int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint32_t *buf)
}
ret = disk_read(drv, p->start + off, len, buf);
if (ret == 0) {
ret = len;
ret = len; /* success expects to return the number of bytes read */
}
return ret;
}
@ -246,7 +247,7 @@ int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint32_t *buf)
*
* @return The number of bytes written to the partition on success, or -1 if an error occurs.
*/
int disk_part_write(int drv, int part, uint64_t off, uint64_t sz, const uint32_t *buf)
int disk_part_write(int drv, int part, uint64_t off, uint64_t sz, const uint8_t *buf)
{
struct disk_partition *p = open_part(drv, part);
int len = sz;
@ -261,6 +262,9 @@ int disk_part_write(int drv, int part, uint64_t off, uint64_t sz, const uint32_t
return -1;
}
ret = disk_write(drv, p->start + off, len, buf);
if (ret == 0) {
ret = len; /* success expects to return the number of bytes written */
}
return ret;
}

View File

@ -69,10 +69,10 @@
#define BOOT_DISK 0
#endif
#ifndef BOOT_PART_A
#define BOOT_PART_A 1
#define BOOT_PART_A 0
#endif
#ifndef BOOT_PART_B
#define BOOT_PART_B 2
#define BOOT_PART_B 1
#endif
#ifndef MAX_FAILURES
@ -99,7 +99,7 @@ extern uint8_t _end_wb[];
*/
void RAMFUNCTION wolfBoot_start(void)
{
uint32_t p_hdr[IMAGE_HEADER_SIZE/sizeof(uint32_t)] XALIGNED_STACK(16);
uint8_t p_hdr[IMAGE_HEADER_SIZE] XALIGNED_STACK(16);
#ifdef WOLFBOOT_FSP
struct stage2_parameter *stage2_params;
#endif
@ -211,7 +211,7 @@ void RAMFUNCTION wolfBoot_start(void)
load_off = 0;
do {
ret = disk_part_read(BOOT_DISK, cur_part, load_off,
DISK_BLOCK_SIZE, (uint32_t*)(load_address + load_off));
DISK_BLOCK_SIZE, (uint8_t *)(load_address + load_off));
if (ret < 0)
break;
load_off += ret;