[PATCH v1 2/3] ARM: protonic-stm32mp1: Add support for reading serial from BSEC

Oleksij Rempel o.rempel at pengutronix.de
Wed Jan 29 05:13:25 PST 2025


From: Michiel Schelfhout <michiel.schelfhout at protonic.nl>

Introduce support for retrieving the board-specific serial number from
BSEC registers via the OP-TEE interface. The serial number is stored
across three 4-byte registers (58, 59, 60), with only the lower 16 bits
of register 58 being relevant.

Signed-off-by: Michiel Schelfhout <michiel.schelfhout at protonic.nl>
Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
---
 arch/arm/boards/protonic-stm32mp1/board.c | 61 +++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/arch/arm/boards/protonic-stm32mp1/board.c b/arch/arm/boards/protonic-stm32mp1/board.c
index 0b46dccb3247..cafdc20c2b42 100644
--- a/arch/arm/boards/protonic-stm32mp1/board.c
+++ b/arch/arm/boards/protonic-stm32mp1/board.c
@@ -6,14 +6,20 @@
 #include <common.h>
 #include <init.h>
 #include <mach/stm32mp/bbu.h>
+#include <mach/stm32mp/bsec.h>
 #include <of_device.h>
 #include <deep-probe.h>
+#include <soc/stm32/stm32-bsec-optee-ta.h>
 
 /* board specific flags */
 #define PRT_STM32_BOOTSRC_SD		BIT(2)
 #define PRT_STM32_BOOTSRC_EMMC		BIT(1)
 #define PRT_STM32_BOOTSRC_SPI_NOR	BIT(0)
 
+/* board specific serial number length is 10 characters without '\0' */
+#define PRT_STM32_SERIAL_LEN		10
+#define PRT_STM32_SERIAL_OFFSET		58
+
 struct prt_stm32_machine_data {
 	u32 flags;
 };
@@ -54,6 +60,59 @@ static const struct prt_stm32_boot_dev prt_stm32_boot_devs[] = {
 	},
 };
 
+static int prt_stm32_set_serial(struct device *dev, char *serial)
+{
+	dev_info(dev, "Serial number: %s\n", serial);
+	barebox_set_serial_number(serial);
+
+	return 0;
+}
+
+static int prt_stm32_read_serial(struct device *dev)
+{
+	/* including first 2 non-serial bytes */
+	char raw_serial[PRT_STM32_SERIAL_LEN + 2];
+	/* board specific serial number + one char for '\0' */
+	char serial[PRT_STM32_SERIAL_LEN + 1];
+	struct tee_context *ctx;
+	int ret;
+
+	/* the ctx pointer will be set in the stm32_bsec_optee_ta_open */
+	ret = stm32_bsec_optee_ta_open(&ctx);
+	if (ret) {
+		dev_err(dev, "Failed to open BSEC TA: %pe\n", ERR_PTR(ret));
+		return ret;
+	}
+
+	ret = stm32_bsec_optee_ta_read(ctx, PRT_STM32_SERIAL_OFFSET * 4,
+				       &raw_serial, sizeof(raw_serial));
+	if (ret)
+		goto exit_pta_read;
+
+	/*
+	 * Shift the serial data left by 2 bytes to remove the non-serial data.
+	 * The serial number is stored across three 4-byte BSEC registers:
+	 *   - Register 58 (4 bytes): Only the lower 16 bits contain serial data.
+	 *   - Register 59 (4 bytes): Fully part of the serial number.
+	 *   - Register 60 (4 bytes): Fully part of the serial number.
+	 * Since we read all three registers as a continuous block (12 bytes),
+	 * the first 2 bytes of Register 58 contain irrelevant data and must
+	 * be discarded.
+	 */
+	memmove(serial, raw_serial + 2, sizeof(serial) - 1);
+
+	serial[PRT_STM32_SERIAL_LEN] = 0;
+
+	stm32_bsec_optee_ta_close(&ctx);
+
+	return prt_stm32_set_serial(dev, serial);
+
+exit_pta_read:
+	stm32_bsec_optee_ta_close(&ctx);
+	dev_err(dev, "Failed to read serial: %pe\n", ERR_PTR(ret));
+	return ret;
+}
+
 static int prt_stm32_probe(struct device *dev)
 {
 	const struct prt_stm32_machine_data *dcfg;
@@ -66,6 +125,8 @@ static int prt_stm32_probe(struct device *dev)
 		goto exit_get_dcfg;
 	}
 
+	prt_stm32_read_serial(dev);
+
 	for (i = 0; i < ARRAY_SIZE(prt_stm32_boot_devs); i++) {
 		const struct prt_stm32_boot_dev *bd = &prt_stm32_boot_devs[i];
 		int bbu_flags = 0;
-- 
2.39.5




More information about the barebox mailing list