aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2012-07-04 11:18:43 +0000
committerPeter Maydell <peter.maydell@linaro.org>2012-07-25 13:33:16 +0100
commita438d971c3c90f02aa6cfbfecc7fcd9f2c752cdb (patch)
tree986eb7121272c7149d7a75bc6f25c6779c32d8b3
parent38718363127eb9b299d57fa337cc9d2fd20ae3dc (diff)
downloadqemu-arm-a438d971c3c90f02aa6cfbfecc7fcd9f2c752cdb.tar.gz
hw/omap_uart.c: Forbid extended MCR bit writes unless in enhanced mode
The OMAP UART defines new functions for MCR bits 5 and 6; these can only be written if the appropriate bit is set in the EFR register. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/omap_uart.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/hw/omap_uart.c b/hw/omap_uart.c
index 8f0ae4e99a..cd568b0436 100644
--- a/hw/omap_uart.c
+++ b/hw/omap_uart.c
@@ -122,8 +122,10 @@ static uint64_t omap_uart_read(void *opaque, target_phys_addr_t addr,
if (s->access_mode == regs_config_b) {
return s->xon[(addr & 7) >> 2];
} else if (addr == 0x10) {
- return s->serial_ops->read(s->serial, addr, size)
- | (s->mcr_cache & 0xe0);
+ /* MCR. Bits 5 and 6 are handled by us, the rest by
+ * the underlying serial implementation.
+ */
+ return s->serial_ops->read(s->serial, addr, size) | s->mcr_cache;
}
return s->serial_ops->read(s->serial, addr, size);
case 0x18:
@@ -211,7 +213,12 @@ static void omap_uart_write(void *opaque, target_phys_addr_t addr,
s->xon[(addr & 7) >> 2] = value;
} else {
if (addr == 0x10) {
- s->mcr_cache = value & 0x7f;
+ /* Bits 5 and 6 are handled at this level; they can
+ * only be written if EFR_REG:ENHANCED_EN is set.
+ */
+ if (s->efr & 0x10) {
+ s->mcr_cache = value & 0x60;
+ }
}
s->serial_ops->write(s->serial, addr, value, size);
}