summaryrefslogtreecommitdiffstats
path: root/hw/char/pl011.c
diff options
context:
space:
mode:
authorPeter Maydell2016-10-17 20:41:23 +0200
committerPeter Maydell2016-10-17 20:41:23 +0200
commit2d02ac10b6644d71c88cc7943e74d7ad6674fff1 (patch)
tree28f11b0787b3fd3fb4b85881feead80f9ad76c81 /hw/char/pl011.c
parentMerge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging (diff)
parenthw/char/pl011: Add trace events (diff)
downloadqemu-2d02ac10b6644d71c88cc7943e74d7ad6674fff1.tar.gz
qemu-2d02ac10b6644d71c88cc7943e74d7ad6674fff1.tar.xz
qemu-2d02ac10b6644d71c88cc7943e74d7ad6674fff1.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20161017' into staging
target-arm: * target-arm: kvm: use AddressSpace-specific listener * aspeed: add SMC controllers * hw/arm/boot: allow using a command line specified dtb without a kernel * hw/dma/pl080: Fix bad bit mask * hw/intc/arm_gic_kvm: Fix build on aarch64 with some compilers * hw/arm/virt: fix ACPI tables for ITS * tests: add a m25p80 test * tests: cleanup ptimer-test * pxa2xx: Auto-assign name for i2c bus in i2c_init_bus * target-arm: handle tagged addresses in A64 code * target-arm: Fix masking of PC lower bits when doing exception returns * target-arm: Implement dummy MDCCINT_EL1 * target-arm: Add trace events for the generic timers * hw/intc/arm_gicv3: Fix ICC register tracepoints * hw/char/pl011: Add trace events # gpg: Signature made Mon 17 Oct 2016 19:39:42 BST # gpg: using RSA key 0x3C2525ED14360CDE # 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-20161017: (25 commits) hw/char/pl011: Add trace events hw/intc/arm_gicv3: Fix ICC register tracepoints target-arm: Add trace events for the generic timers target-arm: Implement dummy MDCCINT_EL1 Fix masking of PC lower bits when doing exception returns target-arm: Comments added to identify cases in a switch target-arm: Code changes to implement overwrite of tag field on PC load target-arm: Infrastucture changes to enable handling of tagged address loading into PC pxa2xx: Auto-assign name for i2c bus in i2c_init_bus. tests: cleanup ptimer-test tests: add a m25p80 test hw/arm/virt: no ITS on older machine types hw/arm/virt-acpi-build: fix MADT generation hw/intc/arm_gic_kvm: Fix build on aarch64 hw/dma/pl080: Fix bad bit mask (PL080_CONF_M1 | PL080_CONF_M1) hw/arm/boot: allow using a command line specified dtb without a kernel aspeed: add support for the SMC segment registers aspeed: create mapping regions for the maximum number of slaves aspeed: add support for the AST2500 SoC SMC controllers aspeed: extend the number of host SPI controllers ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/char/pl011.c')
-rw-r--r--hw/char/pl011.c71
1 files changed, 50 insertions, 21 deletions
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 786e605fdd..1a7911f81f 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -11,6 +11,7 @@
#include "hw/sysbus.h"
#include "sysemu/char.h"
#include "qemu/log.h"
+#include "trace.h"
#define TYPE_PL011 "pl011"
#define PL011(obj) OBJECT_CHECK(PL011State, (obj), TYPE_PL011)
@@ -58,6 +59,7 @@ static void pl011_update(PL011State *s)
uint32_t flags;
flags = s->int_level & s->int_enabled;
+ trace_pl011_irq_state(flags != 0);
qemu_set_irq(s->irq, flags != 0);
}
@@ -66,10 +68,8 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
{
PL011State *s = (PL011State *)opaque;
uint32_t c;
+ uint64_t r;
- if (offset >= 0xfe0 && offset < 0x1000) {
- return s->id[(offset - 0xfe0) >> 2];
- }
switch (offset >> 2) {
case 0: /* UARTDR */
s->flags &= ~PL011_FLAG_RXFF;
@@ -84,41 +84,62 @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
}
if (s->read_count == s->read_trigger - 1)
s->int_level &= ~ PL011_INT_RX;
+ trace_pl011_read_fifo(s->read_count);
s->rsr = c >> 8;
pl011_update(s);
if (s->chr) {
qemu_chr_accept_input(s->chr);
}
- return c;
+ r = c;
+ break;
case 1: /* UARTRSR */
- return s->rsr;
+ r = s->rsr;
+ break;
case 6: /* UARTFR */
- return s->flags;
+ r = s->flags;
+ break;
case 8: /* UARTILPR */
- return s->ilpr;
+ r = s->ilpr;
+ break;
case 9: /* UARTIBRD */
- return s->ibrd;
+ r = s->ibrd;
+ break;
case 10: /* UARTFBRD */
- return s->fbrd;
+ r = s->fbrd;
+ break;
case 11: /* UARTLCR_H */
- return s->lcr;
+ r = s->lcr;
+ break;
case 12: /* UARTCR */
- return s->cr;
+ r = s->cr;
+ break;
case 13: /* UARTIFLS */
- return s->ifl;
+ r = s->ifl;
+ break;
case 14: /* UARTIMSC */
- return s->int_enabled;
+ r = s->int_enabled;
+ break;
case 15: /* UARTRIS */
- return s->int_level;
+ r = s->int_level;
+ break;
case 16: /* UARTMIS */
- return s->int_level & s->int_enabled;
+ r = s->int_level & s->int_enabled;
+ break;
case 18: /* UARTDMACR */
- return s->dmacr;
+ r = s->dmacr;
+ break;
+ case 0x3f8 ... 0x400:
+ r = s->id[(offset - 0xfe0) >> 2];
+ break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
"pl011_read: Bad offset %x\n", (int)offset);
- return 0;
+ r = 0;
+ break;
}
+
+ trace_pl011_read(offset, r);
+ return r;
}
static void pl011_set_read_trigger(PL011State *s)
@@ -141,6 +162,8 @@ static void pl011_write(void *opaque, hwaddr offset,
PL011State *s = (PL011State *)opaque;
unsigned char ch;
+ trace_pl011_write(offset, value);
+
switch (offset >> 2) {
case 0: /* UARTDR */
/* ??? Check if transmitter is enabled. */
@@ -207,11 +230,15 @@ static void pl011_write(void *opaque, hwaddr offset,
static int pl011_can_receive(void *opaque)
{
PL011State *s = (PL011State *)opaque;
+ int r;
- if (s->lcr & 0x10)
- return s->read_count < 16;
- else
- return s->read_count < 1;
+ if (s->lcr & 0x10) {
+ r = s->read_count < 16;
+ } else {
+ r = s->read_count < 1;
+ }
+ trace_pl011_can_receive(s->lcr, s->read_count, r);
+ return r;
}
static void pl011_put_fifo(void *opaque, uint32_t value)
@@ -225,7 +252,9 @@ static void pl011_put_fifo(void *opaque, uint32_t value)
s->read_fifo[slot] = value;
s->read_count++;
s->flags &= ~PL011_FLAG_RXFE;
+ trace_pl011_put_fifo(value, s->read_count);
if (!(s->lcr & 0x10) || s->read_count == 16) {
+ trace_pl011_put_fifo_full();
s->flags |= PL011_FLAG_RXFF;
}
if (s->read_count == s->read_trigger) {