aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-10-22 12:09:17 -0700
committerRichard Henderson <richard.henderson@linaro.org>2021-10-22 12:09:17 -0700
commit660efed8b37aedec9b5fcc555da1f88f7d12c98a (patch)
tree287704d8285afe25df49dcd082ad714d06fce9a9 /hw
parent2c64ff92ecef4db0169f7238a26f1124268345c8 (diff)
parent11ec06f9eaedc801ded34c79861367b76ab2b731 (diff)
downloadqemu-660efed8b37aedec9b5fcc555da1f88f7d12c98a.zip
qemu-660efed8b37aedec9b5fcc555da1f88f7d12c98a.tar.gz
qemu-660efed8b37aedec9b5fcc555da1f88f7d12c98a.tar.bz2
Merge remote-tracking branch 'remotes/alistair23/tags/pull-riscv-to-apply-20211022-2' into staging
Fourth RISC-V PR for QEMU 6.2 - Vector extension bug fixes - Bit manipulation extension bug fix - Support vhost-user and numa mem options on all boards - Rationalise XLEN and operand lengths - Bump the OpenTitan FPGA support - Remove the Ibex PLIC - General code cleanup # gpg: Signature made Fri 22 Oct 2021 06:36:10 AM PDT # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full] * remotes/alistair23/tags/pull-riscv-to-apply-20211022-2: (33 commits) hw/riscv: spike: Use MachineState::ram and MachineClass::default_ram_id hw/riscv: sifive_u: Use MachineState::ram and MachineClass::default_ram_id hw/riscv: sifive_e: Use MachineState::ram and MachineClass::default_ram_id hw/riscv: shakti_c: Use MachineState::ram and MachineClass::default_ram_id hw/riscv: opentitan: Use MachineState::ram and MachineClass::default_ram_id hw/riscv: microchip_pfsoc: Use MachineState::ram and MachineClass::default_ram_id hw/intc: sifive_plic: Cleanup the irq_request function hw/intc: sifive_plic: Cleanup the realize function hw/intc: sifive_plic: Move the properties hw/intc: Remove the Ibex PLIC hw/riscv: opentitan: Update to the latest build target/riscv: Compute mstatus.sd on demand target/riscv: Use riscv_csrrw_debug for cpu_dump target/riscv: Use gen_shift*_per_ol for RVB, RVI target/riscv: Use gen_unary_per_ol for RVB target/riscv: Adjust trans_rev8_32 for riscv64 target/riscv: Use gen_arith_per_ol for RVM target/riscv: Replace DisasContext.w with DisasContext.ol target/riscv: Replace is_32bit with get_xl/get_xlen target/riscv: Properly check SEW in amo_op ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/intc/ibex_plic.c307
-rw-r--r--hw/intc/meson.build1
-rw-r--r--hw/intc/sifive_plic.c85
-rw-r--r--hw/riscv/boot.c2
-rw-r--r--hw/riscv/microchip_pfsoc.c36
-rw-r--r--hw/riscv/opentitan.c38
-rw-r--r--hw/riscv/shakti_c.c6
-rw-r--r--hw/riscv/sifive_e.c16
-rw-r--r--hw/riscv/sifive_u.c6
-rw-r--r--hw/riscv/spike.c6
-rw-r--r--hw/riscv/virt.c6
11 files changed, 113 insertions, 396 deletions
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
deleted file mode 100644
index ff43035..0000000
--- a/hw/intc/ibex_plic.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * QEMU RISC-V lowRISC Ibex PLIC
- *
- * Copyright (c) 2020 Western Digital
- *
- * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2 or later, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "hw/qdev-properties.h"
-#include "hw/core/cpu.h"
-#include "hw/boards.h"
-#include "hw/pci/msi.h"
-#include "target/riscv/cpu_bits.h"
-#include "target/riscv/cpu.h"
-#include "hw/intc/ibex_plic.h"
-#include "hw/irq.h"
-
-static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
-{
- uint32_t end = base + (num * 0x04);
-
- if (addr >= base && addr < end) {
- return true;
- }
-
- return false;
-}
-
-static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
-{
- int pending_num = irq / 32;
-
- if (!level) {
- /*
- * If the level is low make sure we clear the hidden_pending.
- */
- s->hidden_pending[pending_num] &= ~(1 << (irq % 32));
- }
-
- if (s->claimed[pending_num] & 1 << (irq % 32)) {
- /*
- * The interrupt has been claimed, but not completed.
- * The pending bit can't be set.
- * Save the pending level for after the interrupt is completed.
- */
- s->hidden_pending[pending_num] |= level << (irq % 32);
- } else {
- s->pending[pending_num] |= level << (irq % 32);
- }
-}
-
-static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
-{
- int i;
- uint32_t max_irq = 0;
- uint32_t max_prio = s->threshold;
-
- for (i = 0; i < s->pending_num; i++) {
- uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
-
- if (!(s->pending[i] & s->enable[i])) {
- /* No pending and enabled IRQ */
- continue;
- }
-
- if (s->priority[irq_num] > max_prio) {
- max_irq = irq_num;
- max_prio = s->priority[irq_num];
- }
- }
-
- if (max_irq) {
- s->claim = max_irq;
- return true;
- }
-
- return false;
-}
-
-static void ibex_plic_update(IbexPlicState *s)
-{
- int i;
-
- for (i = 0; i < s->num_cpus; i++) {
- qemu_set_irq(s->external_irqs[i], ibex_plic_irqs_pending(s, 0));
- }
-}
-
-static void ibex_plic_reset(DeviceState *dev)
-{
- IbexPlicState *s = IBEX_PLIC(dev);
-
- s->threshold = 0x00000000;
- s->claim = 0x00000000;
-}
-
-static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
- unsigned int size)
-{
- IbexPlicState *s = opaque;
- int offset;
- uint32_t ret = 0;
-
- if (addr_between(addr, s->pending_base, s->pending_num)) {
- offset = (addr - s->pending_base) / 4;
- ret = s->pending[offset];
- } else if (addr_between(addr, s->source_base, s->source_num)) {
- qemu_log_mask(LOG_UNIMP,
- "%s: Interrupt source mode not supported\n", __func__);
- } else if (addr_between(addr, s->priority_base, s->priority_num)) {
- offset = (addr - s->priority_base) / 4;
- ret = s->priority[offset];
- } else if (addr_between(addr, s->enable_base, s->enable_num)) {
- offset = (addr - s->enable_base) / 4;
- ret = s->enable[offset];
- } else if (addr_between(addr, s->threshold_base, 1)) {
- ret = s->threshold;
- } else if (addr_between(addr, s->claim_base, 1)) {
- int pending_num = s->claim / 32;
- s->pending[pending_num] &= ~(1 << (s->claim % 32));
-
- /* Set the interrupt as claimed, but not completed */
- s->claimed[pending_num] |= 1 << (s->claim % 32);
-
- /* Return the current claimed interrupt */
- ret = s->claim;
-
- /* Clear the claimed interrupt */
- s->claim = 0x00000000;
-
- /* Update the interrupt status after the claim */
- ibex_plic_update(s);
- }
-
- return ret;
-}
-
-static void ibex_plic_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned int size)
-{
- IbexPlicState *s = opaque;
-
- if (addr_between(addr, s->pending_base, s->pending_num)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Pending registers are read only\n", __func__);
- } else if (addr_between(addr, s->source_base, s->source_num)) {
- qemu_log_mask(LOG_UNIMP,
- "%s: Interrupt source mode not supported\n", __func__);
- } else if (addr_between(addr, s->priority_base, s->priority_num)) {
- uint32_t irq = ((addr - s->priority_base) >> 2) + 1;
- s->priority[irq] = value & 7;
- ibex_plic_update(s);
- } else if (addr_between(addr, s->enable_base, s->enable_num)) {
- uint32_t enable_reg = (addr - s->enable_base) / 4;
-
- s->enable[enable_reg] = value;
- } else if (addr_between(addr, s->threshold_base, 1)) {
- s->threshold = value & 3;
- } else if (addr_between(addr, s->claim_base, 1)) {
- if (s->claim == value) {
- /* Interrupt was completed */
- s->claim = 0;
- }
- if (s->claimed[value / 32] & 1 << (value % 32)) {
- int pending_num = value / 32;
-
- /* This value was already claimed, clear it. */
- s->claimed[pending_num] &= ~(1 << (value % 32));
-
- if (s->hidden_pending[pending_num] & (1 << (value % 32))) {
- /*
- * If the bit in hidden_pending is set then that means we
- * received an interrupt between claiming and completing
- * the interrupt that hasn't since been de-asserted.
- * On hardware this would trigger an interrupt, so let's
- * trigger one here as well.
- */
- s->pending[pending_num] |= 1 << (value % 32);
- }
- }
- }
-
- ibex_plic_update(s);
-}
-
-static const MemoryRegionOps ibex_plic_ops = {
- .read = ibex_plic_read,
- .write = ibex_plic_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4
- }
-};
-
-static void ibex_plic_irq_request(void *opaque, int irq, int level)
-{
- IbexPlicState *s = opaque;
-
- ibex_plic_irqs_set_pending(s, irq, level > 0);
- ibex_plic_update(s);
-}
-
-static Property ibex_plic_properties[] = {
- DEFINE_PROP_UINT32("num-cpus", IbexPlicState, num_cpus, 1),
- DEFINE_PROP_UINT32("num-sources", IbexPlicState, num_sources, 176),
-
- DEFINE_PROP_UINT32("pending-base", IbexPlicState, pending_base, 0),
- DEFINE_PROP_UINT32("pending-num", IbexPlicState, pending_num, 6),
-
- DEFINE_PROP_UINT32("source-base", IbexPlicState, source_base, 0x18),
- DEFINE_PROP_UINT32("source-num", IbexPlicState, source_num, 6),
-
- DEFINE_PROP_UINT32("priority-base", IbexPlicState, priority_base, 0x30),
- DEFINE_PROP_UINT32("priority-num", IbexPlicState, priority_num, 177),
-
- DEFINE_PROP_UINT32("enable-base", IbexPlicState, enable_base, 0x300),
- DEFINE_PROP_UINT32("enable-num", IbexPlicState, enable_num, 6),
-
- DEFINE_PROP_UINT32("threshold-base", IbexPlicState, threshold_base, 0x318),
-
- DEFINE_PROP_UINT32("claim-base", IbexPlicState, claim_base, 0x31c),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void ibex_plic_init(Object *obj)
-{
- IbexPlicState *s = IBEX_PLIC(obj);
-
- memory_region_init_io(&s->mmio, obj, &ibex_plic_ops, s,
- TYPE_IBEX_PLIC, 0x400);
- sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
-}
-
-static void ibex_plic_realize(DeviceState *dev, Error **errp)
-{
- IbexPlicState *s = IBEX_PLIC(dev);
- int i;
-
- s->pending = g_new0(uint32_t, s->pending_num);
- s->hidden_pending = g_new0(uint32_t, s->pending_num);
- s->claimed = g_new0(uint32_t, s->pending_num);
- s->source = g_new0(uint32_t, s->source_num);
- s->priority = g_new0(uint32_t, s->priority_num);
- s->enable = g_new0(uint32_t, s->enable_num);
-
- qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
-
- s->external_irqs = g_malloc(sizeof(qemu_irq) * s->num_cpus);
- qdev_init_gpio_out(dev, s->external_irqs, s->num_cpus);
-
- /*
- * We can't allow the supervisor to control SEIP as this would allow the
- * supervisor to clear a pending external interrupt which will result in
- * a lost interrupt in the case a PLIC is attached. The SEIP bit must be
- * hardware controlled when a PLIC is attached.
- */
- MachineState *ms = MACHINE(qdev_get_machine());
- unsigned int smp_cpus = ms->smp.cpus;
- for (i = 0; i < smp_cpus; i++) {
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
- if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
- error_report("SEIP already claimed");
- exit(1);
- }
- }
-
- msi_nonbroken = true;
-}
-
-static void ibex_plic_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->reset = ibex_plic_reset;
- device_class_set_props(dc, ibex_plic_properties);
- dc->realize = ibex_plic_realize;
-}
-
-static const TypeInfo ibex_plic_info = {
- .name = TYPE_IBEX_PLIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(IbexPlicState),
- .instance_init = ibex_plic_init,
- .class_init = ibex_plic_class_init,
-};
-
-static void ibex_plic_register_types(void)
-{
- type_register_static(&ibex_plic_info);
-}
-
-type_init(ibex_plic_register_types)
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index a1d00aa..c89d2ca 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -32,7 +32,6 @@ specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
specific_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_vic.c'))
specific_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_gic.c', 'exynos4210_combiner.c'))
specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c'))
-specific_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_plic.c'))
specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: files('loongson_liointc.c'))
specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 9ba36dc..877e768 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -355,21 +355,6 @@ static const MemoryRegionOps sifive_plic_ops = {
}
};
-static Property sifive_plic_properties[] = {
- DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
- DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
- DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
- DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
- DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
- DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
- DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
- DEFINE_PROP_UINT32("enable-stride", SiFivePLICState, enable_stride, 0),
- DEFINE_PROP_UINT32("context-base", SiFivePLICState, context_base, 0),
- DEFINE_PROP_UINT32("context-stride", SiFivePLICState, context_stride, 0),
- DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0),
- DEFINE_PROP_END_OF_LIST(),
-};
-
/*
* parse PLIC hart/mode address offset config
*
@@ -427,45 +412,46 @@ static void parse_hart_config(SiFivePLICState *plic)
static void sifive_plic_irq_request(void *opaque, int irq, int level)
{
- SiFivePLICState *plic = opaque;
- if (RISCV_DEBUG_PLIC) {
- qemu_log("sifive_plic_irq_request: irq=%d level=%d\n", irq, level);
- }
- sifive_plic_set_pending(plic, irq, level > 0);
- sifive_plic_update(plic);
+ SiFivePLICState *s = opaque;
+
+ sifive_plic_set_pending(s, irq, level > 0);
+ sifive_plic_update(s);
}
static void sifive_plic_realize(DeviceState *dev, Error **errp)
{
- SiFivePLICState *plic = SIFIVE_PLIC(dev);
+ SiFivePLICState *s = SIFIVE_PLIC(dev);
int i;
- memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic,
- TYPE_SIFIVE_PLIC, plic->aperture_size);
- parse_hart_config(plic);
- plic->bitfield_words = (plic->num_sources + 31) >> 5;
- plic->num_enables = plic->bitfield_words * plic->num_addrs;
- plic->source_priority = g_new0(uint32_t, plic->num_sources);
- plic->target_priority = g_new(uint32_t, plic->num_addrs);
- plic->pending = g_new0(uint32_t, plic->bitfield_words);
- plic->claimed = g_new0(uint32_t, plic->bitfield_words);
- plic->enable = g_new0(uint32_t, plic->num_enables);
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
- qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
-
- plic->s_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
- qdev_init_gpio_out(dev, plic->s_external_irqs, plic->num_harts);
-
- plic->m_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
- qdev_init_gpio_out(dev, plic->m_external_irqs, plic->num_harts);
+ memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_plic_ops, s,
+ TYPE_SIFIVE_PLIC, s->aperture_size);
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
+
+ parse_hart_config(s);
+
+ s->bitfield_words = (s->num_sources + 31) >> 5;
+ s->num_enables = s->bitfield_words * s->num_addrs;
+ s->source_priority = g_new0(uint32_t, s->num_sources);
+ s->target_priority = g_new(uint32_t, s->num_addrs);
+ s->pending = g_new0(uint32_t, s->bitfield_words);
+ s->claimed = g_new0(uint32_t, s->bitfield_words);
+ s->enable = g_new0(uint32_t, s->num_enables);
+
+ qdev_init_gpio_in(dev, sifive_plic_irq_request, s->num_sources);
+
+ s->s_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+ qdev_init_gpio_out(dev, s->s_external_irqs, s->num_harts);
+
+ s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+ qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
/* We can't allow the supervisor to control SEIP as this would allow the
* supervisor to clear a pending external interrupt which will result in
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
* hardware controlled when a PLIC is attached.
*/
- for (i = 0; i < plic->num_harts; i++) {
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(plic->hartid_base + i));
+ for (i = 0; i < s->num_harts; i++) {
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
error_report("SEIP already claimed");
exit(1);
@@ -496,6 +482,21 @@ static const VMStateDescription vmstate_sifive_plic = {
}
};
+static Property sifive_plic_properties[] = {
+ DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
+ DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
+ DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
+ DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
+ DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
+ DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
+ DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
+ DEFINE_PROP_UINT32("enable-stride", SiFivePLICState, enable_stride, 0),
+ DEFINE_PROP_UINT32("context-base", SiFivePLICState, context_base, 0),
+ DEFINE_PROP_UINT32("context-stride", SiFivePLICState, context_stride, 0),
+ DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void sifive_plic_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 993bf89..d1ffc7b 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -35,7 +35,7 @@
bool riscv_is_32bit(RISCVHartArrayState *harts)
{
- return riscv_cpu_is_32bit(&harts->harts[0].env);
+ return harts->harts[0].env.misa_mxl_max == MXL_RV32;
}
target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index e475b6d..3fc8545 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -463,7 +463,7 @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
MemoryRegion *mem_low_alias = g_new(MemoryRegion, 1);
MemoryRegion *mem_high = g_new(MemoryRegion, 1);
MemoryRegion *mem_high_alias = g_new(MemoryRegion, 1);
- uint64_t mem_high_size;
+ uint64_t mem_low_size, mem_high_size;
hwaddr firmware_load_addr;
const char *firmware_name;
bool kernel_as_payload = false;
@@ -485,32 +485,35 @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
TYPE_MICROCHIP_PFSOC);
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
+ /* Split RAM into low and high regions using aliases to machine->ram */
+ mem_low_size = memmap[MICROCHIP_PFSOC_DRAM_LO].size;
+ mem_high_size = machine->ram_size - mem_low_size;
+ memory_region_init_alias(mem_low, NULL,
+ "microchip.icicle.kit.ram_low", machine->ram,
+ 0, mem_low_size);
+ memory_region_init_alias(mem_high, NULL,
+ "microchip.icicle.kit.ram_high", machine->ram,
+ mem_low_size, mem_high_size);
+
/* Register RAM */
- memory_region_init_ram(mem_low, NULL, "microchip.icicle.kit.ram_low",
- memmap[MICROCHIP_PFSOC_DRAM_LO].size,
- &error_fatal);
- memory_region_init_alias(mem_low_alias, NULL,
- "microchip.icicle.kit.ram_low.alias",
- mem_low, 0,
- memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].size);
memory_region_add_subregion(system_memory,
memmap[MICROCHIP_PFSOC_DRAM_LO].base,
mem_low);
memory_region_add_subregion(system_memory,
+ memmap[MICROCHIP_PFSOC_DRAM_HI].base,
+ mem_high);
+
+ /* Create aliases for the low and high RAM regions */
+ memory_region_init_alias(mem_low_alias, NULL,
+ "microchip.icicle.kit.ram_low.alias",
+ mem_low, 0, mem_low_size);
+ memory_region_add_subregion(system_memory,
memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].base,
mem_low_alias);
-
- mem_high_size = machine->ram_size - 1 * GiB;
-
- memory_region_init_ram(mem_high, NULL, "microchip.icicle.kit.ram_high",
- mem_high_size, &error_fatal);
memory_region_init_alias(mem_high_alias, NULL,
"microchip.icicle.kit.ram_high.alias",
mem_high, 0, mem_high_size);
memory_region_add_subregion(system_memory,
- memmap[MICROCHIP_PFSOC_DRAM_HI].base,
- mem_high);
- memory_region_add_subregion(system_memory,
memmap[MICROCHIP_PFSOC_DRAM_HI_ALIAS].base,
mem_high_alias);
@@ -606,6 +609,7 @@ static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void *data)
MICROCHIP_PFSOC_COMPUTE_CPU_COUNT;
mc->min_cpus = MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT + 1;
mc->default_cpus = mc->min_cpus;
+ mc->default_ram_id = "microchip.icicle.kit.ram";
/*
* Map 513 MiB high memory, the mimimum required high memory size, because
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 9803ae6..83e1511 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "hw/riscv/opentitan.h"
#include "qapi/error.h"
#include "hw/boards.h"
@@ -46,38 +47,43 @@ static const MemMapEntry ibex_memmap[] = {
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
[IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
- [IBEX_DEV_PLIC] = { 0x41010000, 0x1000 },
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
[IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
[IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
- [IBEX_DEV_KEYMGR] = { 0x41130000, 0x1000 },
+ [IBEX_DEV_OTBN] = { 0x41130000, 0x10000 },
+ [IBEX_DEV_KEYMGR] = { 0x41140000, 0x1000 },
[IBEX_DEV_CSRNG] = { 0x41150000, 0x1000 },
[IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
[IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
[IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
[IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
- [IBEX_DEV_OTBN] = { 0x411d0000, 0x10000 },
[IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
};
static void opentitan_board_init(MachineState *machine)
{
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
const MemMapEntry *memmap = ibex_memmap;
OpenTitanState *s = g_new0(OpenTitanState, 1);
MemoryRegion *sys_mem = get_system_memory();
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
+
+ if (machine->ram_size != mc->default_ram_size) {
+ char *sz = size_to_str(mc->default_ram_size);
+ error_report("Invalid RAM size, should be %s", sz);
+ g_free(sz);
+ exit(EXIT_FAILURE);
+ }
/* Initialize SoC */
object_initialize_child(OBJECT(machine), "soc", &s->soc,
TYPE_RISCV_IBEX_SOC);
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
- memory_region_init_ram(main_mem, NULL, "riscv.lowrisc.ibex.ram",
- memmap[IBEX_DEV_RAM].size, &error_fatal);
memory_region_add_subregion(sys_mem,
- memmap[IBEX_DEV_RAM].base, main_mem);
+ memmap[IBEX_DEV_RAM].base, machine->ram);
if (machine->firmware) {
riscv_load_firmware(machine->firmware, memmap[IBEX_DEV_RAM].base, NULL);
@@ -95,6 +101,8 @@ static void opentitan_machine_init(MachineClass *mc)
mc->init = opentitan_board_init;
mc->max_cpus = 1;
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
+ mc->default_ram_id = "riscv.lowrisc.ibex.ram";
+ mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size;
}
DEFINE_MACHINE("opentitan", opentitan_machine_init)
@@ -105,7 +113,7 @@ static void lowrisc_ibex_soc_init(Object *obj)
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
- object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
+ object_initialize_child(obj, "plic", &s->plic, TYPE_SIFIVE_PLIC);
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
@@ -145,6 +153,18 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
&s->flash_alias);
/* PLIC */
+ qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
+ qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 0x18);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "context-base", 0x200004);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "context-stride", 4);
+ qdev_prop_set_uint32(DEVICE(&s->plic), "aperture-size", memmap[IBEX_DEV_PLIC].size);
+
if (!sysbus_realize(SYS_BUS_DEVICE(&s->plic), errp)) {
return;
}
@@ -153,7 +173,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
for (i = 0; i < ms->smp.cpus; i++) {
CPUState *cpu = qemu_get_cpu(i);
- qdev_connect_gpio_out(DEVICE(&s->plic), i,
+ qdev_connect_gpio_out(DEVICE(&s->plic), ms->smp.cpus + i,
qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
}
diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
index d7d1f91..90e2cf6 100644
--- a/hw/riscv/shakti_c.c
+++ b/hw/riscv/shakti_c.c
@@ -45,7 +45,6 @@ static void shakti_c_machine_state_init(MachineState *mstate)
{
ShaktiCMachineState *sms = RISCV_SHAKTI_MACHINE(mstate);
MemoryRegion *system_memory = get_system_memory();
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
/* Allow only Shakti C CPU for this platform */
if (strcmp(mstate->cpu_type, TYPE_RISCV_CPU_SHAKTI_C) != 0) {
@@ -59,11 +58,9 @@ static void shakti_c_machine_state_init(MachineState *mstate)
qdev_realize(DEVICE(&sms->soc), NULL, &error_abort);
/* register RAM */
- memory_region_init_ram(main_mem, NULL, "riscv.shakti.c.ram",
- mstate->ram_size, &error_fatal);
memory_region_add_subregion(system_memory,
shakti_c_memmap[SHAKTI_C_RAM].base,
- main_mem);
+ mstate->ram);
/* ROM reset vector */
riscv_setup_rom_reset_vec(mstate, &sms->soc.cpus,
@@ -88,6 +85,7 @@ static void shakti_c_machine_class_init(ObjectClass *klass, void *data)
mc->desc = "RISC-V Board compatible with Shakti SDK";
mc->init = shakti_c_machine_state_init;
mc->default_cpu_type = TYPE_RISCV_CPU_SHAKTI_C;
+ mc->default_ram_id = "riscv.shakti.c.ram";
}
static const TypeInfo shakti_c_machine_type_info = {
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 6e95ea5..9b20640 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -29,6 +29,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "hw/boards.h"
@@ -71,22 +72,27 @@ static const MemMapEntry sifive_e_memmap[] = {
static void sifive_e_machine_init(MachineState *machine)
{
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
const MemMapEntry *memmap = sifive_e_memmap;
SiFiveEState *s = RISCV_E_MACHINE(machine);
MemoryRegion *sys_mem = get_system_memory();
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
int i;
+ if (machine->ram_size != mc->default_ram_size) {
+ char *sz = size_to_str(mc->default_ram_size);
+ error_report("Invalid RAM size, should be %s", sz);
+ g_free(sz);
+ exit(EXIT_FAILURE);
+ }
+
/* Initialize SoC */
object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_E_SOC);
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
/* Data Tightly Integrated Memory */
- memory_region_init_ram(main_mem, NULL, "riscv.sifive.e.ram",
- memmap[SIFIVE_E_DEV_DTIM].size, &error_fatal);
memory_region_add_subregion(sys_mem,
- memmap[SIFIVE_E_DEV_DTIM].base, main_mem);
+ memmap[SIFIVE_E_DEV_DTIM].base, machine->ram);
/* Mask ROM reset vector */
uint32_t reset_vec[4];
@@ -142,6 +148,8 @@ static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
mc->init = sifive_e_machine_init;
mc->max_cpus = 1;
mc->default_cpu_type = SIFIVE_E_CPU;
+ mc->default_ram_id = "riscv.sifive.e.ram";
+ mc->default_ram_size = sifive_e_memmap[SIFIVE_E_DEV_DTIM].size;
object_class_property_add_bool(oc, "revb", sifive_e_machine_get_revb,
sifive_e_machine_set_revb);
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index fc5790b..0217006 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -528,7 +528,6 @@ static void sifive_u_machine_init(MachineState *machine)
const MemMapEntry *memmap = sifive_u_memmap;
SiFiveUState *s = RISCV_U_MACHINE(machine);
MemoryRegion *system_memory = get_system_memory();
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *flash0 = g_new(MemoryRegion, 1);
target_ulong start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
target_ulong firmware_end_addr, kernel_start_addr;
@@ -549,10 +548,8 @@ static void sifive_u_machine_init(MachineState *machine)
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
/* register RAM */
- memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram",
- machine->ram_size, &error_fatal);
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_DRAM].base,
- main_mem);
+ machine->ram);
/* register QSPI0 Flash */
memory_region_init_ram(flash0, NULL, "riscv.sifive.u.flash0",
@@ -748,6 +745,7 @@ static void sifive_u_machine_class_init(ObjectClass *oc, void *data)
mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
mc->default_cpu_type = SIFIVE_U_CPU;
mc->default_cpus = mc->min_cpus;
+ mc->default_ram_id = "riscv.sifive.u.ram";
object_class_property_add_bool(oc, "start-in-flash",
sifive_u_machine_get_start_in_flash,
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 79ae355..288d69c 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -180,7 +180,6 @@ static void spike_board_init(MachineState *machine)
const MemMapEntry *memmap = spike_memmap;
SpikeState *s = SPIKE_MACHINE(machine);
MemoryRegion *system_memory = get_system_memory();
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
target_ulong firmware_end_addr, kernel_start_addr;
uint32_t fdt_load_addr;
@@ -239,10 +238,8 @@ static void spike_board_init(MachineState *machine)
}
/* register system main memory (actual RAM) */
- memory_region_init_ram(main_mem, NULL, "riscv.spike.ram",
- machine->ram_size, &error_fatal);
memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base,
- main_mem);
+ machine->ram);
/* create device tree */
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
@@ -326,6 +323,7 @@ static void spike_machine_class_init(ObjectClass *oc, void *data)
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
mc->numa_mem_supported = true;
+ mc->default_ram_id = "riscv.spike.ram";
}
static const TypeInfo spike_machine_typeinfo = {
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index ec0cb69..b3b431c 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -771,7 +771,6 @@ static void virt_machine_init(MachineState *machine)
const MemMapEntry *memmap = virt_memmap;
RISCVVirtState *s = RISCV_VIRT_MACHINE(machine);
MemoryRegion *system_memory = get_system_memory();
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
char *plic_hart_config, *soc_name;
target_ulong start_addr = memmap[VIRT_DRAM].base;
@@ -890,10 +889,8 @@ static void virt_machine_init(MachineState *machine)
}
/* register system main memory (actual RAM) */
- memory_region_init_ram(main_mem, NULL, "riscv_virt_board.ram",
- machine->ram_size, &error_fatal);
memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base,
- main_mem);
+ machine->ram);
/* create device tree */
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
@@ -1032,6 +1029,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
mc->numa_mem_supported = true;
+ mc->default_ram_id = "riscv_virt_board.ram";
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);