aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2013-02-18 16:58:29 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-05-03 21:27:48 +0100
commit022d215412816f41a7943d6b9923df43a317981f (patch)
tree5a16c801a92330ceff464abdc631e697ad505561
parente367aa449a8966214e5caeed37d175e8a2111d45 (diff)
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/char/omap_uart.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
index 5ee352ca2..55982fa4a 100644
--- a/hw/char/omap_uart.c
+++ b/hw/char/omap_uart.c
@@ -124,8 +124,10 @@ static uint64_t omap_uart_read(void *opaque, hwaddr 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:
@@ -213,7 +215,12 @@ static void omap_uart_write(void *opaque, hwaddr 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);
}