[PATCH v1 2/2] riscv: support extension probing using riscv, isa-extensions

Conor Dooley conor at kernel.org
Mon Mar 18 16:16:03 CET 2024


From: Conor Dooley <conor.dooley at microchip.com>

A new property has been added, with an extensive rationale at [1], that
can be used in place of "riscv,isa" to indicate what extensions are
supported by a given platform that is a list of strings rather than a
single string. There are some differences between the new property,
"riscv,isa-extensions" and the incumbent "riscv,isa" - chief among them
for the sake of parsing being the list of strings, as opposed to a
string. Another advantage is strictly defined meanings for each string
in a dt-binding, rather than deriving meaning from RVI standards. This
will likely to some divergence over time, but U-Boot's current use of
extension detection is very limited - there are just four callsites of
supports_extension() in mainline U-Boot.

These checks are limited to two checks for FPU support and two checks
for "s" and "u". "s" and "u" are not supported by the new property, but
they were also not permitted in "riscv,isa". These checks are only
meaningful (or run) in M-Mode, in which case supports_extension() does
not parse the devicetree anyway.

Add support for the new property in U-Boot, prioritising it, before
falling back to the, now deprecated, "riscv,isa" property if it is not
present.

Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
---
I moved the kernel devicetrees to use the new properties, I'd do the
same here, but I'd rather just move things to use dt-rebasing instead,
where possible.
---
 arch/riscv/cpu/cpu.c | 56 +++++++++++++++++++++++++++-----------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index 99083e11df..affe70081b 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -38,9 +38,10 @@ static inline bool supports_extension(char ext)
 #if CONFIG_IS_ENABLED(RISCV_MMODE)
 	return csr_read(CSR_MISA) & (1 << (ext - 'a'));
 #elif CONFIG_CPU
+	char sext[2] = {ext};
 	struct udevice *dev;
 	const char *isa;
-	int i;
+	int ret, i;
 
 	uclass_find_first_device(UCLASS_CPU, &dev);
 	if (!dev) {
@@ -48,27 +49,40 @@ static inline bool supports_extension(char ext)
 		return false;
 	}
 
+	ret = dev_read_stringlist_search(dev, "riscv,isa-extensions", sext);
+	if (ret >= 0)
+		return true;
+
+	/*
+	 * Only if the property is not found (ENODATA) is the fallback to
+	 * riscv,isa used, otherwise the extension is not present in this
+	 * CPU.
+	 */
+	if (ret != -ENODATA)
+		return false;
+
 	isa = dev_read_string(dev, "riscv,isa");
-	if (isa) {
-		/*
-		 * skip the first 4 characters (rv32|rv64)
-		 */
-		for (i = 4; i < sizeof(isa); i++) {
-			switch (isa[i]) {
-			case 's':
-			case 'x':
-			case 'z':
-			case '_':
-			case '\0':
-				/*
-				 * Any of these characters mean the single
-				 * letter extensions have all been consumed.
-				 */
-				return false;
-			default:
-				if (isa[i] == ext)
-					return true;
-			}
+	if (!isa)
+		return false;
+
+	/*
+	 * Skip the first 4 characters (rv32|rv64).
+	 */
+	for (i = 4; i < sizeof(isa); i++) {
+		switch (isa[i]) {
+		case 's':
+		case 'x':
+		case 'z':
+		case '_':
+		case '\0':
+			/*
+			 * Any of these characters mean the single
+			 * letter extensions have all been consumed.
+			 */
+			return false;
+		default:
+			if (isa[i] == ext)
+				return true;
 		}
 	}
 
-- 
2.43.0



More information about the U-Boot mailing list