summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv/cpu/cpu.c56
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;
}
}