[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v6 08/15] emul/ns16x50: implement MCR/MSR registers
From: Denis Mukhin <dmukhin@xxxxxxxx> Add MCR/MSR registers emulation to the I/O port handler. Add implementation of ns16x50_iir_check_msi(). Signed-off-by: Denis Mukhin <dmukhin@xxxxxxxx> --- Changes in v5: - Moved earlier in the series - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-10-dmukhin@xxxxxxxx/ --- xen/common/emul/vuart/ns16x50.c | 62 ++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c index 9d1fe0284362..a8ec9f6c3a04 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -108,7 +108,7 @@ static bool cf_check ns16x50_iir_check_thr(const struct vuart_ns16x50 *vdev) static bool cf_check ns16x50_iir_check_msi(const struct vuart_ns16x50 *vdev) { - return false; + return vdev->regs[UART_MSR] & UART_MSR_CHANGE; } /* @@ -230,12 +230,63 @@ 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; + } + /* NB: Firmware (e.g. OVMF) may rely on SCR presence. */ case UART_SCR: regs[UART_SCR] = val; break; case UART_LSR: /* RO */ + case UART_MSR: /* RO */ default: rc = -EINVAL; break; @@ -321,11 +372,20 @@ 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; regs[UART_LSR] = val & ~UART_LSR_MASK; break; + case UART_MSR: + val = regs[UART_MSR]; + regs[UART_MSR] &= ~UART_MSR_CHANGE; + break; + case UART_SCR: val = regs[UART_SCR]; break; -- 2.51.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |