diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2013-02-18 16:58:29 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-05-03 21:27:48 +0100 |
commit | 022d215412816f41a7943d6b9923df43a317981f (patch) | |
tree | 5a16c801a92330ceff464abdc631e697ad505561 | |
parent | e367aa449a8966214e5caeed37d175e8a2111d45 (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.c | 13 |
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); } |