aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-01-19 11:39:38 +0000
committerPeter Maydell <peter.maydell@linaro.org>2024-01-19 11:39:38 +0000
commit3f2a357b95845ea0bf7463eff6661e43b97d1afc (patch)
treeabc918e3c0e776d37aac6801a1bca1c672f8c82d /hw
parente566fb85939bec58a75f22ff9d80d0bac8717806 (diff)
parent7ec5d7d91215815e885d2b38e62256e8fd8e2bce (diff)
Merge tag 'hw-cpus-20240119' of https://github.com/philmd/qemu into staging
HW core patch queue . Deprecate unmaintained SH-4 models (Samuel) . HPET: Convert DPRINTF calls to trace events (Daniel) . Implement buffered block writes in Intel PFlash (Gerd) . Ignore ELF loadable segments with zero size (Bin) . ESP/NCR53C9x: PCI DMA fixes (Mark) . PIIX: Simplify Xen PCI IRQ routing (Bernhard) . Restrict CPU 'start-powered-off' property to sysemu (Phil) . target/alpha: Only build sys_helper.c on system emulation (Phil) . target/xtensa: Use generic instruction breakpoint API & add test (Max) . Restrict icount to system emulation (Phil) . Do not set CPUState TCG-specific flags in non-TCG accels (Phil) . Cleanup TCG tb_invalidate API (Phil) . Correct LoongArch/KVM include path (Bibo) . Do not ignore throttle errors in crypto backends (Phil) . MAINTAINERS updates (Raphael, Zhao) # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmWqXbkACgkQ4+MsLN6t # wN6VVBAAkP/Bs2JfQYobPZVV868wceM97KeUJMXP2YWf6dSLpHRCQN5KtuJcACM9 # y3k3R7nMeVJSGmzl/1gF1G9JhjoCLoVLX/ejeBppv4Wq//9sEdggaQfdCwkhWw2o # IK/gPjTZpimE7Er4hPlxmuhSRuM1MX4duKFRRfuZpE7XY14Y7/Hk12VIG7LooO0x # 2Sl8CaU0DN7CWmRVDoUkwVx7JBy28UVarRDsgpBim7oKmjjBFnCJkH6B6NJXEiYr # z1BmIcHa87S09kG1ek+y8aZpG9iPC7nUWjPIQyJGhnfrnBuO7hQHwCLIjHHp5QBR # BoMr8YQNTI34/M/D8pBfg96LrGDjkQOfwRyRddkMP/jJcNPMAPMNGbfVaIrfij1e # T+jFF4gQenOvy1XKCY3Uk/a11P3tIRFBEeOlzzQg4Aje9W2MhUNwK2HTlRfBbrRr # V30R764FDmHlsyOu6/E3jqp4GVCgryF1bglPOBjVEU5uytbQTP8jshIpGVnxBbF+ # OpFwtsoDbsousNKVcO5+B0mlHcB9Ru9h11M5/YD/jfLMk95Ga90JGdgYpqQ5tO5Y # aqQhKfCKbfgKuKhysxpsdWAwHZzVrlSf+UrObF0rl2lMXXfcppjCqNaw4QJ0oedc # DNBxTPcCE2vWhUzP3A60VH7jLh4nLaqSTrxxQKkbx+Je1ERGrxs= # =KmQh # -----END PGP SIGNATURE----- # gpg: Signature made Fri 19 Jan 2024 11:32:09 GMT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full] # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'hw-cpus-20240119' of https://github.com/philmd/qemu: (36 commits) configure: Add linux header compile support for LoongArch MAINTAINERS: Update hw/core/cpu.c entry MAINTAINERS: Update Raphael Norwitz email hw/elf_ops: Ignore loadable segments with zero size hw/scsi/esp-pci: set DMA_STAT_BCMBLT when BLAST command issued hw/scsi/esp-pci: synchronise setting of DMA_STAT_DONE with ESP completion interrupt hw/scsi/esp-pci: generate PCI interrupt from separate ESP and PCI sources hw/scsi/esp-pci: use correct address register for PCI DMA transfers target/riscv: Rename tcg_cpu_FOO() to include 'riscv' target/i386: Rename tcg_cpu_FOO() to include 'x86' hw/s390x: Rename cpu_class_init() to include 'sclp' hw/core/cpu: Rename cpu_class_init() to include 'common' accel: Rename accel_init_ops_interfaces() to include 'system' cpus: Restrict 'start-powered-off' property to system emulation system/watchpoint: Move TCG specific code to accel/tcg/ system/replay: Restrict icount to system emulation hw/pflash: implement update buffer for block writes hw/pflash: use ldn_{be,le}_p and stn_{be,le}_p hw/pflash: refactor pflash_data_write() hw/i386/pc_piix: Make piix_intx_routing_notifier_xen() more device independent ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/block/pflash_cfi01.c171
-rw-r--r--hw/block/pflash_cfi02.c2
-rw-r--r--hw/block/tc58128.c1
-rw-r--r--hw/block/trace-events7
-rw-r--r--hw/core/cpu-common.c4
-rw-r--r--hw/i386/pc_piix.c9
-rw-r--r--hw/s390x/sclpcpu.c4
-rw-r--r--hw/scsi/esp-pci.c61
-rw-r--r--hw/sh4/shix.c1
-rw-r--r--hw/timer/hpet.c55
-rw-r--r--hw/timer/trace-events15
11 files changed, 184 insertions, 146 deletions
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 3e2dc08bd7..f956f8bcf7 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -80,16 +80,39 @@ struct PFlashCFI01 {
uint16_t ident3;
uint8_t cfi_table[0x52];
uint64_t counter;
- unsigned int writeblock_size;
+ uint32_t writeblock_size;
MemoryRegion mem;
char *name;
void *storage;
VMChangeStateEntry *vmstate;
bool old_multiple_chip_handling;
+
+ /* block update buffer */
+ unsigned char *blk_bytes;
+ uint32_t blk_offset;
};
static int pflash_post_load(void *opaque, int version_id);
+static bool pflash_blk_write_state_needed(void *opaque)
+{
+ PFlashCFI01 *pfl = opaque;
+
+ return (pfl->blk_offset != -1);
+}
+
+static const VMStateDescription vmstate_pflash_blk_write = {
+ .name = "pflash_cfi01_blk_write",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = pflash_blk_write_state_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_VBUFFER_UINT32(blk_bytes, PFlashCFI01, 0, NULL, writeblock_size),
+ VMSTATE_UINT32(blk_offset, PFlashCFI01),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static const VMStateDescription vmstate_pflash = {
.name = "pflash_cfi01",
.version_id = 1,
@@ -101,6 +124,10 @@ static const VMStateDescription vmstate_pflash = {
VMSTATE_UINT8(status, PFlashCFI01),
VMSTATE_UINT64(counter, PFlashCFI01),
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription * const []) {
+ &vmstate_pflash_blk_write,
+ NULL
}
};
@@ -225,34 +252,10 @@ static uint32_t pflash_data_read(PFlashCFI01 *pfl, hwaddr offset,
uint32_t ret;
p = pfl->storage;
- switch (width) {
- case 1:
- ret = p[offset];
- break;
- case 2:
- if (be) {
- ret = p[offset] << 8;
- ret |= p[offset + 1];
- } else {
- ret = p[offset];
- ret |= p[offset + 1] << 8;
- }
- break;
- case 4:
- if (be) {
- ret = p[offset] << 24;
- ret |= p[offset + 1] << 16;
- ret |= p[offset + 2] << 8;
- ret |= p[offset + 3];
- } else {
- ret = p[offset];
- ret |= p[offset + 1] << 8;
- ret |= p[offset + 2] << 16;
- ret |= p[offset + 3] << 24;
- }
- break;
- default:
- abort();
+ if (be) {
+ ret = ldn_be_p(p + offset, width);
+ } else {
+ ret = ldn_le_p(p + offset, width);
}
trace_pflash_data_read(pfl->name, offset, width, ret);
return ret;
@@ -400,40 +403,61 @@ static void pflash_update(PFlashCFI01 *pfl, int offset,
}
}
+/* copy current flash content to block update buffer */
+static void pflash_blk_write_start(PFlashCFI01 *pfl, hwaddr offset)
+{
+ hwaddr mask = ~(pfl->writeblock_size - 1);
+
+ trace_pflash_write_block_start(pfl->name, pfl->counter);
+ pfl->blk_offset = offset & mask;
+ memcpy(pfl->blk_bytes, pfl->storage + pfl->blk_offset,
+ pfl->writeblock_size);
+}
+
+/* commit block update buffer changes */
+static void pflash_blk_write_flush(PFlashCFI01 *pfl)
+{
+ g_assert(pfl->blk_offset != -1);
+ trace_pflash_write_block_flush(pfl->name);
+ memcpy(pfl->storage + pfl->blk_offset, pfl->blk_bytes,
+ pfl->writeblock_size);
+ pflash_update(pfl, pfl->blk_offset, pfl->writeblock_size);
+ pfl->blk_offset = -1;
+}
+
+/* discard block update buffer changes */
+static void pflash_blk_write_abort(PFlashCFI01 *pfl)
+{
+ trace_pflash_write_block_abort(pfl->name);
+ pfl->blk_offset = -1;
+}
+
static inline void pflash_data_write(PFlashCFI01 *pfl, hwaddr offset,
uint32_t value, int width, int be)
{
- uint8_t *p = pfl->storage;
+ uint8_t *p;
- trace_pflash_data_write(pfl->name, offset, width, value, pfl->counter);
- switch (width) {
- case 1:
- p[offset] = value;
- break;
- case 2:
- if (be) {
- p[offset] = value >> 8;
- p[offset + 1] = value;
- } else {
- p[offset] = value;
- p[offset + 1] = value >> 8;
- }
- break;
- case 4:
- if (be) {
- p[offset] = value >> 24;
- p[offset + 1] = value >> 16;
- p[offset + 2] = value >> 8;
- p[offset + 3] = value;
- } else {
- p[offset] = value;
- p[offset + 1] = value >> 8;
- p[offset + 2] = value >> 16;
- p[offset + 3] = value >> 24;
+ if (pfl->blk_offset != -1) {
+ /* block write: redirect writes to block update buffer */
+ if ((offset < pfl->blk_offset) ||
+ (offset + width > pfl->blk_offset + pfl->writeblock_size)) {
+ pfl->status |= 0x10; /* Programming error */
+ return;
}
- break;
+ trace_pflash_data_write_block(pfl->name, offset, width, value,
+ pfl->counter);
+ p = pfl->blk_bytes + (offset - pfl->blk_offset);
+ } else {
+ /* write directly to storage */
+ trace_pflash_data_write(pfl->name, offset, width, value);
+ p = pfl->storage + offset;
}
+ if (be) {
+ stn_be_p(p, width, value);
+ } else {
+ stn_le_p(p, width, value);
+ }
}
static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
@@ -548,9 +572,9 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
} else {
value = extract32(value, 0, pfl->bank_width * 8);
}
- trace_pflash_write_block(pfl->name, value);
pfl->counter = value;
pfl->wcycle++;
+ pflash_blk_write_start(pfl, offset);
break;
case 0x60:
if (cmd == 0xd0) {
@@ -581,12 +605,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
switch (pfl->cmd) {
case 0xe8: /* Block write */
/* FIXME check @offset, @width */
- if (!pfl->ro) {
- /*
- * FIXME writing straight to memory is *wrong*. We
- * should write to a buffer, and flush it to memory
- * only on confirm command (see below).
- */
+ if (!pfl->ro && (pfl->blk_offset != -1)) {
pflash_data_write(pfl, offset, value, width, be);
} else {
pfl->status |= 0x10; /* Programming error */
@@ -595,18 +614,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
pfl->status |= 0x80;
if (!pfl->counter) {
- hwaddr mask = pfl->writeblock_size - 1;
- mask = ~mask;
-
trace_pflash_write(pfl->name, "block write finished");
pfl->wcycle++;
- if (!pfl->ro) {
- /* Flush the entire write buffer onto backing storage. */
- /* FIXME premature! */
- pflash_update(pfl, offset & mask, pfl->writeblock_size);
- } else {
- pfl->status |= 0x10; /* Programming error */
- }
}
pfl->counter--;
@@ -618,20 +627,17 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
case 3: /* Confirm mode */
switch (pfl->cmd) {
case 0xe8: /* Block write */
- if (cmd == 0xd0) {
- /* FIXME this is where we should write out the buffer */
+ if ((cmd == 0xd0) && !(pfl->status & 0x10)) {
+ pflash_blk_write_flush(pfl);
pfl->wcycle = 0;
pfl->status |= 0x80;
} else {
- qemu_log_mask(LOG_UNIMP,
- "%s: Aborting write to buffer not implemented,"
- " the data is already written to storage!\n"
- "Flash device reset into READ mode.\n",
- __func__);
+ pflash_blk_write_abort(pfl);
goto mode_read_array;
}
break;
default:
+ pflash_blk_write_abort(pfl);
goto error_flash;
}
break;
@@ -865,6 +871,9 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
pfl->cmd = 0x00;
pfl->status = 0x80; /* WSM ready */
pflash_cfi01_fill_cfi_table(pfl);
+
+ pfl->blk_bytes = g_malloc(pfl->writeblock_size);
+ pfl->blk_offset = -1;
}
static void pflash_cfi01_system_reset(DeviceState *dev)
@@ -884,6 +893,8 @@ static void pflash_cfi01_system_reset(DeviceState *dev)
* This model deliberately ignores this delay.
*/
pfl->status = 0x80;
+
+ pfl->blk_offset = -1;
}
static Property pflash_cfi01_properties[] = {
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 2a99b286b0..6fa56f14c0 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -546,7 +546,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
}
goto reset_flash;
}
- trace_pflash_data_write(pfl->name, offset, width, value, 0);
+ trace_pflash_data_write(pfl->name, offset, width, value);
if (!pfl->ro) {
p = (uint8_t *)pfl->storage + offset;
if (pfl->be) {
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
index d350126b27..6944cf58fa 100644
--- a/hw/block/tc58128.c
+++ b/hw/block/tc58128.c
@@ -202,6 +202,7 @@ static sh7750_io_device tc58128 = {
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
{
+ warn_report_once("The TC58128 flash device is deprecated");
init_dev(&tc58128_devs[0], zone1);
init_dev(&tc58128_devs[1], zone2);
return sh7750_register_io_device(s, &tc58128);
diff --git a/hw/block/trace-events b/hw/block/trace-events
index bab21d3a1c..cc9a9f2460 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -12,7 +12,8 @@ fdctrl_tc_pulse(int level) "TC pulse: %u"
pflash_chip_erase_invalid(const char *name, uint64_t offset) "%s: chip erase: invalid address 0x%" PRIx64
pflash_chip_erase_start(const char *name) "%s: start chip erase"
pflash_data_read(const char *name, uint64_t offset, unsigned size, uint32_t value) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x"
-pflash_data_write(const char *name, uint64_t offset, unsigned size, uint32_t value, uint64_t counter) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x counter:0x%016"PRIx64
+pflash_data_write(const char *name, uint64_t offset, unsigned size, uint32_t value) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x"
+pflash_data_write_block(const char *name, uint64_t offset, unsigned size, uint32_t value, uint64_t counter) "%s: data offset:0x%04"PRIx64" size:%u value:0x%04x counter:0x%016"PRIx64
pflash_device_id(const char *name, uint16_t id) "%s: read device ID: 0x%04x"
pflash_device_info(const char *name, uint64_t offset) "%s: read device information offset:0x%04" PRIx64
pflash_erase_complete(const char *name) "%s: sector erase complete"
@@ -32,7 +33,9 @@ pflash_unlock0_failed(const char *name, uint64_t offset, uint8_t cmd, uint16_t a
pflash_unlock1_failed(const char *name, uint64_t offset, uint8_t cmd) "%s: unlock0 failed 0x%" PRIx64 " 0x%02x"
pflash_unsupported_device_configuration(const char *name, uint8_t width, uint8_t max) "%s: unsupported device configuration: device_width:%d max_device_width:%d"
pflash_write(const char *name, const char *str) "%s: %s"
-pflash_write_block(const char *name, uint32_t value) "%s: block write: bytes:0x%x"
+pflash_write_block_start(const char *name, uint32_t value) "%s: block write start: bytes:0x%x"
+pflash_write_block_flush(const char *name) "%s: block write flush"
+pflash_write_block_abort(const char *name) "%s: block write abort"
pflash_write_block_erase(const char *name, uint64_t offset, uint64_t len) "%s: block erase offset:0x%" PRIx64 " bytes:0x%" PRIx64
pflash_write_failed(const char *name, uint64_t offset, uint8_t cmd) "%s: command failed 0x%" PRIx64 " 0x%02x"
pflash_write_invalid(const char *name, uint8_t cmd) "%s: invalid write for command 0x%02x"
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
index 3ccfe882e2..67db07741d 100644
--- a/hw/core/cpu-common.c
+++ b/hw/core/cpu-common.c
@@ -273,7 +273,7 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu)
return cpu->cpu_index;
}
-static void cpu_class_init(ObjectClass *klass, void *data)
+static void cpu_common_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
@@ -304,7 +304,7 @@ static const TypeInfo cpu_type_info = {
.instance_finalize = cpu_common_finalize,
.abstract = true,
.class_size = sizeof(CPUClass),
- .class_init = cpu_class_init,
+ .class_init = cpu_common_class_init,
};
static void cpu_register_types(void)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 042c13cdbc..abfcfe4d2b 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -92,13 +92,10 @@ static void piix_intx_routing_notifier_xen(PCIDevice *dev)
{
int i;
- /* Scan for updates to PCI link routes (0x60-0x63). */
+ /* Scan for updates to PCI link routes. */
for (i = 0; i < PIIX_NUM_PIRQS; i++) {
- uint8_t v = dev->config_read(dev, PIIX_PIRQCA + i, 1);
- if (v & 0x80) {
- v = 0;
- }
- v &= 0xf;
+ const PCIINTxRoute route = pci_device_route_intx_to_irq(dev, i);
+ const uint8_t v = route.mode == PCI_INTX_ENABLED ? route.irq : 0;
xen_set_pci_link_route(i, v);
}
}
diff --git a/hw/s390x/sclpcpu.c b/hw/s390x/sclpcpu.c
index f2b1a4b037..fa79891f5a 100644
--- a/hw/s390x/sclpcpu.c
+++ b/hw/s390x/sclpcpu.c
@@ -73,7 +73,7 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
return 1;
}
-static void cpu_class_init(ObjectClass *oc, void *data)
+static void sclp_cpu_class_init(ObjectClass *oc, void *data)
{
SCLPEventClass *k = SCLP_EVENT_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
@@ -94,7 +94,7 @@ static const TypeInfo sclp_cpu_info = {
.name = TYPE_SCLP_CPU_HOTPLUG,
.parent = TYPE_SCLP_EVENT,
.instance_size = sizeof(SCLPEvent),
- .class_init = cpu_class_init,
+ .class_init = sclp_cpu_class_init,
.class_size = sizeof(SCLPEventClass),
};
diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index 93b3429e0f..42d9d2e483 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -77,6 +77,41 @@ struct PCIESPState {
ESPState esp;
};
+static void esp_pci_update_irq(PCIESPState *pci)
+{
+ int scsi_level = !!(pci->dma_regs[DMA_STAT] & DMA_STAT_SCSIINT);
+ int dma_level = (pci->dma_regs[DMA_CMD] & DMA_CMD_INTE_D) ?
+ !!(pci->dma_regs[DMA_STAT] & DMA_STAT_DONE) : 0;
+ int level = scsi_level || dma_level;
+
+ pci_set_irq(PCI_DEVICE(pci), level);
+}
+
+static void esp_irq_handler(void *opaque, int irq_num, int level)
+{
+ PCIESPState *pci = PCI_ESP(opaque);
+
+ if (level) {
+ pci->dma_regs[DMA_STAT] |= DMA_STAT_SCSIINT;
+
+ /*
+ * If raising the ESP IRQ to indicate end of DMA transfer, set
+ * DMA_STAT_DONE at the same time. In theory this should be done in
+ * esp_pci_dma_memory_rw(), however there is a delay between setting
+ * DMA_STAT_DONE and the ESP IRQ arriving which is visible to the
+ * guest that can cause confusion e.g. Linux
+ */
+ if ((pci->dma_regs[DMA_CMD] & DMA_CMD_MASK) == 0x3 &&
+ pci->dma_regs[DMA_WBC] == 0) {
+ pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
+ }
+ } else {
+ pci->dma_regs[DMA_STAT] &= ~DMA_STAT_SCSIINT;
+ }
+
+ esp_pci_update_irq(pci);
+}
+
static void esp_pci_handle_idle(PCIESPState *pci, uint32_t val)
{
ESPState *s = &pci->esp;
@@ -89,6 +124,7 @@ static void esp_pci_handle_blast(PCIESPState *pci, uint32_t val)
{
trace_esp_pci_dma_blast(val);
qemu_log_mask(LOG_UNIMP, "am53c974: cmd BLAST not implemented\n");
+ pci->dma_regs[DMA_STAT] |= DMA_STAT_BCMBLT;
}
static void esp_pci_handle_abort(PCIESPState *pci, uint32_t val)
@@ -151,6 +187,7 @@ static void esp_pci_dma_write(PCIESPState *pci, uint32_t saddr, uint32_t val)
/* clear some bits on write */
uint32_t mask = DMA_STAT_ERROR | DMA_STAT_ABORT | DMA_STAT_DONE;
pci->dma_regs[DMA_STAT] &= ~(val & mask);
+ esp_pci_update_irq(pci);
}
break;
default:
@@ -161,17 +198,14 @@ static void esp_pci_dma_write(PCIESPState *pci, uint32_t saddr, uint32_t val)
static uint32_t esp_pci_dma_read(PCIESPState *pci, uint32_t saddr)
{
- ESPState *s = &pci->esp;
uint32_t val;
val = pci->dma_regs[saddr];
if (saddr == DMA_STAT) {
- if (s->rregs[ESP_RSTAT] & STAT_INT) {
- val |= DMA_STAT_SCSIINT;
- }
if (!(pci->sbac & SBAC_STATUS)) {
pci->dma_regs[DMA_STAT] &= ~(DMA_STAT_ERROR | DMA_STAT_ABORT |
DMA_STAT_DONE);
+ esp_pci_update_irq(pci);
}
}
@@ -275,7 +309,7 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len,
qemu_log_mask(LOG_UNIMP, "am53c974: MDL transfer not implemented\n");
}
- addr = pci->dma_regs[DMA_SPA];
+ addr = pci->dma_regs[DMA_WAC];
if (pci->dma_regs[DMA_WBC] < len) {
len = pci->dma_regs[DMA_WBC];
}
@@ -285,9 +319,6 @@ static void esp_pci_dma_memory_rw(PCIESPState *pci, uint8_t *buf, int len,
/* update status registers */
pci->dma_regs[DMA_WBC] -= len;
pci->dma_regs[DMA_WAC] += len;
- if (pci->dma_regs[DMA_WBC] == 0) {
- pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
- }
}
static void esp_pci_dma_memory_read(void *opaque, uint8_t *buf, int len)
@@ -342,23 +373,13 @@ static const VMStateDescription vmstate_esp_pci_scsi = {
}
};
-static void esp_pci_command_complete(SCSIRequest *req, size_t resid)
-{
- ESPState *s = req->hba_private;
- PCIESPState *pci = container_of(s, PCIESPState, esp);
-
- esp_command_complete(req, resid);
- pci->dma_regs[DMA_WBC] = 0;
- pci->dma_regs[DMA_STAT] |= DMA_STAT_DONE;
-}
-
static const struct SCSIBusInfo esp_pci_scsi_info = {
.tcq = false,
.max_target = ESP_MAX_DEVS,
.max_lun = 7,
.transfer_data = esp_transfer_data,
- .complete = esp_pci_command_complete,
+ .complete = esp_command_complete,
.cancel = esp_request_cancelled,
};
@@ -386,7 +407,7 @@ static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp)
"esp-io", 0x80);
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
- s->irq = pci_allocate_irq(dev);
+ s->irq = qemu_allocate_irq(esp_irq_handler, pci, 0);
scsi_bus_init(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info);
}
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index aa812512f0..eb3150b5bc 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -80,6 +80,7 @@ static void shix_machine_init(MachineClass *mc)
mc->init = shix_init;
mc->is_default = true;
mc->default_cpu_type = TYPE_SH7750R_CPU;
+ mc->deprecation_reason = "old and unmaintained";
}
DEFINE_MACHINE("shix", shix_machine_init)
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index f2f1580f81..1672faa4f2 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -39,13 +39,7 @@
#include "hw/timer/i8254.h"
#include "exec/address-spaces.h"
#include "qom/object.h"
-
-//#define HPET_DEBUG
-#ifdef HPET_DEBUG
-#define DPRINTF printf
-#else
-#define DPRINTF(...)
-#endif
+#include "trace.h"
#define HPET_MSI_SUPPORT 0
@@ -431,7 +425,7 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
HPETState *s = opaque;
uint64_t cur_tick, index;
- DPRINTF("qemu: Enter hpet_ram_readl at %" PRIx64 "\n", addr);
+ trace_hpet_ram_read(addr);
index = addr;
/*address range of all TN regs*/
if (index >= 0x100 && index <= 0x3ff) {
@@ -439,7 +433,7 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
HPETTimer *timer = &s->timer[timer_id];
if (timer_id > s->num_timers) {
- DPRINTF("qemu: timer id out of range\n");
+ trace_hpet_timer_id_out_of_range(timer_id);
return 0;
}
@@ -457,7 +451,7 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
case HPET_TN_ROUTE + 4:
return timer->fsb >> 32;
default:
- DPRINTF("qemu: invalid hpet_ram_readl\n");
+ trace_hpet_ram_read_invalid();
break;
}
} else {
@@ -469,7 +463,7 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
case HPET_CFG:
return s->config;
case HPET_CFG + 4:
- DPRINTF("qemu: invalid HPET_CFG + 4 hpet_ram_readl\n");
+ trace_hpet_invalid_hpet_cfg(4);
return 0;
case HPET_COUNTER:
if (hpet_enabled(s)) {
@@ -477,7 +471,7 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
} else {
cur_tick = s->hpet_counter;
}
- DPRINTF("qemu: reading counter = %" PRIx64 "\n", cur_tick);
+ trace_hpet_ram_read_reading_counter(0, cur_tick);
return cur_tick;
case HPET_COUNTER + 4:
if (hpet_enabled(s)) {
@@ -485,12 +479,12 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr,
} else {
cur_tick = s->hpet_counter;
}
- DPRINTF("qemu: reading counter + 4 = %" PRIx64 "\n", cur_tick);
+ trace_hpet_ram_read_reading_counter(4, cur_tick);
return cur_tick >> 32;
case HPET_STATUS:
return s->isr;
default:
- DPRINTF("qemu: invalid hpet_ram_readl\n");
+ trace_hpet_ram_read_invalid();
break;
}
}
@@ -504,8 +498,7 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
HPETState *s = opaque;
uint64_t old_val, new_val, val, index;
- DPRINTF("qemu: Enter hpet_ram_writel at %" PRIx64 " = 0x%" PRIx64 "\n",
- addr, value);
+ trace_hpet_ram_write(addr, value);
index = addr;
old_val = hpet_ram_read(opaque, addr, 4);
new_val = value;
@@ -515,14 +508,14 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
uint8_t timer_id = (addr - 0x100) / 0x20;
HPETTimer *timer = &s->timer[timer_id];
- DPRINTF("qemu: hpet_ram_writel timer_id = 0x%x\n", timer_id);
+ trace_hpet_ram_write_timer_id(timer_id);
if (timer_id > s->num_timers) {
- DPRINTF("qemu: timer id out of range\n");
+ trace_hpet_timer_id_out_of_range(timer_id);
return;
}
switch ((addr - 0x100) % 0x20) {
case HPET_TN_CFG:
- DPRINTF("qemu: hpet_ram_writel HPET_TN_CFG\n");
+ trace_hpet_ram_write_tn_cfg();
if (activating_bit(old_val, new_val, HPET_TN_FSB_ENABLE)) {
update_irq(timer, 0);
}
@@ -540,10 +533,10 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
}
break;
case HPET_TN_CFG + 4: // Interrupt capabilities
- DPRINTF("qemu: invalid HPET_TN_CFG+4 write\n");
+ trace_hpet_ram_write_invalid_tn_cfg(4);
break;
case HPET_TN_CMP: // comparator register
- DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP\n");
+ trace_hpet_ram_write_tn_cmp(0);
if (timer->config & HPET_TN_32BIT) {
new_val = (uint32_t)new_val;
}
@@ -566,7 +559,7 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
}
break;
case HPET_TN_CMP + 4: // comparator register high order
- DPRINTF("qemu: hpet_ram_writel HPET_TN_CMP + 4\n");
+ trace_hpet_ram_write_tn_cmp(4);
if (!timer_is_periodic(timer)
|| (timer->config & HPET_TN_SETVAL)) {
timer->cmp = (timer->cmp & 0xffffffffULL) | new_val << 32;
@@ -591,7 +584,7 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
timer->fsb = (new_val << 32) | (timer->fsb & 0xffffffff);
break;
default:
- DPRINTF("qemu: invalid hpet_ram_writel\n");
+ trace_hpet_ram_write_invalid();
break;
}
return;
@@ -631,7 +624,7 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
}
break;
case HPET_CFG + 4:
- DPRINTF("qemu: invalid HPET_CFG+4 write\n");
+ trace_hpet_invalid_hpet_cfg(4);
break;
case HPET_STATUS:
val = new_val & s->isr;
@@ -643,24 +636,20 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
break;
case HPET_COUNTER:
if (hpet_enabled(s)) {
- DPRINTF("qemu: Writing counter while HPET enabled!\n");
+ trace_hpet_ram_write_counter_write_while_enabled();
}
s->hpet_counter =
(s->hpet_counter & 0xffffffff00000000ULL) | value;
- DPRINTF("qemu: HPET counter written. ctr = 0x%" PRIx64 " -> "
- "%" PRIx64 "\n", value, s->hpet_counter);
+ trace_hpet_ram_write_counter_written(0, value, s->hpet_counter);
break;
case HPET_COUNTER + 4:
- if (hpet_enabled(s)) {
- DPRINTF("qemu: Writing counter while HPET enabled!\n");
- }
+ trace_hpet_ram_write_counter_write_while_enabled();
s->hpet_counter =
(s->hpet_counter & 0xffffffffULL) | (((uint64_t)value) << 32);
- DPRINTF("qemu: HPET counter + 4 written. ctr = 0x%" PRIx64 " -> "
- "%" PRIx64 "\n", value, s->hpet_counter);
+ trace_hpet_ram_write_counter_written(4, value, s->hpet_counter);
break;
default:
- DPRINTF("qemu: invalid hpet_ram_writel\n");
+ trace_hpet_ram_write_invalid();
break;
}
}
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index 8145e18e3d..de769f4b71 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -99,3 +99,18 @@ sifive_pwm_write(uint64_t data, uint64_t offset) "Write 0x%" PRIx64 " at address
sh_timer_start_stop(int enable, int current) "%d (%d)"
sh_timer_read(uint64_t offset) "tmu012_read 0x%" PRIx64
sh_timer_write(uint64_t offset, uint64_t value) "tmu012_write 0x%" PRIx64 " 0x%08" PRIx64
+
+# hpet.c
+hpet_timer_id_out_of_range(uint8_t timer_id) "timer id out of range: 0x%" PRIx8
+hpet_invalid_hpet_cfg(uint8_t reg_off) "invalid HPET_CFG + %u" PRIx8
+hpet_ram_read(uint64_t addr) "enter hpet_ram_readl at 0x%" PRIx64
+hpet_ram_read_reading_counter(uint8_t reg_off, uint64_t cur_tick) "reading counter + %" PRIu8 " = 0x%" PRIx64
+hpet_ram_read_invalid(void) "invalid hpet_ram_readl"
+hpet_ram_write(uint64_t addr, uint64_t value) "enter hpet_ram_writel at 0x%" PRIx64 " = 0x%" PRIx64
+hpet_ram_write_timer_id(uint64_t timer_id) "hpet_ram_writel timer_id = 0x%" PRIx64
+hpet_ram_write_tn_cfg(void) "hpet_ram_writel HPET_TN_CFG"
+hpet_ram_write_invalid_tn_cfg(uint8_t reg_off) "invalid HPET_TN_CFG + %" PRIu8 " write"
+hpet_ram_write_tn_cmp(uint8_t reg_off) "hpet_ram_writel HPET_TN_CMP + %" PRIu8
+hpet_ram_write_invalid(void) "invalid hpet_ram_writel"
+hpet_ram_write_counter_write_while_enabled(void) "Writing counter while HPET enabled!"
+hpet_ram_write_counter_written(uint8_t reg_off, uint64_t value, uint64_t counter) "HPET counter + %" PRIu8 "written. crt = 0x%" PRIx64 " -> 0x%" PRIx64