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.przyw...@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