[PATCH 7/9] platform: generic: Add mechanism to match via mvendorid

Christoph Müllner christoph.muellner at vrull.eu
Wed Mar 27 03:11:35 PDT 2024


Currently, all platforms and their overrides are matched
via FDT-compatible strings. While this is the right approach,
we are sometimes confronted with platforms that don't provide
the necessary FDT-compatible strings.
To still be able to match a platforms, let's add a secondary
matching mechanism for the MVENDORID CSR.

Signed-off-by: Christoph Müllner <christoph.muellner at vrull.eu>
---
 platform/generic/include/platform_override.h |  1 +
 platform/generic/platform.c                  | 38 ++++++++++++++++++--
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/platform/generic/include/platform_override.h b/platform/generic/include/platform_override.h
index 6802126..a968346 100644
--- a/platform/generic/include/platform_override.h
+++ b/platform/generic/include/platform_override.h
@@ -17,6 +17,7 @@
 
 struct platform_override {
 	const struct fdt_match *match_table;
+	const unsigned long *match_vendor_ids;
 	u64 (*features)(const struct fdt_match *match);
 	u64 (*tlbr_flush_limit)(const struct fdt_match *match);
 	u32 (*tlb_num_entries)(const struct fdt_match *match);
diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index 07fa9cc..e1b97c8 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -36,12 +36,28 @@ extern unsigned long platform_override_modules_size;
 static const struct platform_override *generic_plat = NULL;
 static const struct fdt_match *generic_plat_match = NULL;
 
-static void fw_platform_lookup_special(void *fdt, int root_offset)
+static unsigned long vendor_id_match(unsigned long vendor_id,
+				     const unsigned long *vendor_ids)
+{
+	const unsigned long *vid_ptr = vendor_ids;
+
+	while (*vid_ptr) {
+		if (*vid_ptr == vendor_id)
+			return vendor_id;
+
+		vid_ptr++;
+	}
+
+	return 0;
+}
+
+static void fw_platform_lookup_override(void *fdt, int root_offset)
 {
 	const struct platform_override *plat;
 	const struct fdt_match *match;
 	int pos;
 
+	/* First try to find a FDT match. */
 	for (pos = 0; pos < platform_override_modules_size; pos++) {
 		plat = platform_override_modules[pos];
 		if (!plat->match_table)
@@ -53,7 +69,23 @@ static void fw_platform_lookup_special(void *fdt, int root_offset)
 
 		generic_plat = plat;
 		generic_plat_match = match;
-		break;
+		return;
+	}
+
+	/* No match via FDT -> try matching the vendor ID. */
+	const unsigned long vendor_id = csr_read(CSR_MVENDORID);
+	for (pos = 0; pos < platform_override_modules_size; pos++) {
+		plat = platform_override_modules[pos];
+		if (!plat->match_vendor_ids)
+			continue;
+
+		unsigned long match = vendor_id_match(vendor_id, plat->match_vendor_ids);
+		if (!match)
+			continue;
+
+		generic_plat = plat;
+		generic_plat_match = NULL;
+		return;
 	}
 }
 
@@ -154,7 +186,7 @@ unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
 	if (root_offset < 0)
 		goto fail;
 
-	fw_platform_lookup_special(fdt, root_offset);
+	fw_platform_lookup_override(fdt, root_offset);
 
 	if (generic_plat && generic_plat->fw_init)
 		generic_plat->fw_init(fdt, generic_plat_match);
-- 
2.44.0




More information about the opensbi mailing list