Page MenuHomeFreeBSD

D60209.id188794.diff
No OneTemporary

D60209.id188794.diff

Index: sys/riscv/riscv/identcpu.c
===================================================================
--- sys/riscv/riscv/identcpu.c
+++ sys/riscv/riscv/identcpu.c
@@ -86,6 +86,8 @@
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 @@
{
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 @@
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 @@
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);

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 14, 3:35 AM (16 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40724254
Default Alt Text
D60209.id188794.diff (3 KB)

Event Timeline