aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-08-20 13:22:21 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-08-20 13:22:21 +0100
commit62c34848efb41f0e81af0c6b4f1d5d577039eec9 (patch)
tree85f6f2cb120c87ae287e195b082b024212e5229f /hw
parent627fce617868df87b3757375a2a0318ad2beb381 (diff)
parentb85fad1588e812566f897f747e38da345a7016d6 (diff)
downloadqemu-62c34848efb41f0e81af0c6b4f1d5d577039eec9.zip
qemu-62c34848efb41f0e81af0c6b4f1d5d577039eec9.tar.gz
qemu-62c34848efb41f0e81af0c6b4f1d5d577039eec9.tar.bz2
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180820' into staging
target-arm queue: * Fix crash on conditional instruction in an IT block * docs/generic-loader: mention U-Boot and Intel HEX executable formats * hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset * imx_serial: Generate interrupt on receive data ready if enabled * Fix various minor bugs in AArch32 Hyp related coprocessor registers * Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked) * Implement AArch32 ERET instruction * hw/arm/virt: Add virt-3.1 machine type * sdhci: add i.MX SD Stable Clock bit * Remove now-obsolete MMIO request_ptr APIs * hw/timer/m48t59: Move away from old_mmio accessors * hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module * nvic: Expose NMI line * hw/dma/pl080: cleanups and new features required for use in MPS boards # gpg: Signature made Mon 20 Aug 2018 11:30:12 BST # gpg: using RSA key 3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20180820: (25 commits) hw/dma/pl080: Remove hw_error() if DMA is enabled hw/dma/pl080: Correct bug in register address decode logic hw/dma/pl080: Provide device reset function hw/dma/pl080: Don't use CPU address space for DMA accesses hw/dma/pl080: Support all three interrupt lines hw/dma/pl080: Allow use as embedded-struct device nvic: Expose NMI line hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module hw/timer/m48t59: Move away from old_mmio accessors hw/misc: Remove mmio_interface device memory: Remove MMIO request_ptr APIs hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code sdhci: add i.MX SD Stable Clock bit hw/arm/virt: Add virt-3.1 machine type target/arm: Implement AArch32 ERET instruction target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked) target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2 target/arm: Implement AArch32 Hyp FARs target/arm: Implement AArch32 HVBAR target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/armv7m.c1
-rw-r--r--hw/arm/realview.c8
-rw-r--r--hw/arm/versatilepb.c9
-rw-r--r--hw/arm/virt.c21
-rw-r--r--hw/char/imx_serial.c3
-rw-r--r--hw/dma/pl080.c113
-rw-r--r--hw/intc/arm_gicv3_its_kvm.c2
-rw-r--r--hw/intc/armv7m_nvic.c19
-rw-r--r--hw/intc/trace-events1
-rw-r--r--hw/misc/Makefile.objs1
-rw-r--r--hw/misc/mmio_interface.c135
-rw-r--r--hw/sd/sdhci-internal.h2
-rw-r--r--hw/sd/sdhci.c8
-rw-r--r--hw/ssi/xilinx_spips.c46
-rw-r--r--hw/timer/m48t59.c59
-rw-r--r--hw/watchdog/Makefile.objs1
-rw-r--r--hw/watchdog/cmsdk-apb-watchdog.c326
-rw-r--r--hw/watchdog/trace-events6
18 files changed, 476 insertions, 285 deletions
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 8786139..4bf9131 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -202,6 +202,7 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
*/
qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
+ qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");
/* Wire the NVIC up to the CPU */
sbd = SYS_BUS_DEVICE(&s->nvic);
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index cd585d9..ab8c14f 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -201,7 +201,13 @@ static void realview_init(MachineState *machine,
pl011_create(0x1000c000, pic[15], serial_hd(3));
/* DMA controller is optional, apparently. */
- sysbus_create_simple("pl081", 0x10030000, pic[24]);
+ dev = qdev_create(NULL, "pl081");
+ object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
+ &error_fatal);
+ qdev_init_nofail(dev);
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, 0x10030000);
+ sysbus_connect_irq(busdev, 0, pic[24]);
sysbus_create_simple("sp804", 0x10011000, pic[4]);
sysbus_create_simple("sp804", 0x10012000, pic[5]);
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index a5a06b6..8b74857 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -287,7 +287,14 @@ static void versatile_init(MachineState *machine, int board_id)
pl011_create(0x101f3000, pic[14], serial_hd(2));
pl011_create(0x10009000, sic[6], serial_hd(3));
- sysbus_create_simple("pl080", 0x10130000, pic[17]);
+ dev = qdev_create(NULL, "pl080");
+ object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
+ &error_fatal);
+ qdev_init_nofail(dev);
+ busdev = SYS_BUS_DEVICE(dev);
+ sysbus_mmio_map(busdev, 0, 0x10130000);
+ sysbus_connect_irq(busdev, 0, pic[17]);
+
sysbus_create_simple("sp804", 0x101e2000, pic[4]);
sysbus_create_simple("sp804", 0x101e3000, pic[5]);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0807be9..0b57f87 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1791,10 +1791,7 @@ static void machvirt_machine_init(void)
}
type_init(machvirt_machine_init);
-#define VIRT_COMPAT_2_12 \
- HW_COMPAT_2_12
-
-static void virt_3_0_instance_init(Object *obj)
+static void virt_3_1_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
@@ -1864,10 +1861,24 @@ static void virt_3_0_instance_init(Object *obj)
vms->irqmap = a15irqmap;
}
+static void virt_machine_3_1_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(3, 1)
+
+static void virt_3_0_instance_init(Object *obj)
+{
+ virt_3_1_instance_init(obj);
+}
+
static void virt_machine_3_0_options(MachineClass *mc)
{
+ virt_machine_3_1_options(mc);
}
-DEFINE_VIRT_MACHINE_AS_LATEST(3, 0)
+DEFINE_VIRT_MACHINE(3, 0)
+
+#define VIRT_COMPAT_2_12 \
+ HW_COMPAT_2_12
static void virt_2_12_instance_init(Object *obj)
{
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 0747db9..1e36319 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -74,8 +74,9 @@ static void imx_update(IMXSerialState *s)
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
/*
* TCEN and TXDC are both bit 3
+ * RDR and DREN are both bit 0
*/
- mask |= s->ucr4 & UCR4_TCEN;
+ mask |= s->ucr4 & (UCR4_TCEN | UCR4_DREN);
usr2 = s->usr2 & mask;
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 7724c93..ef15d3e 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -11,8 +11,9 @@
#include "hw/sysbus.h"
#include "exec/address-spaces.h"
#include "qemu/log.h"
+#include "hw/dma/pl080.h"
+#include "qapi/error.h"
-#define PL080_MAX_CHANNELS 8
#define PL080_CONF_E 0x1
#define PL080_CONF_M1 0x2
#define PL080_CONF_M2 0x4
@@ -30,36 +31,6 @@
#define PL080_CCTRL_D 0x02000000
#define PL080_CCTRL_S 0x01000000
-typedef struct {
- uint32_t src;
- uint32_t dest;
- uint32_t lli;
- uint32_t ctrl;
- uint32_t conf;
-} pl080_channel;
-
-#define TYPE_PL080 "pl080"
-#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080)
-
-typedef struct PL080State {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- uint8_t tc_int;
- uint8_t tc_mask;
- uint8_t err_int;
- uint8_t err_mask;
- uint32_t conf;
- uint32_t sync;
- uint32_t req_single;
- uint32_t req_burst;
- pl080_channel chan[PL080_MAX_CHANNELS];
- int nchannels;
- /* Flag to avoid recursive DMA invocations. */
- int running;
- qemu_irq irq;
-} PL080State;
-
static const VMStateDescription vmstate_pl080_channel = {
.name = "pl080_channel",
.version_id = 1,
@@ -105,11 +76,12 @@ static const unsigned char pl081_id[] =
static void pl080_update(PL080State *s)
{
- if ((s->tc_int & s->tc_mask)
- || (s->err_int & s->err_mask))
- qemu_irq_raise(s->irq);
- else
- qemu_irq_lower(s->irq);
+ bool tclevel = (s->tc_int & s->tc_mask);
+ bool errlevel = (s->err_int & s->err_mask);
+
+ qemu_set_irq(s->interr, errlevel);
+ qemu_set_irq(s->inttc, tclevel);
+ qemu_set_irq(s->irq, errlevel || tclevel);
}
static void pl080_run(PL080State *s)
@@ -138,7 +110,6 @@ static void pl080_run(PL080State *s)
if ((s->conf & PL080_CONF_E) == 0)
return;
-hw_error("DMA active\n");
/* If we are already in the middle of a DMA operation then indicate that
there may be new DMA requests and return immediately. */
if (s->running) {
@@ -190,14 +161,16 @@ again:
swidth = 1 << ((ch->ctrl >> 18) & 7);
dwidth = 1 << ((ch->ctrl >> 21) & 7);
for (n = 0; n < dwidth; n+= swidth) {
- cpu_physical_memory_read(ch->src, buff + n, swidth);
+ address_space_read(&s->downstream_as, ch->src,
+ MEMTXATTRS_UNSPECIFIED, buff + n, swidth);
if (ch->ctrl & PL080_CCTRL_SI)
ch->src += swidth;
}
xsize = (dwidth < swidth) ? swidth : dwidth;
/* ??? This may pad the value incorrectly for dwidth < 32. */
for (n = 0; n < xsize; n += dwidth) {
- cpu_physical_memory_write(ch->dest + n, buff + n, dwidth);
+ address_space_write(&s->downstream_as, ch->dest + n,
+ MEMTXATTRS_UNSPECIFIED, buff + n, dwidth);
if (ch->ctrl & PL080_CCTRL_DI)
ch->dest += swidth;
}
@@ -207,19 +180,19 @@ again:
if (size == 0) {
/* Transfer complete. */
if (ch->lli) {
- ch->src = address_space_ldl_le(&address_space_memory,
+ ch->src = address_space_ldl_le(&s->downstream_as,
ch->lli,
MEMTXATTRS_UNSPECIFIED,
NULL);
- ch->dest = address_space_ldl_le(&address_space_memory,
+ ch->dest = address_space_ldl_le(&s->downstream_as,
ch->lli + 4,
MEMTXATTRS_UNSPECIFIED,
NULL);
- ch->ctrl = address_space_ldl_le(&address_space_memory,
+ ch->ctrl = address_space_ldl_le(&s->downstream_as,
ch->lli + 12,
MEMTXATTRS_UNSPECIFIED,
NULL);
- ch->lli = address_space_ldl_le(&address_space_memory,
+ ch->lli = address_space_ldl_le(&s->downstream_as,
ch->lli + 8,
MEMTXATTRS_UNSPECIFIED,
NULL);
@@ -255,7 +228,7 @@ static uint64_t pl080_read(void *opaque, hwaddr offset,
i = (offset & 0xe0) >> 5;
if (i >= s->nchannels)
goto bad_offset;
- switch (offset >> 2) {
+ switch ((offset >> 2) & 7) {
case 0: /* SrcAddr */
return s->chan[i].src;
case 1: /* DestAddr */
@@ -316,7 +289,7 @@ static void pl080_write(void *opaque, hwaddr offset,
i = (offset & 0xe0) >> 5;
if (i >= s->nchannels)
goto bad_offset;
- switch (offset >> 2) {
+ switch ((offset >> 2) & 7) {
case 0: /* SrcAddr */
s->chan[i].src = value;
break;
@@ -334,6 +307,7 @@ static void pl080_write(void *opaque, hwaddr offset,
pl080_run(s);
break;
}
+ return;
}
switch (offset >> 2) {
case 2: /* IntTCClear */
@@ -374,6 +348,30 @@ static const MemoryRegionOps pl080_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static void pl080_reset(DeviceState *dev)
+{
+ PL080State *s = PL080(dev);
+ int i;
+
+ s->tc_int = 0;
+ s->tc_mask = 0;
+ s->err_int = 0;
+ s->err_mask = 0;
+ s->conf = 0;
+ s->sync = 0;
+ s->req_single = 0;
+ s->req_burst = 0;
+ s->running = 0;
+
+ for (i = 0; i < s->nchannels; i++) {
+ s->chan[i].src = 0;
+ s->chan[i].dest = 0;
+ s->chan[i].lli = 0;
+ s->chan[i].ctrl = 0;
+ s->chan[i].conf = 0;
+ }
+}
+
static void pl080_init(Object *obj)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
@@ -382,9 +380,23 @@ static void pl080_init(Object *obj)
memory_region_init_io(&s->iomem, OBJECT(s), &pl080_ops, s, "pl080", 0x1000);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq);
+ sysbus_init_irq(sbd, &s->interr);
+ sysbus_init_irq(sbd, &s->inttc);
s->nchannels = 8;
}
+static void pl080_realize(DeviceState *dev, Error **errp)
+{
+ PL080State *s = PL080(dev);
+
+ if (!s->downstream) {
+ error_setg(errp, "PL080 'downstream' link not set");
+ return;
+ }
+
+ address_space_init(&s->downstream_as, s->downstream, "pl080-downstream");
+}
+
static void pl081_init(Object *obj)
{
PL080State *s = PL080(obj);
@@ -392,11 +404,20 @@ static void pl081_init(Object *obj)
s->nchannels = 2;
}
+static Property pl080_properties[] = {
+ DEFINE_PROP_LINK("downstream", PL080State, downstream,
+ TYPE_MEMORY_REGION, MemoryRegion *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void pl080_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
dc->vmsd = &vmstate_pl080;
+ dc->realize = pl080_realize;
+ dc->props = pl080_properties;
+ dc->reset = pl080_reset;
}
static const TypeInfo pl080_info = {
@@ -408,7 +429,7 @@ static const TypeInfo pl080_info = {
};
static const TypeInfo pl081_info = {
- .name = "pl081",
+ .name = TYPE_PL081,
.parent = TYPE_PL080,
.instance_init = pl081_init,
};
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
index 271ebe4..01573ab 100644
--- a/hw/intc/arm_gicv3_its_kvm.c
+++ b/hw/intc/arm_gicv3_its_kvm.c
@@ -211,7 +211,7 @@ static void kvm_arm_its_reset(DeviceState *dev)
return;
}
- error_report("ITS KVM: full reset is not supported by the host kernel");
+ warn_report("ITS KVM: full reset is not supported by the host kernel");
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
GITS_CTLR)) {
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 351b69a..0d816fd 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -774,6 +774,24 @@ static void set_irq_level(void *opaque, int n, int level)
}
}
+/* callback when external NMI line is changed */
+static void nvic_nmi_trigger(void *opaque, int n, int level)
+{
+ NVICState *s = opaque;
+
+ trace_nvic_set_nmi_level(level);
+
+ /*
+ * The architecture doesn't specify whether NMI should share
+ * the normal-interrupt behaviour of being resampled on
+ * exception handler return. We choose not to, so just
+ * set NMI pending here and don't track the current level.
+ */
+ if (level) {
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
+ }
+}
+
static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
{
ARMCPU *cpu = s->cpu;
@@ -2382,6 +2400,7 @@ static void armv7m_nvic_instance_init(Object *obj)
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
M_REG_NUM_BANKS);
+ qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1);
}
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 81c7c39..7769869 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -192,6 +192,7 @@ nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (pr
nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
+nvic_set_nmi_level(int level) "NVIC external NMI level set to %d"
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 51d27b3..22714b0 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -71,5 +71,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
obj-$(CONFIG_AUX) += auxbus.o
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
-obj-y += mmio_interface.o
obj-$(CONFIG_MSF2) += msf2-sysreg.o
diff --git a/hw/misc/mmio_interface.c b/hw/misc/mmio_interface.c
deleted file mode 100644
index 3b0e203..0000000
--- a/hw/misc/mmio_interface.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * mmio_interface.c
- *
- * Copyright (C) 2017 : GreenSocs
- * http://www.greensocs.com/ , email: info@greensocs.com
- *
- * Developed by :
- * Frederic Konrad <fred.konrad@greensocs.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option)any later version.
- *
- * This program is distributed in the hope that 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 "trace.h"
-#include "hw/qdev-properties.h"
-#include "hw/misc/mmio_interface.h"
-#include "qapi/error.h"
-
-#ifndef DEBUG_MMIO_INTERFACE
-#define DEBUG_MMIO_INTERFACE 0
-#endif
-
-static uint64_t mmio_interface_counter;
-
-#define DPRINTF(fmt, ...) do { \
- if (DEBUG_MMIO_INTERFACE) { \
- qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
- } \
-} while (0)
-
-static void mmio_interface_init(Object *obj)
-{
- MMIOInterface *s = MMIO_INTERFACE(obj);
-
- if (DEBUG_MMIO_INTERFACE) {
- s->id = mmio_interface_counter++;
- }
-
- DPRINTF("interface created\n");
- s->host_ptr = 0;
- s->subregion = 0;
-}
-
-static void mmio_interface_realize(DeviceState *dev, Error **errp)
-{
- MMIOInterface *s = MMIO_INTERFACE(dev);
-
- DPRINTF("realize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
- " %p\n", s->start, s->end, s->host_ptr);
-
- if (!s->host_ptr) {
- error_setg(errp, "host_ptr property must be set");
- return;
- }
-
- if (!s->subregion) {
- error_setg(errp, "subregion property must be set");
- return;
- }
-
- memory_region_init_ram_ptr(&s->ram_mem, OBJECT(s), "ram",
- s->end - s->start + 1, s->host_ptr);
- memory_region_set_readonly(&s->ram_mem, s->ro);
- memory_region_add_subregion(s->subregion, s->start, &s->ram_mem);
-}
-
-static void mmio_interface_unrealize(DeviceState *dev, Error **errp)
-{
- MMIOInterface *s = MMIO_INTERFACE(dev);
-
- DPRINTF("unrealize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
- " %p\n", s->start, s->end, s->host_ptr);
- memory_region_del_subregion(s->subregion, &s->ram_mem);
-}
-
-static void mmio_interface_finalize(Object *obj)
-{
- MMIOInterface *s = MMIO_INTERFACE(obj);
-
- DPRINTF("finalize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
- " %p\n", s->start, s->end, s->host_ptr);
- object_unparent(OBJECT(&s->ram_mem));
-}
-
-static Property mmio_interface_properties[] = {
- DEFINE_PROP_UINT64("start", MMIOInterface, start, 0),
- DEFINE_PROP_UINT64("end", MMIOInterface, end, 0),
- DEFINE_PROP_PTR("host_ptr", MMIOInterface, host_ptr),
- DEFINE_PROP_BOOL("ro", MMIOInterface, ro, false),
- DEFINE_PROP_MEMORY_REGION("subregion", MMIOInterface, subregion),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void mmio_interface_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- dc->realize = mmio_interface_realize;
- dc->unrealize = mmio_interface_unrealize;
- dc->props = mmio_interface_properties;
- /* Reason: pointer property "host_ptr", and this device
- * is an implementation detail of the memory subsystem,
- * not intended to be created directly by the user.
- */
- dc->user_creatable = false;
-}
-
-static const TypeInfo mmio_interface_info = {
- .name = TYPE_MMIO_INTERFACE,
- .parent = TYPE_DEVICE,
- .instance_size = sizeof(MMIOInterface),
- .instance_init = mmio_interface_init,
- .instance_finalize = mmio_interface_finalize,
- .class_init = mmio_interface_class_init,
-};
-
-static void mmio_interface_register_types(void)
-{
- type_register_static(&mmio_interface_info);
-}
-
-type_init(mmio_interface_register_types)
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
index 756ef3f..19665fd 100644
--- a/hw/sd/sdhci-internal.h
+++ b/hw/sd/sdhci-internal.h
@@ -302,4 +302,6 @@ extern const VMStateDescription sdhci_vmstate;
#define ESDHC_CTRL_4BITBUS (0x1 << 1)
#define ESDHC_CTRL_8BITBUS (0x2 << 1)
+#define ESDHC_PRNSTS_SDSTB (1 << 3)
+
#endif
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 8f58c31..81bbf03 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1651,6 +1651,14 @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
break;
+ case SDHC_PRNSTS:
+ /* Add SDSTB (SD Clock Stable) bit to PRNSTS */
+ ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB;
+ if (s->clkcon & SDHC_CLOCK_INT_STABLE) {
+ ret |= ESDHC_PRNSTS_SDSTB;
+ }
+ break;
+
case ESDHC_DLL_CTRL:
case ESDHC_TUNE_CTRL_STATUS:
case ESDHC_UNDOCUMENTED_REG27:
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index c052bfc..16f88f7 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -1031,14 +1031,6 @@ static const MemoryRegionOps spips_ops = {
static void xilinx_qspips_invalidate_mmio_ptr(XilinxQSPIPS *q)
{
- XilinxSPIPS *s = &q->parent_obj;
-
- if ((q->mmio_execution_enabled) && (q->lqspi_cached_addr != ~0ULL)) {
- /* Invalidate the current mapped mmio */
- memory_region_invalidate_mmio_ptr(&s->mmlqspi, q->lqspi_cached_addr,
- LQSPI_CACHE_SIZE);
- }
-
q->lqspi_cached_addr = ~0ULL;
}
@@ -1207,23 +1199,6 @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
}
}
-static void *lqspi_request_mmio_ptr(void *opaque, hwaddr addr, unsigned *size,
- unsigned *offset)
-{
- XilinxQSPIPS *q = opaque;
- hwaddr offset_within_the_region;
-
- if (!q->mmio_execution_enabled) {
- return NULL;
- }
-
- offset_within_the_region = addr & ~(LQSPI_CACHE_SIZE - 1);
- lqspi_load_cache(opaque, offset_within_the_region);
- *size = LQSPI_CACHE_SIZE;
- *offset = offset_within_the_region;
- return q->lqspi_buf;
-}
-
static uint64_t
lqspi_read(void *opaque, hwaddr addr, unsigned int size)
{
@@ -1245,7 +1220,6 @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
static const MemoryRegionOps lqspi_ops = {
.read = lqspi_read,
- .request_ptr = lqspi_request_mmio_ptr,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 1,
@@ -1322,15 +1296,6 @@ static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(sbd, &s->mmlqspi);
q->lqspi_cached_addr = ~0ULL;
-
- /* mmio_execution breaks migration better aborting than having strange
- * bugs.
- */
- if (q->mmio_execution_enabled) {
- error_setg(&q->migration_blocker,
- "enabling mmio_execution breaks migration");
- migrate_add_blocker(q->migration_blocker, &error_fatal);
- }
}
static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
@@ -1427,16 +1392,6 @@ static Property xilinx_zynqmp_qspips_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
-static Property xilinx_qspips_properties[] = {
- /* We had to turn this off for 2.10 as it is not compatible with migration.
- * It can be enabled but will prevent the device to be migrated.
- * This will go aways when a fix will be released.
- */
- DEFINE_PROP_BOOL("x-mmio-exec", XilinxQSPIPS, mmio_execution_enabled,
- false),
- DEFINE_PROP_END_OF_LIST(),
-};
-
static Property xilinx_spips_properties[] = {
DEFINE_PROP_UINT8("num-busses", XilinxSPIPS, num_busses, 1),
DEFINE_PROP_UINT8("num-ss-bits", XilinxSPIPS, num_cs, 4),
@@ -1450,7 +1405,6 @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
dc->realize = xilinx_qspips_realize;
- dc->props = xilinx_qspips_properties;
xsc->reg_ops = &qspips_ops;
xsc->rx_fifo_size = RXFF_A_Q;
xsc->tx_fifo_size = TXFF_A_Q;
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index f299176..ca3ed44 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -493,66 +493,29 @@ static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
return retval;
}
-static void nvram_writeb (void *opaque, hwaddr addr, uint32_t value)
-{
- M48t59State *NVRAM = opaque;
-
- m48t59_write(NVRAM, addr, value & 0xff);
-}
-
-static void nvram_writew (void *opaque, hwaddr addr, uint32_t value)
-{
- M48t59State *NVRAM = opaque;
-
- m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
- m48t59_write(NVRAM, addr + 1, value & 0xff);
-}
-
-static void nvram_writel (void *opaque, hwaddr addr, uint32_t value)
-{
- M48t59State *NVRAM = opaque;
-
- m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
- m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
- m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);
- m48t59_write(NVRAM, addr + 3, value & 0xff);
-}
-
-static uint32_t nvram_readb (void *opaque, hwaddr addr)
+static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned size)
{
M48t59State *NVRAM = opaque;
return m48t59_read(NVRAM, addr);
}
-static uint32_t nvram_readw (void *opaque, hwaddr addr)
-{
- M48t59State *NVRAM = opaque;
- uint32_t retval;
-
- retval = m48t59_read(NVRAM, addr) << 8;
- retval |= m48t59_read(NVRAM, addr + 1);
- return retval;
-}
-
-static uint32_t nvram_readl (void *opaque, hwaddr addr)
+static void nvram_write(void *opaque, hwaddr addr, uint64_t value,
+ unsigned size)
{
M48t59State *NVRAM = opaque;
- uint32_t retval;
- retval = m48t59_read(NVRAM, addr) << 24;
- retval |= m48t59_read(NVRAM, addr + 1) << 16;
- retval |= m48t59_read(NVRAM, addr + 2) << 8;
- retval |= m48t59_read(NVRAM, addr + 3);
- return retval;
+ return m48t59_write(NVRAM, addr, value);
}
static const MemoryRegionOps nvram_ops = {
- .old_mmio = {
- .read = { nvram_readb, nvram_readw, nvram_readl, },
- .write = { nvram_writeb, nvram_writew, nvram_writel, },
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .read = nvram_read,
+ .write = nvram_write,
+ .impl.min_access_size = 1,
+ .impl.max_access_size = 1,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+ .endianness = DEVICE_BIG_ENDIAN,
};
static const VMStateDescription vmstate_m48t59 = {
diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs
index 9589bed..3f536d1 100644
--- a/hw/watchdog/Makefile.objs
+++ b/hw/watchdog/Makefile.objs
@@ -1,4 +1,5 @@
common-obj-y += watchdog.o
+common-obj-$(CONFIG_CMSDK_APB_WATCHDOG) += cmsdk-apb-watchdog.o
common-obj-$(CONFIG_WDT_IB6300ESB) += wdt_i6300esb.o
common-obj-$(CONFIG_WDT_IB700) += wdt_ib700.o
common-obj-$(CONFIG_WDT_DIAG288) += wdt_diag288.o
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
new file mode 100644
index 0000000..eb79a73
--- /dev/null
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
@@ -0,0 +1,326 @@
+/*
+ * ARM CMSDK APB watchdog emulation
+ *
+ * Copyright (c) 2018 Linaro Limited
+ * Written by Peter Maydell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or
+ * (at your option) any later version.
+ */
+
+/*
+ * This is a model of the "APB watchdog" which is part of the Cortex-M
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "qapi/error.h"
+#include "qemu/main-loop.h"
+#include "sysemu/watchdog.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
+
+REG32(WDOGLOAD, 0x0)
+REG32(WDOGVALUE, 0x4)
+REG32(WDOGCONTROL, 0x8)
+ FIELD(WDOGCONTROL, INTEN, 0, 1)
+ FIELD(WDOGCONTROL, RESEN, 1, 1)
+#define R_WDOGCONTROL_VALID_MASK (R_WDOGCONTROL_INTEN_MASK | \
+ R_WDOGCONTROL_RESEN_MASK)
+REG32(WDOGINTCLR, 0xc)
+REG32(WDOGRIS, 0x10)
+ FIELD(WDOGRIS, INT, 0, 1)
+REG32(WDOGMIS, 0x14)
+REG32(WDOGLOCK, 0xc00)
+#define WDOG_UNLOCK_VALUE 0x1ACCE551
+REG32(WDOGITCR, 0xf00)
+ FIELD(WDOGITCR, ENABLE, 0, 1)
+#define R_WDOGITCR_VALID_MASK R_WDOGITCR_ENABLE_MASK
+REG32(WDOGITOP, 0xf04)
+ FIELD(WDOGITOP, WDOGRES, 0, 1)
+ FIELD(WDOGITOP, WDOGINT, 1, 1)
+#define R_WDOGITOP_VALID_MASK (R_WDOGITOP_WDOGRES_MASK | \
+ R_WDOGITOP_WDOGINT_MASK)
+REG32(PID4, 0xfd0)
+REG32(PID5, 0xfd4)
+REG32(PID6, 0xfd8)
+REG32(PID7, 0xfdc)
+REG32(PID0, 0xfe0)
+REG32(PID1, 0xfe4)
+REG32(PID2, 0xfe8)
+REG32(PID3, 0xfec)
+REG32(CID0, 0xff0)
+REG32(CID1, 0xff4)
+REG32(CID2, 0xff8)
+REG32(CID3, 0xffc)
+
+/* PID/CID values */
+static const int watchdog_id[] = {
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
+ 0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
+};
+
+static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
+{
+ /* Return masked interrupt status */
+ return s->intstatus && (s->control & R_WDOGCONTROL_INTEN_MASK);
+}
+
+static bool cmsdk_apb_watchdog_resetstatus(CMSDKAPBWatchdog *s)
+{
+ /* Return masked reset status */
+ return s->resetstatus && (s->control & R_WDOGCONTROL_RESEN_MASK);
+}
+
+static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
+{
+ bool wdogint;
+ bool wdogres;
+
+ if (s->itcr) {
+ wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
+ wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
+ } else {
+ wdogint = cmsdk_apb_watchdog_intstatus(s);
+ wdogres = cmsdk_apb_watchdog_resetstatus(s);
+ }
+
+ qemu_set_irq(s->wdogint, wdogint);
+ if (wdogres) {
+ watchdog_perform_action();
+ }
+}
+
+static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
+ uint64_t r;
+
+ switch (offset) {
+ case A_WDOGLOAD:
+ r = ptimer_get_limit(s->timer);
+ break;
+ case A_WDOGVALUE:
+ r = ptimer_get_count(s->timer);
+ break;
+ case A_WDOGCONTROL:
+ r = s->control;
+ break;
+ case A_WDOGRIS:
+ r = s->intstatus;
+ break;
+ case A_WDOGMIS:
+ r = cmsdk_apb_watchdog_intstatus(s);
+ break;
+ case A_WDOGLOCK:
+ r = s->lock;
+ break;
+ case A_WDOGITCR:
+ r = s->itcr;
+ break;
+ case A_PID4 ... A_CID3:
+ r = watchdog_id[(offset - A_PID4) / 4];
+ break;
+ case A_WDOGINTCLR:
+ case A_WDOGITOP:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "CMSDK APB watchdog read: read of WO offset %x\n",
+ (int)offset);
+ r = 0;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "CMSDK APB watchdog read: bad offset %x\n", (int)offset);
+ r = 0;
+ break;
+ }
+ trace_cmsdk_apb_watchdog_read(offset, r, size);
+ return r;
+}
+
+static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
+
+ trace_cmsdk_apb_watchdog_write(offset, value, size);
+
+ if (s->lock && offset != A_WDOGLOCK) {
+ /* Write access is disabled via WDOGLOCK */
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "CMSDK APB watchdog write: write to locked watchdog\n");
+ return;
+ }
+
+ switch (offset) {
+ case A_WDOGLOAD:
+ /*
+ * Reset the load value and the current count, and make sure
+ * we're counting.
+ */
+ ptimer_set_limit(s->timer, value, 1);
+ ptimer_run(s->timer, 0);
+ break;
+ case A_WDOGCONTROL:
+ s->control = value & R_WDOGCONTROL_VALID_MASK;
+ cmsdk_apb_watchdog_update(s);
+ break;
+ case A_WDOGINTCLR:
+ s->intstatus = 0;
+ ptimer_set_count(s->timer, ptimer_get_limit(s->timer));
+ cmsdk_apb_watchdog_update(s);
+ break;
+ case A_WDOGLOCK:
+ s->lock = (value != WDOG_UNLOCK_VALUE);
+ break;
+ case A_WDOGITCR:
+ s->itcr = value & R_WDOGITCR_VALID_MASK;
+ cmsdk_apb_watchdog_update(s);
+ break;
+ case A_WDOGITOP:
+ s->itop = value & R_WDOGITOP_VALID_MASK;
+ cmsdk_apb_watchdog_update(s);
+ break;
+ case A_WDOGVALUE:
+ case A_WDOGRIS:
+ case A_WDOGMIS:
+ case A_PID4 ... A_CID3:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "CMSDK APB watchdog write: write to RO offset 0x%x\n",
+ (int)offset);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "CMSDK APB watchdog write: bad offset 0x%x\n",
+ (int)offset);
+ break;
+ }
+}
+
+static const MemoryRegionOps cmsdk_apb_watchdog_ops = {
+ .read = cmsdk_apb_watchdog_read,
+ .write = cmsdk_apb_watchdog_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ /* byte/halfword accesses are just zero-padded on reads and writes */
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 4,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+};
+
+static void cmsdk_apb_watchdog_tick(void *opaque)
+{
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
+
+ if (!s->intstatus) {
+ /* Count expired for the first time: raise interrupt */
+ s->intstatus = R_WDOGRIS_INT_MASK;
+ } else {
+ /* Count expired for the second time: raise reset and stop clock */
+ s->resetstatus = 1;
+ ptimer_stop(s->timer);
+ }
+ cmsdk_apb_watchdog_update(s);
+}
+
+static void cmsdk_apb_watchdog_reset(DeviceState *dev)
+{
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
+
+ trace_cmsdk_apb_watchdog_reset();
+ s->control = 0;
+ s->intstatus = 0;
+ s->lock = 0;
+ s->itcr = 0;
+ s->itop = 0;
+ s->resetstatus = 0;
+ /* Set the limit and the count */
+ ptimer_set_limit(s->timer, 0xffffffff, 1);
+ ptimer_run(s->timer, 0);
+}
+
+static void cmsdk_apb_watchdog_init(Object *obj)
+{
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);
+
+ memory_region_init_io(&s->iomem, obj, &cmsdk_apb_watchdog_ops,
+ s, "cmsdk-apb-watchdog", 0x1000);
+ sysbus_init_mmio(sbd, &s->iomem);
+ sysbus_init_irq(sbd, &s->wdogint);
+}
+
+static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
+{
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
+ QEMUBH *bh;
+
+ if (s->wdogclk_frq == 0) {
+ error_setg(errp,
+ "CMSDK APB watchdog: wdogclk-frq property must be set");
+ return;
+ }
+
+ bh = qemu_bh_new(cmsdk_apb_watchdog_tick, s);
+ s->timer = ptimer_init(bh,
+ PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
+ PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
+
+ ptimer_set_freq(s->timer, s->wdogclk_frq);
+}
+
+static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
+ .name = "cmsdk-apb-watchdog",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
+ VMSTATE_UINT32(control, CMSDKAPBWatchdog),
+ VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
+ VMSTATE_UINT32(lock, CMSDKAPBWatchdog),
+ VMSTATE_UINT32(itcr, CMSDKAPBWatchdog),
+ VMSTATE_UINT32(itop, CMSDKAPBWatchdog),
+ VMSTATE_UINT32(resetstatus, CMSDKAPBWatchdog),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static Property cmsdk_apb_watchdog_properties[] = {
+ DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = cmsdk_apb_watchdog_realize;
+ dc->vmsd = &cmsdk_apb_watchdog_vmstate;
+ dc->reset = cmsdk_apb_watchdog_reset;
+ dc->props = cmsdk_apb_watchdog_properties;
+}
+
+static const TypeInfo cmsdk_apb_watchdog_info = {
+ .name = TYPE_CMSDK_APB_WATCHDOG,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(CMSDKAPBWatchdog),
+ .instance_init = cmsdk_apb_watchdog_init,
+ .class_init = cmsdk_apb_watchdog_class_init,
+};
+
+static void cmsdk_apb_watchdog_register_types(void)
+{
+ type_register_static(&cmsdk_apb_watchdog_info);
+}
+
+type_init(cmsdk_apb_watchdog_register_types);
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
new file mode 100644
index 0000000..fee9584
--- /dev/null
+++ b/hw/watchdog/trace-events
@@ -0,0 +1,6 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# hw/char/cmsdk_apb_watchdog.c
+cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
+cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"