From nobody Tue Feb 10 06:58:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1757114865; cv=none; d=zohomail.com; s=zohoarc; b=EMi60PXqzvBc0XIS3NPw8BPJ46cP6FAec7cMKpn5zM0Bvw//uX3h5Ix/Yjo2ekcdTZonkfJIAn+OzqeavS8wI7rNk3YICJrZdieVaz6N2W7xyDelNhyWIC8bzzdQp6j6MPOQEdwQ17mqdme2U9NV4eEKghWhA1Ub1YnFyKerV1w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1757114865; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=H6Jsk6o0mPE6CkIqUYbOmKkRmoSPy4kytmL3+MJblb8=; b=DbR0dgia/EpXK1Xo1dEkrhLlOZKSyquwAiYoDYfmXFBwQwYt0mHVeAH2nYcY9RVYf9TIUsjwYYq8MCF2fIVogSYbsSNmNT6uL080/l8fcza8tnzCRYnbZG6Xn3tPQ52GtV7L62eyPnHjPVQ97pksiiG/MrShzrsZfF4+g9uNns4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1757114865421879.7417631457745; Fri, 5 Sep 2025 16:27:45 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1112638.1460919 (Exim 4.92) (envelope-from ) id 1uufq7-0003V3-Eh; Fri, 05 Sep 2025 23:27:31 +0000 Received: by outflank-mailman (output) from mailman id 1112638.1460919; Fri, 05 Sep 2025 23:27:31 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq6-0003TV-Sy; Fri, 05 Sep 2025 23:27:30 +0000 Received: by outflank-mailman (input) for mailman id 1112638; Fri, 05 Sep 2025 23:27:29 +0000 Received: from mail.xenproject.org ([104.130.215.37]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uufq5-0003Gd-RP for xen-devel@lists.xenproject.org; Fri, 05 Sep 2025 23:27:29 +0000 Received: from xenbits.xenproject.org ([104.239.192.120]) by mail.xenproject.org with esmtp (Exim 4.96) (envelope-from ) id 1uufq5-008AC6-1Z; Fri, 05 Sep 2025 23:27:29 +0000 Received: from [19.12.91.86] (helo=localhost) by xenbits.xenproject.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uufq5-0005DQ-1V; Fri, 05 Sep 2025 23:27:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=xen.org; s=20200302mail; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From; bh=H6Jsk6o0mPE6CkIqUYbOmKkRmoSPy4kytmL3+MJblb8=; b=hAKeWQc5fQbyKAWWfsxPT2V4il qo1Sw8jQGZOdOCoJAhbjlfTv2UVT4ZFG0zBVcVMWnml8M8C+/cO2nJzedz/iGBXKZctnTORvtZXII xr/LHyQCvERV0DRxNpfSl9NxEf3gZFm6CWow4pFQBOTb4Dq2nsrhO94bUsN4oPTcVCRM=; From: dmukhin@xen.org To: xen-devel@lists.xenproject.org Cc: andrew.cooper3@citrix.com, anthony.perard@vates.tech, jbeulich@suse.com, julien@xen.org, michal.orzel@amd.com, roger.pau@citrix.com, sstabellini@kernel.org, dmukhin@ford.com Subject: [PATCH v6 10/15] emul/ns16x50: implement THR register Date: Fri, 5 Sep 2025 16:27:09 -0700 Message-ID: <20250905232715.440758-11-dmukhin@ford.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20250905232715.440758-1-dmukhin@ford.com> References: <20250905232715.440758-1-dmukhin@ford.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @xen.org) X-ZM-MESSAGEID: 1757114866852124100 Content-Type: text/plain; charset="utf-8" From: Denis Mukhin =20 Add THR register emulation to the I/O port handlder. Add TX FIFO management code since THR depends on TX FIFO. TX FIFOs is not emulated as per UART specs for simplicity (not need to emul= ate baud rate). Emulator does not emulate NS8250 (no FIFO), NS16550a (16 bytes)= or NS16750 (64 bytes). TX FIFOs is emulated by using xencons_interface which conveniently provides primitives for buffer management and later can be used for inter-domain communication similarly to vpl011. Add UART_IIR_THR interrupt reason handling since it depends on THR register access. Signed-off-by: Denis Mukhin --- Changes since v5: - new patch - Link to v5 (both THR/RBR): https://lore.kernel.org/xen-devel/202508282354= 09.2835815-7-dmukhin@ford.com/ --- xen/common/emul/vuart/ns16x50.c | 103 +++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/xen/common/emul/vuart/ns16x50.c b/xen/common/emul/vuart/ns16x5= 0.c index cac5128f0573..987d4c06e23b 100644 --- a/xen/common/emul/vuart/ns16x50.c +++ b/xen/common/emul/vuart/ns16x50.c @@ -148,6 +148,66 @@ static int ns16x50_fifo_rx_putchar(struct vuart_ns16x5= 0 *vdev, char c) return rc; } =20 +static bool ns16x50_fifo_tx_full(const struct vuart_ns16x50 *vdev) +{ + const struct xencons_interface *cons =3D &vdev->cons; + + return cons->out_prod - cons->out_cons =3D=3D ARRAY_SIZE(cons->out); +} + +static void ns16x50_fifo_tx_reset(struct vuart_ns16x50 *vdev) +{ + struct xencons_interface *cons =3D &vdev->cons; + + cons->out_cons =3D cons->out_prod; +} + +/* + * Flush cached output to Xen console. + */ +static void ns16x50_fifo_tx_flush(struct vuart_ns16x50 *vdev) +{ + struct xencons_interface *cons =3D &vdev->cons; + struct domain *d =3D vdev->owner; + XENCONS_RING_IDX i, n, len =3D cons->out_prod - cons->out_cons; + + ASSERT(len <=3D ARRAY_SIZE(cons->out)); + if ( !len ) + return; + + i =3D MASK_XENCONS_IDX(cons->out_cons, cons->out); + n =3D min_t(XENCONS_RING_IDX, len, ARRAY_SIZE(cons->out) - i); + if ( n ) + guest_printk(d, guest_prefix "%.*s", n, &cons->out[i]); + + i =3D 0; + n =3D len - n; + if ( n ) + guest_printk(d, guest_prefix "%.*s", n, &cons->out[i]); + + cons->out_cons +=3D len; +} + +/* + * Accumulate guest OS output before sending to Xen console. + */ +static void ns16x50_fifo_tx_putchar(struct vuart_ns16x50 *vdev, char ch) +{ + struct xencons_interface *cons =3D &vdev->cons; + + if ( !is_console_printable(ch) ) + return; + + if ( !ns16x50_fifo_tx_full(vdev) ) + { + cons->out[MASK_XENCONS_IDX(cons->out_prod, cons->out)] =3D ch; + cons->out_prod++; + } + + if ( ch =3D=3D '\n' || ch =3D=3D '\0' || ns16x50_fifo_tx_full(vdev) ) + ns16x50_fifo_tx_flush(vdev); +} + static uint8_t ns16x50_dlab_get(const struct vuart_ns16x50 *vdev) { return vdev->regs[UART_LCR] & UART_LCR_DLAB ? 1 : 0; @@ -165,7 +225,7 @@ static bool cf_check ns16x50_iir_check_rda(const struct= vuart_ns16x50 *vdev) =20 static bool cf_check ns16x50_iir_check_thr(const struct vuart_ns16x50 *vde= v) { - return false; + return vdev->regs[NS16X50_REGS_NUM + UART_IIR] & UART_IIR_THR; } =20 static bool cf_check ns16x50_iir_check_msi(const struct vuart_ns16x50 *vde= v) @@ -284,7 +344,31 @@ static int ns16x50_io_write8( { switch ( reg ) { + case UART_THR: + if ( regs[UART_MCR] & UART_MCR_LOOP ) + { + if ( ns16x50_fifo_rx_putchar(vdev, val) ) + regs[UART_LSR] |=3D UART_LSR_OE; + + regs[UART_LSR] |=3D UART_LSR_DR; + } + else + { + ns16x50_fifo_tx_putchar(vdev, val); + regs[NS16X50_REGS_NUM + UART_IIR] |=3D UART_IIR_THR; + } + + break; + case UART_IER: + /* + * NB: Make sure THR interrupt is re-triggered once guest OS + * re-enables ETHREI in IER since all THR writes are immediate, + * there's no baud rate emulation. + */ + if ( val & regs[UART_IER] & UART_IER_ETHREI ) + regs[NS16X50_REGS_NUM + UART_IIR] |=3D UART_IIR_THR; + regs[UART_IER] =3D val & UART_IER_MASK; break; =20 @@ -439,6 +523,16 @@ static int ns16x50_io_read8( =20 case UART_IIR: /* RO */ val =3D ns16x50_iir_get(vdev); + + /* + * Since there's no baud rate emulation, transmits are immedia= te + * to the guest. Clear IIR scratch location to make sure there + * will be interrupt generated once guest re-enabled ETHREI in + * IER. + */ + if ( val & UART_IIR_THR ) + regs[NS16X50_REGS_NUM + UART_IIR] &=3D ~UART_IIR_THR; + break; =20 case UART_LCR: @@ -620,6 +714,9 @@ static int ns16x50_init(void *arg) vdev->regs[NS16X50_REGS_NUM + UART_DLL] =3D divisor & 0xff; vdev->regs[NS16X50_REGS_NUM + UART_DLM] =3D (divisor >> 8) & 0xff; =20 + /* Report UART is ready to transmit. */ + vdev->regs[NS16X50_REGS_NUM + UART_IIR] =3D UART_IIR_THR; + register_portio_handler(d, info->base_addr, info->size, ns16x50_io_han= dle); =20 spin_lock(&vdev->lock); @@ -634,6 +731,10 @@ static void cf_check ns16x50_deinit(void *arg) struct vuart_ns16x50 *vdev =3D arg; =20 ASSERT(vdev); + + spin_lock(&vdev->lock); + ns16x50_fifo_tx_flush(vdev); + spin_unlock(&vdev->lock); } =20 static void * cf_check ns16x50_alloc(struct domain *d, const struct vuart_= info *info) --=20 2.51.0