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:13 +0100
commitb9a27c40902d8d51eb07beed0aa85776fc0b84fe (patch)
treeb846e772d9800b26544408981c44d747c5b0f4e1
parent62b7d74a174e995283fae63f3969576b4f55d2ec (diff)
downloadqemu-arm-b9a27c40902d8d51eb07beed0aa85776fc0b84fe.tar.gz
hw/omap_uart.c: Unconditionally enable non-16550 extensions
Uncondionally enable the OMAP UART modelling of the extensions over plain 16550A, instead of having them guarded by #ifdefs and disabled by default. Newer Linux kernels have an OMAP specific serial driver which relies on these being implemented. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/omap_uart.c49
1 files changed, 19 insertions, 30 deletions
diff --git a/hw/omap_uart.c b/hw/omap_uart.c
index 280b6fd505..bd159b4694 100644
--- a/hw/omap_uart.c
+++ b/hw/omap_uart.c
@@ -25,13 +25,18 @@
#include "exec-memory.h"
#include "sysbus.h"
-/* The OMAP UART functionality is similar to the TI16C752 rather than
- * the 16550A. When the flag below is enabled, the code will however
- * offer 'only' the basic 16550A emulation. */
-/* TODO: real functionality for the TI16C752 enhanced features. Note
- * QEMU's SerialState emulation internally always uses a 16-byte FIFO
- * whereas we would need a 64-byte FIFO for OMAP. */
-#define OMAP_UART_16550A
+/* The OMAP UART functionality is similar to the TI16C752; it is
+ * an enhanced version of the 16550A and we piggy-back on the 16550
+ * model.
+ *
+ * Currently unmodelled functionality:
+ * + We should have a 64 byte FIFO but QEMU's SerialState emulation
+ * always uses a 16 byte FIFO
+ * + DMA
+ * + interrupts based on TCR/TLR values
+ * + XON/XOFF flow control
+ * + UASR auto-baudrate-detection
+ */
struct omap_uart_s {
SysBusDevice busdev;
@@ -55,13 +60,11 @@ struct omap_uart_s {
uint8_t blr;
uint8_t acreg;
-#ifndef OMAP_UART_16550A
uint8_t mcr_cache;
uint8_t efr;
uint8_t tcr;
uint8_t tlr;
uint8_t xon[2], xoff[2];
-#endif
};
static void omap_uart_reset(DeviceState *qdev)
@@ -77,14 +80,12 @@ static void omap_uart_reset(DeviceState *qdev)
s->acreg = 0;
s->lcr_cache = 0;
-#ifndef OMAP_UART_16550A
s->mcr_cache = 0;
s->tcr = 0x0f;
s->tlr = 0;
s->efr = 0;
s->xon[0] = s->xon[1] = 0;
s->xoff[0] = s->xoff[1] = 0;
-#endif
}
static uint64_t omap_uart_read(void *opaque, target_phys_addr_t addr,
@@ -98,33 +99,27 @@ static uint64_t omap_uart_read(void *opaque, target_phys_addr_t addr,
case 0x0c:
return s->serial_ops->read(s->serial, addr, size);
case 0x08:
-#ifndef OMAP_UART_16550A
if (s->lcr_cache == 0xbf) {
return s->efr;
}
-#endif
return s->serial_ops->read(s->serial, addr, size);
case 0x10:
case 0x14:
-#ifndef OMAP_UART_16550A
if (s->lcr_cache == 0xbf) {
return s->xon[(addr & 7) >> 2];
} else if (addr == 0x10) {
return s->serial_ops->read(s->serial, addr, size)
| (s->mcr_cache & 0xe0);
}
-#endif
return s->serial_ops->read(s->serial, addr, size);
case 0x18:
case 0x1c:
-#ifndef OMAP_UART_16550A
if ((s->efr & 0x10) && (s->mcr_cache & 0x40)) {
return (addr == 0x18) ? s->tcr : s->tlr;
}
if (s->lcr_cache == 0xbf) {
return s->xoff[(addr & 7) >> 2];
}
-#endif
return s->serial_ops->read(s->serial, addr, size);
case 0x20: /* MDR1 */
return s->mdr[0];
@@ -180,12 +175,11 @@ static void omap_uart_write(void *opaque, target_phys_addr_t addr,
s->serial_ops->write(s->serial, addr, value, size);
break;
case 0x08:
-#ifndef OMAP_UART_16550A
if (s->lcr_cache == 0xbf) {
s->efr = value;
- } else
-#endif
- s->serial_ops->write(s->serial, addr, value, size);
+ } else {
+ s->serial_ops->write(s->serial, addr, value, size);
+ }
break;
case 0x0c:
s->lcr_cache = value;
@@ -193,22 +187,17 @@ static void omap_uart_write(void *opaque, target_phys_addr_t addr,
break;
case 0x10:
case 0x14:
-#ifndef OMAP_UART_16550A
if (s->lcr_cache == 0xbf) {
s->xon[(addr & 7) >> 2] = value;
} else {
if (addr == 0x10) {
s->mcr_cache = value & 0x7f;
}
-#endif
- s->serial_ops->write(s->serial, addr, value, size);
-#ifndef OMAP_UART_16550A
+ s->serial_ops->write(s->serial, addr, value, size);
}
-#endif
break;
case 0x18:
case 0x1c:
-#ifndef OMAP_UART_16550A
if ((s->efr & 0x10) && (s->mcr_cache & 0x40)) {
if (addr == 0x18) {
s->tcr = value & 0xff;
@@ -217,9 +206,9 @@ static void omap_uart_write(void *opaque, target_phys_addr_t addr,
}
} else if (s->lcr_cache == 0xbf) {
s->xoff[(addr & 7) >> 2] = value;
- } else
-#endif
- s->serial_ops->write(s->serial, addr, value, size);
+ } else {
+ s->serial_ops->write(s->serial, addr, value, size);
+ }
break;
case 0x20: /* MDR1 */
s->mdr[0] = value & 0x7f;