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

[PATCH v8 05/26] emul/ns16x50: implement DLL/DLM registers


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: dmukhin@xxxxxxxx
  • Date: Wed, 11 Nov 2026 11:47:39 -0800
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 205.220.161.53) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=ford.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=ford.com; dkim=pass (signature was verified) header.d=saarlouis.ford.com; dkim=pass (signature was verified) header.d=ford.com; arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=7HCKkpNOBEKlTr0ei7RZ0b9j9J+svbeaoHEGbMMT6R4=; b=RDUIeOMhsBpmmIbLoXoHO076jGV4h0ck0HGR4XbnTeu8ccFob3qEDfZAnO6Cmgl2YnPL1f5S8t5k/Uq4t+DcLqZ9XBdqiNourkCHN5kBXu2x/SV829rh8FoOyGeJPGuSszH9db/PDzilZPyBAsb2zFsNizRfI6HfNlYv96ONpyxnulrExmPeEaUMYGqxWSVwvbTmTS7129fFpcJ8rZLzwdWJONvQ7Jq2VyyQNeWAvLX2MmbPf3NF4DBUN34rlm5TIVEfBDVmn/A5nqPO5lPspBykYynScGgnrDdQ4XSFGHpGsTtTQicF0efulG4Ly8XUU5fSD5Bv+LSEty3rSKuk4A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=g8s7ZCpJRFZ1Ijo3jmw0FcIKEGdnPBs0SiWpBQJuTrA0rCtsGEnZMwXTqoZPFpZbhwq8yxcqXvRm6yd2dvKT78AajXJ0iGuz1FBuKDYfxEbsHUy1Hz8Q03WtVQcDklDubTGoSUiSahQDqzt2dPlb1ILkWEwk6jWIdoz1UXvxjOuQzeBT08A/xySyoPaGovhy9a0fuWsC6lMXRyRe1Yga+wPUPFft6owY5RDCNZG2SV/idynQ16f0ZdjiUW4FASq9c8nOlLg+TWNcKKn+JZtA82pQENiSSVr6yXF/Ju9tCNW/TLfwK6nlHMOtXynMyzqF0inUoUz6RcSrZ0TYfSF7Nw==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=ppford header.d=ford.com header.i="@ford.com" header.h="Cc:Content-Transfer-Encoding:Content-Type:Date:From:In-Reply-To:Message-ID:MIME-Version:References:Subject:To"; dkim=pass header.s=selector2-azureford-onmicrosoft-com header.d=azureford.onmicrosoft.com header.i="@azureford.onmicrosoft.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"; dkim=pass header.s=ppserprodsaar header.d=saarlouis.ford.com header.i="@saarlouis.ford.com" header.h="Cc:Content-Transfer-Encoding:Date:From:In-Reply-To:Message-ID:MIME-Version:References:Subject:To"; dkim=pass header.s=ppfserpocford header.d=ford.com header.i="@ford.com" header.h="Cc:Content-Transfer-Encoding:Date:From:In-Reply-To:Message-ID:MIME-Version:References:Subject:To"
  • Cc: andrew.cooper3@xxxxxxxxxx, anthony.perard@xxxxxxxxxx, jbeulich@xxxxxxxx, julien@xxxxxxx, michal.orzel@xxxxxxx, roger@xxxxxxxxxxxxxx, sstabellini@xxxxxxxxxx, xakep.amatop@xxxxxxxxx, dmukhin@xxxxxxx, Denis Mukhin <dmukhin@xxxxxxxx>
  • Delivery-date: Wed, 11 Nov 2026 19:48:38 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Pser-m365-app: SER-APP

From: Denis Mukhin <dmukhin@xxxxxxxx>

Add DLL/DLM registers emulation.

DLL/DLM registers report hardcoded 115200 baud rate to the guest OS.

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

diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x50.c
index 6e1cfecbaa55..80805ee6ecc6 100644
--- a/xen/common/emul/vuart/ns16x50.c
+++ b/xen/common/emul/vuart/ns16x50.c
@@ -119,8 +119,37 @@ static inline void ns16x50_unlock(struct vuart_ns16x50 
*vdev,
 static int ns16x50_io_write8(
     struct vuart_ns16x50 *vdev, uint32_t reg, uint8_t *data)
 {
+    uint8_t *regs = vdev->regs;
+    uint8_t val = *data;
     int rc = 0;
 
+    switch ( reg )
+    {
+    case UART_THR: /* DLAB=0 --> UART_RBR, DLAB=1 --> UART_DLL */
+        /* DLAB=1 */
+        if ( regs[UART_LCR] & UART_LCR_DLAB )
+        {
+            regs[NS16X50_REGS_NUM + UART_DLL] = val;
+            break;
+        }
+
+        /* DLAB=0 */
+        break;
+
+    case UART_IER: /* DLAB=0 --> UART_IER, DLAB=1 --> UART_DLM */
+        /* DLAB=1 */
+        if ( regs[UART_LCR] & UART_LCR_DLAB )
+        {
+            regs[NS16X50_REGS_NUM + UART_DLM] = val;
+        }
+        /* DLAB=0 */
+        break;
+
+    default:
+        rc = -EINVAL;
+        break;
+    }
+
     return rc;
 }
 
@@ -131,8 +160,17 @@ static int ns16x50_io_write8(
 static int ns16x50_io_write16(
     struct vuart_ns16x50 *vdev, uint32_t reg, uint16_t *data)
 {
+    uint8_t *regs = vdev->regs;
+    uint16_t val = *data;
     int rc = -EINVAL;
 
+    if ( (regs[UART_LCR] & UART_LCR_DLAB) && reg == UART_DLL )
+    {
+        vdev->regs[NS16X50_REGS_NUM + UART_DLL] = val & UINT8_MAX;
+        vdev->regs[NS16X50_REGS_NUM + UART_DLM] = (val >> 8) & UINT8_MAX;
+        rc = 0;
+    }
+
     return rc;
 }
 
@@ -168,9 +206,39 @@ static int ns16x50_io_write(
 static int ns16x50_io_read8(
     struct vuart_ns16x50 *vdev, uint32_t reg, uint8_t *data)
 {
+    uint8_t *regs = vdev->regs;
     uint8_t val = UINT8_MAX;
     int rc = 0;
 
+    switch ( reg )
+    {
+    case UART_RBR: /* DLAB=0 --> UART_RBR, DLAB=1 --> UART_DLL */
+        /* DLAB=1 */
+        if ( regs[UART_LCR] & UART_LCR_DLAB )
+        {
+            val = regs[NS16X50_REGS_NUM + UART_DLL];
+            break;
+        }
+
+        /* DLAB=0 */
+        break;
+
+    case UART_IER: /* DLAB=0 --> UART_IER, DLAB=1 --> UART_DLM */
+        /* DLAB=1 */
+        if ( regs[UART_LCR] & UART_LCR_DLAB )
+        {
+            val = regs[NS16X50_REGS_NUM + UART_DLM];
+            break;
+        }
+
+        /* DLAB=0 */
+        break;
+
+    default:
+        rc = -EINVAL;
+        break;
+    }
+
     *data = val;
 
     return rc;
@@ -182,9 +250,17 @@ static int ns16x50_io_read8(
 static int ns16x50_io_read16(
     struct vuart_ns16x50 *vdev, uint32_t reg, uint16_t *data)
 {
+    uint8_t *regs = vdev->regs;
     uint16_t val = UINT16_MAX;
     int rc = -EINVAL;
 
+    if ( (regs[UART_LCR] & UART_LCR_DLAB) && reg == UART_DLL )
+    {
+        val = vdev->regs[NS16X50_REGS_NUM + UART_DLM] << 8 |
+              vdev->regs[NS16X50_REGS_NUM + UART_DLL];
+        rc = 0;
+    }
+
     *data = val;
 
     return rc;
@@ -310,7 +386,13 @@ static int cf_check ns16x50_io_handle(
 
 static void ns16x50_reset(struct vuart_ns16x50 *vdev)
 {
+    const uint16_t divisor = (UART_CLOCK_HZ / 115200) >> 4;
+
     memset(vdev->regs, 0, sizeof(vdev->regs));
+
+    /* NB: report 115200 baud rate. */
+    vdev->regs[NS16X50_REGS_NUM + UART_DLL] = divisor & UINT8_MAX;
+    vdev->regs[NS16X50_REGS_NUM + UART_DLM] = (divisor >> 8) & UINT8_MAX;
 }
 
 static int ns16x50_init(void *arg)
-- 
2.56.0




 


Rackspace

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