From patchwork Mon Jan 31 09:42:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshinori Sato X-Patchwork-Id: 1586578 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 bilbo.ozlabs.org (Postfix) with ESMTPS id 4JnNRg5Vgwz9s8s for ; Mon, 31 Jan 2022 20:43:43 +1100 (AEDT) Received: from localhost ([::1]:55502 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nETDp-0001oT-I5 for incoming@patchwork.ozlabs.org; Mon, 31 Jan 2022 04:43:41 -0500 Received: from eggs.gnu.org ([209.51.188.92]:43110) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nETD5-0001i7-SF for qemu-devel@nongnu.org; Mon, 31 Jan 2022 04:42:55 -0500 Received: from mail02.asahi-net.or.jp ([202.224.55.14]:60748) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nETD3-0000zT-SE for qemu-devel@nongnu.org; Mon, 31 Jan 2022 04:42:55 -0500 Received: from sakura.ysato.name (ik1-413-38519.vs.sakura.ne.jp [153.127.30.23]) (Authenticated sender: PQ4Y-STU) by mail02.asahi-net.or.jp (Postfix) with ESMTPA id 77CCE206C5; Mon, 31 Jan 2022 18:42:51 +0900 (JST) Received: from SIOS1075.ysato.name (ZM005235.ppp.dion.ne.jp [222.8.5.235]) by sakura.ysato.name (Postfix) with ESMTPSA id 24E661C0023; Mon, 31 Jan 2022 18:42:51 +0900 (JST) From: Yoshinori Sato To: qemu-devel@nongnu.org Subject: [PATCH 1/2] hw/char/renesas_sci: Add fifo buffer to backend interface. Date: Mon, 31 Jan 2022 18:42:45 +0900 Message-Id: <20220131094246.772550-1-ysato@users.sourceforge.jp> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Received-SPF: softfail client-ip=202.224.55.14; envelope-from=ysato@users.sourceforge.jp; helo=mail02.asahi-net.or.jp X-Spam_score_int: -11 X-Spam_score: -1.2 X-Spam_bar: - X-Spam_report: (-1.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action 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: , Cc: Yoshinori Sato Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" SCI does not have a fifo, it is necessary to send and receive at a bit rate speed. But, qemu's chardev backend does not have a buffer, so it sends received data continuously. By buffering the received data with the FIFO, continuous received data can be received. Signed-off-by: Yoshinori Sato --- include/hw/char/renesas_sci.h | 11 ++- hw/char/renesas_sci.c | 124 +++++++++++++++++++++++++--------- 2 files changed, 101 insertions(+), 34 deletions(-) diff --git a/include/hw/char/renesas_sci.h b/include/hw/char/renesas_sci.h index a4764e3eee..017711867a 100644 --- a/include/hw/char/renesas_sci.h +++ b/include/hw/char/renesas_sci.h @@ -12,6 +12,7 @@ #include "chardev/char-fe.h" #include "hw/sysbus.h" #include "qom/object.h" +#include "qemu/fifo8.h" #define TYPE_RENESAS_SCI "renesas-sci" typedef struct RSCIState RSCIState; @@ -26,13 +27,18 @@ enum { SCI_NR_IRQ = 4 }; +enum { + TXTIMER = 0, + RXTIMER = 1, + NR_TIMER = 2, +}; + struct RSCIState { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ MemoryRegion memory; - QEMUTimer timer; CharBackend chr; qemu_irq irq[SCI_NR_IRQ]; @@ -47,8 +53,9 @@ struct RSCIState { uint8_t read_ssr; int64_t trtime; - int64_t rx_next; uint64_t input_freq; + Fifo8 rxfifo; + QEMUTimer timer[NR_TIMER]; }; #endif diff --git a/hw/char/renesas_sci.c b/hw/char/renesas_sci.c index 1c63467290..e6513a24b6 100644 --- a/hw/char/renesas_sci.c +++ b/hw/char/renesas_sci.c @@ -69,32 +69,63 @@ REG8(SEMR, 7) FIELD(SEMR, ACS0, 0, 1) FIELD(SEMR, ABCS, 4, 1) -static int can_receive(void *opaque) +enum { + RXFIFO_DEPTH = 16, +}; + +static void set_next_event(RSCIState *sci, int evt, int64_t expire) { - RSCIState *sci = RSCI(opaque); - if (sci->rx_next > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) { - return 0; + int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + + if (expire > 0) { + timer_mod(&sci->timer[evt], now + expire); } else { - return FIELD_EX8(sci->scr, SCR, RE); + timer_del(&sci->timer[evt]); } } -static void receive(void *opaque, const uint8_t *buf, int size) +static int can_receive(void *opaque) { RSCIState *sci = RSCI(opaque); - sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime; - if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) { + return FIELD_EX8(sci->scr, SCR, RE) ? fifo8_num_free(&sci->rxfifo) : 0; +} + +static void sci_rx_event(void *opaque) +{ + RSCIState *sci = RSCI(opaque); + uint32_t rd; + + if (fifo8_is_empty(&sci->rxfifo)) { + /* receiver idle state */ + set_next_event(sci, RXTIMER, 0); + return; + } + rd = fifo8_pop(&sci->rxfifo); + if (FIELD_EX8(sci->ssr, SSR, RDRF)) { + /* Don't receive last byte */ sci->ssr = FIELD_DP8(sci->ssr, SSR, ORER, 1); if (FIELD_EX8(sci->scr, SCR, RIE)) { qemu_set_irq(sci->irq[ERI], 1); } } else { - sci->rdr = buf[0]; + sci->rdr = rd; sci->ssr = FIELD_DP8(sci->ssr, SSR, RDRF, 1); if (FIELD_EX8(sci->scr, SCR, RIE)) { qemu_irq_pulse(sci->irq[RXI]); } } + set_next_event(sci, RXTIMER, sci->trtime); +} + +static void receive(void *opaque, const uint8_t *buf, int size) +{ + RSCIState *sci = RSCI(opaque); + fifo8_push_all(&sci->rxfifo, buf, size); + + if (!timer_pending(&sci->timer[RXTIMER])) { + /* reciever idle state, start rx */ + sci_rx_event(sci); + } } static void send_byte(RSCIState *sci) @@ -102,22 +133,26 @@ static void send_byte(RSCIState *sci) if (qemu_chr_fe_backend_connected(&sci->chr)) { qemu_chr_fe_write_all(&sci->chr, &sci->tdr, 1); } - timer_mod(&sci->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime); + set_next_event(sci, TXTIMER, sci->trtime); sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 0); sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 1); qemu_set_irq(sci->irq[TEI], 0); - if (FIELD_EX8(sci->scr, SCR, TIE)) { + if (FIELD_EX8(sci->scr, SCR, TE) && FIELD_EX8(sci->scr, SCR, TIE)) { qemu_irq_pulse(sci->irq[TXI]); } } -static void txend(void *opaque) +static void sci_tx_event(void *opaque) { RSCIState *sci = RSCI(opaque); - if (!FIELD_EX8(sci->ssr, SSR, TDRE)) { + + if (FIELD_EX8(sci->ssr, SSR, TDRE) == 0) { + /* next tx ready */ send_byte(sci); } else { + /* no next tx */ sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1); + set_next_event(sci, TXTIMER, 0); if (FIELD_EX8(sci->scr, SCR, TEIE)) { qemu_set_irq(sci->irq[TEI], 1); } @@ -126,15 +161,15 @@ static void txend(void *opaque) static void update_trtime(RSCIState *sci) { + int64_t baseclk = NANOSECONDS_PER_SECOND / sci->input_freq; + baseclk *= 64 - 32 * FIELD_EX8(sci->semr, SEMR, ABCS); + baseclk *= 1 << (2 * FIELD_EX8(sci->smr, SMR, CKS)); + baseclk *= sci->brr + 1; /* char per bits */ sci->trtime = 8 - FIELD_EX8(sci->smr, SMR, CHR); sci->trtime += FIELD_EX8(sci->smr, SMR, PE); sci->trtime += FIELD_EX8(sci->smr, SMR, STOP) + 1; - /* x bit transmit time (32 * divrate * brr) / base freq */ - sci->trtime *= 32 * sci->brr; - sci->trtime *= 1 << (2 * FIELD_EX8(sci->smr, SMR, CKS)); - sci->trtime *= NANOSECONDS_PER_SECOND; - sci->trtime /= sci->input_freq; + sci->trtime *= baseclk; } static bool sci_is_tr_enabled(RSCIState *sci) @@ -151,23 +186,37 @@ static void sci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) if (!sci_is_tr_enabled(sci)) { sci->smr = val; update_trtime(sci); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: Register 0x%" + HWADDR_PRIX " write protected.\n", offset); } break; case A_BRR: if (!sci_is_tr_enabled(sci)) { sci->brr = val; update_trtime(sci); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: Register 0x%" + HWADDR_PRIX " write protected.\n", offset); } break; case A_SCR: - sci->scr = val; - if (FIELD_EX8(sci->scr, SCR, TE)) { - sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 1); - sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1); - if (FIELD_EX8(sci->scr, SCR, TIE)) { - qemu_irq_pulse(sci->irq[TXI]); + if (FIELD_EX8(sci->scr, SCR, TE) != FIELD_EX8(val, SCR, TE)) { + if (FIELD_EX8(val, SCR, TE)) { + /* Disable -> Enable to reset TX*/ + sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 1); + sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1); + if (FIELD_EX8(val, SCR, TIE)) { + qemu_irq_pulse(sci->irq[TXI]); + } + } else { + /* disable TX clock */ + set_next_event(sci, TXTIMER, 0); + sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0); + sci->ssr = FIELD_DP8(sci->ssr, SSR, TEND, 1); } } + sci->scr = val; if (!FIELD_EX8(sci->scr, SCR, TEIE)) { qemu_set_irq(sci->irq[TEI], 0); } @@ -177,10 +226,14 @@ static void sci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) break; case A_TDR: sci->tdr = val; - if (FIELD_EX8(sci->ssr, SSR, TEND)) { - send_byte(sci); + if (FIELD_EX8(sci->scr, SCR, TE)) { + if (FIELD_EX8(sci->ssr, SSR, TEND)) { + send_byte(sci); + } else { + sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0); + } } else { - sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0); + qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: Transmit disabled.\n"); } break; case A_SSR: @@ -224,6 +277,9 @@ static uint64_t sci_read(void *opaque, hwaddr offset, unsigned size) sci->read_ssr = sci->ssr; return sci->ssr; case A_RDR: + if (!FIELD_EX8(sci->scr, SCR, RE)) { + qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: Receive disabled.\n"); + } sci->ssr = FIELD_DP8(sci->ssr, SSR, RDRF, 0); return sci->rdr; case A_SCMR: @@ -255,7 +311,7 @@ static void rsci_reset(DeviceState *dev) sci->ssr = 0x84; sci->scmr = 0x00; sci->semr = 0x00; - sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + update_trtime(sci); } static void sci_event(void *opaque, QEMUChrEvent event) @@ -263,6 +319,7 @@ static void sci_event(void *opaque, QEMUChrEvent event) RSCIState *sci = RSCI(opaque); if (event == CHR_EVENT_BREAK) { sci->ssr = FIELD_DP8(sci->ssr, SSR, FER, 1); + sci->rdr = 0; if (FIELD_EX8(sci->scr, SCR, RIE)) { qemu_set_irq(sci->irq[ERI], 1); } @@ -295,16 +352,19 @@ static void rsci_init(Object *obj) for (i = 0; i < SCI_NR_IRQ; i++) { sysbus_init_irq(d, &sci->irq[i]); } - timer_init_ns(&sci->timer, QEMU_CLOCK_VIRTUAL, txend, sci); + timer_init_ns(&sci->timer[TXTIMER], + QEMU_CLOCK_VIRTUAL, sci_tx_event, sci); + timer_init_ns(&sci->timer[RXTIMER], + QEMU_CLOCK_VIRTUAL, sci_rx_event, sci); + fifo8_create(&sci->rxfifo, RXFIFO_DEPTH); } static const VMStateDescription vmstate_rsci = { .name = "renesas-sci", - .version_id = 1, + .version_id = 2, .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_INT64(trtime, RSCIState), - VMSTATE_INT64(rx_next, RSCIState), VMSTATE_UINT8(smr, RSCIState), VMSTATE_UINT8(brr, RSCIState), VMSTATE_UINT8(scr, RSCIState), @@ -314,7 +374,7 @@ static const VMStateDescription vmstate_rsci = { VMSTATE_UINT8(scmr, RSCIState), VMSTATE_UINT8(semr, RSCIState), VMSTATE_UINT8(read_ssr, RSCIState), - VMSTATE_TIMER(timer, RSCIState), + VMSTATE_TIMER_ARRAY(timer, RSCIState, NR_TIMER), VMSTATE_END_OF_LIST() } }; From patchwork Mon Jan 31 09:42:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yoshinori Sato X-Patchwork-Id: 1586577 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 bilbo.ozlabs.org (Postfix) with ESMTPS id 4JnNRf5HvXz9s8s for ; Mon, 31 Jan 2022 20:43:42 +1100 (AEDT) Received: from localhost ([::1]:55434 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nETDo-0001ky-GW for incoming@patchwork.ozlabs.org; Mon, 31 Jan 2022 04:43:40 -0500 Received: from eggs.gnu.org ([209.51.188.92]:43104) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nETD5-0001gh-4o for qemu-devel@nongnu.org; Mon, 31 Jan 2022 04:42:55 -0500 Received: from mail02.asahi-net.or.jp ([202.224.55.14]:60745) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nETD3-0000zR-00 for qemu-devel@nongnu.org; Mon, 31 Jan 2022 04:42:54 -0500 Received: from sakura.ysato.name (ik1-413-38519.vs.sakura.ne.jp [153.127.30.23]) (Authenticated sender: PQ4Y-STU) by mail02.asahi-net.or.jp (Postfix) with ESMTPA id 9786720801; Mon, 31 Jan 2022 18:42:51 +0900 (JST) Received: from SIOS1075.ysato.name (ZM005235.ppp.dion.ne.jp [222.8.5.235]) by sakura.ysato.name (Postfix) with ESMTPSA id 4D6C01C006A; Mon, 31 Jan 2022 18:42:51 +0900 (JST) From: Yoshinori Sato To: qemu-devel@nongnu.org Subject: [PATCH 2/2] test/avocado: Update machibe_rx_gdbsim tests. Date: Mon, 31 Jan 2022 18:42:46 +0900 Message-Id: <20220131094246.772550-2-ysato@users.sourceforge.jp> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220131094246.772550-1-ysato@users.sourceforge.jp> References: <20220131094246.772550-1-ysato@users.sourceforge.jp> MIME-Version: 1.0 Received-SPF: softfail client-ip=202.224.55.14; envelope-from=ysato@users.sourceforge.jp; helo=mail02.asahi-net.or.jp X-Spam_score_int: -11 X-Spam_score: -1.2 X-Spam_bar: - X-Spam_report: (-1.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action 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: , Cc: Yoshinori Sato Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Since SCI supports continuous data receive, Added that test. Signed-off-by: Yoshinori Sato --- tests/avocado/machine_rx_gdbsim.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/tests/avocado/machine_rx_gdbsim.py b/tests/avocado/machine_rx_gdbsim.py index 6cd8704b01..04ba1e3ca3 100644 --- a/tests/avocado/machine_rx_gdbsim.py +++ b/tests/avocado/machine_rx_gdbsim.py @@ -9,6 +9,7 @@ # later. See the COPYING file in the top-level directory. import os +import time from avocado import skipIf from avocado_qemu import QemuSystemTest @@ -20,7 +21,7 @@ class RxGdbSimMachine(QemuSystemTest): timeout = 30 - KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' + KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 console=ttySC0,9600' @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_uboot(self): @@ -31,8 +32,8 @@ def test_uboot(self): :avocado: tags=machine:gdbsim-r5f562n8 :avocado: tags=endian:little """ - uboot_url = ('https://acc.dl.osdn.jp/users/23/23888/u-boot.bin.gz') - uboot_hash = '9b78dbd43b40b2526848c0b1ce9de02c24f4dcdb' + uboot_url = ('https://osdn.dl.osdn.net/users/37/37476/u-boot.bin.gz') + uboot_hash = '5299a1deb6540ed8699a21ab32b61d862f8d3e32' uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash) uboot_path = archive.uncompress(uboot_path, self.workdir) @@ -40,11 +41,14 @@ def test_uboot(self): self.vm.add_args('-bios', uboot_path, '-no-reboot') self.vm.launch() - uboot_version = 'U-Boot 2016.05-rc3-23705-ga1ef3c71cb-dirty' + uboot_version = 'U-Boot 2021.10-rc3-00012-g92f3eb4647 ' \ + '(Jan 02 2022 - 21:06:23 +0900)' wait_for_console_pattern(self, uboot_version) - gcc_version = 'rx-unknown-linux-gcc (GCC) 9.0.0 20181105 (experimental)' - # FIXME limit baudrate on chardev, else we type too fast - #exec_command_and_wait_for_pattern(self, 'version', gcc_version) + gcc_version = 'rx-unknown-linux-gcc (GCC) 12.0.0 20210903 ' \ + '(experimental)' + # Wait for prompt + time.sleep(1) + exec_command_and_wait_for_pattern(self, 'version', gcc_version) @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_linux_sash(self): @@ -55,18 +59,19 @@ def test_linux_sash(self): :avocado: tags=machine:gdbsim-r5f562n7 :avocado: tags=endian:little """ - dtb_url = ('https://acc.dl.osdn.jp/users/23/23887/rx-virt.dtb') - dtb_hash = '7b4e4e2c71905da44e86ce47adee2210b026ac18' + dtb_url = ('https://osdn.dl.osdn.net/users/37/37625/rx-virt.dtb') + dtb_hash = 'c69ee47d322285d1fc359d18d50b74e385b4d76c' dtb_path = self.fetch_asset(dtb_url, asset_hash=dtb_hash) - kernel_url = ('http://acc.dl.osdn.jp/users/23/23845/zImage') - kernel_hash = '39a81067f8d72faad90866ddfefa19165d68fc99' + kernel_url = ('https://osdn.dl.osdn.net/users/37/37623/zImage') + kernel_hash = '7aa396cd62d81d05fb5f8d7e56154cf4bf20e029' kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) self.vm.set_console() kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'earlycon' self.vm.add_args('-kernel', kernel_path, '-dtb', dtb_path, - '-no-reboot') + '-no-reboot', + '-append', kernel_command_line) self.vm.launch() wait_for_console_pattern(self, 'Sash command shell (version 1.1.1)', failure_message='Kernel panic - not syncing')