diff mbox series

[5/8] hw/char/escc2: Add Receiver Reset (RRES) command

Message ID 20200617082402.242631-6-jasper.lowell@bt.com (mailing list archive)
State New, archived
Headers show
Series ESCC2 | expand

Commit Message

Jasper Lowell June 17, 2020, 8:23 a.m. UTC
Commands are initiated by setting certain bits in the CMDR register. The
Receiver Reset (RRES) command clears the receiver FIFO (RFIFO).

Signed-off-by: Jasper Lowell <jasper.lowell@bt.com>
---
 hw/char/escc2.c      | 24 ++++++++++++++++++++++++
 hw/char/trace-events |  1 +
 2 files changed, 25 insertions(+)
diff mbox series

Patch

diff --git a/hw/char/escc2.c b/hw/char/escc2.c
index 059e033089..5afb8aa6d9 100644
--- a/hw/char/escc2.c
+++ b/hw/char/escc2.c
@@ -29,6 +29,12 @@ 
 
 /* CMDR. */
 #define REGISTER_CMDR_OFFSET                    0x20
+#define REGISTER_CMDR_RMC                       0x80
+#define REGISTER_CMDR_RRES                      0x40
+#define REGISTER_CMDR_RFRD                      0x20
+#define REGISTER_CMDR_STI                       0x10
+#define REGISTER_CMDR_XF                        0x8
+#define REGISTER_CMDR_XRES                      0x1
 
 /* MODE. */
 #define REGISTER_MODE_OFFSET                    0x22
@@ -741,6 +747,23 @@  static uint64_t escc2_mem_read(void *opaque, hwaddr addr, unsigned size)
     return value;
 }
 
+static void escc2_channel_command(ESCC2ChannelState *channel)
+{
+    uint8_t tmp, command;
+
+    command = REGISTER_READ(channel, REGISTER_CMDR);
+    trace_escc2_channel_command(CHANNEL_CHAR(channel), command);
+
+    if (command & REGISTER_CMDR_RRES) {
+        memset(channel->fifo_receive, 0, sizeof(channel->fifo_receive));
+        REGISTER_WRITE(channel, REGISTER_RBCL, 0);
+
+        tmp = REGISTER_READ(channel, REGISTER_STAR);
+        tmp &= ~(REGISTER_STAR_RFNE);
+        REGISTER_WRITE(channel, REGISTER_STAR, tmp);
+    }
+}
+
 static void escc2_mem_write(void *opaque, hwaddr addr, uint64_t value,
         unsigned size)
 {
@@ -767,6 +790,7 @@  static void escc2_mem_write(void *opaque, hwaddr addr, uint64_t value,
         break;
     case REGISTER_CMDR_OFFSET:
         REGISTER_WRITE(channel, REGISTER_CMDR, value);
+        escc2_channel_command(channel);
         break;
     case REGISTER_MODE_OFFSET:
         REGISTER_WRITE(channel, REGISTER_MODE, value);
diff --git a/hw/char/trace-events b/hw/char/trace-events
index b4f4f30815..47b46b92c9 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -59,6 +59,7 @@  escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=0x%0
 # escc2.c
 escc2_irq_update(uint8_t gis) "value 0x%x"
 escc2_mem_read(char channel, uint32_t addr, uint8_t value) "channel %c addr 0x%x value 0x%x"
+escc2_channel_command(char channel, uint8_t command) "channel %c command 0x%x"
 escc2_mem_write(char channel, uint32_t addr, uint8_t value) "channel %c addr 0x%x value 0x%x"
 
 # pl011.c