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;
