All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <andrew.jones@linux.dev>
To: kvm-riscv@lists.infradead.org
Subject: [kvm-unit-tests PATCH 02/24] riscv: Initial port, hello world
Date: Wed, 24 Jan 2024 08:18:18 +0100	[thread overview]
Message-ID: <20240124071815.6898-28-andrew.jones@linux.dev> (raw)
In-Reply-To: <20240124071815.6898-26-andrew.jones@linux.dev>

Add the minimal amount of code possible in order to launch a first
test, which just prints "Hello, world" using the expected UART
address of the QEMU virt machine. Add files, stubs, and some support,
such as barriers and MMIO read/write along the way in order to
satisfy the compiler. Basically everything is either copied from
the arm64 port of kvm-unit-tests, or at least inspired by it, and,
in that case, the RISC-V Linux kernel code was copied.

Run with
  qemu-system-riscv64 -nographic -M virt -kernel riscv/selftest.flat

and then go to the monitor (ctrl-a c) and use 'q' to quit, since
the unit test will just hang after printing hello world and the
exit code.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
 configure                   | 14 ++++++
 lib/riscv/.gitignore        |  1 +
 lib/riscv/asm-offsets.c     |  6 +++
 lib/riscv/asm/asm-offsets.h |  1 +
 lib/riscv/asm/barrier.h     | 13 ++++++
 lib/riscv/asm/csr.h         |  7 +++
 lib/riscv/asm/io.h          | 78 +++++++++++++++++++++++++++++++
 lib/riscv/asm/page.h        |  7 +++
 lib/riscv/asm/setup.h       |  7 +++
 lib/riscv/asm/spinlock.h    |  7 +++
 lib/riscv/asm/stack.h       |  9 ++++
 lib/riscv/io.c              | 44 ++++++++++++++++++
 lib/riscv/setup.c           | 12 +++++
 riscv/Makefile              | 83 +++++++++++++++++++++++++++++++++
 riscv/cstart.S              | 92 +++++++++++++++++++++++++++++++++++++
 riscv/flat.lds              | 75 ++++++++++++++++++++++++++++++
 riscv/selftest.c            | 13 ++++++
 17 files changed, 469 insertions(+)
 create mode 100644 lib/riscv/.gitignore
 create mode 100644 lib/riscv/asm-offsets.c
 create mode 100644 lib/riscv/asm/asm-offsets.h
 create mode 100644 lib/riscv/asm/barrier.h
 create mode 100644 lib/riscv/asm/csr.h
 create mode 100644 lib/riscv/asm/io.h
 create mode 100644 lib/riscv/asm/page.h
 create mode 100644 lib/riscv/asm/setup.h
 create mode 100644 lib/riscv/asm/spinlock.h
 create mode 100644 lib/riscv/asm/stack.h
 create mode 100644 lib/riscv/io.c
 create mode 100644 lib/riscv/setup.c
 create mode 100644 riscv/Makefile
 create mode 100644 riscv/cstart.S
 create mode 100644 riscv/flat.lds
 create mode 100644 riscv/selftest.c

diff --git a/configure b/configure
index ada6512702a1..05e6702eab06 100755
--- a/configure
+++ b/configure
@@ -200,6 +200,11 @@ arch_name=$arch
 [ "$arch_name" = "arm64" ] && arch_name="aarch64"
 arch_libdir=$arch
 
+if [ "$arch" = "riscv" ]; then
+    echo "riscv32 or riscv64 must be specified"
+    exit 1
+fi
+
 if [ -z "$target" ]; then
     target="qemu"
 else
@@ -307,6 +312,9 @@ elif [ "$arch" = "ppc64" ]; then
         echo "You must provide endianness (big or little)!"
         usage
     fi
+elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
+    testdir=riscv
+    arch_libdir=riscv
 else
     testdir=$arch
 fi
@@ -438,6 +446,12 @@ cat <<EOF >> lib/config.h
 #define CONFIG_ERRATA_FORCE ${errata_force}
 #define CONFIG_PAGE_SIZE _AC(${page_size}, UL)
 
+EOF
+elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
+cat <<EOF >> lib/config.h
+
+#define CONFIG_UART_EARLY_BASE 0x10000000
+
 EOF
 fi
 echo "#endif" >> lib/config.h
