[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 18/18] target-riscv: Add generic test board, activat
From: |
Sagar Karandikar |
Subject: |
[Qemu-devel] [PATCH 18/18] target-riscv: Add generic test board, activate target |
Date: |
Mon, 26 Sep 2016 03:56:48 -0700 |
Signed-off-by: Sagar Karandikar <address@hidden>
---
configure | 6 +
default-configs/riscv32-softmmu.mak | 38 ++++++
default-configs/riscv64-softmmu.mak | 38 ++++++
hw/riscv/Makefile.objs | 2 +
hw/riscv/riscv_board.c | 264 ++++++++++++++++++++++++++++++++++++
hw/riscv/riscv_int.c | 67 +++++++++
6 files changed, 415 insertions(+)
create mode 100644 default-configs/riscv32-softmmu.mak
create mode 100644 default-configs/riscv64-softmmu.mak
create mode 100644 hw/riscv/riscv_board.c
create mode 100644 hw/riscv/riscv_int.c
diff --git a/configure b/configure
index 8fa62ad..e3381b8 100755
--- a/configure
+++ b/configure
@@ -5667,6 +5667,12 @@ case "$target_name" in
TARGET_BASE_ARCH=mips
echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak
;;
+ riscv32)
+ TARGET_BASE_ARCH=riscv
+ ;;
+ riscv64)
+ TARGET_BASE_ARCH=riscv
+ ;;
moxie)
;;
or32)
diff --git a/default-configs/riscv32-softmmu.mak
b/default-configs/riscv32-softmmu.mak
new file mode 100644
index 0000000..c8b7fa1
--- /dev/null
+++ b/default-configs/riscv32-softmmu.mak
@@ -0,0 +1,38 @@
+# Default configuration for riscv-softmmu
+
+#include pci.mak
+#include sound.mak
+#include usb.mak
+#CONFIG_ESP=y
+#CONFIG_VGA=y
+#CONFIG_VGA_PCI=y
+#CONFIG_VGA_ISA=y
+#CONFIG_VGA_ISA_MM=y
+#CONFIG_VGA_CIRRUS=y
+#CONFIG_VMWARE_VGA=y
+CONFIG_SERIAL=y
+#CONFIG_PARALLEL=y
+#CONFIG_I8254=y
+#CONFIG_PCSPK=y
+#CONFIG_PCKBD=y
+#CONFIG_FDC=y
+#CONFIG_ACPI=y
+#CONFIG_APM=y
+#CONFIG_I8257=y
+#CONFIG_PIIX4=y
+#CONFIG_IDE_ISA=y
+#CONFIG_IDE_PIIX=y
+#CONFIG_NE2000_ISA=y
+#CONFIG_RC4030=y
+#CONFIG_DP8393X=y
+#CONFIG_DS1225Y=y
+#CONFIG_MIPSNET=y
+#CONFIG_PFLASH_CFI01=y
+#CONFIG_G364FB=y
+CONFIG_I8259=y
+#CONFIG_JAZZ_LED=y
+#CONFIG_MC146818RTC=y
+#CONFIG_VT82C686=y
+#CONFIG_ISA_TESTDEV=y
+#CONFIG_EMPTY_SLOT=y
+CONFIG_VIRTIO=y
diff --git a/default-configs/riscv64-softmmu.mak
b/default-configs/riscv64-softmmu.mak
new file mode 100644
index 0000000..c8b7fa1
--- /dev/null
+++ b/default-configs/riscv64-softmmu.mak
@@ -0,0 +1,38 @@
+# Default configuration for riscv-softmmu
+
+#include pci.mak
+#include sound.mak
+#include usb.mak
+#CONFIG_ESP=y
+#CONFIG_VGA=y
+#CONFIG_VGA_PCI=y
+#CONFIG_VGA_ISA=y
+#CONFIG_VGA_ISA_MM=y
+#CONFIG_VGA_CIRRUS=y
+#CONFIG_VMWARE_VGA=y
+CONFIG_SERIAL=y
+#CONFIG_PARALLEL=y
+#CONFIG_I8254=y
+#CONFIG_PCSPK=y
+#CONFIG_PCKBD=y
+#CONFIG_FDC=y
+#CONFIG_ACPI=y
+#CONFIG_APM=y
+#CONFIG_I8257=y
+#CONFIG_PIIX4=y
+#CONFIG_IDE_ISA=y
+#CONFIG_IDE_PIIX=y
+#CONFIG_NE2000_ISA=y
+#CONFIG_RC4030=y
+#CONFIG_DP8393X=y
+#CONFIG_DS1225Y=y
+#CONFIG_MIPSNET=y
+#CONFIG_PFLASH_CFI01=y
+#CONFIG_G364FB=y
+CONFIG_I8259=y
+#CONFIG_JAZZ_LED=y
+#CONFIG_MC146818RTC=y
+#CONFIG_VT82C686=y
+#CONFIG_ISA_TESTDEV=y
+#CONFIG_EMPTY_SLOT=y
+CONFIG_VIRTIO=y
diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index d830e5d..de6017e 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -1,3 +1,5 @@
obj-y += riscv_rtc.o
+obj-y += riscv_int.o
obj-y += htif/elf_symb.o
obj-y += htif/htif.o
+obj-y += riscv_board.o
diff --git a/hw/riscv/riscv_board.c b/hw/riscv/riscv_board.c
new file mode 100644
index 0000000..1c136e2
--- /dev/null
+++ b/hw/riscv/riscv_board.c
@@ -0,0 +1,264 @@
+/*
+ * QEMU RISC-V Generic Board Support
+ *
+ * Author: Sagar Karandikar, address@hidden
+ *
+ * This provides a RISC-V Board with the following devices:
+ *
+ * 0) HTIF Test Pass/Fail Reporting (no syscall proxy)
+ * 1) HTIF Console
+ *
+ * These are created by htif_mm_init below.
+ *
+ * This board currently uses a hardcoded devicetree that indicates one hart.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/char/serial.h"
+#include "hw/riscv/htif/htif.h"
+#include "hw/riscv/riscv_rtc.h"
+#include "hw/boards.h"
+#include "hw/riscv/cpudevs.h"
+#include "sysemu/char.h"
+#include "sysemu/arch_init.h"
+#include "qemu/log.h"
+#include "hw/loader.h"
+#include "elf.h"
+#include "exec/address-spaces.h"
+#include "hw/sysbus.h" /* SysBusDevice */
+#include "qemu/host-utils.h"
+#include "sysemu/qtest.h"
+#include "qemu/error-report.h"
+#include "hw/empty_slot.h"
+#include "qemu/error-report.h"
+#include "sysemu/block-backend.h"
+
+#define TYPE_RISCV_BOARD "riscv"
+#define RISCV_BOARD(obj) OBJECT_CHECK(BoardState, (obj), TYPE_RISCV_BOARD)
+
+typedef struct {
+ SysBusDevice parent_obj;
+} BoardState;
+
+static struct _loaderparams {
+ int ram_size;
+ const char *kernel_filename;
+ const char *kernel_cmdline;
+ const char *initrd_filename;
+} loaderparams;
+
+uint64_t identity_translate(void *opaque, uint64_t addr)
+{
+ return addr;
+}
+
+static int64_t load_kernel(void)
+{
+ int64_t kernel_entry, kernel_high;
+ int big_endian;
+ big_endian = 0;
+
+ if (load_elf(loaderparams.kernel_filename, identity_translate, NULL,
+ (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
+ big_endian, ELF_MACHINE, 1, 0) < 0) {
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ loaderparams.kernel_filename);
+ exit(1);
+ }
+ return kernel_entry;
+}
+
+static void main_cpu_reset(void *opaque)
+{
+ RISCVCPU *cpu = opaque;
+ cpu_reset(CPU(cpu));
+}
+
+static void riscv_board_init(MachineState *args)
+{
+ ram_addr_t ram_size = args->ram_size;
+ const char *cpu_model = args->cpu_model;
+ const char *kernel_filename = args->kernel_filename;
+ const char *kernel_cmdline = args->kernel_cmdline;
+ const char *initrd_filename = args->initrd_filename;
+ MemoryRegion *system_memory = get_system_memory();
+ MemoryRegion *main_mem = g_new(MemoryRegion, 1);
+ RISCVCPU *cpu;
+ CPURISCVState *env;
+ int i;
+ DeviceState *dev = qdev_create(NULL, TYPE_RISCV_BOARD);
+ object_property_set_bool(OBJECT(dev), true, "realized", NULL);
+
+ /* Make sure the first 3 serial ports are associated with a device. */
+ for (i = 0; i < 3; i++) {
+ if (!serial_hds[i]) {
+ char label[32];
+ snprintf(label, sizeof(label), "serial%d", i);
+ serial_hds[i] = qemu_chr_new(label, "null", NULL);
+ }
+ }
+
+ /* init CPUs */
+ if (cpu_model == NULL) {
+ cpu_model = "riscv";
+ }
+
+ for (i = 0; i < smp_cpus; i++) {
+ cpu = cpu_riscv_init(cpu_model);
+ if (cpu == NULL) {
+ fprintf(stderr, "Unable to find CPU definition\n");
+ exit(1);
+ }
+ env = &cpu->env;
+
+ /* Init internal devices */
+ cpu_riscv_irq_init_cpu(env);
+ cpu_riscv_clock_init(env);
+ qemu_register_reset(main_cpu_reset, cpu);
+ }
+ cpu = RISCV_CPU(first_cpu);
+ env = &cpu->env;
+
+ /* register system main memory (actual RAM) */
+ memory_region_init_ram(main_mem, NULL, "riscv_board.ram", 2147483648L +
+ ram_size, &error_fatal);
+ /* for phys mem size check in page table walk */
+ env->memsize = ram_size;
+ vmstate_register_ram_global(main_mem);
+ memory_region_add_subregion(system_memory, 0x0, main_mem);
+
+ if (kernel_filename) {
+ loaderparams.ram_size = ram_size;
+ loaderparams.kernel_filename = kernel_filename;
+ loaderparams.kernel_cmdline = kernel_cmdline;
+ loaderparams.initrd_filename = initrd_filename;
+ load_kernel();
+ }
+
+ uint32_t reset_vec[8] = {
+ 0x297 + 0x80000000 - 0x1000, /* reset vector */
+ 0x00028067, /* jump to DRAM_BASE */
+ 0x00000000, /* reserved */
+ 0x0, /* config string pointer */
+ 0, 0, 0, 0 /* trap vector */
+ };
+ reset_vec[3] = 0x1000 + sizeof(reset_vec); /* config string pointer */
+
+ /* part one of config string - before memory size specified */
+ const char *config_string1 = "platform {\n"
+ " vendor ucb;\n"
+ " arch spike;\n"
+ "};\n"
+ "rtc {\n"
+ " addr 0x" "40000000" ";\n"
+ "};\n"
+ "ram {\n"
+ " 0 {\n"
+ " addr 0x" "80000000" ";\n"
+ " size 0x";
+
+
+ /* part two of config string - after memory size specified */
+ const char *config_string2 = ";\n"
+ " };\n"
+ "};\n"
+ "core {\n"
+ " 0" " {\n"
+ " " "0 {\n"
+ " isa " "rv64imafd" ";\n"
+ " timecmp 0x" "40000008" ";\n"
+ " ipi 0x" "40001000" ";\n"
+ " };\n"
+ " };\n"
+ "};\n";
+
+ /* build config string with supplied memory size */
+ uint64_t rsz = ram_size;
+ char *ramsize_as_hex_str = malloc(17);
+ sprintf(ramsize_as_hex_str, "%016lx", rsz);
+ char *config_string = malloc(strlen(config_string1) +
+ strlen(ramsize_as_hex_str) +
+ strlen(config_string2) + 1);
+ config_string[0] = 0;
+ strcat(config_string, config_string1);
+ strcat(config_string, ramsize_as_hex_str);
+ strcat(config_string, config_string2);
+
+ /* copy in the reset vec and configstring */
+ int q;
+ for (q = 0; q < sizeof(reset_vec) / sizeof(reset_vec[0]); q++) {
+ stl_p(memory_region_get_ram_ptr(main_mem) + 0x1000 + q * 4,
+ reset_vec[q]);
+ }
+
+ int confstrlen = strlen(config_string);
+ for (q = 0; q < confstrlen; q++) {
+ stb_p(memory_region_get_ram_ptr(main_mem) + reset_vec[3] + q,
+ config_string[q]);
+ }
+
+ /* add memory mapped htif registers at location specified in the symbol
+ table of the elf being loaded (thus kernel_filename is passed to the
+ init rather than an address) */
+ htif_mm_init(system_memory, kernel_filename, env->irq[4], main_mem,
+ env, serial_hds[0]);
+
+ /* timer device at 0x40000000, as specified in the config string above */
+ timer_mm_init(system_memory, 0x40000000, env);
+
+ /* TODO: VIRTIO */
+}
+
+static int riscv_board_sysbus_device_init(SysBusDevice *sysbusdev)
+{
+ return 0;
+}
+
+static void riscv_board_class_init(ObjectClass *klass, void *data)
+{
+ SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ k->init = riscv_board_sysbus_device_init;
+}
+
+static const TypeInfo riscv_board_device = {
+ .name = TYPE_RISCV_BOARD,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BoardState),
+ .class_init = riscv_board_class_init,
+};
+
+static void riscv_board_machine_init(MachineClass *mc)
+{
+ mc->desc = "RISC-V Generic Board";
+ mc->init = riscv_board_init;
+ mc->max_cpus = 1;
+ mc->is_default = 1;
+}
+
+DEFINE_MACHINE("riscv", riscv_board_machine_init)
+
+static void riscv_board_register_types(void)
+{
+ type_register_static(&riscv_board_device);
+}
+
+type_init(riscv_board_register_types);
diff --git a/hw/riscv/riscv_int.c b/hw/riscv/riscv_int.c
new file mode 100644
index 0000000..9eaf221
--- /dev/null
+++ b/hw/riscv/riscv_int.c
@@ -0,0 +1,67 @@
+/*
+ * QEMU RISC-V - QEMU IRQ Support
+ *
+ * Author: Sagar Karandikar, address@hidden
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/riscv/cpudevs.h"
+#include "cpu.h"
+
+static void cpu_riscv_irq_request(void *opaque, int irq, int level)
+{
+ /* These are not the same irq numbers visible to the emulated processor. */
+ RISCVCPU *cpu = opaque;
+ CPURISCVState *env = &cpu->env;
+ CPUState *cs = CPU(cpu);
+
+ /* current irqs:
+ 4: Host Interrupt. mfromhost should have a nonzero value
+ 3: Machine Timer. MIP_MTIP should have already been set
+ 2, 1, 0: Interrupts triggered by the CPU. At least one of
+ MIP_STIP, MIP_SSIP, MIP_MSIP should already be set */
+ if (unlikely(!(irq < 5 && irq >= 0))) {
+ printf("IRQNO: %d\n", irq);
+ fprintf(stderr, "Unused IRQ was raised.\n");
+ exit(1);
+ }
+
+ if (level) {
+ cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+ } else {
+ if (!env->csr[CSR_MIP] && !env->mfromhost) {
+ /* no interrupts pending, no host interrupt for HTIF, reset */
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+ }
+ }
+}
+
+void cpu_riscv_irq_init_cpu(CPURISCVState *env)
+{
+ qemu_irq *qi;
+ int i;
+
+ qi = qemu_allocate_irqs(cpu_riscv_irq_request, riscv_env_get_cpu(env), 8);
+ for (i = 0; i < 8; i++) {
+ env->irq[i] = qi[i];
+ }
+}
--
2.9.3
- [Qemu-devel] [PATCH 12/18] target-riscv: Add system instructions, (continued)
- [Qemu-devel] [PATCH 13/18] target-riscv: Add CSR read/write helpers, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 09/18] target-riscv: Add FMADD, FMSUB, FNMADD, FNMSUB Instructions,, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 05/18] target-riscv: Add Arithmetic instructions, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 18/18] target-riscv: Add generic test board, activate target,
Sagar Karandikar <=
- [Qemu-devel] [PATCH 11/18] target-riscv: Add Double Precision Floating-Point Instructions, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 10/18] target-riscv: Add Single Precision Floating-Point Instructions, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 04/18] target-riscv: Add framework for instruction decode, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 02/18] target-riscv: Add RISC-V Target stubs inside target-riscv/, Sagar Karandikar, 2016/09/26
- [Qemu-devel] [PATCH 17/18] target-riscv: Add support for Host-Target Interface (HTIF) Devices, Sagar Karandikar, 2016/09/26