The BCM2835 AUX UART is compatible with the 16650 model, when
the registers belong the the 16650 block, use its trace events,
else use bcm2835_aux_read/write.
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
hw/char/bcm2835_aux.c | 55 +++++++++++++++++++++++++++++++------------
hw/char/trace-events | 4 ++++
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index a6fc1bf152..b26a255630 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -27,6 +27,7 @@
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
+#include "trace.h"
#define AUX_IRQ 0x0
#define AUX_ENABLES 0x4
@@ -62,17 +63,24 @@ static void bcm2835_aux_update(BCM2835AuxState *s)
qemu_set_irq(s->irq, s->iir != 0);
}
+static bool is_16650(hwaddr offset)
+{
+ return offset >= AUX_MU_IO_REG && offset < AUX_MU_CNTL_REG;
+}
+
static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
{
BCM2835AuxState *s = opaque;
- uint32_t c, res;
+ uint32_t c, res = 0;
switch (offset) {
case AUX_IRQ:
- return s->iir != 0;
+ res = s->iir != 0;
+ break;
case AUX_ENABLES:
- return 1; /* mini UART permanently enabled */
+ res = 1; /* mini UART permanently enabled */
+ break;
case AUX_MU_IO_REG:
/* "DLAB bit set means access baudrate register" is NYI */
@@ -85,11 +93,13 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
}
qemu_chr_fe_accept_input(&s->chr);
bcm2835_aux_update(s);
- return c;
+ res = c;
+ break;
case AUX_MU_IER_REG:
/* "DLAB bit set means access baudrate register" is NYI */
- return 0xc0 | s->ier; /* FIFO enables always read 1 */
+ res = 0xc0 | s->ier; /* FIFO enables always read 1 */
+ break;
case AUX_MU_IIR_REG:
res = 0xc0; /* FIFO enables */
@@ -105,33 +115,34 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
if (s->iir == 0) {
res |= 0x1;
}
- return res;
+ break;
case AUX_MU_LCR_REG:
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_LCR_REG unsupported\n", __func__);
- return 0;
+ break;
case AUX_MU_MCR_REG:
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MCR_REG unsupported\n", __func__);
- return 0;
+ break;
case AUX_MU_LSR_REG:
res = 0x60; /* tx idle, empty */
if (s->read_count != 0) {
res |= 0x1;
}
- return res;
+ break;
case AUX_MU_MSR_REG:
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_MSR_REG unsupported\n", __func__);
- return 0;
+ break;
case AUX_MU_SCRATCH:
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_SCRATCH unsupported\n", __func__);
- return 0;
+ break;
case AUX_MU_CNTL_REG:
- return 0x3; /* tx, rx enabled */
+ res = 0x3; /* tx, rx enabled */
+ break;
case AUX_MU_STAT_REG:
res = 0x30e; /* space in the output buffer, empty tx fifo, idle tx/rx */
@@ -140,17 +151,25 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size)
assert(s->read_count < BCM2835_AUX_RX_FIFO_LEN);
res |= ((uint32_t)s->read_count) << 16; /* rx fifo fill level */
}
- return res;
+ break;
case AUX_MU_BAUD_REG:
qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_BAUD_REG unsupported\n", __func__);
- return 0;
+ break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
__func__, offset);
- return 0;
+ break;
}
+
+ if (is_16650(offset)) {
+ trace_serial_ioport_read((offset & 0x1f) >> 2, res);
+ } else {
+ trace_bcm2835_aux_read(offset, res);
+ }
+
+ return res;
}
static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
@@ -159,6 +178,12 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value,
BCM2835AuxState *s = opaque;
unsigned char ch;
+ if (is_16650(offset)) {
+ trace_serial_ioport_write((offset & 0x1f) >> 2, value);
+ } else {
+ trace_bcm2835_aux_write(offset, value);
+ }
+
switch (offset) {
case AUX_ENABLES:
if (value != 1) {
diff --git a/hw/char/trace-events b/hw/char/trace-events
index 2ce7f2f998..a7d477ab1e 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -1,5 +1,9 @@
# See docs/devel/tracing.txt for syntax documentation.
+# bcm2835_aux.c
+bcm2835_aux_read(uint64_t addr, uint32_t value) "read addr 0x%"PRIx64" value 0x%x"
+bcm2835_aux_write(uint64_t addr, uint32_t value) "read addr 0x%"PRIx64" value 0x%x"
+
# parallel.c
parallel_ioport_read(const char *desc, uint16_t addr, uint8_t value) "read [%s] addr 0x%02x val 0x%02x"
parallel_ioport_write(const char *desc, uint16_t addr, uint8_t value) "write [%s] addr 0x%02x val 0x%02x"
--
2.20.1