From: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>
To: WX Chen <wxchen0913@gmail.com>, qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Chao Liu" <chao.liu.zevorn@gmail.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Alistair Francis" <alistair.francis@wdc.com>,
"Weiwei Li" <liwei1518@gmail.com>,
"Liu Zhiwei" <zhiwei_liu@linux.alibaba.com>,
qemu-riscv@nongnu.org, "Fabiano Rosas" <farosas@suse.de>,
"Laurent Vivier" <lvivier@redhat.com>
Subject: Re: [PATCH RESEND v2 3/3] tests/qtest: add K230 UART test
Date: Wed, 5 Aug 2026 17:10:17 -0300 [thread overview]
Message-ID: <af3d837c-e7f2-48ce-9b9c-c2ea9e4d8fb8@oss.qualcomm.com> (raw)
In-Reply-To: <20260725-feat-k230-uart-v2-v2-3-d5fe82c47c28@gmail.com>
On 7/25/2026 12:52 AM, WX Chen wrote:
> Add 8 test cases covering the main register paths and driver usage
> scenarios: device probe, init & baud, TX/RX datapath, THRE interrupt,
> RX interrupts (timeout & trigger level), error interrupts & IIR
> priority, USR & busy detect, and advanced features (shadow registers,
> HTX, SRR, PTIME/TET).
>
> All tests pass.
>
> Signed-off-by: WX Chen <wxchen0913@gmail.com>
> ---
This also LGTM with a minor observation down there:
> tests/qtest/k230-uart-test.c | 514 +++++++++++++++++++++++++++++++++++++++++++
> tests/qtest/meson.build | 2 +-
> 2 files changed, 515 insertions(+), 1 deletion(-)
>
> diff --git a/tests/qtest/k230-uart-test.c b/tests/qtest/k230-uart-test.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..f85c690ebb57abb5b7f753f36c06c0900c3cfbb9
> --- /dev/null
> +++ b/tests/qtest/k230-uart-test.c
> @@ -0,0 +1,514 @@
> +/*
> + * QTest for the K230 UART — functional-path coverage.
> + *
> + * Tests are organised around driver usage scenarios rather than
> + * enumerating every register in isolation.
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "libqtest.h"
> +#include <string.h>
> +
> +#define UART_BASE 0x91400000
> +#define R(off) (UART_BASE + (off))
> +
> +/* register offsets */
> +#define THR 0x00
> +#define IER 0x04
> +#define IIR 0x08
> +#define LCR 0x0c
> +#define MCR 0x10
> +#define LSR 0x14
> +#define SCR 0x1c
> +#define USR 0x7c
> +#define TFL 0x80
> +#define RFL 0x84
> +#define SRR 0x88
> +#define SRTS 0x8c
> +#define SBCR 0x90
> +#define SDMAM 0x94
> +#define SFE 0x98
> +#define SRT 0x9c
> +#define STET 0xa0
> +#define HTX 0xa4
> +#define CPR 0xf4
> +#define CTR 0xfc
> +
> +/* bit fields */
> +#define LCR_DLAB 0x80
> +#define LCR_BC 0x40
> +#define LCR_8N1 0x03
> +
> +#define LSR_DR 0x01
> +#define LSR_OE 0x02
> +#define LSR_THRE 0x20
> +#define LSR_TEMT 0x40
> +#define LSR_RESET 0x60
> +
> +#define IIR_IID 0x0f
> +#define IIR_NONE 0x01
> +#define IIR_THR 0x02
> +#define IIR_RX 0x04
> +#define IIR_LINE 0x06
> +#define IIR_BUSY 0x07
> +#define IIR_TO 0x0c
> +#define IIR_FF 0xc0
> +
> +#define IER_RX 0x01
> +#define IER_TX 0x02
> +#define IER_LS 0x04
> +#define IER_COLR 0x10
> +#define IER_PTIME 0x80
> +
> +#define MCR_LB 0x10
> +#define MCR_RTS 0x02
> +
> +#define FCR_FE 0x01
> +#define FCR_RR 0x02
> +#define FCR_XR 0x04
> +#define FCR_TET_H (3 << 4)
> +#define FCR_RT_Q (1 << 6)
> +#define FCR_RT_F (3 << 6)
> +
> +#define USR_BUSY 0x01
> +#define USR_RESET 0x06
> +
> +#define SRR_UR 0x01
> +#define SRR_RFR 0x02
> +
> +/* helpers */
> +static uint32_t rd(QTestState *qts, uint32_t o)
> +{
> + return qtest_readl(qts, R(o));
> +}
> +static uint32_t iid(QTestState *qts)
> +{
> + return rd(qts, IIR) & IIR_IID;
> +}
> +
> +static void poll_lsr(QTestState *qts, uint32_t m)
> +{
> + int i;
> +
> + for (i = 0; i < 1000; i++) {
> + if (rd(qts, LSR) & m) {
> + return;
> + }
> + g_usleep(1000);
Any reason to use g_usleep() instead of qtest_clock_step()? There are a couple
of g_usleep() uses in the code but you used lots of qtest_clock_step() too.
AFAIK g_usleep() is wall time and qtest_clock_step() is simulated time, and
I guess you should be using qtest_clock_step() for all the pollings you're
doing in this file.
Thanks,
Daniel
> + }
> + g_assert_not_reached();
> +}
> +
> +static void s1(QTestState *qts, int fd, char c)
> +{
> + g_assert_cmpint(send(fd, &c, 1, 0), ==, 1);
> + poll_lsr(qts, LSR_DR);
> +}
> +
> +static void sn(QTestState *qts, int fd, const char *d, int n)
> +{
> + g_assert_cmpint(send(fd, d, n, 0), ==, n);
> + poll_lsr(qts, LSR_DR);
> +}
> +
> +static void oe_nf(QTestState *qts, int fd)
> +{
> + int i;
> +
> + s1(qts, fd, 'A');
> + {
> + char c = 'B';
> + g_assert_cmpint(send(fd, &c, 1, 0), ==, 1);
> + }
> + for (i = 0; i < 200; i++) {
> + rd(qts, SCR);
> + g_usleep(1000);
> + }
> +}
> +
> +/* 1. device probe */
> +static void test_device_probe(void)
> +{
> + QTestState *qts = qtest_init("-machine k230");
> + uint32_t cpr = rd(qts, CPR);
> +
> + g_assert_cmphex(cpr & 0x3, ==, 0x2);
> + g_assert_cmphex(cpr & (1 << 5), ==, (1 << 5));
> + g_assert_cmphex(cpr & (1 << 8), ==, (1 << 8));
> + g_assert_cmphex((cpr >> 16) & 0xff, ==, 0x2);
> + g_assert_cmphex(cpr & (1 << 4), ==, 0);
> + g_assert_cmphex(rd(qts, CTR), ==, 0x44570110);
> + g_assert_cmphex(rd(qts, LSR), ==, LSR_RESET);
> + g_assert_cmphex(rd(qts, USR), ==, USR_RESET);
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> + g_assert_cmphex(rd(qts, IIR) & IIR_FF, ==, 0);
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, 0);
> +
> + qtest_writel(qts, R(IIR), FCR_FE);
> + g_assert_cmphex(rd(qts, IIR) & IIR_FF, ==, IIR_FF);
> + qtest_quit(qts);
> +}
> +
> +/* 2. init & baud */
> +static void test_init_and_baud(void)
> +{
> + int fd;
> + QTestState *qts = qtest_init_with_serial("-machine k230", &fd);
> +
> + qtest_writel(qts, R(LCR), LCR_DLAB);
> + qtest_writel(qts, R(THR), 0x55);
> + g_assert_cmphex(rd(qts, THR), ==, 0x55);
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + g_assert_cmphex(rd(qts, THR), ==, 0x00);
> +
> + qtest_writel(qts, R(IIR), FCR_FE | FCR_RT_F);
> + qtest_writel(qts, R(IER), IER_RX);
> +
> + /* divisor=1 -> timeout=12800ns */
> + qtest_writel(qts, R(LCR), LCR_8N1 | LCR_DLAB);
> + qtest_writel(qts, R(THR), 1); qtest_writel(qts, R(IER), 0);
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + s1(qts, fd, 'X');
> + qtest_clock_step(qts, 13000);
> + g_assert_cmphex(iid(qts), ==, IIR_TO);
> +
> + /* divisor=100 -> timeout=1.28e6ns; 13000ns too short */
> + rd(qts, THR);
> + qtest_writel(qts, R(LCR), LCR_8N1 | LCR_DLAB);
> + qtest_writel(qts, R(THR), 100); qtest_writel(qts, R(IER), 0);
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + s1(qts, fd, 'Y');
> + qtest_clock_step(qts, 13000);
> + g_assert_cmphex(iid(qts), !=, IIR_TO);
> + qtest_clock_step(qts, 1300000);
> + g_assert_cmphex(iid(qts), ==, IIR_TO);
> +
> + close(fd); qtest_quit(qts);
> +}
> +
> +/* 3. TX / RX datapath */
> +static void test_tx_rx_datapath(void)
> +{
> + int fd;
> + QTestState *qts = qtest_init_with_serial("-machine k230", &fd);
> +
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + g_assert_cmphex(rd(qts, LSR) & (LSR_THRE | LSR_TEMT),
> + ==, LSR_THRE | LSR_TEMT);
> + qtest_writel(qts, R(THR), 'A');
> + g_assert_cmphex(rd(qts, LSR) & (LSR_THRE | LSR_TEMT),
> + ==, LSR_THRE | LSR_TEMT);
> +
> + /* external RX (FIFO mode) */
> + qtest_writel(qts, R(IIR), FCR_FE);
> + qtest_writel(qts, R(IER), IER_RX);
> + sn(qts, fd, "K230", 4);
> + for (int i = 0; i < 4; i++) {
> + if (i < 3) {
> + g_assert_cmphex(iid(qts), ==, IIR_RX);
> + }
> + g_assert_cmphex(rd(qts, THR), ==, "K230"[i]);
> + }
> + g_assert_cmphex(rd(qts, LSR) & LSR_DR, ==, 0);
> +
> + /* loopback */
> + qtest_writel(qts, R(MCR), MCR_LB);
> + qtest_writel(qts, R(THR), 'L');
> + g_assert_cmphex(rd(qts, THR), ==, 'L');
> + g_assert_cmphex(rd(qts, LSR) & LSR_DR, ==, 0);
> +
> + /* no loopback */
> + qtest_writel(qts, R(MCR), 0);
> + qtest_writel(qts, R(THR), 'Z');
> + g_assert_cmphex(rd(qts, LSR) & LSR_DR, ==, 0);
> +
> + /* TFL / RFL */
> + qtest_writel(qts, R(MCR), MCR_LB);
> + qtest_writel(qts, R(IIR), FCR_FE | FCR_RR | FCR_XR);
> + qtest_writel(qts, R(THR), 'X'); qtest_writel(qts, R(THR), 'Y');
> + g_assert_cmphex(rd(qts, TFL), ==, 0);
> + g_assert_cmphex(rd(qts, RFL), ==, 2);
> +
> + /* non-FIFO mode */
> + qtest_writel(qts, R(MCR), 0);
> + qtest_writel(qts, R(IIR), 0);
> + s1(qts, fd, 'N');
> + g_assert_cmphex(rd(qts, THR), ==, 'N');
> + g_assert_cmphex(rd(qts, LSR) & LSR_DR, ==, 0);
> +
> + /* non-FIFO overrun */
> + int i;
> + s1(qts, fd, 'n');
> + g_assert_cmphex(rd(qts, LSR) & LSR_DR, ==, LSR_DR);
> + {
> + char c = 'o';
> + send(fd, &c, 1, 0);
> + }
> + for (i = 0; i < 200; i++) {
> + rd(qts, SCR);
> + g_usleep(1000);
> + }
> + g_assert_cmphex(rd(qts, LSR) & LSR_OE, ==, LSR_OE);
> +
> + close(fd); qtest_quit(qts);
> +}
> +
> +/* 4. THRE interrupt */
> +static void test_thre_interrupt(void)
> +{
> + QTestState *qts = qtest_init("-machine k230 "
> + "-chardev null,id=c0 -serial chardev:c0");
> + qtest_writel(qts, R(LCR), LCR_8N1);
> +
> + qtest_writel(qts, R(THR), 'A');
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> +
> + qtest_writel(qts, R(IER), IER_TX);
> + g_assert_cmphex(iid(qts), ==, IIR_THR);
> +
> + qtest_writel(qts, R(THR), 'B');
> + g_assert_cmphex(iid(qts), ==, IIR_THR);
> +
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> + qtest_quit(qts);
> +}
> +
> +/* 5. RX interrupts: timeout & trigger level */
> +static void test_rx_interrupts(void)
> +{
> + int fd;
> + QTestState *qts = qtest_init_with_serial("-machine k230", &fd);
> +
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + qtest_writel(qts, R(IIR), FCR_FE | FCR_RT_F);
> + qtest_writel(qts, R(IER), IER_RX);
> +
> + /* basic timeout */
> + s1(qts, fd, 'T');
> + qtest_clock_step(qts, 400000);
> + g_assert_cmphex(iid(qts), ==, IIR_TO);
> + g_assert_cmphex(rd(qts, THR), ==, 'T');
> + g_assert_cmphex(iid(qts), !=, IIR_TO);
> +
> + /* timeout reset by new byte */
> + s1(qts, fd, 'A'); qtest_clock_step(qts, 200000);
> + s1(qts, fd, 'B');
> + qtest_clock_step(qts, 200000);
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> + qtest_clock_step(qts, 200000);
> + g_assert_cmphex(iid(qts), ==, IIR_TO);
> + rd(qts, THR);
> + rd(qts, THR);
> +
> + /* timeout rearmed by partial drain */
> + s1(qts, fd, 'X');
> + s1(qts, fd, 'Y');
> + qtest_clock_step(qts, 400000);
> + g_assert_cmphex(iid(qts), ==, IIR_TO);
> + g_assert_cmphex(rd(qts, THR), ==, 'X');
> + qtest_clock_step(qts, 200000);
> + g_assert_cmphex(iid(qts), !=, IIR_TO);
> + qtest_clock_step(qts, 250000);
> + g_assert_cmphex(iid(qts), ==, IIR_TO);
> + g_assert_cmphex(rd(qts, THR), ==, 'Y');
> +
> + /* RX trigger level: RT=Q -> trigger at 8 bytes */
> + qtest_writel(qts, R(IIR), FCR_FE | FCR_RT_Q);
> + sn(qts, fd, "ABCDEFG", 7);
> + g_usleep(20000);
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> + qtest_clock_step(qts, 400000);
> + g_assert_cmphex(iid(qts), ==, IIR_TO);
> + for (int i = 0; i < 7; i++) {
> + rd(qts, THR);
> + }
> +
> + sn(qts, fd, "12345678", 8);
> + for (int i = 0; i < 1000; i++) {
> + if (iid(qts) == IIR_RX) {
> + break;
> + }
> + g_usleep(1000);
> + }
> + g_assert_cmphex(iid(qts), ==, IIR_RX);
> +
> + close(fd); qtest_quit(qts);
> +}
> +
> +/* 6. error interrupts & IIR priority */
> +static void test_error_interrupts(void)
> +{
> + int fd;
> + QTestState *qts = qtest_init_with_serial("-machine k230", &fd);
> +
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + qtest_writel(qts, R(IER), IER_LS);
> +
> + /* OE -> IIR=0x6; LSR clears; ELCOLR=0: RBR clears; ELCOLR=1: RBR keeps */
> + oe_nf(qts, fd);
> + g_assert_cmphex(iid(qts), ==, IIR_LINE);
> + rd(qts, LSR);
> + g_assert_cmphex(iid(qts), !=, IIR_LINE);
> +
> + oe_nf(qts, fd);
> + g_assert_cmphex(iid(qts), ==, IIR_LINE);
> + rd(qts, THR);
> + g_assert_cmphex(iid(qts), !=, IIR_LINE);
> +
> + qtest_writel(qts, R(IER), IER_LS | IER_COLR);
> + oe_nf(qts, fd);
> + g_assert_cmphex(iid(qts), ==, IIR_LINE);
> + rd(qts, THR);
> + g_assert_cmphex(iid(qts), ==, IIR_LINE);
> + rd(qts, LSR);
> + g_assert_cmphex(iid(qts), !=, IIR_LINE);
> +
> + /* IIR priority: RX > TX (loopback) */
> + qtest_writel(qts, R(IIR), FCR_FE);
> + qtest_writel(qts, R(MCR), MCR_LB);
> + qtest_writel(qts, R(IER), IER_TX | IER_RX);
> + qtest_writel(qts, R(THR), 'P');
> + g_assert_cmphex(iid(qts), ==, IIR_RX);
> + g_assert_cmphex(rd(qts, THR), ==, 'P');
> + g_assert_cmphex(iid(qts), ==, IIR_THR);
> + iid(qts);
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> +
> + /* OE in FIFO mode via loopback */
> + qtest_writel(qts, R(IER), IER_LS);
> + for (int i = 0; i < 32; i++) {
> + qtest_writel(qts, R(THR), 'a');
> + }
> + g_assert_cmphex(rd(qts, LSR) & LSR_OE, ==, 0);
> + qtest_writel(qts, R(THR), 'z');
> + g_assert_cmphex(iid(qts), ==, IIR_LINE);
> + g_assert_cmphex(rd(qts, LSR) & LSR_OE, ==, LSR_OE);
> +
> + close(fd); qtest_quit(qts);
> +}
> +
> +/* 7. USR & busy detect */
> +static void test_busy_detect(void)
> +{
> + int fd;
> + QTestState *qts = qtest_init_with_serial("-machine k230", &fd);
> +
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + qtest_writel(qts, R(IIR), FCR_FE);
> +
> + g_assert_cmphex(rd(qts, USR) & 0x1e, ==, 0x06);
> +
> + qtest_writel(qts, R(MCR), MCR_LB);
> + qtest_writel(qts, R(THR), 'A');
> + g_assert_cmphex(rd(qts, USR) & 0x08, ==, 0x08);
> + rd(qts, THR);
> + g_assert_cmphex(rd(qts, USR) & 0x08, ==, 0);
> + qtest_writel(qts, R(MCR), 0);
> +
> + /* BUSY via RX & loopback */
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, 0);
> + s1(qts, fd, 'Z');
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, USR_BUSY);
> + rd(qts, THR);
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, 0);
> +
> + qtest_writel(qts, R(MCR), MCR_LB);
> + qtest_writel(qts, R(THR), 'L');
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, USR_BUSY);
> + rd(qts, THR);
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, 0);
> +
> + /* busy-detect: LCR write rejected while BUSY=1 */
> + qtest_writel(qts, R(MCR), 0);
> + qtest_writel(qts, R(IIR), FCR_FE | FCR_RR | FCR_XR);
> + s1(qts, fd, 'B');
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, USR_BUSY);
> + qtest_writel(qts, R(LCR), LCR_8N1 | LCR_DLAB);
> + g_assert_cmphex(rd(qts, LCR), ==, LCR_8N1);
> + g_assert_cmphex(iid(qts), ==, IIR_BUSY);
> + rd(qts, USR);
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> + qtest_writel(qts, R(IIR), FCR_FE | FCR_RR);
> + g_assert_cmphex(rd(qts, USR) & USR_BUSY, ==, 0);
> + qtest_writel(qts, R(LCR), LCR_8N1 | LCR_DLAB);
> + g_assert_cmphex(rd(qts, LCR), ==, LCR_8N1 | LCR_DLAB);
> +
> + close(fd); qtest_quit(qts);
> +}
> +
> +/* 8. advanced features */
> +static void test_advanced_features(void)
> +{
> + QTestState *qts = qtest_init("-machine k230 "
> + "-chardev null,id=c0 -serial chardev:c0");
> +
> + /* shadow: SRTS<->MCR.RTS, SBCR<->LCR.BC, SDMAM, SFE, SRT, STET, HTX */
> + qtest_writel(qts, R(SRTS), 1);
> + g_assert_cmphex(rd(qts, MCR) & MCR_RTS, ==, MCR_RTS);
> + qtest_writel(qts, R(MCR), 0); g_assert_cmphex(rd(qts, SRTS), ==, 0);
> + qtest_writel(qts, R(SBCR), 1);
> + g_assert_cmphex(rd(qts, LCR) & LCR_BC, ==, LCR_BC);
> + qtest_writel(qts, R(LCR), 0); g_assert_cmphex(rd(qts, SBCR), ==, 0);
> + qtest_writel(qts, R(SDMAM), 1); g_assert_cmphex(rd(qts, SDMAM), ==, 1);
> + qtest_writel(qts, R(SRT), 0x2); g_assert_cmphex(rd(qts, SRT), ==, 0x2);
> + qtest_writel(qts, R(STET), 0x3); g_assert_cmphex(rd(qts, STET), ==, 0x3);
> + qtest_writel(qts, R(SFE), 1); g_assert_cmphex(rd(qts, SFE), ==, 1);
> + g_assert_cmphex(rd(qts, IIR) & IIR_FF, ==, IIR_FF);
> + qtest_writel(qts, R(HTX), 1); g_assert_cmphex(rd(qts, HTX), ==, 1);
> + qtest_writel(qts, R(HTX), 0); g_assert_cmphex(rd(qts, HTX), ==, 0);
> +
> + /* HTX halt TX */
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + qtest_writel(qts, R(IIR), FCR_FE);
> + qtest_writel(qts, R(MCR), MCR_LB);
> +
> + qtest_writel(qts, R(HTX), 1);
> + qtest_writel(qts, R(THR), 'H');
> + g_assert_cmphex(rd(qts, TFL), ==, 1);
> + g_assert_cmphex(rd(qts, RFL), ==, 0);
> +
> + qtest_writel(qts, R(HTX), 0);
> + g_assert_cmphex(rd(qts, TFL), ==, 0);
> + g_assert_cmphex(rd(qts, RFL), ==, 1);
> + g_assert_cmphex(rd(qts, THR), ==, 'H');
> +
> + /* SRR: RFR & UR */
> + qtest_writel(qts, R(THR), 'Z');
> + g_assert_cmphex(rd(qts, RFL), ==, 1);
> + g_assert_cmphex(rd(qts, LSR) & LSR_DR, ==, LSR_DR);
> + qtest_writel(qts, R(SRR), SRR_RFR);
> + g_assert_cmphex(rd(qts, RFL), ==, 0);
> + g_assert_cmphex(rd(qts, LSR) & LSR_DR, ==, 0);
> + g_assert_cmphex(rd(qts, SRR), ==, 0);
> + qtest_writel(qts, R(THR), 'Y');
> + qtest_writel(qts, R(SRR), SRR_UR);
> + g_assert_cmphex(rd(qts, LSR), ==, LSR_RESET);
> + g_assert_cmphex(iid(qts), ==, IIR_NONE);
> + g_assert_cmphex(rd(qts, RFL), ==, 0);
> +
> + /* PTIME + TET programmable THRE */
> + qtest_writel(qts, R(LCR), LCR_8N1);
> + qtest_writel(qts, R(IIR), FCR_FE | FCR_TET_H);
> + qtest_writel(qts, R(IER), IER_TX | IER_PTIME);
> + qtest_writel(qts, R(THR), 'A');
> + g_assert_cmphex(rd(qts, LSR) & LSR_THRE, ==, LSR_THRE);
> + g_assert_cmphex(iid(qts), ==, IIR_THR);
> +
> + qtest_quit(qts);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + g_test_init(&argc, &argv, NULL);
> + qtest_add_func("/k230-uart/device_probe", test_device_probe);
> + qtest_add_func("/k230-uart/init_and_baud", test_init_and_baud);
> + qtest_add_func("/k230-uart/tx_rx_datapath", test_tx_rx_datapath);
> + qtest_add_func("/k230-uart/thre_interrupt", test_thre_interrupt);
> + qtest_add_func("/k230-uart/rx_interrupts", test_rx_interrupts);
> + qtest_add_func("/k230-uart/error_interrupts", test_error_interrupts);
> + qtest_add_func("/k230-uart/busy_detect", test_busy_detect);
> + qtest_add_func("/k230-uart/advanced_features", test_advanced_features);
> + return g_test_run();
> +}
> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 822e0bd286970339fe28127649feb131ce8a81b2..93246d9bf77206e9cebb9d8ade5801f4541d3b8d 100644
> --- a/tests/qtest/meson.build
> +++ b/tests/qtest/meson.build
> @@ -294,7 +294,7 @@ qtests_riscv64 = ['riscv-csr-test'] + \
> (config_all_devices.has_key('CONFIG_IOMMU_TESTDEV') and
> config_all_devices.has_key('CONFIG_RISCV_IOMMU') ?
> ['iommu-riscv-test'] : []) + \
> - (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test'] : [])
> + (config_all_devices.has_key('CONFIG_K230') ? ['k230-wdt-test', 'k230-uart-test'] : [])
>
> qtests_hexagon = ['boot-serial-test']
>
>
next prev parent reply other threads:[~2026-08-05 20:11 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-25 3:52 [PATCH RESEND v2 0/3] riscv: Add K230 DW 8250-compatible UART WX Chen
2026-07-25 3:52 ` [PATCH RESEND v2 1/3] hw/char: add " WX Chen
2026-08-05 20:01 ` Daniel Henrique Barboza
2026-08-07 9:49 ` zhenbaii
2026-07-25 3:52 ` [PATCH RESEND v2 2/3] hw/riscv: k230: connect DW 8250 UART WX Chen
2026-08-05 20:02 ` Daniel Henrique Barboza
2026-07-25 3:52 ` [PATCH RESEND v2 3/3] tests/qtest: add K230 UART test WX Chen
2026-08-05 20:10 ` Daniel Henrique Barboza [this message]
2026-08-07 11:53 ` WX Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=af3d837c-e7f2-48ce-9b9c-c2ea9e4d8fb8@oss.qualcomm.com \
--to=daniel.barboza@oss.qualcomm.com \
--cc=alistair.francis@wdc.com \
--cc=chao.liu.zevorn@gmail.com \
--cc=farosas@suse.de \
--cc=liwei1518@gmail.com \
--cc=lvivier@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=palmer@dabbelt.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=wxchen0913@gmail.com \
--cc=zhiwei_liu@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.