[PATCH 2/2] platform: generic: Optimize extensions_init() to parse ISA extensions once

Anup Patel <[email protected]>
Newsgroups org.infradead.lists.opensbi
Message-ID <[email protected]>
Instead of parsing ISA extensions separately for each hart in the
generic_extensions_init() function, it is better to parse ISA extensions
for all available harts in the cold boot path. Also, this allows us
to remove fdt_isa_bitmap from scratch space and directly initialize
"extensions" in struct sbi_hart_features for each hart.

Signed-off-by: Anup Patel <[email protected]>
---
 include/sbi/sbi_platform.h                   |  7 ++-
 include/sbi_utils/fdt/fdt_helper.h           |  3 +-
 lib/sbi/sbi_hart.c                           |  7 ++-
 lib/utils/fdt/fdt_helper.c                   | 47 ++++----------------
 platform/generic/allwinner/sun20i-d1.c       |  7 ++-
 platform/generic/andes/andes_pmu.c           |  5 ++-
 platform/generic/eswin/eic770x.c             |  1 +
 platform/generic/include/andes/andes_pmu.h   |  4 +-
 platform/generic/include/platform_override.h |  3 +-
 platform/generic/platform.c                  |  8 ++--
 platform/generic/sophgo/sg2042.c             |  4 +-
 platform/generic/starfive/jh7110.c           |  1 +
 platform/generic/thead/thead-generic.c       |  4 +-
 13 files changed, 37 insertions(+), 64 deletions(-)

diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h
index fe382b56..7a4f9242 100644
--- a/include/sbi/sbi_platform.h
+++ b/include/sbi/sbi_platform.h
@@ -55,7 +55,6 @@
 struct sbi_domain_memregion;
 struct sbi_ecall_return;
 struct sbi_trap_regs;
-struct sbi_hart_features;
 union sbi_ldst_data;
 
 /** Possible feature flags of a platform */
@@ -105,7 +104,7 @@ struct sbi_platform_operations {
 	int (*misa_get_xlen)(void);
 
 	/** Initialize (or populate) HART extensions for the platform */
-	int (*extensions_init)(struct sbi_hart_features *hfeatures);
+	int (*extensions_init)(bool cold_boot);
 
 	/** Initialize (or populate) domains for the platform */
 	int (*domains_init)(void);
@@ -486,10 +485,10 @@ static inline int sbi_platform_misa_xlen(const struct sbi_platform *plat)
  */
 static inline int sbi_platform_extensions_init(
 					const struct sbi_platform *plat,
-					struct sbi_hart_features *hfeatures)
+					bool cold_boot)
 {
 	if (plat && sbi_platform_ops(plat)->extensions_init)
-		return sbi_platform_ops(plat)->extensions_init(hfeatures);
+		return sbi_platform_ops(plat)->extensions_init(cold_boot);
 	return 0;
 }
 
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 04c850cc..75a564d1 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -54,8 +54,7 @@ int fdt_parse_cbom_block_size(const void *fdt, int cpu_offset, unsigned long  *c
 
 int fdt_parse_timebase_frequency(const void *fdt, unsigned long *freq);
 
-int fdt_parse_isa_extensions(const void *fdt, unsigned int hartid,
-			     unsigned long *extensions);
+int fdt_parse_isa_extensions_all_harts(const void *fdt);
 
 int fdt_parse_gaisler_uart_node(const void *fdt, int nodeoffset,
 				struct platform_uart_data *uart);
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index e7360712..21713816 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -508,7 +508,7 @@ static int hart_mhpm_get_allowed_bits(void)
 	return num_bits;
 }
 
-static int hart_detect_features(struct sbi_scratch *scratch)
+static int hart_detect_features(struct sbi_scratch *scratch, bool cold_boot)
 {
 	struct sbi_trap_info trap = {0};
 	struct sbi_hart_features *hfeatures =
@@ -525,8 +525,7 @@ static int hart_detect_features(struct sbi_scratch *scratch)
 	 * Needed to detect Smrnmi and install NMI handlers before CSR probes
 	 * that may trigger traps.
 	 */
-	rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(),
-					  hfeatures);
+	rc = sbi_platform_extensions_init(sbi_platform_ptr(scratch), cold_boot);
 	if (rc)
 		return rc;
 
