public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <andrew.jones@linux.dev>
To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org,
	kvmarm@lists.linux.dev
Cc: ajones@ventanamicro.com, anup@brainfault.org,
	atishp@atishpatra.org, pbonzini@redhat.com, thuth@redhat.com,
	alexandru.elisei@arm.com, eric.auger@redhat.com
Subject: [kvm-unit-tests PATCH v2 22/24] riscv: Add isa string parsing
Date: Fri, 26 Jan 2024 15:23:47 +0100	[thread overview]
Message-ID: <20240126142324.66674-48-andrew.jones@linux.dev> (raw)
In-Reply-To: <20240126142324.66674-26-andrew.jones@linux.dev>

We can probably get away with just assuming several important
and popular extensions (at least everything covered by G), but
we'll also want to use some extensions which we should ensure
are present by parsing the isa string. Add a parser and already
apply it to Sstc.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
Acked-by: Thomas Huth <thuth@redhat.com>
---
 lib/riscv/asm/isa.h       |  33 ++++++++++
 lib/riscv/asm/processor.h |   1 +
 lib/riscv/isa.c           | 126 ++++++++++++++++++++++++++++++++++++++
 lib/riscv/processor.c     |   2 +
 riscv/Makefile            |   1 +
 5 files changed, 163 insertions(+)
 create mode 100644 lib/riscv/asm/isa.h
 create mode 100644 lib/riscv/isa.c

diff --git a/lib/riscv/asm/isa.h b/lib/riscv/asm/isa.h
new file mode 100644
index 000000000000..df874173f4ed
--- /dev/null
+++ b/lib/riscv/asm/isa.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_ISA_H_
+#define _ASMRISCV_ISA_H_
+#include <bitops.h>
+#include <asm/setup.h>
+
+/*
+ * We assume and use several extensions, such as Zicsr and Zifencei.
+ * Here we only track extensions which we don't assume and the
+ * framework may want to use. Unit tests may check for extensions
+ * by name not tracked here with cpu_has_extension_name()
+ */
+enum {
+	ISA_SSTC,
+	ISA_MAX,
+};
+_Static_assert(ISA_MAX <= __riscv_xlen, "Need to increase thread_info.isa");
+
+static inline bool cpu_has_extension(int cpu, int ext)
+{
+	return test_bit(ext, cpus[cpu].isa);
+}
+
+bool cpu_has_extension_name(int cpu, const char *ext);
+
+static inline bool has_ext(const char *ext)
+{
+	return cpu_has_extension_name(current_thread_info()->cpu, ext);
+}
+
+void isa_init(struct thread_info *info);
+
+#endif /* _ASMRISCV_ISA_H_ */
diff --git a/lib/riscv/asm/processor.h b/lib/riscv/asm/processor.h
index f20774d02d8e..32c499d0c0ab 100644
--- a/lib/riscv/asm/processor.h
+++ b/lib/riscv/asm/processor.h
@@ -11,6 +11,7 @@ typedef void (*exception_fn)(struct pt_regs *);
 struct thread_info {
 	int cpu;
 	unsigned long hartid;
+	unsigned long isa[1];
 	exception_fn exception_handlers[EXCEPTION_CAUSE_MAX];
 };
 
diff --git a/lib/riscv/isa.c b/lib/riscv/isa.c
new file mode 100644
index 000000000000..bc1c9c72045c
--- /dev/null
+++ b/lib/riscv/isa.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+#include <bitops.h>
+#include <devicetree.h>
+#include <string.h>
+#include <asm/isa.h>
+#include <asm/setup.h>
+
+typedef void (*isa_func_t)(const char *, int, void *);
+
+struct isa_info {
+	unsigned long hartid;
+	isa_func_t func;
+	void *data;
+};
+
+static bool isa_match(const char *ext, const char *name, int len)
+{
+	return len == strlen(ext) && !strncasecmp(name, ext, len);
+}
+
+struct isa_check {
+	const char *ext;
+	bool found;
+};
+
+static void isa_name(const char *name, int len, void *data)
+{
+	struct isa_check *check = (struct isa_check *)data;
+
+	if (isa_match(check->ext, name, len))
+		check->found = true;
+}
+
+static void isa_bit(const char *name, int len, void *data)
+{
+	struct thread_info *info = (struct thread_info *)data;
+
+	if (isa_match("sstc", name, len))
+		set_bit(ISA_SSTC, info->isa);
+}
+
+static void isa_parse(const char *isa_string, int len, struct isa_info *info)
+{
+	assert(isa_string[0] == 'r' && isa_string[1] == 'v');
+#if __riscv_xlen == 32
+	assert(isa_string[2] == '3' && isa_string[3] == '2');
+#else
+	assert(isa_string[2] == '6' && isa_string[3] == '4');
+#endif
+
+	for (int i = 4; i < len; ++i) {
+		if (isa_string[i] == '_') {
+			const char *multi = &isa_string[++i];
+			int start = i;
+
+			while (i < len - 1 && isa_string[i] != '_')
+				++i;
+			info->func(multi, i - start, info->data);
+			if (i < len - 1)
+				--i;
+		} else {
+			info->func(&isa_string[i], 1, info->data);
+		}
+	}
+}
+
+static void isa_parse_fdt(int cpu_node, u64 hartid, void *data)
+{
+	struct isa_info *info = (struct isa_info *)data;
+	const struct fdt_property *prop;
+	int len;
+
+	if (hartid != info->hartid)
+		return;
+
+	prop = fdt_get_property(dt_fdt(), cpu_node, "riscv,isa", &len);
+	assert(prop);
+
+	isa_parse(prop->data, len, info);
+}
+
+static void isa_init_acpi(void)
+{
+	assert_msg(false, "ACPI not available");
+}
+
+void isa_init(struct thread_info *ti)
+{
+	struct isa_info info = {
+		.hartid = ti->hartid,
+		.func = isa_bit,
+		.data = ti,
+	};
+	int ret;
+
+	if (dt_available()) {
+		ret = dt_for_each_cpu_node(isa_parse_fdt, &info);
+		assert(ret == 0);
+	} else {
+		isa_init_acpi();
+	}
+}
+
+bool cpu_has_extension_name(int cpu, const char *ext)
+{
+	struct isa_info info = {
+		.hartid = cpus[cpu].hartid,
+		.func = isa_name,
+		.data = &(struct isa_check){ .ext = ext, },
+	};
+	struct isa_check *check = info.data;
+	int ret;
+
+	if (dt_available()) {
+		ret = dt_for_each_cpu_node(isa_parse_fdt, &info);
+		assert(ret == 0);
+	} else {
+		assert_msg(false, "ACPI not available");
+	}
+
+	return check->found;
+}
diff --git a/lib/riscv/processor.c b/lib/riscv/processor.c
index 2bfbd4e9b274..e0904209c0da 100644
--- a/lib/riscv/processor.c
+++ b/lib/riscv/processor.c
@@ -4,6 +4,7 @@
  */
 #include <libcflat.h>
 #include <asm/csr.h>
