git: 3e01ebda6829 - main - riscv: support the new "riscv,isa-extensions" string-array.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 06 Oct 2026 19:10:42 UTC
The branch main has been updated by br:
URL: https://cgit.FreeBSD.org/src/commit/?id=3e01ebda68291db307a5e6c23d4995c638be9228
commit 3e01ebda68291db307a5e6c23d4995c638be9228
Author: Ruslan Bukin <br@FreeBSD.org>
AuthorDate: 2026-10-06 18:55:39 +0000
Commit: Ruslan Bukin <br@FreeBSD.org>
CommitDate: 2026-10-06 19:09:04 +0000
riscv: support the new "riscv,isa-extensions" string-array.
Support the new "riscv,isa-extensions" property on RISC-V hart nodes
in FDT.
The "riscv,isa" property is deprecated, but cannot be removed because
doing so would break compatibility with existing DTBs. The new properties
replace it: "riscv,isa-base" describes the base ISA and
"riscv,isa-extensions" is a string array containing the supported ISA
extensions.
The "riscv,isa-extensions" property can be relatively large; on the
Spacemit K3 SoC it is approximately 300 bytes.
The FreeBSD OFW interface does not provide access to the underlying FDT
property data without copying it, and memory allocation is not possible
this early. So allocate a static buffer for the property instead.
Reuse the existing parse_riscv_isa() implementation to parse both the new
extension property and the legacy "riscv,isa" property.
Reviewed by: bnovkov, mhorne
Sponsored by: EPSRC ("UKRI3001: CHERI Research Centre")
Differential Revision: https://reviews.freebsd.org/D60209
---
sys/riscv/riscv/identcpu.c | 106 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 80 insertions(+), 26 deletions(-)
diff --git a/sys/riscv/riscv/identcpu.c b/sys/riscv/riscv/identcpu.c
index ca1b2b9ae1af..81e8afde8499 100644
--- a/sys/riscv/riscv/identcpu.c
+++ b/sys/riscv/riscv/identcpu.c
@@ -86,6 +86,8 @@ bool has_zicbom;
bool has_zicboz;
bool has_zicbop;
+static char isa_extensions[PAGE_SIZE];
+
struct cpu_desc {
const char *cpu_mvendor_name;
const char *cpu_march_name;
@@ -271,14 +273,7 @@ parse_riscv_isa(struct cpu_desc *desc, char *isa, int len)
{
int i;
- /* Check the string prefix. */
- if (strncmp(isa, ISA_PREFIX, ISA_PREFIX_LEN) != 0) {
- printf("%s: Unrecognized ISA string: %s\n", __func__, isa);
- return (-1);
- }
-
- i = ISA_PREFIX_LEN;
- while (i < len) {
+ for (i = 0; i < len; ) {
switch(isa[i]) {
case 'a':
case 'b':
@@ -372,14 +367,82 @@ parse_cbo_fdt(struct cpu_desc *desc, phandle_t node)
desc->cboz_block_size = 0;
}
+static int
+parse_isa_extensions(phandle_t node, u_int cpu, struct cpu_desc *desc)
+{
+ ssize_t len, off, i;
+ char *ext;
+
+ len = OF_getprop(node, "riscv,isa-extensions", isa_extensions,
+ sizeof(isa_extensions));
+ if (len == -1)
+ return (ESRCH);
+ if (len > sizeof(isa_extensions))
+ panic("isa_extensions string truncated");
+
+ for (i = 0; i < len; i++)
+ isa_extensions[i] = tolower(isa_extensions[i]);
+
+ for (off = 0; off < len; ) {
+ ext = isa_extensions + off;
+ if (*ext == '\0')
+ break;
+ if (bootverbose)
+ printf("riscv extension: %s\n", ext);
+ parse_riscv_isa(desc, ext, strlen(ext));
+ off += strlen(ext) + 1;
+ }
+
+ return (0);
+}
+
+static int
+parse_riscv_isa_legacy(phandle_t node, u_int cpu, struct cpu_desc *desc)
+{
+ u_int hart;
+ ssize_t len;
+ int i;
+
+ hart = pcpu_find(cpu)->pc_hart;
+
+ len = OF_getprop(node, "riscv,isa", isa_extensions,
+ sizeof(isa_extensions));
+ if (len == -1) {
+ printf("%s: could not find 'riscv,isa' property "
+ "for CPU %d, hart %u\n", __func__, cpu, hart);
+ return (ESRCH);
+ }
+ if (len > sizeof(isa_extensions))
+ panic("isa string truncated");
+
+ if (bootverbose)
+ printf("hart %d isa: %s\n", hart, isa_extensions);
+
+ /*
+ * The string is specified to be lowercase, but let's be
+ * certain.
+ */
+ for (i = 0; i < len; i++)
+ isa_extensions[i] = tolower(isa_extensions[i]);
+
+ /* Check the string prefix. */
+ if (strncmp(isa_extensions, ISA_PREFIX, ISA_PREFIX_LEN) != 0) {
+ printf("%s: Unrecognized ISA string: %s\n", __func__,
+ isa_extensions);
+ return (-1);
+ }
+
+ return (parse_riscv_isa(desc, &isa_extensions[ISA_PREFIX_LEN],
+ len - ISA_PREFIX_LEN));
+}
+
static void
identify_cpu_features_fdt(u_int cpu, struct cpu_desc *desc)
{
- char isa[1024];
phandle_t node;
- ssize_t len;
pcell_t reg;
u_int hart;
+ int error;
node = OF_finddevice("/cpus");
if (node == -1) {
@@ -403,26 +466,17 @@ identify_cpu_features_fdt(u_int cpu, struct cpu_desc *desc)
reg != hart)
continue;
- len = OF_getprop(node, "riscv,isa", isa, sizeof(isa));
- KASSERT(len <= sizeof(isa), ("ISA string truncated"));
- if (len == -1) {
- printf("%s: could not find 'riscv,isa' property "
+ error = parse_isa_extensions(node, cpu, desc);
+ if (error != 0) {
+ /* Fall-back to the legacy riscv,isa string. */
+ error = parse_riscv_isa_legacy(node, cpu, desc);
+ }
+ if (error != 0) {
+ printf("%s: could not parse ISA string "
"for CPU %d, hart %u\n", __func__, cpu, hart);
return;
}
- if (bootverbose)
- printf("hart %d isa: %s\n", hart, isa);
-
- /*
- * The string is specified to be lowercase, but let's be
- * certain.
- */
- for (int i = 0; i < len; i++)
- isa[i] = tolower(isa[i]);
- if (parse_riscv_isa(desc, isa, len) != 0)
- return;
-
/* Check MMU features. */
parse_mmu_fdt(desc, node);