diff mbox series

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

Message ID 20240318151604.865025-4-conor@kernel.org
State Accepted
Commit f39b1b77d822916498f4dc9b9f50fe740df9afb6
Delegated to: Andes
Headers show
Series Support new RISC-V ISA extension properties | expand

Commit Message

Conor Dooley March 18, 2024, 3:16 p.m. UTC
From: Conor Dooley <conor.dooley@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@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(-)

Comments

Leo Liang March 28, 2024, 7:12 a.m. UTC | #1
On Mon, Mar 18, 2024 at 03:16:03PM +0000, Conor Dooley wrote:
> From: Conor Dooley <conor.dooley@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@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(-)

Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
diff mbox series

Patch

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;
 		}
 	}