mirror of https://github.com/wolfSSL/wolfBoot.git
Add support for fixing up the Ethernet MAC using device serial number (matches U-Boot behavior).
parent
46677d76e7
commit
4673c8272d
|
|
@ -1094,7 +1094,8 @@ set architecture riscv:rv64
|
|||
### PolarFire Example Boot Output
|
||||
|
||||
```
|
||||
wolfBoot Version: 2.7.0 (Dec 29 2025 11:34:01)
|
||||
wolfBoot Version: 2.7.0 (Dec 31 2025 15:33:35)
|
||||
Disk encryption enabled
|
||||
Reading MBR...
|
||||
Found GPT PTE at sector 1
|
||||
Found valid boot signature in MBR
|
||||
|
|
@ -1111,12 +1112,13 @@ disk0.p3 (7_65AFFE00h@ 0_8900000)
|
|||
Total partitions on disk0: 4
|
||||
Checking primary OS image in 0,1...
|
||||
Checking secondary OS image in 0,2...
|
||||
Versions, A:1 B:1
|
||||
Versions, A:1 B:0
|
||||
Load address 0x8E000000
|
||||
Attempting boot from P:A
|
||||
Boot partition: 0x801FFD80 (sz 19767004, ver 0x1, type 0x601)
|
||||
Loading image from disk...done. (846 ms)
|
||||
Boot partition: 0x8E000000 (sz 19767004, ver 0x1, type 0x601)
|
||||
Boot partition: 0x801FFD90 (sz 19767004, ver 0x0, type 0x0)
|
||||
Loading image from disk...done. (877 ms)
|
||||
Decrypting image...done. (2894 ms)
|
||||
Boot partition: 0x8E000000 (sz 19767004, ver 0x0, type 0x0)
|
||||
Checking image integrity...done. (1507 ms)
|
||||
Verifying image signature...done. (68 ms)
|
||||
Firmware Valid.
|
||||
|
|
@ -1128,6 +1130,11 @@ Image fdt-1: 0x8A000000 (19897 bytes)
|
|||
Loading DTS: 0x8A000000 -> 0x8A000000 (19897 bytes)
|
||||
Invalid elf, falling back to raw binary
|
||||
Booting at 80200000
|
||||
FDT: Version 17, Size 19897
|
||||
FDT: Set chosen (13840), bootargs=earlycon root=/dev/mmcblk0p4 rootwait uio_pdrv_genirq.of_id=generic-uio
|
||||
FDT: Device serial: 219A437C-6AE1F1C2-8EDC4324-685B2288
|
||||
FDT: MAC0 = 00:04:A3:5B:22:88
|
||||
FDT: MAC1 = 00:04:A3:5B:22:89
|
||||
[ 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
|
||||
|
|
@ -1193,7 +1200,6 @@ Benchmark complete
|
|||
|
||||
### PolarFire TODO
|
||||
|
||||
* 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
|
||||
|
|
|
|||
154
hal/mpfs250.c
154
hal/mpfs250.c
|
|
@ -56,6 +56,89 @@ void hal_init(void)
|
|||
LIBWOLFBOOT_VERSION_STRING,__DATE__, __TIME__);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* System Controller Mailbox Functions
|
||||
*
|
||||
* The MPFS system controller provides various system services via a mailbox
|
||||
* interface. Commands are sent by writing the opcode to the control register
|
||||
* and responses are read from the mailbox RAM.
|
||||
* ============================================================================ */
|
||||
|
||||
/**
|
||||
* mpfs_scb_mailbox_busy - Check if the system controller mailbox is busy
|
||||
*
|
||||
* Returns: non-zero if busy, 0 if ready
|
||||
*/
|
||||
static int mpfs_scb_mailbox_busy(void)
|
||||
{
|
||||
return (SCBCTRL_REG(SERVICES_SR_OFFSET) & SERVICES_SR_BUSY_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* mpfs_read_serial_number - Read the device serial number via system services
|
||||
* @serial: Buffer to store the 16-byte device serial number
|
||||
*
|
||||
* This function sends a serial number request (opcode 0x00) to the system
|
||||
* controller and reads the 16-byte response from the mailbox RAM.
|
||||
*
|
||||
* Returns: 0 on success, negative error code on failure
|
||||
*/
|
||||
static int mpfs_read_serial_number(uint8_t *serial)
|
||||
{
|
||||
uint32_t cmd, status;
|
||||
int i, timeout;
|
||||
|
||||
if (serial == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if mailbox is busy */
|
||||
if (mpfs_scb_mailbox_busy()) {
|
||||
wolfBoot_printf("SCB mailbox busy\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Send serial number request command (opcode 0x00)
|
||||
* Command format: [31:16] = opcode, [0] = request bit */
|
||||
cmd = (SYS_SERV_CMD_SERIAL_NUMBER << SERVICES_CR_COMMAND_SHIFT) |
|
||||
SERVICES_CR_REQ_MASK;
|
||||
SCBCTRL_REG(SERVICES_CR_OFFSET) = cmd;
|
||||
|
||||
/* Wait for request bit to clear (command accepted) */
|
||||
timeout = 10000;
|
||||
while ((SCBCTRL_REG(SERVICES_CR_OFFSET) & SERVICES_CR_REQ_MASK) && timeout > 0) {
|
||||
timeout--;
|
||||
}
|
||||
if (timeout == 0) {
|
||||
wolfBoot_printf("SCB mailbox request timeout\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Wait for busy bit to clear (command completed) */
|
||||
timeout = 10000;
|
||||
while (mpfs_scb_mailbox_busy() && timeout > 0) {
|
||||
timeout--;
|
||||
}
|
||||
if (timeout == 0) {
|
||||
wolfBoot_printf("SCB mailbox busy timeout\n");
|
||||
return -4;
|
||||
}
|
||||
|
||||
/* Check status (upper 16 bits of status register) */
|
||||
status = (SCBCTRL_REG(SERVICES_SR_OFFSET) >> SERVICES_SR_STATUS_SHIFT) & 0xFFFF;
|
||||
if (status != 0) {
|
||||
wolfBoot_printf("SCB mailbox error: 0x%x\n", status);
|
||||
return -5;
|
||||
}
|
||||
|
||||
/* Read serial number from mailbox RAM (16 bytes) */
|
||||
for (i = 0; i < DEVICE_SERIAL_NUMBER_SIZE; i++) {
|
||||
serial[i] = SCBMBOX_BYTE(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Linux kernel command line arguments */
|
||||
#ifndef LINUX_BOOTARGS
|
||||
#ifndef LINUX_BOOTARGS_ROOT
|
||||
|
|
@ -66,10 +149,17 @@ void hal_init(void)
|
|||
"earlycon root="LINUX_BOOTARGS_ROOT" rootwait uio_pdrv_genirq.of_id=generic-uio"
|
||||
#endif
|
||||
|
||||
/* Microchip OUI (Organizationally Unique Identifier) for MAC address */
|
||||
#define MICROCHIP_OUI_0 0x00
|
||||
#define MICROCHIP_OUI_1 0x04
|
||||
#define MICROCHIP_OUI_2 0xA3
|
||||
|
||||
int hal_dts_fixup(void* dts_addr)
|
||||
{
|
||||
int off, ret;
|
||||
struct fdt_header *fdt = (struct fdt_header *)dts_addr;
|
||||
uint8_t device_serial_number[DEVICE_SERIAL_NUMBER_SIZE];
|
||||
uint8_t mac_addr[6];
|
||||
|
||||
/* Verify FDT header */
|
||||
ret = fdt_check_header(dts_addr);
|
||||
|
|
@ -96,8 +186,68 @@ int hal_dts_fixup(void* dts_addr)
|
|||
fdt_fixup_str(fdt, off, "chosen", "bootargs", LINUX_BOOTARGS);
|
||||
}
|
||||
|
||||
/* TODO: Consider additional FDT fixups:
|
||||
* ethernet0: local-mac-address {0x00, 0x04, 0xA3, SERIAL2, SERIAL1, SERIAL0} */
|
||||
/* Read device serial number from system controller */
|
||||
ret = mpfs_read_serial_number(device_serial_number);
|
||||
if (ret != 0) {
|
||||
wolfBoot_printf("FDT: Failed to read serial number (%d)\n", ret);
|
||||
/* Continue without setting MAC addresses */
|
||||
return 0;
|
||||
}
|
||||
|
||||
wolfBoot_printf("FDT: Device serial: %02x%02x%02x%02x-%02x%02x%02x%02x-"
|
||||
"%02x%02x%02x%02x-%02x%02x%02x%02x\n",
|
||||
device_serial_number[15], device_serial_number[14],
|
||||
device_serial_number[13], device_serial_number[12],
|
||||
device_serial_number[11], device_serial_number[10],
|
||||
device_serial_number[9], device_serial_number[8],
|
||||
device_serial_number[7], device_serial_number[6],
|
||||
device_serial_number[5], device_serial_number[4],
|
||||
device_serial_number[3], device_serial_number[2],
|
||||
device_serial_number[1], device_serial_number[0]);
|
||||
|
||||
/* Build MAC address: Microchip OUI + lower 3 bytes of serial number
|
||||
* Format: {0x00, 0x04, 0xA3, serial[2], serial[1], serial[0]} */
|
||||
mac_addr[0] = MICROCHIP_OUI_0;
|
||||
mac_addr[1] = MICROCHIP_OUI_1;
|
||||
mac_addr[2] = MICROCHIP_OUI_2;
|
||||
mac_addr[3] = device_serial_number[2];
|
||||
mac_addr[4] = device_serial_number[1];
|
||||
mac_addr[5] = device_serial_number[0];
|
||||
|
||||
wolfBoot_printf("FDT: MAC0 = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2],
|
||||
mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
|
||||
/* Set local-mac-address for ethernet@20110000 (mac0) */
|
||||
off = fdt_find_node_offset(fdt, -1, "ethernet@20110000");
|
||||
if (off >= 0) {
|
||||
ret = fdt_setprop(fdt, off, "local-mac-address", mac_addr, 6);
|
||||
if (ret != 0) {
|
||||
wolfBoot_printf("FDT: Failed to set mac0 address (%d)\n", ret);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wolfBoot_printf("FDT: ethernet@20110000 not found\n");
|
||||
}
|
||||
|
||||
/* Set local-mac-address for ethernet@20112000 (mac1)
|
||||
* Use MAC address + 1 for the second interface */
|
||||
mac_addr[5] = device_serial_number[0] + 1;
|
||||
|
||||
wolfBoot_printf("FDT: MAC1 = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
mac_addr[0], mac_addr[1], mac_addr[2],
|
||||
mac_addr[3], mac_addr[4], mac_addr[5]);
|
||||
|
||||
off = fdt_find_node_offset(fdt, -1, "ethernet@20112000");
|
||||
if (off >= 0) {
|
||||
ret = fdt_setprop(fdt, off, "local-mac-address", mac_addr, 6);
|
||||
if (ret != 0) {
|
||||
wolfBoot_printf("FDT: Failed to set mac1 address (%d)\n", ret);
|
||||
}
|
||||
}
|
||||
else {
|
||||
wolfBoot_printf("FDT: ethernet@20112000 not found\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,39 @@
|
|||
* ============================================================================ */
|
||||
#define EMMC_SD_BASE 0x20008000UL
|
||||
|
||||
/* ============================================================================
|
||||
* System Controller Mailbox
|
||||
* Control Base: 0x37020000
|
||||
* Mailbox RAM: 0x37020800
|
||||
*
|
||||
* Used for system services like reading the device serial number.
|
||||
* ============================================================================ */
|
||||
#define SCBCTRL_BASE 0x37020000UL
|
||||
#define SCBMBOX_BASE 0x37020800UL
|
||||
|
||||
/* System Services Control and Status Register offsets (from SCBCTRL_BASE) */
|
||||
#define SERVICES_CR_OFFSET 0x50u
|
||||
#define SERVICES_SR_OFFSET 0x54u
|
||||
|
||||
/* Control Register bits */
|
||||
#define SERVICES_CR_REQ_MASK 0x01u
|
||||
#define SERVICES_CR_COMMAND_SHIFT 16
|
||||
|
||||
/* Status Register bits */
|
||||
#define SERVICES_SR_BUSY_MASK 0x02u
|
||||
#define SERVICES_SR_STATUS_SHIFT 16
|
||||
|
||||
/* System Service command opcodes */
|
||||
#define SYS_SERV_CMD_SERIAL_NUMBER 0x00u
|
||||
|
||||
/* Device serial number size in bytes */
|
||||
#define DEVICE_SERIAL_NUMBER_SIZE 16
|
||||
|
||||
/* System Controller register access */
|
||||
#define SCBCTRL_REG(off) (*((volatile uint32_t*)(SCBCTRL_BASE + (off))))
|
||||
#define SCBMBOX_REG(off) (*((volatile uint32_t*)(SCBMBOX_BASE + (off))))
|
||||
#define SCBMBOX_BYTE(off) (*((volatile uint8_t*)(SCBMBOX_BASE + (off))))
|
||||
|
||||
|
||||
/* Crypto Engine: Athena F5200 TeraFire Crypto Processor (1x), 200 MHz */
|
||||
#define ATHENA_BASE (SYSREG_BASE + 0x125000)
|
||||
|
|
|
|||
Loading…
Reference in New Issue