diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2012-07-04 11:18:43 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2012-07-25 13:33:16 +0100 |
commit | a438d971c3c90f02aa6cfbfecc7fcd9f2c752cdb (patch) | |
tree | 986eb7121272c7149d7a75bc6f25c6779c32d8b3 | |
parent | 38718363127eb9b299d57fa337cc9d2fd20ae3dc (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/omap_uart.c | 13 |
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); } |