Most SoCs have a unique ID (UID) which can be used to identify a particular SoC instance. This is exposed to the environment by some SoC drivers as soc0.serial_number like also done in Linux. The SoC UID can also conveniently be used to generate a unique machine_id on systems with a readonly rootfs. The two usecases require the SoC UID in different formats. While machine_id_set_hashable() takes a binary representation of the SoC UID, soc0.serial_number is a string. The conversion from the binary representation to the string is SoC specific, some SoCs interpret the binary data as a byte array (AM62x for example), others interpret it as words of different lengths in different endianesses (i.MX). Others even print the binary data as decimal (qcom).
Needing a SoC driver for providing the SoC UID is an unlucky choice as some SoCs do not have a SoC driver, but instead read the SoC UID in their eFuse driver in drivers/nvmem (STM32MP bsec). These drivers provide hashable data to generate a machine_id, but do not expose the SoC ID. This patch introduces barebox_set_soc_uid(). This function provides a new environment variable global.soc_uid which contains the SoC UID. It also passes the SoC UID to machine_id_set_hashable() for generating a machine_id. To accomodate for different string representations of the binary data barebox_set_soc_uid() takes both the binary data and a string in the SoCs preferred format of the same data. Signed-off-by: Sascha Hauer <[email protected]> --- common/misc.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/barebox-info.h | 4 ++++ 2 files changed, 62 insertions(+) diff --git a/common/misc.c b/common/misc.c index 0af5a9cf30cdb952063974969c368061420a6e2b..ef6687f01389beaed44fc446b25ec5f21e712366 100644 --- a/common/misc.c +++ b/common/misc.c @@ -16,6 +16,7 @@ #include <restart.h> #include <poweroff.h> #include <string.h> +#include <machine_id.h> #include <linux/stringify.h> int errno; @@ -252,6 +253,63 @@ const char *barebox_get_serial_number(void) BAREBOX_MAGICVAR(global.serial_number, "Board serial number"); +static char *soc_uid_str; +static void *soc_uid; +static size_t soc_uid_len; + +/* + * barebox_set_soc_uid - set a Unique SoC ID + * + * Set a Unique SoC ID. The ID is usually read from SoC internal eFuses. It + * can vary in length on different SoCs and can have different canonical hex + * representations. @uidstr can be NULL in which case uidbuf is interpreted + * as a byte array. + * + * barebox uses the SoC ID to generate a machine_id and exports it to the + * environment via global.soc_uid. + * + * In Linux the serial number is exported as /sys/devices/soc0/serial_number + * which should generally have the same format as *uidstr. + */ +void barebox_set_soc_uid(const char *uidstr, const void *uidbuf, size_t len) +{ + if (soc_uid_str) { + pr_warn("SoC UID already set. Ignoring\n"); + return; + } + + soc_uid = xmemdup(uidbuf, len); + soc_uid_len = len; + + if (uidstr) { + soc_uid_str = xstrdup(uidstr); + } else { + soc_uid_str = xzalloc(len * 2 + 1); + bin2hex(soc_uid_str, uidbuf, len); + } + + machine_id_set_hashable(uidbuf, len); + + globalvar_add_simple_string("soc_uid", &soc_uid_str); +} +BAREBOX_MAGICVAR(global.soc_uid, "SoC Unique ID"); + +const char *barebox_get_soc_uid(void) +{ + return soc_uid_str; +} + +int barebox_get_soc_uid_bin(const void **buf, size_t *len) +{ + if (!soc_uid) + return -ENOENT; + + *buf = soc_uid; + *len = soc_uid_len; + + return 0; +} + #ifdef CONFIG_OFTREE static char *of_machine_compatible; diff --git a/include/barebox-info.h b/include/barebox-info.h index bcceb7b0e0211c8c7dccd6b9f480c9fbc13dcf63..898fb493b6348ee64670f928a3598a7c3d277554 100644 --- a/include/barebox-info.h +++ b/include/barebox-info.h @@ -25,6 +25,10 @@ bool barebox_hostname_is_valid(const char *s); const char *barebox_get_serial_number(void); void barebox_set_serial_number(const char *); +void barebox_set_soc_uid(const char *uidstr, const void *uidbuf, size_t len); +const char *barebox_get_soc_uid(void); +int barebox_get_soc_uid_bin(const void **buf, size_t *len); + #ifdef CONFIG_OFTREE void barebox_set_of_machine_compatible(const char *); const char *barebox_get_of_machine_compatible(void); -- 2.47.3
