diff options
author | Richard Henderson | 2021-10-07 16:18:39 +0200 |
---|---|---|
committer | Richard Henderson | 2021-10-07 16:18:39 +0200 |
commit | 3c019339830affe7974b738e0c2b71bd28778ef0 (patch) | |
tree | 66718f21492d05ef2bc63d0a9bcb3ddc9c1a0d82 /hw | |
parent | Merge remote-tracking branch 'remotes/quic/tags/pull-hex-20211006' into staging (diff) | |
parent | hw/riscv: shakti_c: Mark as not user creatable (diff) | |
download | qemu-3c019339830affe7974b738e0c2b71bd28778ef0.tar.gz qemu-3c019339830affe7974b738e0c2b71bd28778ef0.tar.xz qemu-3c019339830affe7974b738e0c2b71bd28778ef0.zip |
Merge remote-tracking branch 'remotes/alistair23/tags/pull-riscv-to-apply-20211007' into staging
Third RISC-V PR for QEMU 6.2
- Add Zb[abcs] instruction support
- Remove RVB support
- Bug fix of setting mstatus_hs.[SD|FS] bits
- Mark some UART devices as 'input'
- QOMify PolarFire MMUART
- Fixes for sifive PDMA
- Mark shakti_c as not user creatable
# gpg: Signature made Wed 06 Oct 2021 11:42:53 PM PDT
# gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full]
* remotes/alistair23/tags/pull-riscv-to-apply-20211007: (26 commits)
hw/riscv: shakti_c: Mark as not user creatable
hw/dma: sifive_pdma: Don't run DMA when channel is disclaimed
hw/dma: sifive_pdma: Fix Control.claim bit detection
hw/char/mchp_pfsoc_mmuart: QOM'ify PolarFire MMUART
hw/char/mchp_pfsoc_mmuart: Use a MemoryRegion container
hw/char/mchp_pfsoc_mmuart: Simplify MCHP_PFSOC_MMUART_REG definition
hw/char: sifive_uart: Register device in 'input' category
hw/char: shakti_uart: Register device in 'input' category
hw/char: ibex_uart: Register device in 'input' category
target/riscv: Set mstatus_hs.[SD|FS] bits if Clean and V=1 in mark_fs_dirty()
disas/riscv: Add Zb[abcs] instructions
target/riscv: Remove RVB (replaced by Zb[abcs])
target/riscv: Add zext.h instructions to Zbb, removing pack/packu/packh
target/riscv: Add rev8 instruction, removing grev/grevi
target/riscv: Add a REQUIRE_32BIT macro
target/riscv: Add orc.b instruction for Zbb, removing gorc/gorci
target/riscv: Reassign instructions to the Zbb-extension
target/riscv: Add instructions of the Zbc-extension
target/riscv: Reassign instructions to the Zbs-extension
target/riscv: Remove shift-one instructions (proposed Zbo in pre-0.93 draft-B)
...
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/char/ibex_uart.c | 1 | ||||
-rw-r--r-- | hw/char/mchp_pfsoc_mmuart.c | 116 | ||||
-rw-r--r-- | hw/char/shakti_uart.c | 1 | ||||
-rw-r--r-- | hw/char/sifive_uart.c | 1 | ||||
-rw-r--r-- | hw/dma/sifive_pdma.c | 13 | ||||
-rw-r--r-- | hw/riscv/shakti_c.c | 7 |
6 files changed, 117 insertions, 22 deletions
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c index 9b0a817713..e58181fcf4 100644 --- a/hw/char/ibex_uart.c +++ b/hw/char/ibex_uart.c @@ -550,6 +550,7 @@ static void ibex_uart_class_init(ObjectClass *klass, void *data) dc->realize = ibex_uart_realize; dc->vmsd = &vmstate_ibex_uart; device_class_set_props(dc, ibex_uart_properties); + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } static const TypeInfo ibex_uart_info = { diff --git a/hw/char/mchp_pfsoc_mmuart.c b/hw/char/mchp_pfsoc_mmuart.c index 2facf85c2d..22f3e78eb9 100644 --- a/hw/char/mchp_pfsoc_mmuart.c +++ b/hw/char/mchp_pfsoc_mmuart.c @@ -22,20 +22,25 @@ #include "qemu/osdep.h" #include "qemu/log.h" -#include "chardev/char.h" +#include "qapi/error.h" +#include "migration/vmstate.h" #include "hw/char/mchp_pfsoc_mmuart.h" +#include "hw/qdev-properties.h" + +#define REGS_OFFSET 0x20 static uint64_t mchp_pfsoc_mmuart_read(void *opaque, hwaddr addr, unsigned size) { MchpPfSoCMMUartState *s = opaque; - if (addr >= MCHP_PFSOC_MMUART_REG_SIZE) { + addr >>= 2; + if (addr >= MCHP_PFSOC_MMUART_REG_COUNT) { qemu_log_mask(LOG_GUEST_ERROR, "%s: read: addr=0x%" HWADDR_PRIx "\n", - __func__, addr); + __func__, addr << 2); return 0; } - return s->reg[addr / sizeof(uint32_t)]; + return s->reg[addr]; } static void mchp_pfsoc_mmuart_write(void *opaque, hwaddr addr, @@ -44,13 +49,14 @@ static void mchp_pfsoc_mmuart_write(void *opaque, hwaddr addr, MchpPfSoCMMUartState *s = opaque; uint32_t val32 = (uint32_t)value; - if (addr >= MCHP_PFSOC_MMUART_REG_SIZE) { + addr >>= 2; + if (addr >= MCHP_PFSOC_MMUART_REG_COUNT) { qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%" HWADDR_PRIx - " v=0x%x\n", __func__, addr, val32); + " v=0x%x\n", __func__, addr << 2, val32); return; } - s->reg[addr / sizeof(uint32_t)] = val32; + s->reg[addr] = val32; } static const MemoryRegionOps mchp_pfsoc_mmuart_ops = { @@ -63,23 +69,95 @@ static const MemoryRegionOps mchp_pfsoc_mmuart_ops = { }, }; -MchpPfSoCMMUartState *mchp_pfsoc_mmuart_create(MemoryRegion *sysmem, - hwaddr base, qemu_irq irq, Chardev *chr) +static void mchp_pfsoc_mmuart_reset(DeviceState *dev) +{ + MchpPfSoCMMUartState *s = MCHP_PFSOC_UART(dev); + + memset(s->reg, 0, sizeof(s->reg)); + device_cold_reset(DEVICE(&s->serial_mm)); +} + +static void mchp_pfsoc_mmuart_init(Object *obj) +{ + MchpPfSoCMMUartState *s = MCHP_PFSOC_UART(obj); + + object_initialize_child(obj, "serial-mm", &s->serial_mm, TYPE_SERIAL_MM); + object_property_add_alias(obj, "chardev", OBJECT(&s->serial_mm), "chardev"); +} + +static void mchp_pfsoc_mmuart_realize(DeviceState *dev, Error **errp) { - MchpPfSoCMMUartState *s; + MchpPfSoCMMUartState *s = MCHP_PFSOC_UART(dev); + + qdev_prop_set_uint8(DEVICE(&s->serial_mm), "regshift", 2); + qdev_prop_set_uint32(DEVICE(&s->serial_mm), "baudbase", 399193); + qdev_prop_set_uint8(DEVICE(&s->serial_mm), "endianness", + DEVICE_LITTLE_ENDIAN); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->serial_mm), errp)) { + return; + } + + sysbus_pass_irq(SYS_BUS_DEVICE(dev), SYS_BUS_DEVICE(&s->serial_mm)); - s = g_new0(MchpPfSoCMMUartState, 1); + memory_region_init(&s->container, OBJECT(s), "mchp.pfsoc.mmuart", 0x1000); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container); - memory_region_init_io(&s->iomem, NULL, &mchp_pfsoc_mmuart_ops, s, - "mchp.pfsoc.mmuart", 0x1000); + memory_region_add_subregion(&s->container, 0, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->serial_mm), 0)); + + memory_region_init_io(&s->iomem, OBJECT(s), &mchp_pfsoc_mmuart_ops, s, + "mchp.pfsoc.mmuart.regs", 0x1000 - REGS_OFFSET); + memory_region_add_subregion(&s->container, REGS_OFFSET, &s->iomem); +} - s->base = base; - s->irq = irq; +static const VMStateDescription mchp_pfsoc_mmuart_vmstate = { + .name = "mchp.pfsoc.uart", + .version_id = 0, + .minimum_version_id = 0, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(reg, MchpPfSoCMMUartState, + MCHP_PFSOC_MMUART_REG_COUNT), + VMSTATE_END_OF_LIST() + } +}; + +static void mchp_pfsoc_mmuart_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = mchp_pfsoc_mmuart_realize; + dc->reset = mchp_pfsoc_mmuart_reset; + dc->vmsd = &mchp_pfsoc_mmuart_vmstate; + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); +} + +static const TypeInfo mchp_pfsoc_mmuart_info = { + .name = TYPE_MCHP_PFSOC_UART, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(MchpPfSoCMMUartState), + .instance_init = mchp_pfsoc_mmuart_init, + .class_init = mchp_pfsoc_mmuart_class_init, +}; + +static void mchp_pfsoc_mmuart_register_types(void) +{ + type_register_static(&mchp_pfsoc_mmuart_info); +} + +type_init(mchp_pfsoc_mmuart_register_types) + +MchpPfSoCMMUartState *mchp_pfsoc_mmuart_create(MemoryRegion *sysmem, + hwaddr base, + qemu_irq irq, Chardev *chr) +{ + DeviceState *dev = qdev_new(TYPE_MCHP_PFSOC_UART); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - s->serial = serial_mm_init(sysmem, base, 2, irq, 399193, chr, - DEVICE_LITTLE_ENDIAN); + qdev_prop_set_chr(dev, "chardev", chr); + sysbus_realize(sbd, &error_fatal); - memory_region_add_subregion(sysmem, base + 0x20, &s->iomem); + memory_region_add_subregion(sysmem, base, sysbus_mmio_get_region(sbd, 0)); + sysbus_connect_irq(sbd, 0, irq); - return s; + return MCHP_PFSOC_UART(dev); } diff --git a/hw/char/shakti_uart.c b/hw/char/shakti_uart.c index 6870821325..98b142c7df 100644 --- a/hw/char/shakti_uart.c +++ b/hw/char/shakti_uart.c @@ -168,6 +168,7 @@ static void shakti_uart_class_init(ObjectClass *klass, void *data) dc->reset = shakti_uart_reset; dc->realize = shakti_uart_realize; device_class_set_props(dc, shakti_uart_properties); + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } static const TypeInfo shakti_uart_info = { diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c index 278e21c434..1c75f792b3 100644 --- a/hw/char/sifive_uart.c +++ b/hw/char/sifive_uart.c @@ -248,6 +248,7 @@ static void sifive_uart_class_init(ObjectClass *oc, void *data) rc->phases.enter = sifive_uart_reset_enter; rc->phases.hold = sifive_uart_reset_hold; device_class_set_props(dc, sifive_uart_properties); + set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } static const TypeInfo sifive_uart_info = { diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c index b4fd40573a..85fe34f5f3 100644 --- a/hw/dma/sifive_pdma.c +++ b/hw/dma/sifive_pdma.c @@ -232,7 +232,7 @@ static void sifive_pdma_write(void *opaque, hwaddr offset, { SiFivePDMAState *s = opaque; int ch = SIFIVE_PDMA_CHAN_NO(offset); - bool claimed; + bool claimed, run; if (ch >= SIFIVE_PDMA_CHANS) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid channel no %d\n", @@ -243,7 +243,8 @@ static void sifive_pdma_write(void *opaque, hwaddr offset, offset &= 0xfff; switch (offset) { case DMA_CONTROL: - claimed = !!s->chan[ch].control & CONTROL_CLAIM; + claimed = !!(s->chan[ch].control & CONTROL_CLAIM); + run = !!(s->chan[ch].control & CONTROL_RUN); if (!claimed && (value & CONTROL_CLAIM)) { /* reset Next* registers */ @@ -254,13 +255,19 @@ static void sifive_pdma_write(void *opaque, hwaddr offset, s->chan[ch].next_src = 0; } + /* claim bit can only be cleared when run is low */ + if (run && !(value & CONTROL_CLAIM)) { + value |= CONTROL_CLAIM; + } + s->chan[ch].control = value; /* * If channel was not claimed before run bit is set, + * or if the channel is disclaimed when run was low, * DMA won't run. */ - if (!claimed) { + if (!claimed || (!run && !(value & CONTROL_CLAIM))) { s->chan[ch].control &= ~CONTROL_RUN; return; } diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c index 2f084d3c8d..d7d1f91fa5 100644 --- a/hw/riscv/shakti_c.c +++ b/hw/riscv/shakti_c.c @@ -150,6 +150,13 @@ static void shakti_c_soc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = shakti_c_soc_state_realize; + /* + * Reasons: + * - Creates CPUS in riscv_hart_realize(), and can create unintended + * CPUs + * - Uses serial_hds in realize function, thus can't be used twice + */ + dc->user_creatable = false; } static void shakti_c_soc_instance_init(Object *obj) |