diff --git a/lib/riscv/.gitignore b/lib/riscv/.gitignore
new file mode 100644
index 000000000000..82da12e6bd4e
--- /dev/null
+++ b/lib/riscv/.gitignore
@@ -0,0 +1 @@
+/asm-offsets.[hs]
diff --git a/lib/riscv/asm-offsets.c b/lib/riscv/asm-offsets.c
new file mode 100644
index 000000000000..4a74df9e4a09
--- /dev/null
+++ b/lib/riscv/asm-offsets.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+int main(void)
+{
+	return 0;
+}
diff --git a/lib/riscv/asm/asm-offsets.h b/lib/riscv/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /dev/null
+++ b/lib/riscv/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/lib/riscv/asm/barrier.h b/lib/riscv/asm/barrier.h
new file mode 100644
index 000000000000..c6a09066b2c7
--- /dev/null
+++ b/lib/riscv/asm/barrier.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_BARRIER_H_
+#define _ASMRISCV_BARRIER_H_
+
+#define RISCV_FENCE(p, s) \
+	__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
+
+/* These barriers need to enforce ordering on both devices or memory. */
+#define mb()		RISCV_FENCE(iorw,iorw)
+#define rmb()		RISCV_FENCE(ir,ir)
+#define wmb()		RISCV_FENCE(ow,ow)
+
+#endif /* _ASMRISCV_BARRIER_H_ */
diff --git a/lib/riscv/asm/csr.h b/lib/riscv/asm/csr.h
new file mode 100644
index 000000000000..5c4f2de34f64
--- /dev/null
+++ b/lib/riscv/asm/csr.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_CSR_H_
+#define _ASMRISCV_CSR_H_
+
+#define CSR_SSCRATCH		0x140
+
+#endif /* _ASMRISCV_CSR_H_ */
diff --git a/lib/riscv/asm/io.h b/lib/riscv/asm/io.h
new file mode 100644
index 000000000000..d2eb3acc9fda
--- /dev/null
+++ b/lib/riscv/asm/io.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * From Linux arch/riscv/include/asm/mmio.h
+ */
+#ifndef _ASMRISCV_IO_H_
+#define _ASMRISCV_IO_H_
+#include <libcflat.h>
+
+#define __iomem
+
+/* Generic IO read/write.  These perform native-endian accesses. */
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+	asm volatile("sb %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+	asm volatile("sh %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+	asm volatile("sw %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_writeq __raw_writeq
+static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
+{
+	asm volatile("sd %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+#endif
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+	u8 val;
+
+	asm volatile("lb %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+	u16 val;
+
+	asm volatile("lh %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+	u32 val;
+
+	asm volatile("lw %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_readq __raw_readq
+static inline u64 __raw_readq(const volatile void __iomem *addr)
+{
+	u64 val;
+
+	asm volatile("ld %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+#endif
+
+#include <asm-generic/io.h>
+
+#endif /* _ASMRISCV_IO_H_ */
diff --git a/lib/riscv/asm/page.h b/lib/riscv/asm/page.h
new file mode 100644
index 000000000000..7d7c9191605a
--- /dev/null
+++ b/lib/riscv/asm/page.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_PAGE_H_
+#define _ASMRISCV_PAGE_H_
+
+#include <asm-generic/page.h>
+
+#endif /* _ASMRISCV_PAGE_H_ */
diff --git a/lib/riscv/asm/setup.h b/lib/riscv/asm/setup.h
new file mode 100644
index 000000000000..385455f341cc
--- /dev/null
+++ b/lib/riscv/asm/setup.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_SETUP_H_
+#define _ASMRISCV_SETUP_H_
+
+void setup(const void *fdt, phys_addr_t freemem_start);
+
+#endif /* _ASMRISCV_SETUP_H_ */
diff --git a/lib/riscv/asm/spinlock.h b/lib/riscv/asm/spinlock.h
new file mode 100644
index 000000000000..6e2b3009abf3
--- /dev/null
+++ b/lib/riscv/asm/spinlock.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_SPINLOCK_H_
+#define _ASMRISCV_SPINLOCK_H_
+
+#include <asm-generic/spinlock.h>
+
+#endif /* _ASMRISCV_SPINLOCK_H_ */
diff --git a/lib/riscv/asm/stack.h b/lib/riscv/asm/stack.h
new file mode 100644
index 000000000000..d081d0716d7b
--- /dev/null
+++ b/lib/riscv/asm/stack.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_STACK_H_
+#define _ASMRISCV_STACK_H_
+
+#ifndef _STACK_H_
+#error Do not directly include <asm/stack.h>. Just use <stack.h>.
+#endif
+
+#endif
diff --git a/lib/riscv/io.c b/lib/riscv/io.c
new file mode 100644
index 000000000000..3cfc235d19a6
--- /dev/null
+++ b/lib/riscv/io.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Each architecture must implement puts() and exit() with the I/O
+ * devices exposed from QEMU, e.g. ns16550a.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/spinlock.h>
+
+/*
+ * Use this guess for the uart base in order to make an attempt at
+ * having earlier printf support. We'll overwrite it with the real
+ * base address that we read from the device tree later. This is
+ * the address we expect the virtual machine manager to put in
+ * its generated device tree.
+ */
+#define UART_EARLY_BASE ((u8 *)(unsigned long)CONFIG_UART_EARLY_BASE)
+static volatile u8 *uart0_base = UART_EARLY_BASE;
+static struct spinlock uart_lock;
+
+void puts(const char *s)
+{
+	spin_lock(&uart_lock);
+	while (*s)
+		writeb(*s++, uart0_base);
+	spin_unlock(&uart_lock);
+}
+
+/*
+ * Defining halt to take 'code' as an argument guarantees that it will
+ * be in a0 when we halt. That gives us a final chance to see the exit
+ * status while inspecting the halted unit test state.
+ */
+void halt(int code);
+
+void exit(int code)
+{
+	printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
+	halt(code);
+	__builtin_unreachable();
+}
diff --git a/lib/riscv/setup.c b/lib/riscv/setup.c
new file mode 100644
index 000000000000..8937525ccb7f
--- /dev/null
+++ b/lib/riscv/setup.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Initialize machine setup information and I/O.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+#include <asm/setup.h>
+
+void setup(const void *fdt, phys_addr_t freemem_start)
+{
+}
diff --git a/riscv/Makefile b/riscv/Makefile
new file mode 100644
index 000000000000..f2e89f0e4c38
--- /dev/null
+++ b/riscv/Makefile
@@ -0,0 +1,83 @@
+#
+# riscv makefile
+#
+# Authors: Andrew Jones <ajones@ventanamicro.com>
+#
+
+ifeq ($(CONFIG_EFI),y)
+exe = efi
+else
+exe = flat
+endif
+
+tests =
+tests += $(TEST_DIR)/selftest.$(exe)
+#tests += $(TEST_DIR)/sieve.$(exe)
+
+all: $(tests)
+
+$(TEST_DIR)/sieve.elf: AUXFLAGS = 0x1
+
+cstart.o = $(TEST_DIR)/cstart.o
+
+cflatobjs += lib/riscv/io.o
+cflatobjs += lib/riscv/setup.o
+
+########################################
+
+OBJDIRS += lib/riscv
+FLATLIBS = $(libcflat) $(LIBFDT_archive)
+
+AUXFLAGS ?= 0x0
+
+# stack.o relies on frame pointers.
+KEEP_FRAME_POINTER := y
+
+# We want to keep intermediate files
+.PRECIOUS: %.elf %.o
+
+define arch_elf_check =
+	$(if $(shell ! $(READELF) -rW $(1) >&/dev/null && echo "nok"),
+		$(error $(shell $(READELF) -rW $(1) 2>&1)))
+	$(if $(shell $(READELF) -rW $(1) | grep R_ | grep -v R_RISCV_RELATIVE),
+		$(error $(1) has unsupported reloc types))
+endef
+
+ifeq ($(ARCH),riscv64)
+CFLAGS += -DCONFIG_64BIT
+endif
+CFLAGS += -DCONFIG_RELOC
+CFLAGS += -mcmodel=medany
+CFLAGS += -mstrict-align
+CFLAGS += -std=gnu99
+CFLAGS += -ffreestanding
+CFLAGS += -O2
+CFLAGS += -I $(SRCDIR)/lib -I $(SRCDIR)/lib/libfdt
+
+asm-offsets = lib/riscv/asm-offsets.h
+include $(SRCDIR)/scripts/asm-offsets.mak
+
+ifeq ($(CONFIG_EFI),y)
+	# TODO
+else
+%.elf: LDFLAGS += -pie -n -z notext
+%.elf: %.o $(FLATLIBS) $(SRCDIR)/riscv/flat.lds $(cstart.o)
+	$(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) $(SRCDIR)/lib/auxinfo.c \
+		-DPROGNAME=\"$(notdir $(@:.elf=.flat))\" -DAUXFLAGS=$(AUXFLAGS)
+	$(LD) $(LDFLAGS) -o $@ -T $(SRCDIR)/riscv/flat.lds \
+		$(filter %.o, $^) $(FLATLIBS) $(@:.elf=.aux.o)
+	$(RM) $(@:.elf=.aux.o)
+	@chmod a-x $@
+
+%.flat: %.elf
+	$(call arch_elf_check, $^)
+	$(OBJCOPY) -O binary $^ $@
+	@chmod a-x $@
+endif
+
+generated-files = $(asm-offsets)
+$(tests:.$(exe)=.o) $(cstart.o) $(cflatobjs): $(generated-files)
+
+arch_clean: asm_offsets_clean
+	$(RM) $(TEST_DIR)/*.{o,flat,elf,so,efi,debug} \
+	      $(TEST_DIR)/.*.d $(TEST_DIR)/efi/.*.d lib/riscv/.*.d
diff --git a/riscv/cstart.S b/riscv/cstart.S
new file mode 100644
index 000000000000..a28d75e8021e
--- /dev/null
+++ b/riscv/cstart.S
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Boot entry point and assembler functions for riscv.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <asm/csr.h>
+
+.macro zero_range, tmp1, tmp2
+9998:	beq	\tmp1, \tmp2, 9997f
+	sd	zero, 0(\tmp1)
+	addi	\tmp1, \tmp1, 8
+	j	9998b
+9997:
+.endm
+
+	.section .init
+
+/*
+ * The hartid of the current core is in a0
+ * The address of the devicetree is in a1
+ *
+ * See Linux kernel doc Documentation/riscv/boot.rst
+ */
+.global start
+start:
+	/*
+	 * Stash the hartid in scratch and shift the dtb
+	 * address into a0
+	 */
+	csrw	CSR_SSCRATCH, a0
+	mv	a0, a1
+
+	/*
+	 * Update all R_RISCV_RELATIVE relocations using the table
+	 * of Elf64_Rela entries between reloc_start/end. The build
+	 * will not emit other relocation types.
+	 *
+	 * struct Elf64_Rela {
+	 * 	uint64_t r_offset;
+	 * 	uint64_t r_info;
+	 * 	int64_t  r_addend;
+	 * }
+	 */
+	la	a1, reloc_start
+	la	a2, reloc_end
+	la	a3, start			// base
+1:
+	bge	a1, a2, 1f
+	ld	a4, 0(a1)			// r_offset
+	ld	a5, 16(a1)			// r_addend
+	add	a4, a3, a4			// addr = base + r_offset
+	add	a5, a3, a5			// val = base + r_addend
+	sd	a5, 0(a4)			// *addr = val
+	addi	a1, a1, 24
+	j	1b
+
+1:
+	/* zero BSS */
+	la	a1, bss
+	la	a2, ebss
+	zero_range a1, a2
+
+	/* zero and set up stack */
+	la	sp, stacktop
+	li	a1, -8192
+	add	a1, sp, a1
+	zero_range a1, sp
+
+	/* set up exception handling */
+	//TODO
+
+	/* complete setup */
+	la	a1, stacktop			// a1 is the base of free memory
+	call	setup				// a0 is the addr of the dtb
+
+	/* run the test */
+	la	a0, __argc
+	ld	a0, 0(a0)
+	la	a1, __argv
+	la	a2, __environ
+	call	main
+	call	exit
+	j	halt
+
+	.text
+
+.balign 4
+.global halt
+halt:
+1:	wfi
+	j	1b
diff --git a/riscv/flat.lds b/riscv/flat.lds
new file mode 100644
index 000000000000..d4853f82ba1c
--- /dev/null
+++ b/riscv/flat.lds
@@ -0,0 +1,75 @@
+/*
+ * init::start will pass stacktop to setup() as the base of free memory.
+ * setup() will then move the FDT and initrd to that base before calling
+ * mem_init(). With those movements and this linker script, we'll end up
+ * having the following memory layout:
+ *
+ *    +----------------------+   <-- top of physical memory
+ *    |                      |
+ *    ~                      ~
+ *    |                      |
+ *    +----------------------+   <-- top of initrd
+ *    |                      |
+ *    +----------------------+   <-- top of FDT
+ *    |                      |
+ *    +----------------------+   <-- top of cpu0's stack
+ *    |                      |
+ *    +----------------------+   <-- top of text/data/bss sections
+ *    |                      |
+ *    |                      |
+ *    +----------------------+   <-- load address
+ *    |                      |
+ *    +----------------------+   <-- physical address 0x0
+ */
+
+PHDRS
+{
+    text PT_LOAD FLAGS(5);
+    data PT_LOAD FLAGS(6);
+}
+
+SECTIONS
+{
+    PROVIDE(_text = .);
+    .text : { *(.init) *(.text) *(.text.*) } :text
+    . = ALIGN(4K);
+    PROVIDE(_etext = .);
+
+    PROVIDE(reloc_start = .);
+    .rela.dyn : { *(.rela.dyn) }
+    PROVIDE(reloc_end = .);
+    .dynsym   : { *(.dynsym) }
+    .dynstr   : { *(.dynstr) }
+    .hash     : { *(.hash) }
+    .gnu.hash : { *(.gnu.hash) }
+    .got      : { *(.got) *(.got.plt) }
+    .eh_frame : { *(.eh_frame) }
+
+    .rodata   : { *(.rodata*) } :data
+    .data     : { *(.data) } :data
+    . = ALIGN(16);
+    PROVIDE(bss = .);
+    .bss      : { *(.bss) }
+    . = ALIGN(16);
+    PROVIDE(ebss = .);
+    . = ALIGN(4K);
+    PROVIDE(edata = .);
+
+    /*
+     * stack depth is 8K and sp must be 16 byte aligned
+     * sp must always be strictly less than the true stacktop
+     */
+    . += 12K;
+    . = ALIGN(4K);
+    PROVIDE(stackptr = . - 16);
+    PROVIDE(stacktop = .);
+
+    /DISCARD/ : {
+        *(.note*)
+        *(.interp)
+        *(.comment)
+        *(.dynamic)
+    }
+}
+
+ENTRY(start)
diff --git a/riscv/selftest.c b/riscv/selftest.c
new file mode 100644
index 000000000000..88afa732649e
--- /dev/null
+++ b/riscv/selftest.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test the framework itself. These tests confirm that setup works.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+
+int main(void)
+{
+	puts("Hello, world\n");
+	return 0;
+}
-- 
2.43.0



WARNING: multiple messages have this Message-ID (diff)
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 02/24] riscv: Initial port, hello world
Date: Wed, 24 Jan 2024 08:18:18 +0100	[thread overview]
Message-ID: <20240124071815.6898-28-andrew.jones@linux.dev> (raw)
In-Reply-To: <20240124071815.6898-26-andrew.jones@linux.dev>

Add the minimal amount of code possible in order to launch a first
test, which just prints "Hello, world" using the expected UART
address of the QEMU virt machine. Add files, stubs, and some support,
such as barriers and MMIO read/write along the way in order to
satisfy the compiler. Basically everything is either copied from
the arm64 port of kvm-unit-tests, or at least inspired by it, and,
in that case, the RISC-V Linux kernel code was copied.

Run with
  qemu-system-riscv64 -nographic -M virt -kernel riscv/selftest.flat

and then go to the monitor (ctrl-a c) and use 'q' to quit, since
the unit test will just hang after printing hello world and the
exit code.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
 configure                   | 14 ++++++
 lib/riscv/.gitignore        |  1 +
 lib/riscv/asm-offsets.c     |  6 +++
 lib/riscv/asm/asm-offsets.h |  1 +
 lib/riscv/asm/barrier.h     | 13 ++++++
 lib/riscv/asm/csr.h         |  7 +++
 lib/riscv/asm/io.h          | 78 +++++++++++++++++++++++++++++++
 lib/riscv/asm/page.h        |  7 +++
 lib/riscv/asm/setup.h       |  7 +++
 lib/riscv/asm/spinlock.h    |  7 +++
 lib/riscv/asm/stack.h       |  9 ++++
 lib/riscv/io.c              | 44 ++++++++++++++++++
 lib/riscv/setup.c           | 12 +++++
 riscv/Makefile              | 83 +++++++++++++++++++++++++++++++++
 riscv/cstart.S              | 92 +++++++++++++++++++++++++++++++++++++
 riscv/flat.lds              | 75 ++++++++++++++++++++++++++++++
 riscv/selftest.c            | 13 ++++++
 17 files changed, 469 insertions(+)
 create mode 100644 lib/riscv/.gitignore
 create mode 100644 lib/riscv/asm-offsets.c
 create mode 100644 lib/riscv/asm/asm-offsets.h
 create mode 100644 lib/riscv/asm/barrier.h
 create mode 100644 lib/riscv/asm/csr.h
 create mode 100644 lib/riscv/asm/io.h
 create mode 100644 lib/riscv/asm/page.h
 create mode 100644 lib/riscv/asm/setup.h
 create mode 100644 lib/riscv/asm/spinlock.h
 create mode 100644 lib/riscv/asm/stack.h
 create mode 100644 lib/riscv/io.c
 create mode 100644 lib/riscv/setup.c
 create mode 100644 riscv/Makefile
 create mode 100644 riscv/cstart.S
 create mode 100644 riscv/flat.lds
 create mode 100644 riscv/selftest.c

diff --git a/configure b/configure
index ada6512702a1..05e6702eab06 100755
--- a/configure
+++ b/configure
@@ -200,6 +200,11 @@ arch_name=$arch
 [ "$arch_name" = "arm64" ] && arch_name="aarch64"
 arch_libdir=$arch
 
+if [ "$arch" = "riscv" ]; then
+    echo "riscv32 or riscv64 must be specified"
+    exit 1
+fi
+
 if [ -z "$target" ]; then
     target="qemu"
 else
@@ -307,6 +312,9 @@ elif [ "$arch" = "ppc64" ]; then
         echo "You must provide endianness (big or little)!"
         usage
     fi
+elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
+    testdir=riscv
+    arch_libdir=riscv
 else
     testdir=$arch
 fi
@@ -438,6 +446,12 @@ cat <<EOF >> lib/config.h
 #define CONFIG_ERRATA_FORCE ${errata_force}
 #define CONFIG_PAGE_SIZE _AC(${page_size}, UL)
 
+EOF
+elif [ "$arch" = "riscv32" ] || [ "$arch" = "riscv64" ]; then
+cat <<EOF >> lib/config.h
+
+#define CONFIG_UART_EARLY_BASE 0x10000000
+
 EOF
 fi
 echo "#endif" >> lib/config.h
diff --git a/lib/riscv/.gitignore b/lib/riscv/.gitignore
new file mode 100644
index 000000000000..82da12e6bd4e
--- /dev/null
+++ b/lib/riscv/.gitignore
@@ -0,0 +1 @@
+/asm-offsets.[hs]
diff --git a/lib/riscv/asm-offsets.c b/lib/riscv/asm-offsets.c
new file mode 100644
index 000000000000..4a74df9e4a09
--- /dev/null
+++ b/lib/riscv/asm-offsets.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+int main(void)
+{
+	return 0;
+}
diff --git a/lib/riscv/asm/asm-offsets.h b/lib/riscv/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /dev/null
+++ b/lib/riscv/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/lib/riscv/asm/barrier.h b/lib/riscv/asm/barrier.h
new file mode 100644
index 000000000000..c6a09066b2c7
--- /dev/null
+++ b/lib/riscv/asm/barrier.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_BARRIER_H_
+#define _ASMRISCV_BARRIER_H_
+
+#define RISCV_FENCE(p, s) \
+	__asm__ __volatile__ ("fence " #p "," #s : : : "memory")
+
+/* These barriers need to enforce ordering on both devices or memory. */
+#define mb()		RISCV_FENCE(iorw,iorw)
+#define rmb()		RISCV_FENCE(ir,ir)
+#define wmb()		RISCV_FENCE(ow,ow)
+
+#endif /* _ASMRISCV_BARRIER_H_ */
diff --git a/lib/riscv/asm/csr.h b/lib/riscv/asm/csr.h
new file mode 100644
index 000000000000..5c4f2de34f64
--- /dev/null
+++ b/lib/riscv/asm/csr.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_CSR_H_
+#define _ASMRISCV_CSR_H_
+
+#define CSR_SSCRATCH		0x140
+
+#endif /* _ASMRISCV_CSR_H_ */
diff --git a/lib/riscv/asm/io.h b/lib/riscv/asm/io.h
new file mode 100644
index 000000000000..d2eb3acc9fda
--- /dev/null
+++ b/lib/riscv/asm/io.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * From Linux arch/riscv/include/asm/mmio.h
+ */
+#ifndef _ASMRISCV_IO_H_
+#define _ASMRISCV_IO_H_
+#include <libcflat.h>
+
+#define __iomem
+
+/* Generic IO read/write.  These perform native-endian accesses. */
+#define __raw_writeb __raw_writeb
+static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
+{
+	asm volatile("sb %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writew __raw_writew
+static inline void __raw_writew(u16 val, volatile void __iomem *addr)
+{
+	asm volatile("sh %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#define __raw_writel __raw_writel
+static inline void __raw_writel(u32 val, volatile void __iomem *addr)
+{
+	asm volatile("sw %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_writeq __raw_writeq
+static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
+{
+	asm volatile("sd %0, 0(%1)" : : "r" (val), "r" (addr));
+}
+#endif
+
+#define __raw_readb __raw_readb
+static inline u8 __raw_readb(const volatile void __iomem *addr)
+{
+	u8 val;
+
+	asm volatile("lb %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#define __raw_readw __raw_readw
+static inline u16 __raw_readw(const volatile void __iomem *addr)
+{
+	u16 val;
+
+	asm volatile("lh %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#define __raw_readl __raw_readl
+static inline u32 __raw_readl(const volatile void __iomem *addr)
+{
+	u32 val;
+
+	asm volatile("lw %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+
+#ifdef CONFIG_64BIT
+#define __raw_readq __raw_readq
+static inline u64 __raw_readq(const volatile void __iomem *addr)
+{
+	u64 val;
+
+	asm volatile("ld %0, 0(%1)" : "=r" (val) : "r" (addr));
+	return val;
+}
+#endif
+
+#include <asm-generic/io.h>
+
+#endif /* _ASMRISCV_IO_H_ */
diff --git a/lib/riscv/asm/page.h b/lib/riscv/asm/page.h
new file mode 100644
index 000000000000..7d7c9191605a
--- /dev/null
+++ b/lib/riscv/asm/page.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_PAGE_H_
+#define _ASMRISCV_PAGE_H_
+
+#include <asm-generic/page.h>
+
+#endif /* _ASMRISCV_PAGE_H_ */
diff --git a/lib/riscv/asm/setup.h b/lib/riscv/asm/setup.h
new file mode 100644
index 000000000000..385455f341cc
--- /dev/null
+++ b/lib/riscv/asm/setup.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_SETUP_H_
+#define _ASMRISCV_SETUP_H_
+
+void setup(const void *fdt, phys_addr_t freemem_start);
+
+#endif /* _ASMRISCV_SETUP_H_ */
diff --git a/lib/riscv/asm/spinlock.h b/lib/riscv/asm/spinlock.h
new file mode 100644
index 000000000000..6e2b3009abf3
--- /dev/null
+++ b/lib/riscv/asm/spinlock.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_SPINLOCK_H_
+#define _ASMRISCV_SPINLOCK_H_
+
+#include <asm-generic/spinlock.h>
+
+#endif /* _ASMRISCV_SPINLOCK_H_ */
diff --git a/lib/riscv/asm/stack.h b/lib/riscv/asm/stack.h
new file mode 100644
index 000000000000..d081d0716d7b
--- /dev/null
+++ b/lib/riscv/asm/stack.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_STACK_H_
+#define _ASMRISCV_STACK_H_
+
+#ifndef _STACK_H_
+#error Do not directly include <asm/stack.h>. Just use <stack.h>.
+#endif
+
+#endif
diff --git a/lib/riscv/io.c b/lib/riscv/io.c
new file mode 100644
index 000000000000..3cfc235d19a6
--- /dev/null
+++ b/lib/riscv/io.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Each architecture must implement puts() and exit() with the I/O
+ * devices exposed from QEMU, e.g. ns16550a.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/spinlock.h>
+
+/*
+ * Use this guess for the uart base in order to make an attempt at
+ * having earlier printf support. We'll overwrite it with the real
+ * base address that we read from the device tree later. This is
+ * the address we expect the virtual machine manager to put in
+ * its generated device tree.
+ */
+#define UART_EARLY_BASE ((u8 *)(unsigned long)CONFIG_UART_EARLY_BASE)
+static volatile u8 *uart0_base = UART_EARLY_BASE;
+static struct spinlock uart_lock;
+
+void puts(const char *s)
+{
+	spin_lock(&uart_lock);
+	while (*s)
+		writeb(*s++, uart0_base);
+	spin_unlock(&uart_lock);
+}
+
+/*
+ * Defining halt to take 'code' as an argument guarantees that it will
+ * be in a0 when we halt. That gives us a final chance to see the exit
+ * status while inspecting the halted unit test state.
+ */
+void halt(int code);
+
+void exit(int code)
+{
+	printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
+	halt(code);
+	__builtin_unreachable();
+}
diff --git a/lib/riscv/setup.c b/lib/riscv/setup.c
new file mode 100644
index 000000000000..8937525ccb7f
--- /dev/null
+++ b/lib/riscv/setup.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Initialize machine setup information and I/O.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+#include <asm/setup.h>
+
+void setup(const void *fdt, phys_addr_t freemem_start)
+{
+}
diff --git a/riscv/Makefile b/riscv/Makefile
new file mode 100644
index 000000000000..f2e89f0e4c38
--- /dev/null
+++ b/riscv/Makefile
@@ -0,0 +1,83 @@
+#
+# riscv makefile
+#
+# Authors: Andrew Jones <ajones@ventanamicro.com>
+#
+
+ifeq ($(CONFIG_EFI),y)
+exe = efi
+else
+exe = flat
+endif
+
+tests =
+tests += $(TEST_DIR)/selftest.$(exe)
+#tests += $(TEST_DIR)/sieve.$(exe)
+
+all: $(tests)
+
+$(TEST_DIR)/sieve.elf: AUXFLAGS = 0x1
+
+cstart.o = $(TEST_DIR)/cstart.o
+
+cflatobjs += lib/riscv/io.o
+cflatobjs += lib/riscv/setup.o
+
+########################################
+
+OBJDIRS += lib/riscv
+FLATLIBS = $(libcflat) $(LIBFDT_archive)
+
+AUXFLAGS ?= 0x0
+
+# stack.o relies on frame pointers.
+KEEP_FRAME_POINTER := y
+
+# We want to keep intermediate files
+.PRECIOUS: %.elf %.o
+
+define arch_elf_check =
+	$(if $(shell ! $(READELF) -rW $(1) >&/dev/null && echo "nok"),
+		$(error $(shell $(READELF) -rW $(1) 2>&1)))
+	$(if $(shell $(READELF) -rW $(1) | grep R_ | grep -v R_RISCV_RELATIVE),
+		$(error $(1) has unsupported reloc types))
+endef
+
+ifeq ($(ARCH),riscv64)
+CFLAGS += -DCONFIG_64BIT
+endif
+CFLAGS += -DCONFIG_RELOC
+CFLAGS += -mcmodel=medany
+CFLAGS += -mstrict-align
+CFLAGS += -std=gnu99
+CFLAGS += -ffreestanding
+CFLAGS += -O2
+CFLAGS += -I $(SRCDIR)/lib -I $(SRCDIR)/lib/libfdt
+
+asm-offsets = lib/riscv/asm-offsets.h
+include $(SRCDIR)/scripts/asm-offsets.mak
+
+ifeq ($(CONFIG_EFI),y)
+	# TODO
+else
+%.elf: LDFLAGS += -pie -n -z notext
+%.elf: %.o $(FLATLIBS) $(SRCDIR)/riscv/flat.lds $(cstart.o)
+	$(CC) $(CFLAGS) -c -o $(@:.elf=.aux.o) $(SRCDIR)/lib/auxinfo.c \
+		-DPROGNAME=\"$(notdir $(@:.elf=.flat))\" -DAUXFLAGS=$(AUXFLAGS)
+	$(LD) $(LDFLAGS) -o $@ -T $(SRCDIR)/riscv/flat.lds \
+		$(filter %.o, $^) $(FLATLIBS) $(@:.elf=.aux.o)
+	$(RM) $(@:.elf=.aux.o)
+	@chmod a-x $@
+
+%.flat: %.elf
+	$(call arch_elf_check, $^)
+	$(OBJCOPY) -O binary $^ $@
+	@chmod a-x $@
+endif
+
+generated-files = $(asm-offsets)
+$(tests:.$(exe)=.o) $(cstart.o) $(cflatobjs): $(generated-files)
+
+arch_clean: asm_offsets_clean
+	$(RM) $(TEST_DIR)/*.{o,flat,elf,so,efi,debug} \
+	      $(TEST_DIR)/.*.d $(TEST_DIR)/efi/.*.d lib/riscv/.*.d
diff --git a/riscv/cstart.S b/riscv/cstart.S
new file mode 100644
index 000000000000..a28d75e8021e
--- /dev/null
+++ b/riscv/cstart.S
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Boot entry point and assembler functions for riscv.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <asm/csr.h>
+
+.macro zero_range, tmp1, tmp2
+9998:	beq	\tmp1, \tmp2, 9997f
+	sd	zero, 0(\tmp1)
+	addi	\tmp1, \tmp1, 8
+	j	9998b
+9997:
+.endm
+
+	.section .init
+
+/*
+ * The hartid of the current core is in a0
+ * The address of the devicetree is in a1
+ *
+ * See Linux kernel doc Documentation/riscv/boot.rst
+ */
+.global start
+start:
+	/*
+	 * Stash the hartid in scratch and shift the dtb
+	 * address into a0
+	 */
+	csrw	CSR_SSCRATCH, a0
+	mv	a0, a1
+
+	/*
+	 * Update all R_RISCV_RELATIVE relocations using the table
+	 * of Elf64_Rela entries between reloc_start/end. The build
+	 * will not emit other relocation types.
+	 *
+	 * struct Elf64_Rela {
+	 * 	uint64_t r_offset;
+	 * 	uint64_t r_info;
+	 * 	int64_t  r_addend;
+	 * }
+	 */
+	la	a1, reloc_start
+	la	a2, reloc_end
+	la	a3, start			// base
+1:
+	bge	a1, a2, 1f
+	ld	a4, 0(a1)			// r_offset
+	ld	a5, 16(a1)			// r_addend
+	add	a4, a3, a4			// addr = base + r_offset
+	add	a5, a3, a5			// val = base + r_addend
+	sd	a5, 0(a4)			// *addr = val
+	addi	a1, a1, 24
+	j	1b
+
+1:
+	/* zero BSS */
+	la	a1, bss
+	la	a2, ebss
+	zero_range a1, a2
+
+	/* zero and set up stack */
+	la	sp, stacktop
+	li	a1, -8192
+	add	a1, sp, a1
+	zero_range a1, sp
+
+	/* set up exception handling */
+	//TODO
+
+	/* complete setup */
+	la	a1, stacktop			// a1 is the base of free memory
+	call	setup				// a0 is the addr of the dtb
+
+	/* run the test */
+	la	a0, __argc
+	ld	a0, 0(a0)
+	la	a1, __argv
+	la	a2, __environ
+	call	main
+	call	exit
+	j	halt
+
+	.text
+
+.balign 4
+.global halt
+halt:
+1:	wfi
+	j	1b
diff --git a/riscv/flat.lds b/riscv/flat.lds
new file mode 100644
index 000000000000..d4853f82ba1c
--- /dev/null
+++ b/riscv/flat.lds
@@ -0,0 +1,75 @@
+/*
+ * init::start will pass stacktop to setup() as the base of free memory.
+ * setup() will then move the FDT and initrd to that base before calling
+ * mem_init(). With those movements and this linker script, we'll end up
+ * having the following memory layout:
+ *
+ *    +----------------------+   <-- top of physical memory
+ *    |                      |
+ *    ~                      ~
+ *    |                      |
+ *    +----------------------+   <-- top of initrd
+ *    |                      |
+ *    +----------------------+   <-- top of FDT
+ *    |                      |
+ *    +----------------------+   <-- top of cpu0's stack
+ *    |                      |
+ *    +----------------------+   <-- top of text/data/bss sections
+ *    |                      |
+ *    |                      |
+ *    +----------------------+   <-- load address
+ *    |                      |
+ *    +----------------------+   <-- physical address 0x0
+ */
+
+PHDRS
+{
+    text PT_LOAD FLAGS(5);
+    data PT_LOAD FLAGS(6);
+}
+
+SECTIONS
+{
+    PROVIDE(_text = .);
+    .text : { *(.init) *(.text) *(.text.*) } :text
+    . = ALIGN(4K);
+    PROVIDE(_etext = .);
+
+    PROVIDE(reloc_start = .);
+    .rela.dyn : { *(.rela.dyn) }
+    PROVIDE(reloc_end = .);
+    .dynsym   : { *(.dynsym) }
+    .dynstr   : { *(.dynstr) }
+    .hash     : { *(.hash) }
+    .gnu.hash : { *(.gnu.hash) }
+    .got      : { *(.got) *(.got.plt) }
+    .eh_frame : { *(.eh_frame) }
+
+    .rodata   : { *(.rodata*) } :data
+    .data     : { *(.data) } :data
+    . = ALIGN(16);
+    PROVIDE(bss = .);
+    .bss      : { *(.bss) }
+    . = ALIGN(16);
+    PROVIDE(ebss = .);
+    . = ALIGN(4K);
+    PROVIDE(edata = .);
+
+    /*
+     * stack depth is 8K and sp must be 16 byte aligned
+     * sp must always be strictly less than the true stacktop
+     */
+    . += 12K;
+    . = ALIGN(4K);
+    PROVIDE(stackptr = . - 16);
+    PROVIDE(stacktop = .);
+
+    /DISCARD/ : {
+        *(.note*)
+        *(.interp)
+        *(.comment)
+        *(.dynamic)
+    }
+}
+
+ENTRY(start)
diff --git a/riscv/selftest.c b/riscv/selftest.c
new file mode 100644
index 000000000000..88afa732649e
--- /dev/null
+++ b/riscv/selftest.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test the framework itself. These tests confirm that setup works.
+ *
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+
+int main(void)
+{
+	puts("Hello, world\n");
+	return 0;
+}
-- 
2.43.0


  parent reply	other threads:[~2024-01-24  7:18 UTC|newest]

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

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=20240124071815.6898-28-andrew.jones@linux.dev \
    --to=andrew.jones@linux.dev \
    --cc=kvm-riscv@lists.infradead.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.