[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v5 09/15] emul/ns16x50: implement MCR/MSR registers



From: Denis Mukhin <dmukhin@xxxxxxxx> 

Add MCR/MCR registers emulation to the I/O port handler.

Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx>
---
Changes since v4:
- new patch
---
 xen/common/emul/vuart/ns16x50.c | 60 +++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index 687a7ea2fabe..670c3c6dba9d 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -394,7 +394,58 @@ static int ns16x50_io_write8(
             regs[UART_LCR] = val;
             break;
 
+        case UART_MCR: {
+            uint8_t msr_curr, msr_next, msr_delta;
+
+            msr_curr = regs[UART_MSR];
+            msr_next = 0;
+            msr_delta = 0;
+
+            if ( val & UART_MCR_RESERVED0 )
+                ns16x50_warn(vdev, "MCR: attempt to set reserved bit: %x\n",
+                             UART_MCR_RESERVED0);
+
+            if ( val & UART_MCR_TCRTLR )
+                ns16x50_warn(vdev, "MCR: not supported: %x\n",
+                             UART_MCR_TCRTLR);
+
+            if ( val & UART_MCR_RESERVED1 )
+                ns16x50_warn(vdev, "MCR: attempt to set reserved bit: %x\n",
+                             UART_MCR_RESERVED1);
+
+            /* Set modem status */
+            if ( val & UART_MCR_LOOP )
+            {
+                if ( val & UART_MCR_DTR )
+                    msr_next |= UART_MSR_DSR;
+                if ( val & UART_MCR_RTS )
+                    msr_next |= UART_MSR_CTS;
+                if ( val & UART_MCR_OUT1 )
+                    msr_next |= UART_MSR_RI;
+                if ( val & UART_MCR_OUT2 )
+                    msr_next |= UART_MSR_DCD;
+            }
+            else
+                msr_next |= UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
+
+            /* Calculate changes in modem status */
+            if ( (msr_curr & UART_MSR_CTS) ^ (msr_next & UART_MSR_CTS) )
+                msr_delta |= UART_MSR_DCTS;
+            if ( (msr_curr & UART_MSR_DSR) ^ (msr_next & UART_MSR_DSR) )
+                msr_delta |= UART_MSR_DDSR;
+            if ( (msr_curr & UART_MSR_RI)  & (msr_next & UART_MSR_RI) )
+                msr_delta |= UART_MSR_TERI;
+            if ( (msr_curr & UART_MSR_DCD) ^ (msr_next & UART_MSR_DCD) )
+                msr_delta |= UART_MSR_DDCD;
+
+            regs[UART_MCR] = val & UART_MCR_MASK;
+            regs[UART_MSR] = msr_next | msr_delta;
+
+            break;
+        }
+
         case UART_LSR: /* RO */
+        case UART_MSR: /* RO */
         default:
             rc = -EINVAL;
             break;
@@ -495,6 +546,10 @@ static int ns16x50_io_read8(
             val = regs[UART_LCR];
             break;
 
+        case UART_MCR:
+            val = regs[UART_MCR];
+            break;
+
         case UART_LSR:
             val = regs[UART_LSR] | UART_LSR_THRE | UART_LSR_TEMT;
             if ( ns16x50_fifo_rx_empty(vdev) )
@@ -506,6 +561,11 @@ static int ns16x50_io_read8(
 
             break;
 
+        case UART_MSR:
+            val = regs[UART_MSR];
+            regs[UART_MSR] &= ~UART_MSR_CHANGE;
+            break;
+
         default:
             rc = -EINVAL;
             break;
-- 
2.51.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.