diff options
-rw-r--r-- | arch/riscv/cpu/cpu.c | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 99083e11dfa..affe70081b5 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; } } |