@@ -764,7 +763,7 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
 			return SBI_ENOMEM;
 	}
 
-	rc = hart_detect_features(scratch);
+	rc = hart_detect_features(scratch, cold_boot);
 	if (rc)
 		return rc;
 
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index b57eae1a..ad4efaaf 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -328,8 +328,6 @@ int fdt_parse_timebase_frequency(const void *fdt, unsigned long *freq)
 
 #define RISCV_ISA_EXT_NAME_LEN_MAX	32
 
-static unsigned long fdt_isa_bitmap_offset;
-
 static int fdt_parse_isa_one_hart(const char *isa, unsigned long *extensions)
 {
 	size_t i, j, isa_len;
@@ -409,15 +407,15 @@ static void fdt_parse_isa_extensions_one_hart(const char *isa,
 	}
 }
 
-static int fdt_parse_isa_all_harts(const void *fdt)
+int fdt_parse_isa_extensions_all_harts(const void *fdt)
 {
 	u32 hartid;
 	const fdt32_t *val;
-	unsigned long *hart_exts;
 	struct sbi_scratch *scratch;
+	struct sbi_hart_features *hfeatures;
 	int err, cpu_offset, cpus_offset, len;
 
-	if (!fdt || !fdt_isa_bitmap_offset)
+	if (!fdt)
 		return SBI_EINVAL;
 
 	cpus_offset = fdt_path_offset(fdt, "/cpus");
@@ -436,13 +434,14 @@ static int fdt_parse_isa_all_harts(const void *fdt)
 		if (!scratch)
 			return SBI_ENOENT;
 
-		hart_exts = sbi_scratch_offset_ptr(scratch,
-						   fdt_isa_bitmap_offset);
+		hfeatures = sbi_hart_features_ptr(scratch);
+		if (!hfeatures)
+			return SBI_ENOENT;
 
 		val = fdt_getprop(fdt, cpu_offset, "riscv,isa-extensions", &len);
 		if (val && len > 0) {
 			fdt_parse_isa_extensions_one_hart((const char *)val,
-							  hart_exts, len);
+							  hfeatures->extensions, len);
 			continue;
 		}
 
@@ -450,7 +449,7 @@ static int fdt_parse_isa_all_harts(const void *fdt)
 		if (!val || len <= 0)
 			return SBI_ENOENT;
 
-		err = fdt_parse_isa_one_hart((const char *)val, hart_exts);
+		err = fdt_parse_isa_one_hart((const char *)val, hfeatures->extensions);
 		if (err)
 			return err;
 	}
@@ -458,36 +457,6 @@ static int fdt_parse_isa_all_harts(const void *fdt)
 	return 0;
 }
 
-int fdt_parse_isa_extensions(const void *fdt, unsigned int hartid,
-			unsigned long *extensions)
-{
-	int rc, i;
-	unsigned long *hart_exts;
-	struct sbi_scratch *scratch;
-
-	if (!fdt_isa_bitmap_offset) {
-		fdt_isa_bitmap_offset = sbi_scratch_alloc_offset(
-					sizeof(*hart_exts) *
-					BITS_TO_LONGS(SBI_HART_EXT_MAX));
-		if (!fdt_isa_bitmap_offset)
-			return SBI_ENOMEM;
-
-		rc = fdt_parse_isa_all_harts(fdt);
-		if (rc)
-			return rc;
-	}
-
-	scratch = sbi_hartid_to_scratch(hartid);
-	if (!scratch)
-		return SBI_ENOENT;
-
-	hart_exts = sbi_scratch_offset_ptr(scratch, fdt_isa_bitmap_offset);
-
-	for (i = 0; i < BITS_TO_LONGS(SBI_HART_EXT_MAX); i++)
-		extensions[i] |= hart_exts[i];
-	return 0;
-}
-
 static int fdt_parse_uart_node_common(const void *fdt, int nodeoffset,
 				      struct platform_uart_data *uart,
 				      unsigned long default_freq,
diff --git a/platform/generic/allwinner/sun20i-d1.c b/platform/generic/allwinner/sun20i-d1.c
index 666473c1..4ea90158 100644
--- a/platform/generic/allwinner/sun20i-d1.c
+++ b/platform/generic/allwinner/sun20i-d1.c
@@ -12,6 +12,7 @@
 #include <sbi/sbi_bitops.h>
 #include <sbi/sbi_ecall_interface.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_hart.h>
 #include <sbi/sbi_hsm.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_pmu.h>
@@ -197,11 +198,12 @@ static int sun20i_d1_final_init(bool cold_boot)
 	return generic_final_init(cold_boot);
 }
 
