From: Conor Dooley Date: Mon, 18 Mar 2024 15:16:03 +0000 (+0000) Subject: riscv: support extension probing using riscv, isa-extensions X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=f39b1b77d822916498f4dc9b9f50fe740df9afb6;p=u-boot.git riscv: support extension probing using riscv, isa-extensions 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 Reviewed-by: Leo Yu-Chi Liang --- 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; } }