From patchwork Fri Jan 26 14:23:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 1891365 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=Ey1mWlWa; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linux.dev header.i=@linux.dev header.a=rsa-sha256 header.s=key1 header.b=cSf6sJNB; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=198.137.202.133; helo=bombadil.infradead.org; envelope-from=kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TM0SF1GYWz23gJ for ; Sat, 27 Jan 2024 01:29:01 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=shasq9gAQPzB3JNdtWZZtCRusQpkCkdqrx5EmTN+d2Y=; b=Ey1mWlWabL0cKh IcKBIN5olVTeqRPaXfV5gcliYb2XrIHu46cQZavcqvnMA7ljG35drrL+OlBfrMcMcpWqNA9SRpZbJ 4tP+sTLgG43DliSWcFXsOMdQEjblfjOvIrqqTys7Y7WElZOWwfMuUWYVPSN45Xi4RC29H0bKqjsSO 2v5B3JMVwTN/LvRMNb7DbJWyGB3JRMzzLIP+U/8G+MV9lzuvwDs9W7I8xlZ6iIiDGq7b04j250C2k daGFqxUiYnAFcMXwIlakzxnw8p3hfTFMPGT2t/io50E/sROx/z59L2kkKyERk2T5gUtMR8nZpkmbb 1BWL0Jh1RN0H/AoEc+dQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rTN8B-00000004K3y-2I6O; Fri, 26 Jan 2024 14:24:31 +0000 Received: from out-176.mta1.migadu.com ([2001:41d0:203:375::b0]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rTN88-00000004Jzs-0e5e for kvm-riscv@lists.infradead.org; Fri, 26 Jan 2024 14:24:29 +0000 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1706279066; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=utoylgPTkJdXuAHqdAXp52bAVwYjYgFvheHgylCUS70=; b=cSf6sJNBlayx+5i2UKKh1cEpVGX+R+gFpPJ2dZS5nc9/HxbtsexmA3uuf0rhQeCD8zIcsd 93qd8WWpCXehoaD5bimLsW7PD+pf9wX19WlLObsghwGOMg0FdXeYcatPaORBT75UN9R7ly S6A3rn9+cgyc9KM9PiAeOTRsIyKulyA= From: Andrew Jones 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 Message-ID: <20240126142324.66674-48-andrew.jones@linux.dev> In-Reply-To: <20240126142324.66674-26-andrew.jones@linux.dev> References: <20240126142324.66674-26-andrew.jones@linux.dev> MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240126_062428_394722_D409BF53 X-CRM114-Status: GOOD ( 19.62 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: 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 b [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 T_SCC_BODY_TEXT_LINE No description available. X-BeenThere: kvm-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kvm-riscv" Errors-To: kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org 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 Acked-by: Thomas Huth --- 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 +#include + +/* + * 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 + */ +#include +#include +#include +#include +#include +#include + +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 #include +#include #include #include @@ -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