-static int sun20i_d1_extensions_init(struct sbi_hart_features *hfeatures)
+static int sun20i_d1_extensions_init(bool cold_boot)
 {
+	struct sbi_hart_features *hfeatures;
 	int rc;
 
-	rc = generic_extensions_init(hfeatures);
+	rc = generic_extensions_init(cold_boot);
 	if (rc)
 		return rc;
 
@@ -209,6 +211,7 @@ static int sun20i_d1_extensions_init(struct sbi_hart_features *hfeatures)
 
 	/* auto-detection doesn't work on t-head c9xx cores */
 	/* D1 has 29 mhpmevent csrs, but only 3-9,13-17 have valid value */
+	hfeatures = sbi_hart_features_ptr(sbi_scratch_thishart_ptr());
 	hfeatures->mhpm_mask = 0x0003e3f8;
 	hfeatures->mhpm_bits = 64;
 
diff --git a/platform/generic/andes/andes_pmu.c b/platform/generic/andes/andes_pmu.c
index 9eee4edc..b3e49e8d 100644
--- a/platform/generic/andes/andes_pmu.c
+++ b/platform/generic/andes/andes_pmu.c
@@ -9,6 +9,7 @@
 #include <andes/andes_pmu.h>
 #include <sbi/sbi_bitops.h>
 #include <sbi/sbi_error.h>
+#include <sbi/sbi_hart.h>
 #include <sbi/sbi_pmu.h>
 #include <libfdt.h>
 #include <platform_override.h>
@@ -58,12 +59,12 @@ static struct sbi_pmu_device andes_pmu = {
 	.hw_counter_filter_mode = andes_hw_counter_filter_mode
 };
 
-int andes_pmu_extensions_init(struct sbi_hart_features *hfeatures)
+int andes_pmu_extensions_init(bool cold_boot)
 {
 	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 	int rc;
 
-	rc = generic_extensions_init(hfeatures);
+	rc = generic_extensions_init(cold_boot);
 	if (rc)
 		return rc;
 
diff --git a/platform/generic/eswin/eic770x.c b/platform/generic/eswin/eic770x.c
index 7330df9f..60d28c51 100644
--- a/platform/generic/eswin/eic770x.c
+++ b/platform/generic/eswin/eic770x.c
@@ -10,6 +10,7 @@
 #include <sbi/sbi_console.h>
 #include <sbi/sbi_system.h>
 #include <sbi/sbi_math.h>
+#include <sbi/sbi_hart.h>
 #include <sbi/sbi_hart_pmp.h>
 #include <sbi/sbi_hart_protection.h>
 #include <eswin/eic770x.h>
diff --git a/platform/generic/include/andes/andes_pmu.h b/platform/generic/include/andes/andes_pmu.h
index ad4564a6..e4446364 100644
--- a/platform/generic/include/andes/andes_pmu.h
+++ b/platform/generic/include/andes/andes_pmu.h
@@ -7,9 +7,9 @@
 #ifndef _RISCV_ANDES_PMU_H
 #define _RISCV_ANDES_PMU_H
 
-#include <sbi/sbi_hart.h>
+#include <sbi/sbi_types.h>
 
 int andes_pmu_init(void);
-int andes_pmu_extensions_init(struct sbi_hart_features *hfeatures);
+int andes_pmu_extensions_init(bool cold_boot);
 
 #endif /* _RISCV_ANDES_PMU_H */
diff --git a/platform/generic/include/platform_override.h b/platform/generic/include/platform_override.h
index 3e6e5044..1b8127cb 100644
--- a/platform/generic/include/platform_override.h
+++ b/platform/generic/include/platform_override.h
@@ -10,7 +10,6 @@
 #ifndef __PLATFORM_OVERRIDE_H__
 #define __PLATFORM_OVERRIDE_H__
 
-#include <sbi/sbi_hart.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_types.h>
 #include <sbi_utils/fdt/fdt_driver.h>
@@ -19,7 +18,7 @@ bool generic_cold_boot_allowed(u32 hartid);
 int generic_nascent_init(void);
 int generic_early_init(bool cold_boot);
 int generic_final_init(bool cold_boot);
-int generic_extensions_init(struct sbi_hart_features *hfeatures);
+int generic_extensions_init(bool cold_boot);
 int generic_domains_init(void);
 int generic_pmu_init(void);
 uint64_t generic_pmu_xlate_to_mhpmevent(uint32_t event_idx, uint64_t data);
diff --git a/platform/generic/platform.c b/platform/generic/platform.c
index 01fa03e0..1df0280d 100644
--- a/platform/generic/platform.c
+++ b/platform/generic/platform.c
@@ -253,11 +253,13 @@ int generic_final_init(bool cold_boot)
 	return 0;
 }
 
-int generic_extensions_init(struct sbi_hart_features *hfeatures)
+int generic_extensions_init(bool cold_boot)
 {
+	if (!cold_boot)
+		return 0;
+
 	/* Parse the ISA string from FDT and enable the listed extensions */
-	return fdt_parse_isa_extensions(fdt_get_address(), current_hartid(),
-					hfeatures->extensions);
+	return fdt_parse_isa_extensions_all_harts(fdt_get_address());
 }
 
 int generic_domains_init(void)
diff --git a/platform/generic/sophgo/sg2042.c b/platform/generic/sophgo/sg2042.c
index c2447c3c..ac8840e8 100644
--- a/platform/generic/sophgo/sg2042.c
+++ b/platform/generic/sophgo/sg2042.c
@@ -49,11 +49,11 @@ static int sophgo_sg2042_early_init(bool cold_boot)
 	return 0;
 }
 
