[PATCH] sunxi: Use existing serial number for MAC address generation
Andre Przywara
andre.przywara at arm.com
Tue Apr 8 00:48:36 CEST 2025
On Allwinner boards we use the first few words of the SID efuse storage
to generate a serial number, and also MAC addresses for Ethernet and
WiFi interfaces.
On some SoCs (A64, at least), when they are using Secure Boot, the SID
device contains all zeroes when read from U-Boot, because we are running
in non-secure state. In this case the MAC address would either be random
or would have to be assigned manually.
Now Trusted-Firmware, which runs in (always) secure EL3, can read the
SID storage, and has the ability to generate the serial number using the
same algorithm as U-Boot. It will write this serial number into the DTB,
from where U-Boot can easily retrieve it.
Add a function that reads the "serial-number" property from the DTB, and
re-generates the SID fields it has been derived from. This will then be
used by the existing MAC address generation code to assign addresses to
Ethernet, WiFi, and Bluetooth devices. This code will trigger when an
MMIO read from the SID returns zeroes.
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
Hi,
the corresponding TF-A patch is here:
https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/13229
Cheers,
Andre
board/sunxi/board.c | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index ac9cefc6eac..6225e7d4b10 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -726,13 +726,38 @@ static void parse_spl_header(const uint32_t spl_addr)
env_set_hex("fel_scriptaddr", spl->fel_script_address);
}
-static bool get_unique_sid(unsigned int *sid)
+/*
+ * On a secure device the SID MMIO region reads all zeroes, when accessed
+ * from non-secure world, which U-Boot proper runs in.
+ * Hopefully TF-A has read the SID content and dumped a serial number,
+ * compatible with the U-Boot algorithm, into the DTB for us.
+ */
+static bool get_sid_from_serial_number(const void *fdt, unsigned int *sid)
+{
+ const struct fdt_property *prop;
+ unsigned char buffer[9] = { 0 };
+ int len;
+
+ prop = fdt_get_property(fdt, 0, "serial-number", &len);
+ if (!prop || len != 17)
+ return false;
+
+ sid[3] = hextoul(prop->data + 8, NULL);
+ memcpy(buffer, prop->data, 8);
+ sid[0] = hextoul(buffer, NULL);
+ sid[1] = 0;
+ sid[2] = 0;
+
+ return true;
+}
+
+static bool get_unique_sid(const void *fdt, unsigned int *sid)
{
if (sunxi_get_sid(sid) != 0)
return false;
if (!sid[0])
- return false;
+ return get_sid_from_serial_number(fdt, sid);
/*
* The single words 1 - 3 of the SID have quite a few bits
@@ -770,7 +795,7 @@ static void setup_environment(const void *fdt)
char ethaddr[16];
int i;
- if (!get_unique_sid(sid))
+ if (!get_unique_sid(fdt, sid))
return;
for (i = 0; i < 4; i++) {
@@ -867,7 +892,7 @@ static void bluetooth_dt_fixup(void *blob)
for (i = 0; i < ETH_ALEN; ++i)
bdaddr[i] = tmp[ETH_ALEN - i - 1];
} else {
- if (!get_unique_sid(sid))
+ if (!get_unique_sid(blob, sid))
return;
bdaddr[0] = ((sid[3] >> 0) & 0xff) ^ 1;
--
2.46.3
More information about the U-Boot
mailing list