+#include <asm/isa.h>
 #include <asm/processor.h>
 #include <asm/setup.h>
 
@@ -58,5 +59,6 @@ void thread_info_init(void)
 	unsigned long hartid = csr_read(CSR_SSCRATCH);
 	int cpu = hartid_to_cpu(hartid);
 
+	isa_init(&cpus[cpu]);
 	csr_write(CSR_SSCRATCH, &cpus[cpu]);
 }
diff --git a/riscv/Makefile b/riscv/Makefile
index 61a1ff88d8ec..b51d9edfb792 100644
--- a/riscv/Makefile
+++ b/riscv/Makefile
@@ -30,6 +30,7 @@ cflatobjs += lib/on-cpus.o
 cflatobjs += lib/vmalloc.o
 cflatobjs += lib/riscv/bitops.o
 cflatobjs += lib/riscv/io.o
+cflatobjs += lib/riscv/isa.o
 cflatobjs += lib/riscv/mmu.o
 cflatobjs += lib/riscv/processor.o
 cflatobjs += lib/riscv/sbi.o
-- 
2.43.0


  parent reply	other threads:[~2024-01-26 14:24 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-26 14:23 [kvm-unit-tests PATCH v2 00/24] Introduce RISC-V Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 01/24] configure: Add ARCH_LIBDIR Andrew Jones
2024-02-01  8:29   ` Eric Auger
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 02/24] riscv: Initial port, hello world Andrew Jones
2024-02-01  8:29   ` Eric Auger
2024-02-01 14:07     ` Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 03/24] arm/arm64: Move cpumask.h to common lib Andrew Jones
2024-02-01  8:29   ` Eric Auger
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 04/24] arm/arm64: Share cpu online, present and idle masks Andrew Jones
2024-02-01  8:29   ` Eric Auger
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 05/24] riscv: Add DT parsing Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 06/24] riscv: Add initial SBI support Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 07/24] riscv: Add run script and unittests.cfg Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 08/24] riscv: Add riscv32 support Andrew Jones
2024-02-01 15:24   ` Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 09/24] riscv: Add exception handling Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 10/24] riscv: Add backtrace support Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 11/24] arm/arm64: Generalize wfe/sev names in smp.c Andrew Jones
2024-02-01  9:22   ` Eric Auger
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 12/24] arm/arm64: Remove spinlocks from on_cpu_async Andrew Jones
2024-02-01  9:34   ` Eric Auger
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 13/24] arm/arm64: Share on_cpus Andrew Jones
2024-02-01  9:36   ` Eric Auger
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 14/24] riscv: Compile with march Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 15/24] riscv: Add SMP support Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 16/24] arm/arm64: Share memregions Andrew Jones
2024-02-01 12:03   ` Eric Auger
2024-02-01 14:21     ` Andrew Jones
2024-02-01 17:46       ` Eric Auger
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 17/24] riscv: Populate memregions and switch to page allocator Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 18/24] riscv: Add MMU support Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 19/24] riscv: Enable the MMU in secondaries Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 20/24] riscv: Enable vmalloc Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 21/24] lib: Add strcasecmp and strncasecmp Andrew Jones
2024-02-01  9:45   ` Eric Auger
2024-01-26 14:23 ` Andrew Jones [this message]
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 23/24] gitlab-ci: Add riscv64 tests Andrew Jones
2024-01-26 14:23 ` [kvm-unit-tests PATCH v2 24/24] MAINTAINERS: Add riscv Andrew Jones
2024-02-02 14:22 ` [kvm-unit-tests PATCH v2 00/24] Introduce RISC-V Andrew Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240126142324.66674-48-andrew.jones@linux.dev \
    --to=andrew.jones@linux.dev \
    --cc=ajones@ventanamicro.com \
    --cc=alexandru.elisei@arm.com \
    --cc=anup@brainfault.org \
    --cc=atishp@atishpatra.org \
    --cc=eric.auger@redhat.com \
    --cc=kvm-riscv@lists.infradead.org \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=pbonzini@redhat.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox