From patchwork Sun Nov 17 22:56:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= X-Patchwork-Id: 13877980 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7CD47D10F39 for ; Sun, 17 Nov 2024 23:01:48 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCoGI-0008DC-S3; Sun, 17 Nov 2024 18:00:59 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCoCp-0007gu-Oz for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:23 -0500 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCoCn-0002rp-Vl for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:23 -0500 Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-4314f38d274so22193485e9.1 for ; Sun, 17 Nov 2024 14:57:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731884239; x=1732489039; darn=nongnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=1NcEwOeWHFjScd3fyiWygZ/Gn+PwBjhmbkNrTkjnAq0=; b=mupT/e7qdYOYXt7+377+465MdHDdTAL3RMBh5s2FDz04dxM6h3VeHww7cTej85Y7Ct F/1klm5+e+VyZnITo3AOmiunE3GJtDobz0xyDpJ7vaYLlZYlWoB9J2Qai/PFJicru6nR lKHxfUy/BLiRB8D42vGgTOD5bkWs14mhIZim5cFIlNjcAo/58P6l49znOGleUDe+2TS+ rB4nl4Zd1SbSH/pNXQjJeq8rk9159Bsq8hDNHv/uBX/Z68tM5DoaXdvvSDuF40mb1Iic fs42ONvCOXT2JCxP53gMuhsFj8Af1GGg2i9Kg02oCjwoB8904Mt8+YM7j7/tX+guPQuz S3hA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731884239; x=1732489039; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=1NcEwOeWHFjScd3fyiWygZ/Gn+PwBjhmbkNrTkjnAq0=; b=nwQD8s0L/Q0ZQav7oU2FHmiJM1Fs/RQw2l3eZaGnD8vQ7QB1sRwWgpTjmlVlvywqq/ uKz8EBRp+XL5JBeMt/XtDCLoGuhmxkIJkECcI6Cm1kbPLWQxN9SHjmrq8JlUcBgnm5JF WD9awAjc8grFiWhx4q+rkCZPust6lDhlQ1lCUi9s0Kxai0KPvY1zsQo2JWuU7oICUY0c H07zdT98gbQmKs8n4IhnjCsHXQO0v32IobP0n0L4nOfunrtaxm0S99S5dIubXc8FhsuM 7ZUlTI0w7MY3IlJ4i6z9pudRJQPS6/K7dZ3sguc5wtXR2z0ZhPWTU7ufGvVNfPoLBAOW C3bQ== X-Gm-Message-State: AOJu0Yy+k5x1q5YsHlUPZaFiDvuSrJbk5KRItgRmhcpMakoltrxGP1UJ oLrzHIO4tFrsmvA8TKl823uZ8FY0jrviy2UKbwTS2w68n4yc3cEAGxf7RJ4of46pWg== X-Google-Smtp-Source: AGHT+IGityb++P2QNHfzL1tQFPXgnzhhnm2gEnYCP+wueEUgsHkCwmXS8D9lwl3W2HTByrQFFEvmeA== X-Received: by 2002:a05:600c:501e:b0:431:4847:47c0 with SMTP id 5b1f17b1804b1-432df722c63mr103673425e9.7.1731884238771; Sun, 17 Nov 2024 14:57:18 -0800 (PST) Received: from asus-xubuntu.. ([82.78.167.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432da2800absm136351505e9.25.2024.11.17.14.57.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Nov 2024 14:57:18 -0800 (PST) From: " =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= " X-Google-Original-From: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= To: qemu-devel@nongnu.org Cc: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= Subject: [PATCH 1/7] [BCM2835 AUX 1/7] Replace hard-coded FIFO Date: Mon, 18 Nov 2024 00:56:37 +0200 Message-Id: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::334; envelope-from=jean.christian.cirstea@gmail.com; helo=mail-wm1-x334.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 18:00:54 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The previous BCM2835 mini UART implementation used a hard-coded FIFO. This commit changes the implementation by making use of the provided Fifo8. Signed-off-by: Ioan-Cristian CÎRSTEA --- hw/char/bcm2835_aux.c | 61 ++++++++++++++++++----------------- include/hw/char/bcm2835_aux.h | 10 +++--- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index fca2f27a55..540cb30872 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -47,14 +47,23 @@ #define RX_INT 0x1 #define TX_INT 0x2 +/* FIFOs length */ +#define BCM2835_AUX_RX_FIFO_LEN 8 +#define BCM2835_AUX_TX_FIOF_LEN 8 + +/* TODO: Add separate functions for RX and TX interrupts */ static void bcm2835_aux_update(BCM2835AuxState *s) { + /* TODO: this should be a pointer to const data. However, the fifo8 API + * requires a pointer to non-const data. + */ + Fifo8 *rx_fifo = &s->rx_fifo; /* signal an interrupt if either: * 1. rx interrupt is enabled and we have a non-empty rx fifo, or * 2. the tx interrupt is enabled (since we instantly drain the tx fifo) */ s->iir = 0; - if ((s->ier & RX_INT) && s->read_count != 0) { + if ((s->ier & RX_INT) && fifo8_is_empty(rx_fifo) == false) { s->iir |= RX_INT; } if (s->ier & TX_INT) { @@ -66,7 +75,10 @@ static void bcm2835_aux_update(BCM2835AuxState *s) static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) { BCM2835AuxState *s = opaque; - uint32_t c, res; + Fifo8 *rx_fifo = &s->rx_fifo; + const bool is_rx_fifo_not_empty = !fifo8_is_empty(rx_fifo); + const uint32_t rx_fifo_fill_level = fifo8_num_used(rx_fifo); + uint32_t c = 0, res; switch (offset) { case AUX_IRQ: @@ -77,12 +89,8 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) case AUX_MU_IO_REG: /* "DLAB bit set means access baudrate register" is NYI */ - c = s->read_fifo[s->read_pos]; - if (s->read_count > 0) { - s->read_count--; - if (++s->read_pos == BCM2835_AUX_RX_FIFO_LEN) { - s->read_pos = 0; - } + if (is_rx_fifo_not_empty) { + c = fifo8_pop(rx_fifo); } qemu_chr_fe_accept_input(&s->chr); bcm2835_aux_update(s); @@ -98,7 +106,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) * interrupts are active, besides that this cannot occur. At * present, we choose to prioritise the rx interrupt, since * the tx fifo is always empty. */ - if (s->read_count != 0) { + if (is_rx_fifo_not_empty) { res |= 0x4; } else { res |= 0x2; @@ -118,7 +126,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) case AUX_MU_LSR_REG: res = 0x60; /* tx idle, empty */ - if (s->read_count != 0) { + if (is_rx_fifo_not_empty) { res |= 0x1; } return res; @@ -136,10 +144,10 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) case AUX_MU_STAT_REG: res = 0x30e; /* space in the output buffer, empty tx fifo, idle tx/rx */ - if (s->read_count > 0) { + if (is_rx_fifo_not_empty) { res |= 0x1; /* data in input buffer */ - assert(s->read_count <= BCM2835_AUX_RX_FIFO_LEN); - res |= ((uint32_t)s->read_count) << 16; /* rx fifo fill level */ + assert(rx_fifo_fill_level <= BCM2835_AUX_RX_FIFO_LEN); + res |= ((uint32_t)rx_fifo_fill_level) << 16; /* rx fifo fill level */ } return res; @@ -158,6 +166,7 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { BCM2835AuxState *s = opaque; + Fifo8 *rx_fifo = &s->rx_fifo; unsigned char ch; switch (offset) { @@ -185,7 +194,7 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, case AUX_MU_IIR_REG: if (value & 0x2) { - s->read_count = 0; + fifo8_reset(rx_fifo); } break; @@ -221,24 +230,18 @@ static int bcm2835_aux_can_receive(void *opaque) { BCM2835AuxState *s = opaque; - return s->read_count < BCM2835_AUX_RX_FIFO_LEN; + return !fifo8_is_full(&s->rx_fifo); } static void bcm2835_aux_put_fifo(void *opaque, uint8_t value) { BCM2835AuxState *s = opaque; - int slot; + Fifo8 *rx_fifo = &s->rx_fifo; - slot = s->read_pos + s->read_count; - if (slot >= BCM2835_AUX_RX_FIFO_LEN) { - slot -= BCM2835_AUX_RX_FIFO_LEN; - } - s->read_fifo[slot] = value; - s->read_count++; - if (s->read_count == BCM2835_AUX_RX_FIFO_LEN) { - /* buffer full */ + if (fifo8_is_full(rx_fifo) == false) { + fifo8_push(rx_fifo, value); + bcm2835_aux_update(s); } - bcm2835_aux_update(s); } static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size) @@ -261,10 +264,8 @@ static const VMStateDescription vmstate_bcm2835_aux = { .version_id = 1, .minimum_version_id = 1, .fields = (const VMStateField[]) { - VMSTATE_UINT8_ARRAY(read_fifo, BCM2835AuxState, - BCM2835_AUX_RX_FIFO_LEN), - VMSTATE_UINT8(read_pos, BCM2835AuxState), - VMSTATE_UINT8(read_count, BCM2835AuxState), + VMSTATE_FIFO8(rx_fifo, BCM2835AuxState), + VMSTATE_FIFO8(_tx_fifo, BCM2835AuxState), VMSTATE_UINT8(ier, BCM2835AuxState), VMSTATE_UINT8(iir, BCM2835AuxState), VMSTATE_END_OF_LIST() @@ -276,6 +277,8 @@ static void bcm2835_aux_init(Object *obj) SysBusDevice *sbd = SYS_BUS_DEVICE(obj); BCM2835AuxState *s = BCM2835_AUX(obj); + fifo8_create(&s->rx_fifo, BCM2835_AUX_RX_FIFO_LEN); + memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_aux_ops, s, TYPE_BCM2835_AUX, 0x100); sysbus_init_mmio(sbd, &s->iomem); diff --git a/include/hw/char/bcm2835_aux.h b/include/hw/char/bcm2835_aux.h index 9e081793a0..cb1a824994 100644 --- a/include/hw/char/bcm2835_aux.h +++ b/include/hw/char/bcm2835_aux.h @@ -9,15 +9,14 @@ #ifndef BCM2835_AUX_H #define BCM2835_AUX_H -#include "hw/sysbus.h" #include "chardev/char-fe.h" +#include "hw/sysbus.h" +#include "qemu/fifo8.h" #include "qom/object.h" #define TYPE_BCM2835_AUX "bcm2835-aux" OBJECT_DECLARE_SIMPLE_TYPE(BCM2835AuxState, BCM2835_AUX) -#define BCM2835_AUX_RX_FIFO_LEN 8 - struct BCM2835AuxState { /*< private >*/ SysBusDevice parent_obj; @@ -27,8 +26,9 @@ struct BCM2835AuxState { CharBackend chr; qemu_irq irq; - uint8_t read_fifo[BCM2835_AUX_RX_FIFO_LEN]; - uint8_t read_pos, read_count; + Fifo8 rx_fifo; + /* Unused for now */ + Fifo8 _tx_fifo; uint8_t ier, iir; }; From patchwork Sun Nov 17 22:56:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= X-Patchwork-Id: 13877983 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B2A78D10F38 for ; Sun, 17 Nov 2024 23:02:45 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCoGO-0008Ee-3Y; Sun, 17 Nov 2024 18:01:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCoCp-0007gs-L8 for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:23 -0500 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCoCn-0002rx-WC for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:23 -0500 Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-4314c4cb752so21914835e9.2 for ; Sun, 17 Nov 2024 14:57:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731884240; x=1732489040; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=18E/3zGs9HMVV32crijwYqItWb76EfGhA7NDcdf18zI=; b=ZY2ie++C3qDnao3snaSM/v2tuJBRVuMbnSmBk1zEzfJDZ1dCt6w8slSzUU0UIlJPWO MPiXGGVd6LFnl8phdRrKj+WWnRCSpll/7nqflIovwkQzB4Ks6R0YTZKQUI6adkGhQ3do GHdzAg3GC07Tj66uTSOCEdXiLgSMpZW2j025ejBU7wYzxZh7981BsKUfNjvU3neqrNWl J+vVxKYp8O1LKqiTxgYwuB54cxLPASWTRAhYrGN241ZAsXGzUZtvo4OFMta+y40JcAh2 d1+n6kLNUWLTObD7eKNfQaoVEh7MTuLOiS4G8jhJL0ZSS6Ah7S/uLI2t7CJ3wDyl0S/0 E9OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731884240; x=1732489040; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=18E/3zGs9HMVV32crijwYqItWb76EfGhA7NDcdf18zI=; b=C7Ze6E75CIjnOjIJMzmpiN3FrucmrZwdQl/D9dumNcm3GTknwSdQ5MHA1YYpF8pvpp fpPQWbaK2L2pBExLi4Ic9mJ2P4LR6ybLuinbRNwo++CkdaQpI8pqSxg8oHh274zvgeO0 DlNR0AAXn9U14YLQ3djfFF4PKEiaa6b9KEEFbjumHv2vKMt2CN16egZv9Nkfd4LPQMvC wfVEK4VhTYVHzmec2huP+wP6cIj9Pdl/O2Z7koc2VxDJpuZvQZD3gwoegxL/9iTR2TLD Oh97N1hViOQaf163eWNc1oD4b90kYB0dt3OCiRVo5zZ3g5lBKrgrs3G8wtdlJMwyIhb8 gkvw== X-Gm-Message-State: AOJu0Yw87o+SzNRIYLPMZe3zO+zUKNyzICsN7KYGc93tc4AQHpST/+BH FfHuV5TjpcuvVfFK6XQkQtP97MMDwL/UNeaDxujjGMW5rvRPFxGv+el7HqVqXuclnQ== X-Google-Smtp-Source: AGHT+IHLc6Sm+j9iQX+jKzbrHRuFIBpPEfgrjZQYK0sgcCONCFBIN1qTQNe5lmRmmMZCPooj8R7N+A== X-Received: by 2002:a05:6000:186e:b0:382:442c:2c54 with SMTP id ffacd0b85a97d-382442c2f00mr1758432f8f.28.1731884240294; Sun, 17 Nov 2024 14:57:20 -0800 (PST) Received: from asus-xubuntu.. ([82.78.167.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432da2800absm136351505e9.25.2024.11.17.14.57.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Nov 2024 14:57:19 -0800 (PST) From: " =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= " X-Google-Original-From: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= To: qemu-devel@nongnu.org Cc: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= Subject: [PATCH 2/7] [BCM2835 AUX 2/7] Add basic support for CNTL register Date: Mon, 18 Nov 2024 00:56:38 +0200 Message-Id: <20241117225643.768322-2-ioan-cristian.cirstea@tutanota.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> References: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::334; envelope-from=jean.christian.cirstea@gmail.com; helo=mail-wm1-x334.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 18:00:54 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit allows software to enable/disable both the receiver and the transmitter through the CNTL register. Signed-off-by: Ioan-Cristian CÎRSTEA --- hw/char/bcm2835_aux.c | 50 +++++++++++++++++++++++++++++------ include/hw/char/bcm2835_aux.h | 3 ++- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index 540cb30872..ebc7f5ade5 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -29,6 +29,7 @@ #include "qemu/log.h" #include "qemu/module.h" +/* TODO: These constants need to be unsigned */ #define AUX_IRQ 0x0 #define AUX_ENABLES 0x4 #define AUX_MU_IO_REG 0x40 @@ -43,10 +44,17 @@ #define AUX_MU_STAT_REG 0x64 #define AUX_MU_BAUD_REG 0x68 +/* Register masks */ +#define MASK_AUX_MU_CNTL_REG 0x3 + /* bits in IER/IIR registers */ #define RX_INT 0x1 #define TX_INT 0x2 +/* bits in CNTL register */ +#define RX_ENABLE 0x1 +#define TX_ENABLE 0x2 + /* FIFOs length */ #define BCM2835_AUX_RX_FIFO_LEN 8 #define BCM2835_AUX_TX_FIOF_LEN 8 @@ -72,13 +80,27 @@ static void bcm2835_aux_update(BCM2835AuxState *s) qemu_set_irq(s->irq, s->iir != 0); } +static bool bcm2835_aux_is_tx_enabled(BCM2835AuxState *s) +{ + return (s->cntl & TX_ENABLE) != 0; +} + +static bool bcm2835_aux_is_rx_enabled(BCM2835AuxState *s) +{ + return (s->cntl & RX_ENABLE) != 0; +} + static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) { BCM2835AuxState *s = opaque; Fifo8 *rx_fifo = &s->rx_fifo; const bool is_rx_fifo_not_empty = !fifo8_is_empty(rx_fifo); const uint32_t rx_fifo_fill_level = fifo8_num_used(rx_fifo); - uint32_t c = 0, res; + /* + * 0xFF trashes terminal output, so device driver bugs can be found quickly + * in case the RX_FIFO is read while empty + */ + uint32_t c = 0xFF, res; switch (offset) { case AUX_IRQ: @@ -140,7 +162,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) return 0; case AUX_MU_CNTL_REG: - return 0x3; /* tx, rx enabled */ + return s->cntl; case AUX_MU_STAT_REG: res = 0x30e; /* space in the output buffer, empty tx fifo, idle tx/rx */ @@ -183,7 +205,9 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, ch = value; /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - qemu_chr_fe_write_all(&s->chr, &ch, 1); + if (bcm2835_aux_is_tx_enabled(s)) { + qemu_chr_fe_write_all(&s->chr, &ch, 1); + } break; case AUX_MU_IER_REG: @@ -211,7 +235,12 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, break; case AUX_MU_CNTL_REG: - qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_CNTL_REG unsupported\n", __func__); + if (value & ~MASK_AUX_MU_CNTL_REG) { + qemu_log_mask(LOG_UNIMP, + "%s: auto flow control not supported\n", + __func__); + } + s->cntl = value & MASK_AUX_MU_CNTL_REG; break; case AUX_MU_BAUD_REG: @@ -233,7 +262,7 @@ static int bcm2835_aux_can_receive(void *opaque) return !fifo8_is_full(&s->rx_fifo); } -static void bcm2835_aux_put_fifo(void *opaque, uint8_t value) +static void bcm2835_aux_put_fifo(BCM2835AuxState *s, uint8_t value) { BCM2835AuxState *s = opaque; Fifo8 *rx_fifo = &s->rx_fifo; @@ -246,7 +275,11 @@ static void bcm2835_aux_put_fifo(void *opaque, uint8_t value) static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size) { - bcm2835_aux_put_fifo(opaque, *buf); + BCM2835AuxState *s = opaque; + + if (bcm2835_aux_is_rx_enabled(s)) { + bcm2835_aux_put_fifo(opaque, *buf); + } } static const MemoryRegionOps bcm2835_aux_ops = { @@ -266,8 +299,9 @@ static const VMStateDescription vmstate_bcm2835_aux = { .fields = (const VMStateField[]) { VMSTATE_FIFO8(rx_fifo, BCM2835AuxState), VMSTATE_FIFO8(_tx_fifo, BCM2835AuxState), - VMSTATE_UINT8(ier, BCM2835AuxState), - VMSTATE_UINT8(iir, BCM2835AuxState), + VMSTATE_UINT32(ier, BCM2835AuxState), + VMSTATE_UINT32(iir, BCM2835AuxState), + VMSTATE_UINT32(cntl, BCM2835AuxState), VMSTATE_END_OF_LIST() } }; diff --git a/include/hw/char/bcm2835_aux.h b/include/hw/char/bcm2835_aux.h index cb1a824994..feaedc9e2f 100644 --- a/include/hw/char/bcm2835_aux.h +++ b/include/hw/char/bcm2835_aux.h @@ -29,7 +29,8 @@ struct BCM2835AuxState { Fifo8 rx_fifo; /* Unused for now */ Fifo8 _tx_fifo; - uint8_t ier, iir; + /* Registers */ + uint32_t ier, iir, cntl; }; #endif From patchwork Sun Nov 17 22:56:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= X-Patchwork-Id: 13877979 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9CDB9D10F38 for ; Sun, 17 Nov 2024 23:01:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCoGG-0008Cx-Rn; Sun, 17 Nov 2024 18:00:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCoCr-0007hA-7N for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:25 -0500 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCoCp-0002s6-Fk for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:25 -0500 Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-4314c4cb752so21914915e9.2 for ; Sun, 17 Nov 2024 14:57:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731884242; x=1732489042; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=OfUX/8zvMAkV8YsOzKiP/pvIj1mwKy7Bw3sUmbojNMA=; b=OjslYWJqhdKmMSRioKSRZij9Zb2JWZFav41vfsg8uiFc+e3u0VgeXVBzp6O5umLghG nRhxJ7x7axR3cfdiPLucvKptnWq+H5I1GYc8JoLpmJBAy+RAb+ugHWlYELouEARC8Zdi G4GaSJ5sGtYUzM/jNPg46o/4D/OFhqRknrmw/hChCOLU5BLsDLJv/bYMxzBOQ8RslDXx kvdnePM5hHdJ+Ab/wjc5mMRpjNBsb3UTg1+rNXr2EVtspNO0ll/4V+sy2/tv5+AGNd6t PAAF7Azu7iy4cYLyG9pczcCA2SUT/PrYZUeCh/b/mtGshmH4fhhSAuK5SKkGCPTPf+2f THew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731884242; x=1732489042; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OfUX/8zvMAkV8YsOzKiP/pvIj1mwKy7Bw3sUmbojNMA=; b=BiBbWQlW9vKgmXkClBVnN92h1bREyD8Rz3hB2RoOLBc6HZN+36K9BCdekz36XHsaMA Jqym+zSRf6XLjjdMXUf/1ozZx8974JOlc4T036JbAP9KlUI9VPjyHmGheC9LXKHkJkw0 I3m3eJUlDW742/rULLrTbskDwoGXHXOrSRGvBSrQqH2UYjWhIGJa4LFijhWcbEEwMeZA /e3Z3jdo+Rc3RNeqPacrtNMsrgM2s/DPhAuGxy8F5f+NZKeXYTlkT78nXNL8f4togoLn JU3YMRFxImoga/L38bcGhctjld9LLN9SDUxKTVe1aqUwUHnXWxlSwkO50GDeqcec1fp5 B98w== X-Gm-Message-State: AOJu0YwZHQD6CFS223KaZ9QwL+eYeHEUS8kmFTRows4J1Bm8AGKr2hBw kh6GVBNGqzziLBkaTSCwGDJEakawrXEQMUxLR/InveU+RZFBMkPjdtm++KfrA22F/Q== X-Google-Smtp-Source: AGHT+IHxVGZsrnGbwKvMGzproedHbdM7SqzzfnNAxoPJfvjQTJ2WD7rhSlfRYmYDKlAuh1g1Mp93Mg== X-Received: by 2002:a05:600c:4693:b0:431:5632:448b with SMTP id 5b1f17b1804b1-432df78ba78mr87569845e9.25.1731884241833; Sun, 17 Nov 2024 14:57:21 -0800 (PST) Received: from asus-xubuntu.. ([82.78.167.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432da2800absm136351505e9.25.2024.11.17.14.57.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Nov 2024 14:57:21 -0800 (PST) From: " =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= " X-Google-Original-From: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= To: qemu-devel@nongnu.org Cc: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= Subject: [PATCH 3/7] [BCM2835 AUX 3/7] Asynchronous transmit Date: Mon, 18 Nov 2024 00:56:39 +0200 Message-Id: <20241117225643.768322-3-ioan-cristian.cirstea@tutanota.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> References: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::336; envelope-from=jean.christian.cirstea@gmail.com; helo=mail-wm1-x336.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 18:00:54 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit changes data transmission: instead of using the blocking function `qemu_chr_fe_write_all()`, the transmit logic using the asynchronous counterpart `qemu_chr_fe_write()`. Signed-off-by: Ioan-Cristian CÎRSTEA --- hw/char/bcm2835_aux.c | 110 ++++++++++++++++++++++++++++++---- include/hw/char/bcm2835_aux.h | 5 +- 2 files changed, 101 insertions(+), 14 deletions(-) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index ebc7f5ade5..2ef3459566 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -55,17 +55,29 @@ #define RX_ENABLE 0x1 #define TX_ENABLE 0x2 +/* bits in STAT register */ +#define STAT_TRANSMITTER_DONE 0x200 + /* FIFOs length */ #define BCM2835_AUX_RX_FIFO_LEN 8 -#define BCM2835_AUX_TX_FIOF_LEN 8 +#define BCM2835_AUX_TX_FIFO_LEN 8 + +#define log_guest_error(fmt, ...) \ + qemu_log_mask(LOG_GUEST_ERROR, \ + "bcm2835_aux:%s:%d: " fmt, \ + __func__, \ + __LINE__, \ + ##__VA_ARGS__ \ + ) /* TODO: Add separate functions for RX and TX interrupts */ -static void bcm2835_aux_update(BCM2835AuxState *s) +static void bcm2835_aux_update_irq(BCM2835AuxState *s) { /* TODO: this should be a pointer to const data. However, the fifo8 API * requires a pointer to non-const data. */ Fifo8 *rx_fifo = &s->rx_fifo; + Fifo8 *tx_fifo = &s->tx_fifo; /* signal an interrupt if either: * 1. rx interrupt is enabled and we have a non-empty rx fifo, or * 2. the tx interrupt is enabled (since we instantly drain the tx fifo) @@ -74,13 +86,19 @@ static void bcm2835_aux_update(BCM2835AuxState *s) if ((s->ier & RX_INT) && fifo8_is_empty(rx_fifo) == false) { s->iir |= RX_INT; } - if (s->ier & TX_INT) { + if (s->ier & TX_INT && fifo8_is_empty(tx_fifo)) { s->iir |= TX_INT; } qemu_set_irq(s->irq, s->iir != 0); } -static bool bcm2835_aux_is_tx_enabled(BCM2835AuxState *s) +static void bcm2835_aux_update(BCM2835AuxState *s) +{ + /* Currently, only IRQ registers are updated */ + bcm2835_aux_update_irq(s); +} + +static bool bcm2835_aux_is_tx_enabled(const BCM2835AuxState *s) { return (s->cntl & TX_ENABLE) != 0; } @@ -90,6 +108,70 @@ static bool bcm2835_aux_is_rx_enabled(BCM2835AuxState *s) return (s->cntl & RX_ENABLE) != 0; } +static bool bcm2835_aux_put_tx_fifo(BCM2835AuxState *s, char ch) +{ + Fifo8 *tx_fifo = &s->tx_fifo; + + if (fifo8_is_full(tx_fifo)) { + log_guest_error("TX buffer overflow"); + + return false; + } + + fifo8_push(tx_fifo, ch); + + return true; +} + +static gboolean bcm2835_aux_xmit_handler(void *do_not_use, GIOCondition cond, + void *opaque) +{ + BCM2835AuxState *s = opaque; + Fifo8 *tx_fifo = &s->tx_fifo; + + if (!fifo8_is_empty(tx_fifo)) { + const uint8_t ch = fifo8_pop(&s->tx_fifo); + qemu_chr_fe_write(&s->chr, &ch, 1); + + return G_SOURCE_CONTINUE; + } else { + bcm2835_aux_update(s); + + return G_SOURCE_REMOVE; + } +} + +static bool bcm2835_aux_is_tx_busy(const BCM2835AuxState *s) +{ + return !(s->stat & STAT_TRANSMITTER_DONE); +} + +static bool bcm2835_aux_can_send(const BCM2835AuxState *s) +{ + return bcm2835_aux_is_tx_enabled(s) && !bcm2835_aux_is_tx_busy(s); +} + +static void bcm2835_aux_send(BCM2835AuxState *s) +{ + if (bcm2835_aux_can_send(s)) { + const uint8_t ch = fifo8_pop(&s->tx_fifo); + qemu_chr_fe_write(&s->chr, &ch, 1); + qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP, + bcm2835_aux_xmit_handler, s); + } +} + +static void bcm2835_aux_transmit(BCM2835AuxState *s, uint8_t ch) +{ + const bool result = bcm2835_aux_put_tx_fifo(s, ch); + + if (result) { + bcm2835_aux_send(s); + } + + bcm2835_aux_update(s); +} + static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) { BCM2835AuxState *s = opaque; @@ -205,9 +287,7 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, ch = value; /* XXX this blocks entire thread. Rewrite to use * qemu_chr_fe_write and background I/O callbacks */ - if (bcm2835_aux_is_tx_enabled(s)) { - qemu_chr_fe_write_all(&s->chr, &ch, 1); - } + bcm2835_aux_transmit(s, ch); break; case AUX_MU_IER_REG: @@ -264,7 +344,6 @@ static int bcm2835_aux_can_receive(void *opaque) static void bcm2835_aux_put_fifo(BCM2835AuxState *s, uint8_t value) { - BCM2835AuxState *s = opaque; Fifo8 *rx_fifo = &s->rx_fifo; if (fifo8_is_full(rx_fifo) == false) { @@ -298,10 +377,11 @@ static const VMStateDescription vmstate_bcm2835_aux = { .minimum_version_id = 1, .fields = (const VMStateField[]) { VMSTATE_FIFO8(rx_fifo, BCM2835AuxState), - VMSTATE_FIFO8(_tx_fifo, BCM2835AuxState), + VMSTATE_FIFO8(tx_fifo, BCM2835AuxState), VMSTATE_UINT32(ier, BCM2835AuxState), VMSTATE_UINT32(iir, BCM2835AuxState), VMSTATE_UINT32(cntl, BCM2835AuxState), + VMSTATE_UINT32(stat, BCM2835AuxState), VMSTATE_END_OF_LIST() } }; @@ -311,8 +391,6 @@ static void bcm2835_aux_init(Object *obj) SysBusDevice *sbd = SYS_BUS_DEVICE(obj); BCM2835AuxState *s = BCM2835_AUX(obj); - fifo8_create(&s->rx_fifo, BCM2835_AUX_RX_FIFO_LEN); - memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_aux_ops, s, TYPE_BCM2835_AUX, 0x100); sysbus_init_mmio(sbd, &s->iomem); @@ -323,6 +401,16 @@ static void bcm2835_aux_realize(DeviceState *dev, Error **errp) { BCM2835AuxState *s = BCM2835_AUX(dev); + fifo8_create(&s->rx_fifo, BCM2835_AUX_RX_FIFO_LEN); + fifo8_create(&s->tx_fifo, BCM2835_AUX_TX_FIFO_LEN); + s->ier = 0x0; + /* FIFOs enabled and interrupt pending */ + s->iir = 0xC1; + /* Both transmitter and receiver are initially enabled */ + s->cntl = 0x3; + /* Transmitter done and FIFO empty */ + s->stat = 0x300; + qemu_chr_fe_set_handlers(&s->chr, bcm2835_aux_can_receive, bcm2835_aux_receive, NULL, NULL, s, NULL, true); } diff --git a/include/hw/char/bcm2835_aux.h b/include/hw/char/bcm2835_aux.h index feaedc9e2f..f024277169 100644 --- a/include/hw/char/bcm2835_aux.h +++ b/include/hw/char/bcm2835_aux.h @@ -27,10 +27,9 @@ struct BCM2835AuxState { qemu_irq irq; Fifo8 rx_fifo; - /* Unused for now */ - Fifo8 _tx_fifo; + Fifo8 tx_fifo; /* Registers */ - uint32_t ier, iir, cntl; + uint32_t ier, iir, cntl, stat; }; #endif From patchwork Sun Nov 17 22:56:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= X-Patchwork-Id: 13877981 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9AB29D10F38 for ; Sun, 17 Nov 2024 23:02:22 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCoGM-0008E3-5E; Sun, 17 Nov 2024 18:01:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCoCt-0007hQ-Ve for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:27 -0500 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCoCr-0002sX-KK for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:27 -0500 Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-43161c0068bso11661175e9.1 for ; Sun, 17 Nov 2024 14:57:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731884244; x=1732489044; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0O44kgEA0H9qZqq+GnlJX1T0whoQU7CXMA7+cZIGsIw=; b=Ky1OCDof5yTQQxU2PhjmZc13vZSJiT+DsoDi3KGceZUMmjiE7lPEzf5QXdJMR1yhkn gYIUpRGrFav9A5+va573HP1hCNZqHKPyNpsSnQWNGzTetteP30u6lmNzxr8ib+4DMgiA tgCM00isKU2H4KeDH3Kcdm5D5xriLNDb+uI7tgLe1Q9H4vmYcbfgYei7Im7vvhq+bLL0 Woysuaw2xgh9VoFgvLkhoqiiHKCFm2P9xZwcsPxoE3cjrtj4vn82FbsuKIWtcqyMDWYf QL31ZqmkkOk90DqDGYZD5XTy2Y3VzM9tkwZ7sljVgWT/lV7KTBuKaXyrLFFAP9Q9lJjj 6KZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731884244; x=1732489044; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0O44kgEA0H9qZqq+GnlJX1T0whoQU7CXMA7+cZIGsIw=; b=GVi0gNREdwasvGzmj9L+CCX8eCmx1QNWEpv4mmukYkEjhozLCBT2lZtlybjiLAGuD4 KDSjpTnVvutcUnt0AbkI1LUnKwUfvVYqBJsYBPxTzpr2vw7sq9HVGLVYU1uB73TLoS0C z6Q39wtXrwV/MoKslkSey0FrNgUI4bK13/AtfXAAwnIFozcnCp+B/OfRNkPUgL/EeN5J SGX385wOpvDbaaMS+ib1oIDpSaz3ewvWg58adYlgmPGZ+GBYtVP27a4d49xXkhI9aqaP vFR13UQbnTLzudpGwzvOTk2r9jkGp7G7bVPmNm6WsHGsSgruEK3Nv5mzj5p9NaGXQ22D AYMg== X-Gm-Message-State: AOJu0Ywe9cVxsf5TSA6sWrfqehX8INVfHC0VNKXrgKCWualGTFNLi/nx oOYjB5hE3UzOfwlyWI1H/8SdqryZy+vk2nd9mv5OoTsqheU0P63Nv45wcst4xwM6PA== X-Google-Smtp-Source: AGHT+IEimwZR0/jQepn+mY7+9751a3OGCNN3DL2zvX91EN1Nw7OSitZhh9NuBG8jsdGnpCdgiFJz4Q== X-Received: by 2002:a05:600c:1f96:b0:431:58c4:2eb9 with SMTP id 5b1f17b1804b1-432df71b177mr97124725e9.3.1731884244015; Sun, 17 Nov 2024 14:57:24 -0800 (PST) Received: from asus-xubuntu.. ([82.78.167.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432da2800absm136351505e9.25.2024.11.17.14.57.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Nov 2024 14:57:22 -0800 (PST) From: " =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= " X-Google-Original-From: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= To: qemu-devel@nongnu.org Cc: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= Subject: [PATCH 4/7] [BCM2835 AUX 4/7] STAT & IIR registers Date: Mon, 18 Nov 2024 00:56:40 +0200 Message-Id: <20241117225643.768322-4-ioan-cristian.cirstea@tutanota.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> References: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::331; envelope-from=jean.christian.cirstea@gmail.com; helo=mail-wm1-x331.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 18:00:54 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commits implements the required logic for STAT & IIR registers. The STAT register is an extension of the UART 16550 that provides useful (more helpful than the base state register) insights of the peripheral state. The STAT register is intrinsically related to the IIR register, so this commit implements the logic for both of them. Interrupt status logic has been updated accordingly. Signed-off-by: Ioan-Cristian CÎRSTEA --- hw/char/bcm2835_aux.c | 173 +++++++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 60 deletions(-) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index 2ef3459566..266d0dfdc7 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -46,14 +46,26 @@ /* Register masks */ #define MASK_AUX_MU_CNTL_REG 0x3 +/* Mask for TX-related bits */ +#define MASK_AUX_MU_STAT_REG_TX 0xF00032A +/* + * Mask for RX-related bits. + * XXX: It does not include receiver IDLE and receiver overrun for now. + */ +#define MASK_AUX_MU_STAT_REG_RX 0xF0001 -/* bits in IER/IIR registers */ -#define RX_INT 0x1 -#define TX_INT 0x2 +/* bits in IER register */ +#define IER_RX_IRQ_ENABLE 0x1 +#define IER_TX_IRQ_ENABLE 0x2 + +/* bits in IIR register */ +#define IIR_IRQ_NOT_PEND 0x1 +#define IIR_TX_EMPTY 0x2 +#define IIR_RX_VALID 0x4 /* bits in CNTL register */ -#define RX_ENABLE 0x1 -#define TX_ENABLE 0x2 +#define CNTL_RX_ENABLE 0x1 +#define CNTL_TX_ENABLE 0x2 /* bits in STAT register */ #define STAT_TRANSMITTER_DONE 0x200 @@ -70,42 +82,102 @@ ##__VA_ARGS__ \ ) -/* TODO: Add separate functions for RX and TX interrupts */ static void bcm2835_aux_update_irq(BCM2835AuxState *s) { - /* TODO: this should be a pointer to const data. However, the fifo8 API + s->iir |= IIR_IRQ_NOT_PEND; + + if (s->iir & IIR_RX_VALID) { + s->iir &= ~IIR_IRQ_NOT_PEND; + } else if (s->iir & IIR_TX_EMPTY) { + s->iir &= ~IIR_IRQ_NOT_PEND; + } + + /* An interrupt is raised whenever the IRQ_NOT_PEND bit is cleared */ + qemu_set_irq(s->irq, (s->iir & IIR_IRQ_NOT_PEND) == 0); +} + +static void bcm2835_aux_rx_iir_update(BCM2835AuxState *s) +{ + /* + * TODO: this should be a pointer to const data. However, the fifo8 API * requires a pointer to non-const data. */ Fifo8 *rx_fifo = &s->rx_fifo; - Fifo8 *tx_fifo = &s->tx_fifo; - /* signal an interrupt if either: - * 1. rx interrupt is enabled and we have a non-empty rx fifo, or - * 2. the tx interrupt is enabled (since we instantly drain the tx fifo) - */ - s->iir = 0; - if ((s->ier & RX_INT) && fifo8_is_empty(rx_fifo) == false) { - s->iir |= RX_INT; - } - if (s->ier & TX_INT && fifo8_is_empty(tx_fifo)) { - s->iir |= TX_INT; + + s->iir &= ~IIR_RX_VALID; + if ((s->ier & IER_RX_IRQ_ENABLE) && fifo8_is_empty(rx_fifo) == false) { + s->iir |= IIR_RX_VALID; } - qemu_set_irq(s->irq, s->iir != 0); + + bcm2835_aux_update_irq(s); +} + +static void bcm2835_aux_rx_stat_update(BCM2835AuxState *s) +{ + Fifo8 *rx_fifo = &s->rx_fifo; + const bool rx_symbol_available = !fifo8_is_empty(rx_fifo); + const uint32_t rx_fifo_level = fifo8_num_used(rx_fifo); + + s->stat &= ~MASK_AUX_MU_STAT_REG_RX; + s->stat |= (rx_fifo_level << 16) | + (rx_symbol_available << 0); +} + +static void bcm2835_aux_rx_update(BCM2835AuxState *s) +{ + bcm2835_aux_rx_stat_update(s); + bcm2835_aux_rx_iir_update(s); } -static void bcm2835_aux_update(BCM2835AuxState *s) +static void bcm2835_aux_tx_iir_update(BCM2835AuxState *s) { - /* Currently, only IRQ registers are updated */ + /* + * TODO: this should be a pointer to const data. However, the fifo8 API + * requires a pointer to non-const data. + */ + Fifo8 *tx_fifo = &s->tx_fifo; + + s->iir &= ~IIR_TX_EMPTY; + if (s->ier & IER_TX_IRQ_ENABLE && fifo8_is_empty(tx_fifo)) { + s->iir |= IIR_TX_EMPTY | IIR_IRQ_NOT_PEND; + } + bcm2835_aux_update_irq(s); } +static void bcm2835_aux_tx_stat_update(BCM2835AuxState *s, bool busy) +{ + Fifo8 *tx_fifo = &s->tx_fifo; + const uint32_t tx_fifo_level = fifo8_num_used(tx_fifo); + const uint32_t tx_fifo_empty = !tx_fifo_level; + const uint32_t tx_fifo_full = + tx_fifo_level == BCM2835_AUX_TX_FIFO_LEN ? 1 : 0; + const uint32_t tx_done = !busy && tx_fifo_empty; + const uint32_t tx_space_available = !tx_fifo_full; + + s->stat &= ~MASK_AUX_MU_STAT_REG_TX; + s->stat = (tx_fifo_level << 24) | + (tx_done << 9) | + (tx_fifo_empty << 8) | + (tx_fifo_full << 5) | + (busy << 3) | + (tx_space_available << 1); +} + +static void bcm2835_aux_tx_update(BCM2835AuxState *s, bool busy) +{ + bcm2835_aux_tx_stat_update(s, busy); + bcm2835_aux_tx_iir_update(s); +} + static bool bcm2835_aux_is_tx_enabled(const BCM2835AuxState *s) { - return (s->cntl & TX_ENABLE) != 0; + return (s->cntl & CNTL_TX_ENABLE) != 0; } static bool bcm2835_aux_is_rx_enabled(BCM2835AuxState *s) { - return (s->cntl & RX_ENABLE) != 0; + return (s->cntl & CNTL_RX_ENABLE) != 0; } static bool bcm2835_aux_put_tx_fifo(BCM2835AuxState *s, char ch) @@ -132,10 +204,11 @@ static gboolean bcm2835_aux_xmit_handler(void *do_not_use, GIOCondition cond, if (!fifo8_is_empty(tx_fifo)) { const uint8_t ch = fifo8_pop(&s->tx_fifo); qemu_chr_fe_write(&s->chr, &ch, 1); + bcm2835_aux_tx_update(s, true); return G_SOURCE_CONTINUE; } else { - bcm2835_aux_update(s); + bcm2835_aux_tx_update(s, false); return G_SOURCE_REMOVE; } @@ -151,25 +224,28 @@ static bool bcm2835_aux_can_send(const BCM2835AuxState *s) return bcm2835_aux_is_tx_enabled(s) && !bcm2835_aux_is_tx_busy(s); } -static void bcm2835_aux_send(BCM2835AuxState *s) +static void bcm2835_aux_try_send(BCM2835AuxState *s) { + bool busy = false; + if (bcm2835_aux_can_send(s)) { const uint8_t ch = fifo8_pop(&s->tx_fifo); qemu_chr_fe_write(&s->chr, &ch, 1); qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP, bcm2835_aux_xmit_handler, s); + busy = true; } + + bcm2835_aux_tx_update(s, busy); } -static void bcm2835_aux_transmit(BCM2835AuxState *s, uint8_t ch) +static void bcm2835_aux_try_transmit(BCM2835AuxState *s, uint8_t ch) { const bool result = bcm2835_aux_put_tx_fifo(s, ch); if (result) { - bcm2835_aux_send(s); + bcm2835_aux_try_send(s); } - - bcm2835_aux_update(s); } static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) @@ -177,7 +253,6 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) BCM2835AuxState *s = opaque; Fifo8 *rx_fifo = &s->rx_fifo; const bool is_rx_fifo_not_empty = !fifo8_is_empty(rx_fifo); - const uint32_t rx_fifo_fill_level = fifo8_num_used(rx_fifo); /* * 0xFF trashes terminal output, so device driver bugs can be found quickly * in case the RX_FIFO is read while empty @@ -197,7 +272,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) c = fifo8_pop(rx_fifo); } qemu_chr_fe_accept_input(&s->chr); - bcm2835_aux_update(s); + bcm2835_aux_rx_update(s); return c; case AUX_MU_IER_REG: @@ -205,20 +280,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) return 0xc0 | s->ier; /* FIFO enables always read 1 */ case AUX_MU_IIR_REG: - res = 0xc0; /* FIFO enables */ - /* The spec is unclear on what happens when both tx and rx - * interrupts are active, besides that this cannot occur. At - * present, we choose to prioritise the rx interrupt, since - * the tx fifo is always empty. */ - if (is_rx_fifo_not_empty) { - res |= 0x4; - } else { - res |= 0x2; - } - if (s->iir == 0) { - res |= 0x1; - } - return res; + return s->iir; case AUX_MU_LCR_REG: qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_LCR_REG unsupported\n", __func__); @@ -247,13 +309,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) return s->cntl; case AUX_MU_STAT_REG: - res = 0x30e; /* space in the output buffer, empty tx fifo, idle tx/rx */ - if (is_rx_fifo_not_empty) { - res |= 0x1; /* data in input buffer */ - assert(rx_fifo_fill_level <= BCM2835_AUX_RX_FIFO_LEN); - res |= ((uint32_t)rx_fifo_fill_level) << 16; /* rx fifo fill level */ - } - return res; + return s->stat; case AUX_MU_BAUD_REG: qemu_log_mask(LOG_UNIMP, "%s: AUX_MU_BAUD_REG unsupported\n", __func__); @@ -285,15 +341,14 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, case AUX_MU_IO_REG: /* "DLAB bit set means access baudrate register" is NYI */ ch = value; - /* XXX this blocks entire thread. Rewrite to use - * qemu_chr_fe_write and background I/O callbacks */ - bcm2835_aux_transmit(s, ch); + bcm2835_aux_try_transmit(s, ch); break; case AUX_MU_IER_REG: /* "DLAB bit set means access baudrate register" is NYI */ - s->ier = value & (TX_INT | RX_INT); - bcm2835_aux_update(s); + s->ier = value & (IER_TX_IRQ_ENABLE | IER_RX_IRQ_ENABLE); + bcm2835_aux_rx_update(s); + bcm2835_aux_tx_update(s, false); break; case AUX_MU_IIR_REG: @@ -331,8 +386,6 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", __func__, offset); } - - bcm2835_aux_update(s); } static int bcm2835_aux_can_receive(void *opaque) @@ -348,7 +401,7 @@ static void bcm2835_aux_put_fifo(BCM2835AuxState *s, uint8_t value) if (fifo8_is_full(rx_fifo) == false) { fifo8_push(rx_fifo, value); - bcm2835_aux_update(s); + bcm2835_aux_rx_update(s); } } From patchwork Sun Nov 17 22:56:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= X-Patchwork-Id: 13877984 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4AF0DD10F3A for ; Sun, 17 Nov 2024 23:02:46 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCoGO-0008Eu-St; Sun, 17 Nov 2024 18:01:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCoCt-0007hP-VV for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:27 -0500 Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCoCs-0002sm-Am for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:27 -0500 Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-431481433bdso21905635e9.3 for ; Sun, 17 Nov 2024 14:57:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731884245; x=1732489045; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BU5iYSnAuyrEV5xBAp7OTGDZ08INsgWhPSSF/a6akAU=; b=WQTne9XwSo7DZZwjnjucP43sDDM8T/nhyMmwY/xW9XV8C0WHEY9VVG8lcRakCysj4M RdvV8M9gJxVrJNn4VtTDnVZVD4l6KYZ7zPOPHIM1TXX1Yd44Ixwe5D1j+5PS1nZDr9Xj afjS+XBAbmrs74DSwnMFq/wzoUKBYF8fNFjWa7/vLYoTNe5yDj+nqKag2L8qmZ3HVLYR 3YC+57gppHH/4WfJyGzGRXn1+07RxSxgP2H9DOcpIzJa9yGE98E4iS3HiY/hevCV+UNs afZF/BDSfj6HohIshemASgnjjdgfdkYOzG9gQn7ASN8n2n1LLDSD/IAGHxMQlmlus54d GS8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731884245; x=1732489045; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BU5iYSnAuyrEV5xBAp7OTGDZ08INsgWhPSSF/a6akAU=; b=aFJzYpRWDVZWSAIkrAK+RhlxDy7HSdQ2Yquc1kLkTxOHGMFfVXYuxuj2ergHM9x58m zo5dfZ/E0nRMDkodaG2mPqz1wTCG3IN0CEcQd3DJQbBlxYuUyo96yEO4Bn/EbtdaZ5nQ fQAPsbqI+G6AQZmTm5M89jcTnCPnG/EI/kwvcykoFj2J+JAv+BreRWzWiM8MkqwKUGP6 sEL19JfmN9H1yUdkSINZy8SRFaRHx7TaTvwOiLY0rQSwycuwtNyXw6Se9PX0j/mT5QGB lojwZnhFU4+TwCa1iktpGi1VQ2/Yp/kxUKFuvAs/0i2AUJJBYIngUY4hYHc8PRYlrYhq lOPg== X-Gm-Message-State: AOJu0YwUjcp8GZFu4AiCTd452xzdAUtNPBCVxp7dIKQ8YxCPsbrlfOkV tZH1tvG3fysR0L4thpnm8I3TwoFDtSJDrAw6JpAz1C3rNkpbbgkcLpmKClmwHdolUw== X-Google-Smtp-Source: AGHT+IFyzJm/bt66HHsHbHfXenoObKKWxM0MX5r7suUHYUC0pfk57muyRcLSEXpPWH3LMZypCPL6Wg== X-Received: by 2002:a05:600c:4e08:b0:431:1512:743b with SMTP id 5b1f17b1804b1-432df78b038mr74724205e9.21.1731884244870; Sun, 17 Nov 2024 14:57:24 -0800 (PST) Received: from asus-xubuntu.. ([82.78.167.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432da2800absm136351505e9.25.2024.11.17.14.57.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Nov 2024 14:57:24 -0800 (PST) From: " =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= " X-Google-Original-From: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= To: qemu-devel@nongnu.org Cc: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= Subject: [PATCH 5/7] [BCM2835 AUX 5/7] Suffix constants Date: Mon, 18 Nov 2024 00:56:41 +0200 Message-Id: <20241117225643.768322-5-ioan-cristian.cirstea@tutanota.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> References: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32f; envelope-from=jean.christian.cirstea@gmail.com; helo=mail-wm1-x32f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 18:00:54 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The constants defined through the preprocessor must be unsigned. Also, unsigned integer constants are consistent across different bases (see section 6.4.4.1 of the C99 standard draft). Signed-off-by: Ioan-Cristian CÎRSTEA --- hw/char/bcm2835_aux.c | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index 266d0dfdc7..e887076d9b 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -30,49 +30,49 @@ #include "qemu/module.h" /* TODO: These constants need to be unsigned */ -#define AUX_IRQ 0x0 -#define AUX_ENABLES 0x4 -#define AUX_MU_IO_REG 0x40 -#define AUX_MU_IER_REG 0x44 -#define AUX_MU_IIR_REG 0x48 -#define AUX_MU_LCR_REG 0x4c -#define AUX_MU_MCR_REG 0x50 -#define AUX_MU_LSR_REG 0x54 -#define AUX_MU_MSR_REG 0x58 -#define AUX_MU_SCRATCH 0x5c -#define AUX_MU_CNTL_REG 0x60 -#define AUX_MU_STAT_REG 0x64 -#define AUX_MU_BAUD_REG 0x68 +#define AUX_IRQ 0x0U +#define AUX_ENABLES 0x4U +#define AUX_MU_IO_REG 0x40U +#define AUX_MU_IER_REG 0x44U +#define AUX_MU_IIR_REG 0x48U +#define AUX_MU_LCR_REG 0x4cU +#define AUX_MU_MCR_REG 0x50U +#define AUX_MU_LSR_REG 0x54U +#define AUX_MU_MSR_REG 0x58U +#define AUX_MU_SCRATCH 0x5cU +#define AUX_MU_CNTL_REG 0x60U +#define AUX_MU_STAT_REG 0x64U +#define AUX_MU_BAUD_REG 0x68U /* Register masks */ -#define MASK_AUX_MU_CNTL_REG 0x3 +#define MASK_AUX_MU_CNTL_REG 0x3U /* Mask for TX-related bits */ -#define MASK_AUX_MU_STAT_REG_TX 0xF00032A +#define MASK_AUX_MU_STAT_REG_TX 0xF00032AU /* * Mask for RX-related bits. * XXX: It does not include receiver IDLE and receiver overrun for now. */ -#define MASK_AUX_MU_STAT_REG_RX 0xF0001 +#define MASK_AUX_MU_STAT_REG_RX 0xF0001U /* bits in IER register */ -#define IER_RX_IRQ_ENABLE 0x1 -#define IER_TX_IRQ_ENABLE 0x2 +#define IER_RX_IRQ_ENABLE 0x1U +#define IER_TX_IRQ_ENABLE 0x2U /* bits in IIR register */ -#define IIR_IRQ_NOT_PEND 0x1 -#define IIR_TX_EMPTY 0x2 -#define IIR_RX_VALID 0x4 +#define IIR_IRQ_NOT_PEND 0x1U +#define IIR_TX_EMPTY 0x2U +#define IIR_RX_VALID 0x4U /* bits in CNTL register */ -#define CNTL_RX_ENABLE 0x1 -#define CNTL_TX_ENABLE 0x2 +#define CNTL_RX_ENABLE 0x1U +#define CNTL_TX_ENABLE 0x2U /* bits in STAT register */ -#define STAT_TRANSMITTER_DONE 0x200 +#define STAT_TRANSMITTER_DONE 0x200U /* FIFOs length */ -#define BCM2835_AUX_RX_FIFO_LEN 8 -#define BCM2835_AUX_TX_FIFO_LEN 8 +#define BCM2835_AUX_RX_FIFO_LEN 8U +#define BCM2835_AUX_TX_FIFO_LEN 8U #define log_guest_error(fmt, ...) \ qemu_log_mask(LOG_GUEST_ERROR, \ From patchwork Sun Nov 17 22:56:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= X-Patchwork-Id: 13877982 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1D1DCD10F38 for ; Sun, 17 Nov 2024 23:02:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCoGO-0008Er-A5; Sun, 17 Nov 2024 18:01:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCoCv-0007hy-1G for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:29 -0500 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCoCt-0002sv-A7 for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:28 -0500 Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-382423e1f7aso489432f8f.2 for ; Sun, 17 Nov 2024 14:57:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731884246; x=1732489046; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0iXs4DVWxzCMdGVyfkyZpFmSv1X5/7YzHmJZ/b9ZOv4=; b=CIAPMp+/VYiYqt+Gh9pPfnBL7OhF9ZOrB0PGJb+e39Kbwxc2fzemKbCdHV6KnNzyT9 AQJNhHo5WJABM/FNlTngXBcCQVTDWvBGpxXsWjCaBOPDCve4ytp3334yfbMMP1h8lWeW J2SKD7iEOfeZzxYRSQOIaABtM/ODyTdGDOvtvv+4QPAFoXt1qbiV/PkhAS7ku5618e0I 53BAYERmeq3/99cjxpmeHGlPHiutzxgcnj7c/1ihQNfHx3zTODSqUCvj4YC05avnqVQP VFR5LkIjGpXw/D/F7LG4FwHeSvP6fBzeR51zpq4yW/pfIv+IMtSHYoj1G8RAw5H0GwUL 9Q/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731884246; x=1732489046; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0iXs4DVWxzCMdGVyfkyZpFmSv1X5/7YzHmJZ/b9ZOv4=; b=wK0EdVaviPToirz6amFFryxC3SQsTdX6192NLwYUxXNXj7XowSi9ISxwj8MkGV9WWL OQrdsYLrNA7lXO1gVLqPjTqRBEsS63ktsP74c61SH2JDuxS+a+TeAxW6SCbIea2rX2Dn Yzzo9elfxVH8bEMyHxAuraEeu3++m6S7tJDFj5y19WLragS0F78jUh1jlKCv/WUn+cJu gpAoLfM32tJYKssa3DDGmtH6r+IjtHYVs1RfTlPDxDkbofLu2SBCI2F+dT6MGX19g372 AGuYupY6pWHofzxrVmK7IYSGt0lwkSm7h42WGbTFP9FRAMGN1YMUYWNFxwM8Jhf0t7Bp +Liw== X-Gm-Message-State: AOJu0YzyB3ZweSMDTyqiRc+TWiy9I2DzJg1ehKHpHG2Lu1TBCFxHvDgt StGpWcJXZVPdmq6lm8bsSvYiNPzJelOrEwQctrU3sKDLBmVW4qTmhkUtayq/N1Dsbg== X-Google-Smtp-Source: AGHT+IE6OM7k1f6I4uDUHTDl7S1fhv7OraRcFmX0kiNghwxvhQYYC+0tzBE9YgXfni1QxI4Z4apwpw== X-Received: by 2002:a5d:6484:0:b0:382:3be6:5502 with SMTP id ffacd0b85a97d-3823be657ffmr4121338f8f.51.1731884245721; Sun, 17 Nov 2024 14:57:25 -0800 (PST) Received: from asus-xubuntu.. ([82.78.167.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432da2800absm136351505e9.25.2024.11.17.14.57.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Nov 2024 14:57:25 -0800 (PST) From: " =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= " X-Google-Original-From: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= To: qemu-devel@nongnu.org Cc: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= Subject: [PATCH 6/7] [BCM2835 AUX 6/7] Add LSR register Date: Mon, 18 Nov 2024 00:56:42 +0200 Message-Id: <20241117225643.768322-6-ioan-cristian.cirstea@tutanota.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> References: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=jean.christian.cirstea@gmail.com; helo=mail-wr1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 18:00:54 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit implements the LSR register found in standard UART 16550. Signed-off-by: Ioan-Cristian CÎRSTEA --- hw/char/bcm2835_aux.c | 64 ++++++++++++++++++++++++++++++++--- include/hw/char/bcm2835_aux.h | 2 +- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index e887076d9b..577d9a9be3 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -45,7 +45,9 @@ #define AUX_MU_BAUD_REG 0x68U /* Register masks */ + #define MASK_AUX_MU_CNTL_REG 0x3U + /* Mask for TX-related bits */ #define MASK_AUX_MU_STAT_REG_TX 0xF00032AU /* @@ -54,6 +56,9 @@ */ #define MASK_AUX_MU_STAT_REG_RX 0xF0001U +/* Mask for TX-related bits */ +#define MASK_AUX_MU_LSR_REG_TX 0x60U + /* bits in IER register */ #define IER_RX_IRQ_ENABLE 0x1U #define IER_TX_IRQ_ENABLE 0x2U @@ -63,6 +68,9 @@ #define IIR_TX_EMPTY 0x2U #define IIR_RX_VALID 0x4U +/* bits in LSR register */ +#define LSR_OVERRUN 0x2U + /* bits in CNTL register */ #define CNTL_RX_ENABLE 0x1U #define CNTL_TX_ENABLE 0x2U @@ -82,6 +90,16 @@ ##__VA_ARGS__ \ ) +static void bcm2835_aux_clear_overrun_bits(BCM2835AuxState *s) +{ + s->lsr &= ~LSR_OVERRUN; +} + +static void bcm2835_aux_set_overrun_bits(BCM2835AuxState *s) +{ + s->lsr |= LSR_OVERRUN; +} + static void bcm2835_aux_update_irq(BCM2835AuxState *s) { s->iir |= IIR_IRQ_NOT_PEND; @@ -123,9 +141,23 @@ static void bcm2835_aux_rx_stat_update(BCM2835AuxState *s) (rx_symbol_available << 0); } +static void bcm2835_aux_rx_lsr_update(BCM2835AuxState *s) +{ + /* + * TODO: this should be a pointer to const data. However, the fifo8 API + * requires a pointer to non-const data. + */ + Fifo8 *rx_fifo = &s->rx_fifo; + const bool data_ready = !fifo8_is_empty(rx_fifo); + + s->lsr &= ~0x1; + s->lsr |= data_ready << 0; +} + static void bcm2835_aux_rx_update(BCM2835AuxState *s) { bcm2835_aux_rx_stat_update(s); + bcm2835_aux_rx_lsr_update(s); bcm2835_aux_rx_iir_update(s); } @@ -164,9 +196,24 @@ static void bcm2835_aux_tx_stat_update(BCM2835AuxState *s, bool busy) (tx_space_available << 1); } +static void bcm2835_aux_tx_lsr_update(BCM2835AuxState *s, bool busy) +{ + /* + * TODO: This should be a pointer to constant data, but the FIFO API + * requires a pointer to mutable data. + */ + Fifo8 *tx_fifo = &s->tx_fifo; + const bool is_tx_idle = !busy; + const bool is_tx_empty = fifo8_is_empty(tx_fifo); + + s->lsr &= ~MASK_AUX_MU_LSR_REG_TX; + s->lsr |= (is_tx_idle << 6) | (is_tx_empty << 5); +} + static void bcm2835_aux_tx_update(BCM2835AuxState *s, bool busy) { bcm2835_aux_tx_stat_update(s, busy); + bcm2835_aux_tx_lsr_update(s, busy); bcm2835_aux_tx_iir_update(s); } @@ -291,10 +338,9 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) return 0; case AUX_MU_LSR_REG: - res = 0x60; /* tx idle, empty */ - if (is_rx_fifo_not_empty) { - res |= 0x1; - } + res = s->lsr; + /* Overrun bit is self-clearing */ + bcm2835_aux_clear_overrun_bits(s); return res; case AUX_MU_MSR_REG: @@ -391,8 +437,14 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, uint64_t value, static int bcm2835_aux_can_receive(void *opaque) { BCM2835AuxState *s = opaque; + const bool is_rx_fifo_full = fifo8_is_full(&s->rx_fifo); + const bool is_rx_enabled = bcm2835_aux_is_rx_enabled(s); + + if (is_rx_fifo_full && is_rx_enabled) { + bcm2835_aux_set_overrun_bits(s); + } - return !fifo8_is_full(&s->rx_fifo); + return !is_rx_fifo_full; } static void bcm2835_aux_put_fifo(BCM2835AuxState *s, uint8_t value) @@ -459,6 +511,8 @@ static void bcm2835_aux_realize(DeviceState *dev, Error **errp) s->ier = 0x0; /* FIFOs enabled and interrupt pending */ s->iir = 0xC1; + /* Transmitter idle and TX FIFO empty */ + s->lsr = 0x60; /* Both transmitter and receiver are initially enabled */ s->cntl = 0x3; /* Transmitter done and FIFO empty */ diff --git a/include/hw/char/bcm2835_aux.h b/include/hw/char/bcm2835_aux.h index f024277169..601c1fabcc 100644 --- a/include/hw/char/bcm2835_aux.h +++ b/include/hw/char/bcm2835_aux.h @@ -29,7 +29,7 @@ struct BCM2835AuxState { Fifo8 rx_fifo; Fifo8 tx_fifo; /* Registers */ - uint32_t ier, iir, cntl, stat; + uint32_t ier, iir, lsr, cntl, stat; }; #endif From patchwork Sun Nov 17 22:56:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= X-Patchwork-Id: 13877978 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9ECA7D10F3A for ; Sun, 17 Nov 2024 23:01:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tCoGH-0008D9-T4; Sun, 17 Nov 2024 18:00:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tCoCw-0007iX-9m for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:30 -0500 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tCoCu-0002tG-NL for qemu-devel@nongnu.org; Sun, 17 Nov 2024 17:57:30 -0500 Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-43161c0068bso11661425e9.1 for ; Sun, 17 Nov 2024 14:57:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731884247; x=1732489047; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zOg4Uf9LmZCDp34QTwcMrfKO0WCHbSBpZDm8O0Hzx0A=; b=fh+MLzusEFYM7Eq3cyjcHjbI/Nwxt+Pld2kin2eNYdCT3zqPNFqfQIQcAuPX7A9v/y l85ybr11oI9py/D8n+0VmrH3Sz21mAGS80Lw2QQRnY+4XgVYDaAfFLhqaWNn6MnWAGRj 0wsnV1YGt+6Mgw/+lEJ/8L2s+VtTKsEMeimUF3mdAk/ymqsVajNSVvXi8lSsPU9wYJs1 5tASmXJvipde5GTn39ESXryIv/OGasQDDVI7MWu/LWw2k7jzqJWvjLlH+/qpGUA8qVE5 eYCT8f15W7VaDtLsYv55f+WmqxplLdur99hAuw8lSGmlFVUnGXiQMnJsGaeQMC8YT0Ai Qa0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731884247; x=1732489047; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zOg4Uf9LmZCDp34QTwcMrfKO0WCHbSBpZDm8O0Hzx0A=; b=NVVEoybGhpSd+5ooG0oCOQoDCqfu/Ry2dRlFlQfS13clOiTxPQ6FkyAv38B80TfrjM mGNBUFePjFgKOd7UZSUO7CwpDmMc3067Fcn/EYL8qmOx39L2B2Ubtpt/L8bNtiVggqs5 b+2xDxbr5mK3qfypI65zYhyR6/KuD2bKmY32YdkruYX1agaO6KWq+3OJzVI7FgGcq0Pa wIwLXBVDIWuLH2PkjBKzsn2bI29QwRC1enBBlmzqa4MMoanxdM+b5Jm9QfizmLKhMSjD N29HqfLtU42D7Bskh3KypY7LuML8T8yCiYRPtU/ZJoksLBAMwQ9YP73+PkWcmjRToxRw LDJQ== X-Gm-Message-State: AOJu0YzqnHunpDr8iq0CLApMoP7m05/KC58X+uslKezjYP+5irMEC4Ti uyO+pthnw3M/X+DG4olcpQg30bYQjUKnd5/NZ8oeDSLfBjHvpHHe96D1b3aErmH1kg== X-Google-Smtp-Source: AGHT+IF4Hxm68QnBptJuwowUfHAoqP/jHKPZsuVqasgx4hRyj5frtBnt7j7vKc8KFK0GEzDvSA5C6Q== X-Received: by 2002:a05:6000:2ca:b0:382:43ee:9f70 with SMTP id ffacd0b85a97d-38243eea2b2mr1734246f8f.22.1731884247275; Sun, 17 Nov 2024 14:57:27 -0800 (PST) Received: from asus-xubuntu.. ([82.78.167.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432da2800absm136351505e9.25.2024.11.17.14.57.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 17 Nov 2024 14:57:26 -0800 (PST) From: " =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= " X-Google-Original-From: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= To: qemu-devel@nongnu.org Cc: =?utf-8?q?Ioan-Cristian_C=C3=8ERSTEA?= Subject: [PATCH 7/7] [BCM2835 AUX 7/7] STAT OVERRUN & IDLE Date: Mon, 18 Nov 2024 00:56:43 +0200 Message-Id: <20241117225643.768322-7-ioan-cristian.cirstea@tutanota.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> References: <20241117225643.768322-1-ioan-cristian.cirstea@tutanota.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::334; envelope-from=jean.christian.cirstea@gmail.com; helo=mail-wm1-x334.google.com X-Spam_score_int: -15 X-Spam_score: -1.6 X-Spam_bar: - X-Spam_report: (-1.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, SUBJ_ALL_CAPS=0.5 autolearn=no autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 17 Nov 2024 18:00:54 -0500 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This commit implements the required logic for receiver overrun and idle bitfields in the STAT register. Currently, the receiver is always reported as idle. Signed-off-by: Ioan-Cristian CÎRSTEA --- hw/char/bcm2835_aux.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index 577d9a9be3..c9bce7d7d3 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -29,7 +29,6 @@ #include "qemu/log.h" #include "qemu/module.h" -/* TODO: These constants need to be unsigned */ #define AUX_IRQ 0x0U #define AUX_ENABLES 0x4U #define AUX_MU_IO_REG 0x40U @@ -50,11 +49,8 @@ /* Mask for TX-related bits */ #define MASK_AUX_MU_STAT_REG_TX 0xF00032AU -/* - * Mask for RX-related bits. - * XXX: It does not include receiver IDLE and receiver overrun for now. - */ -#define MASK_AUX_MU_STAT_REG_RX 0xF0001U +/* Mask for RX-related bits */ +#define MASK_AUX_MU_STAT_REG_RX 0xF0015U /* Mask for TX-related bits */ #define MASK_AUX_MU_LSR_REG_TX 0x60U @@ -70,6 +66,7 @@ /* bits in LSR register */ #define LSR_OVERRUN 0x2U +#define LSR_OVERRUN_OFFSET 0x1U /* bits in CNTL register */ #define CNTL_RX_ENABLE 0x1U @@ -77,6 +74,8 @@ /* bits in STAT register */ #define STAT_TRANSMITTER_DONE 0x200U +#define STAT_OVERRUN 0x10U +#define STAT_RECEIVER_IDLE 0x4U /* FIFOs length */ #define BCM2835_AUX_RX_FIFO_LEN 8U @@ -90,12 +89,12 @@ ##__VA_ARGS__ \ ) -static void bcm2835_aux_clear_overrun_bits(BCM2835AuxState *s) +static void bcm2835_aux_clear_overrun_bit(BCM2835AuxState *s) { s->lsr &= ~LSR_OVERRUN; } -static void bcm2835_aux_set_overrun_bits(BCM2835AuxState *s) +static void bcm2835_aux_set_overrun_bit(BCM2835AuxState *s) { s->lsr |= LSR_OVERRUN; } @@ -134,10 +133,17 @@ static void bcm2835_aux_rx_stat_update(BCM2835AuxState *s) { Fifo8 *rx_fifo = &s->rx_fifo; const bool rx_symbol_available = !fifo8_is_empty(rx_fifo); + const bool rx_overrun = (s->lsr & LSR_OVERRUN) >> LSR_OVERRUN_OFFSET; const uint32_t rx_fifo_level = fifo8_num_used(rx_fifo); s->stat &= ~MASK_AUX_MU_STAT_REG_RX; + /* + * Receiver overrun bit is set separately in bcm2835_aux_set_overrun_bit + * Receiver is always marked as idle. + */ s->stat |= (rx_fifo_level << 16) | + (rx_overrun << 4) | + STAT_RECEIVER_IDLE | (rx_symbol_available << 0); } @@ -340,7 +346,7 @@ static uint64_t bcm2835_aux_read(void *opaque, hwaddr offset, unsigned size) case AUX_MU_LSR_REG: res = s->lsr; /* Overrun bit is self-clearing */ - bcm2835_aux_clear_overrun_bits(s); + bcm2835_aux_clear_overrun_bit(s); return res; case AUX_MU_MSR_REG: @@ -441,7 +447,7 @@ static int bcm2835_aux_can_receive(void *opaque) const bool is_rx_enabled = bcm2835_aux_is_rx_enabled(s); if (is_rx_fifo_full && is_rx_enabled) { - bcm2835_aux_set_overrun_bits(s); + bcm2835_aux_set_overrun_bit(s); } return !is_rx_fifo_full;