-static int sophgo_sg2042_extensions_init(struct sbi_hart_features *hfeatures)
+static int sophgo_sg2042_extensions_init(bool cold_boot)
 {
 	int rc;
 
-	rc = generic_extensions_init(hfeatures);
+	rc = generic_extensions_init(cold_boot);
 	if (rc)
 		return rc;
 
diff --git a/platform/generic/starfive/jh7110.c b/platform/generic/starfive/jh7110.c
index c1328437..7008386a 100644
--- a/platform/generic/starfive/jh7110.c
+++ b/platform/generic/starfive/jh7110.c
@@ -12,6 +12,7 @@
 #include <platform_override.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_bitops.h>
+#include <sbi/sbi_hart.h>
 #include <sbi/sbi_system.h>
 #include <sbi/sbi_console.h>
 #include <sbi/sbi_timer.h>
diff --git a/platform/generic/thead/thead-generic.c b/platform/generic/thead/thead-generic.c
index ddb4f0bf..fef0871b 100644
--- a/platform/generic/thead/thead-generic.c
+++ b/platform/generic/thead/thead-generic.c
@@ -26,11 +26,11 @@ static int thead_tlb_flush_early_init(bool cold_boot)
 	return generic_early_init(cold_boot);
 }
 
-static int thead_pmu_extensions_init(struct sbi_hart_features *hfeatures)
+static int thead_pmu_extensions_init(bool cold_boot)
 {
 	int rc;
 
-	rc = generic_extensions_init(hfeatures);
+	rc = generic_extensions_init(cold_boot);
 	if (rc)
 		return rc;
 
-- 
2.43.0


-- 
opensbi mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/opensbi
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.