[PATCH v6 07/15] emul/ns16x50: implement LCR/LSR registers

dmukhin@xen.org posted 15 patches 5 months, 1 week ago
There is a newer version of this series
[PATCH v6 07/15] emul/ns16x50: implement LCR/LSR registers
Posted by dmukhin@xen.org 5 months, 1 week ago
From: Denis Mukhin <dmukhin@ford.com> 

Add LCR/LSR registers implementation to the I/O port handler.

Add implementation of ns16x50_dlab_get() and ns16x50_iir_check_lsi().

Signed-off-by: Denis Mukhin <dmukhin@ford.com>
---
Changes since v5:
- Moved earlier in the series so follow on patches (THR/RBR) could make use of
  LSR bits more naturally
- Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-9-dmukhin@ford.com/
---
 xen/common/emul/vuart/ns16x50.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index a7429c84c36e..9d1fe0284362 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -88,12 +88,12 @@ struct vuart_ns16x50 {
 
 static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev)
 {
-    return 0;
+    return vdev->regs[UART_LCR] & UART_LCR_DLAB ? 1 : 0;
 }
 
 static bool cf_check ns16x50_iir_check_lsi(const struct vuart_ns16x50 *vdev)
 {
-    return false;
+    return vdev->regs[UART_LSR] & UART_LSR_MASK;
 }
 
 static bool cf_check ns16x50_iir_check_rda(const struct vuart_ns16x50 *vdev)
@@ -226,11 +226,16 @@ static int ns16x50_io_write8(
             regs[UART_IER] = val & UART_IER_MASK;
             break;
 
+        case UART_LCR:
+            regs[UART_LCR] = val;
+            break;
+
         /* NB: Firmware (e.g. OVMF) may rely on SCR presence. */
         case UART_SCR:
             regs[UART_SCR] = val;
             break;
 
+        case UART_LSR: /* RO */
         default:
             rc = -EINVAL;
             break;
@@ -312,6 +317,15 @@ static int ns16x50_io_read8(
             val = ns16x50_iir_get(vdev);
             break;
 
+        case UART_LCR:
+            val = regs[UART_LCR];
+            break;
+
+        case UART_LSR:
+            val = regs[UART_LSR] | UART_LSR_THRE | UART_LSR_TEMT;
+            regs[UART_LSR] = val & ~UART_LSR_MASK;
+            break;
+
         case UART_SCR:
             val = regs[UART_SCR];
             break;
-- 
2.51.0
Re: [PATCH v6 07/15] emul/ns16x50: implement LCR/LSR registers
Posted by Stefano Stabellini 5 months, 1 week ago
On Fri, 5 Sep 2025, dmukhin@xen.org wrote:
> From: Denis Mukhin <dmukhin@ford.com> 
> 
> Add LCR/LSR registers implementation to the I/O port handler.
> 
> Add implementation of ns16x50_dlab_get() and ns16x50_iir_check_lsi().
> 
> Signed-off-by: Denis Mukhin <dmukhin@ford.com>
> ---
> Changes since v5:
> - Moved earlier in the series so follow on patches (THR/RBR) could make use of
>   LSR bits more naturally
> - Link to v5: https://lore.kernel.org/xen-devel/20250828235409.2835815-9-dmukhin@ford.com/
> ---
>  xen/common/emul/vuart/ns16x50.c | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
> index a7429c84c36e..9d1fe0284362 100644
> --- a/xen/common/emul/vuart/ns16x50.c
> +++ b/xen/common/emul/vuart/ns16x50.c
> @@ -88,12 +88,12 @@ struct vuart_ns16x50 {
>  
>  static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev)
>  {
> -    return 0;
> +    return vdev->regs[UART_LCR] & UART_LCR_DLAB ? 1 : 0;
>  }
>  
>  static bool cf_check ns16x50_iir_check_lsi(const struct vuart_ns16x50 *vdev)
>  {
> -    return false;
> +    return vdev->regs[UART_LSR] & UART_LSR_MASK;
>  }
>  
>  static bool cf_check ns16x50_iir_check_rda(const struct vuart_ns16x50 *vdev)
> @@ -226,11 +226,16 @@ static int ns16x50_io_write8(
>              regs[UART_IER] = val & UART_IER_MASK;
>              break;
>  
> +        case UART_LCR:
> +            regs[UART_LCR] = val;
> +            break;
> +
>          /* NB: Firmware (e.g. OVMF) may rely on SCR presence. */
>          case UART_SCR:
>              regs[UART_SCR] = val;
>              break;
>  
> +        case UART_LSR: /* RO */
>          default:
>              rc = -EINVAL;
>              break;
> @@ -312,6 +317,15 @@ static int ns16x50_io_read8(
>              val = ns16x50_iir_get(vdev);
>              break;
>  
> +        case UART_LCR:
> +            val = regs[UART_LCR];
> +            break;
> +
> +        case UART_LSR:
> +            val = regs[UART_LSR] | UART_LSR_THRE | UART_LSR_TEMT;
> +            regs[UART_LSR] = val & ~UART_LSR_MASK;
> +            break;
> +
>          case UART_SCR:
>              val = regs[UART_SCR];
>              break;
> -- 
> 2.51.0
>