From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([209.51.188.92]:53563) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hNJfu-0003gp-2Y for qemu-devel@nongnu.org; Sun, 05 May 2019 12:07:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hNJfs-0006iK-7L for qemu-devel@nongnu.org; Sun, 05 May 2019 12:07:38 -0400 Received: from mail02.asahi-net.or.jp ([202.224.55.14]:52126) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hNJfq-0006gZ-FX for qemu-devel@nongnu.org; Sun, 05 May 2019 12:07:35 -0400 Date: Mon, 06 May 2019 01:07:32 +0900 Message-ID: <87o94g51h7.wl-ysato@users.sourceforge.jp> From: Yoshinori Sato In-Reply-To: <87o94j4l6j.fsf@zen.linaroharston> References: <20190502143409.59600-1-ysato@users.sourceforge.jp> <20190502143409.59600-9-ysato@users.sourceforge.jp> <87o94j4l6j.fsf@zen.linaroharston> MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH RFC v8 08/12] hw/char: RX62N serical communication interface (SCI) List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alex =?ISO-8859-1?Q?Benn=E9e?= Cc: qemu-devel@nongnu.org, peter.maydell@linaro.org, richard.henderson@linaro.org On Sat, 04 May 2019 00:22:44 +0900, Alex Benn=E9e wrote: >=20 >=20 > Yoshinori Sato writes: >=20 >=20 > nit: typo in subject (serical->serial) >=20 > > This module supported only non FIFO type. > > Hardware manual. > > https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh00= 33ej0140_rx62n.pdf > > > > Signed-off-by: Yoshinori Sato > > --- > > include/hw/char/renesas_sci.h | 45 ++++++ > > hw/char/renesas_sci.c | 341 ++++++++++++++++++++++++++++++++++= ++++++++ > > hw/char/Kconfig | 3 + > > hw/char/Makefile.objs | 2 +- > > 4 files changed, 390 insertions(+), 1 deletion(-) > > create mode 100644 include/hw/char/renesas_sci.h > > create mode 100644 hw/char/renesas_sci.c > > > > diff --git a/include/hw/char/renesas_sci.h b/include/hw/char/renesas_sc= i.h > > new file mode 100644 > > index 0000000000..50d1336944 > > --- /dev/null > > +++ b/include/hw/char/renesas_sci.h > > @@ -0,0 +1,45 @@ > > +/* > > + * Renesas Serial Communication Interface > > + * > > + * Copyright (c) 2018 Yoshinori Sato > > + * > > + * This code is licensed under the GPL version 2 or later. > > + * > > + */ > > + > > +#include "chardev/char-fe.h" > > +#include "qemu/timer.h" > > +#include "hw/sysbus.h" > > + > > +#define TYPE_RENESAS_SCI "renesas-sci" > > +#define RSCI(obj) OBJECT_CHECK(RSCIState, (obj), TYPE_RENESAS_SCI) > > + > > +enum { > > + ERI =3D 0, > > + RXI =3D 1, > > + TXI =3D 2, > > + TEI =3D 3, > > + SCI_NR_IRQ =3D 4, > > +}; > > + > > +typedef struct { > > + SysBusDevice parent_obj; > > + MemoryRegion memory; > > + > > + uint8_t smr; > > + uint8_t brr; > > + uint8_t scr; > > + uint8_t tdr; > > + uint8_t ssr; > > + uint8_t rdr; > > + uint8_t scmr; > > + uint8_t semr; > > + > > + uint8_t read_ssr; > > + int64_t trtime; > > + int64_t rx_next; > > + QEMUTimer *timer; > > + CharBackend chr; > > + uint64_t input_freq; > > + qemu_irq irq[SCI_NR_IRQ]; > > +} RSCIState; > > diff --git a/hw/char/renesas_sci.c b/hw/char/renesas_sci.c > > new file mode 100644 > > index 0000000000..719fa2f938 > > --- /dev/null > > +++ b/hw/char/renesas_sci.c > > @@ -0,0 +1,341 @@ > > +/* > > + * Renesas Serial Communication Interface > > + * > > + * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware > > + * (Rev.1.40 R01UH0033EJ0140) > > + * > > + * Copyright (c) 2019 Yoshinori Sato > > + * > > + * This program is free software; you can redistribute it and/or modif= y it > > + * under the terms and conditions of the GNU General Public License, > > + * version 2 or later, as published by the Free Software Foundation. > > + * > > + * This program is distributed in the hope it will be useful, but WITH= OUT > > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY = or > > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licen= se for > > + * more details. > > + * > > + * You should have received a copy of the GNU General Public License a= long with > > + * this program. If not, see . > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "qemu/log.h" > > +#include "qapi/error.h" > > +#include "qemu-common.h" > > +#include "cpu.h" > > +#include "hw/hw.h" > > +#include "hw/sysbus.h" > > +#include "hw/registerfields.h" > > +#include "hw/char/renesas_sci.h" > > +#include "qemu/error-report.h" > > + > > +/* SCI register map */ > > +REG8(SMR, 0) > > + FIELD(SMR, CKS, 0, 2) > > + FIELD(SMR, MP, 2, 1) > > + FIELD(SMR, STOP, 3, 1) > > + FIELD(SMR, PM, 4, 1) > > + FIELD(SMR, PE, 5, 1) > > + FIELD(SMR, CHR, 6, 1) > > + FIELD(SMR, CM, 7, 1) > > +REG8(BRR, 1) > > +REG8(SCR, 2) > > + FIELD(SCR, CKE, 0, 2) > > + FIELD(SCR, TEIE, 2, 1) > > + FIELD(SCR, MPIE, 3, 1) > > + FIELD(SCR, RE, 4, 1) > > + FIELD(SCR, TE, 5, 1) > > + FIELD(SCR, RIE, 6, 1) > > + FIELD(SCR, TIE, 7, 1) > > +REG8(TDR, 3) > > +REG8(SSR, 4) > > + FIELD(SSR, MPBT, 0, 1) > > + FIELD(SSR, MPB, 1, 1) > > + FIELD(SSR, TEND, 2, 1) > > + FIELD(SSR, ERR, 3, 3) > > + FIELD(SSR, PER, 3, 1) > > + FIELD(SSR, FER, 4, 1) > > + FIELD(SSR, ORER, 5, 1) > > + FIELD(SSR, RDRF, 6, 1) > > + FIELD(SSR, TDRE, 7, 1) > > +REG8(RDR, 5) > > +REG8(SCMR, 6) > > + FIELD(SCMR, SMIF, 0, 1) > > + FIELD(SCMR, SINV, 2, 1) > > + FIELD(SCMR, SDIR, 3, 1) > > + FIELD(SCMR, BCP2, 7, 1) > > +REG8(SEMR, 7) > > + FIELD(SEMR, ACS0, 0, 1) > > + FIELD(SEMR, ABCS, 4, 1) > > + > > +static int can_receive(void *opaque) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + if (sci->rx_next > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) { > > + return 0; > > + } else { > > + return FIELD_EX8(sci->scr, SCR, RE); > > + } > > +} > > + > > +static void receive(void *opaque, const uint8_t *buf, int size) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + sci->rx_next =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trti= me; > > + if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, ORER, 1); > > + if (FIELD_EX8(sci->scr, SCR, RIE)) { > > + qemu_set_irq(sci->irq[ERI], 1); > > + } > > + } else { > > + sci->rdr =3D buf[0]; > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, RDRF, 1); > > + if (FIELD_EX8(sci->scr, SCR, RIE)) { > > + qemu_irq_pulse(sci->irq[RXI]); > > + } > > + } > > +} > > + > > +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); > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TEND, 0); > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TDRE, 1); > > + qemu_set_irq(sci->irq[TEI], 0); > > + if (FIELD_EX8(sci->scr, SCR, TIE)) { > > + qemu_irq_pulse(sci->irq[TXI]); > > + } > > +} > > + > > +static void txend(void *opaque) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + if (!FIELD_EX8(sci->ssr, SSR, TDRE)) { > > + send_byte(sci); > > + } else { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TEND, 1); > > + if (FIELD_EX8(sci->scr, SCR, TEIE)) { > > + qemu_set_irq(sci->irq[TEI], 1); > > + } > > + } > > +} > > + > > +static void update_trtime(RSCIState *sci) > > +{ > > + /* char per bits */ > > + sci->trtime =3D 8 - FIELD_EX8(sci->smr, SMR, CHR); > > + sci->trtime +=3D FIELD_EX8(sci->smr, SMR, PE); > > + sci->trtime +=3D FIELD_EX8(sci->smr, SMR, STOP) + 1; > > + /* x bit transmit time (32 * divrate * brr) / base freq */ > > + sci->trtime *=3D 32 * sci->brr; > > + sci->trtime *=3D 1 << (2 * FIELD_EX8(sci->smr, SMR, CKS)); > > + sci->trtime *=3D NANOSECONDS_PER_SECOND; > > + sci->trtime /=3D sci->input_freq; > > +} > > + > > +#define IS_TR_ENABLED(scr) \ > > + (FIELD_EX8(scr, SCR, TE) || FIELD_EX8(scr, SCR, RE)) > > + > > +static void sci_write(void *opaque, hwaddr addr, uint64_t val, unsigne= d size) > > +{ > > + hwaddr offset =3D addr & 0x07; > > + RSCIState *sci =3D RSCI(opaque); > > + > > + switch (offset) { > > + case A_SMR: > > + if (!IS_TR_ENABLED(sci->scr)) { > > + sci->smr =3D val; > > + update_trtime(sci); > > + } > > + break; > > + case A_BRR: > > + if (!IS_TR_ENABLED(sci->scr)) { > > + sci->brr =3D val; > > + update_trtime(sci); > > + } > > + break; > > + case A_SCR: > > + sci->scr =3D val; > > + if (FIELD_EX8(sci->scr, SCR, TE)) { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TDRE, 1); > > + sci->ssr =3D 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, TEIE)) { > > + qemu_set_irq(sci->irq[TEI], 0); > > + } > > + if (!FIELD_EX8(sci->scr, SCR, RIE)) { > > + qemu_set_irq(sci->irq[ERI], 0); > > + } > > + break; > > + case A_TDR: > > + sci->tdr =3D val; > > + if (FIELD_EX8(sci->ssr, SSR, TEND)) { > > + send_byte(sci); > > + } else { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TDRE, 0); > > + } > > + break; > > + case A_SSR: > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, MPBT, > > + FIELD_EX8(val, SSR, MPBT)); > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, ERR, > > + FIELD_EX8(val, SSR, ERR) & 0x07); > > + if (FIELD_EX8(sci->read_ssr, SSR, ERR) && > > + FIELD_EX8(sci->ssr, SSR, ERR) =3D=3D 0) { > > + qemu_set_irq(sci->irq[ERI], 0); > > + } > > + break; > > + case A_RDR: > > + qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: RDR is read only.\= n"); > > + break; > > + case A_SCMR: > > + sci->scmr =3D val; break; > > + case A_SEMR: /* SEMR */ > > + sci->semr =3D val; break; > > + default: > > + qemu_log_mask(LOG_UNIMP, > > + "renesas_sci: Register %08lx not implemented\n",= offset); > > + } > > +} > > + > > +static uint64_t sci_read(void *opaque, hwaddr addr, unsigned size) > > +{ > > + hwaddr offset =3D addr & 0x07; > > + RSCIState *sci =3D RSCI(opaque); > > + > > + switch (offset) { > > + case A_SMR: > > + return sci->smr; > > + case A_BRR: > > + return sci->brr; > > + case A_SCR: > > + return sci->scr; > > + case A_TDR: > > + return sci->tdr; > > + case A_SSR: > > + sci->read_ssr =3D sci->ssr; > > + return sci->ssr; > > + case A_RDR: > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, RDRF, 0); > > + return sci->rdr; > > + case A_SCMR: > > + return sci->scmr; > > + case A_SEMR: > > + return sci->semr; > > + default: > > + qemu_log_mask(LOG_UNIMP, > > + "renesas_sci: Register %08lx not implemented.\n"= , offset); > > + } > > + return -1; > > +} > > + > > +static const MemoryRegionOps sci_ops =3D { > > + .write =3D sci_write, > > + .read =3D sci_read, > > + .endianness =3D DEVICE_NATIVE_ENDIAN, > > + .impl =3D { > > + .max_access_size =3D 1, > > + }, > > +}; > > + > > +static void rsci_reset(DeviceState *dev) > > +{ > > + RSCIState *sci =3D RSCI(dev); > > + sci->smr =3D sci->scr =3D 0x00; > > + sci->brr =3D 0xff; > > + sci->tdr =3D 0xff; > > + sci->rdr =3D 0x00; > > + sci->ssr =3D 0x84; > > + sci->scmr =3D 0x00; > > + sci->semr =3D 0x00; > > + sci->rx_next =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); > > +} > > + > > +static void sci_event(void *opaque, int event) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + if (event =3D=3D CHR_EVENT_BREAK) { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, FER, 1); > > + printf("ssr %s %d %02x\n", __func__, __LINE__, sci->ssr); >=20 > stray debug printf Oh, removed it. > Otherwise: >=20 > Reviewed-by: Alex Benn=E9e >=20 > -- > Alex Benn=E9e >=20 --=20 Yosinori Sato From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41988C004C9 for ; Sun, 5 May 2019 16:13:08 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 037562082F for ; Sun, 5 May 2019 16:13:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 037562082F Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=users.sourceforge.jp Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([127.0.0.1]:43290 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hNJlD-0007ne-94 for qemu-devel@archiver.kernel.org; Sun, 05 May 2019 12:13:07 -0400 Received: from eggs.gnu.org ([209.51.188.92]:53563) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hNJfu-0003gp-2Y for qemu-devel@nongnu.org; Sun, 05 May 2019 12:07:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hNJfs-0006iK-7L for qemu-devel@nongnu.org; Sun, 05 May 2019 12:07:38 -0400 Received: from mail02.asahi-net.or.jp ([202.224.55.14]:52126) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hNJfq-0006gZ-FX for qemu-devel@nongnu.org; Sun, 05 May 2019 12:07:35 -0400 Received: from h61-195-96-97.vps.ablenet.jp (h61-195-96-97.vps.ablenet.jp [61.195.96.97]) (Authenticated sender: PQ4Y-STU) by mail02.asahi-net.or.jp (Postfix) with ESMTPA id CBDE43ACC3; Mon, 6 May 2019 01:07:32 +0900 (JST) Received: from yo-satoh-debian.ysato.ml (ZM005235.ppp.dion.ne.jp [222.8.5.235]) by h61-195-96-97.vps.ablenet.jp (Postfix) with ESMTPSA id 7BEAF240085; Mon, 6 May 2019 01:07:32 +0900 (JST) Date: Mon, 06 May 2019 01:07:32 +0900 Message-ID: <87o94g51h7.wl-ysato@users.sourceforge.jp> From: Yoshinori Sato To: Alex =?ISO-8859-1?Q?Benn=E9e?= In-Reply-To: <87o94j4l6j.fsf@zen.linaroharston> References: <20190502143409.59600-1-ysato@users.sourceforge.jp> <20190502143409.59600-9-ysato@users.sourceforge.jp> <87o94j4l6j.fsf@zen.linaroharston> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM/1.14.9 (=?ISO-8859-4?Q?Goj=F2?=) APEL/10.8 EasyPG/1.0.0 Emacs/25.1 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 202.224.55.14 Subject: Re: [Qemu-devel] [PATCH RFC v8 08/12] hw/char: RX62N serical communication interface (SCI) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, richard.henderson@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Message-ID: <20190505160732.ZT3Qw9o3pR7Ry6zaBQwChyxBsX6aBYc4A_uBfdZboDQ@z> On Sat, 04 May 2019 00:22:44 +0900, Alex Benn=E9e wrote: >=20 >=20 > Yoshinori Sato writes: >=20 >=20 > nit: typo in subject (serical->serial) >=20 > > This module supported only non FIFO type. > > Hardware manual. > > https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh00= 33ej0140_rx62n.pdf > > > > Signed-off-by: Yoshinori Sato > > --- > > include/hw/char/renesas_sci.h | 45 ++++++ > > hw/char/renesas_sci.c | 341 ++++++++++++++++++++++++++++++++++= ++++++++ > > hw/char/Kconfig | 3 + > > hw/char/Makefile.objs | 2 +- > > 4 files changed, 390 insertions(+), 1 deletion(-) > > create mode 100644 include/hw/char/renesas_sci.h > > create mode 100644 hw/char/renesas_sci.c > > > > diff --git a/include/hw/char/renesas_sci.h b/include/hw/char/renesas_sc= i.h > > new file mode 100644 > > index 0000000000..50d1336944 > > --- /dev/null > > +++ b/include/hw/char/renesas_sci.h > > @@ -0,0 +1,45 @@ > > +/* > > + * Renesas Serial Communication Interface > > + * > > + * Copyright (c) 2018 Yoshinori Sato > > + * > > + * This code is licensed under the GPL version 2 or later. > > + * > > + */ > > + > > +#include "chardev/char-fe.h" > > +#include "qemu/timer.h" > > +#include "hw/sysbus.h" > > + > > +#define TYPE_RENESAS_SCI "renesas-sci" > > +#define RSCI(obj) OBJECT_CHECK(RSCIState, (obj), TYPE_RENESAS_SCI) > > + > > +enum { > > + ERI =3D 0, > > + RXI =3D 1, > > + TXI =3D 2, > > + TEI =3D 3, > > + SCI_NR_IRQ =3D 4, > > +}; > > + > > +typedef struct { > > + SysBusDevice parent_obj; > > + MemoryRegion memory; > > + > > + uint8_t smr; > > + uint8_t brr; > > + uint8_t scr; > > + uint8_t tdr; > > + uint8_t ssr; > > + uint8_t rdr; > > + uint8_t scmr; > > + uint8_t semr; > > + > > + uint8_t read_ssr; > > + int64_t trtime; > > + int64_t rx_next; > > + QEMUTimer *timer; > > + CharBackend chr; > > + uint64_t input_freq; > > + qemu_irq irq[SCI_NR_IRQ]; > > +} RSCIState; > > diff --git a/hw/char/renesas_sci.c b/hw/char/renesas_sci.c > > new file mode 100644 > > index 0000000000..719fa2f938 > > --- /dev/null > > +++ b/hw/char/renesas_sci.c > > @@ -0,0 +1,341 @@ > > +/* > > + * Renesas Serial Communication Interface > > + * > > + * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware > > + * (Rev.1.40 R01UH0033EJ0140) > > + * > > + * Copyright (c) 2019 Yoshinori Sato > > + * > > + * This program is free software; you can redistribute it and/or modif= y it > > + * under the terms and conditions of the GNU General Public License, > > + * version 2 or later, as published by the Free Software Foundation. > > + * > > + * This program is distributed in the hope it will be useful, but WITH= OUT > > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY = or > > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licen= se for > > + * more details. > > + * > > + * You should have received a copy of the GNU General Public License a= long with > > + * this program. If not, see . > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "qemu/log.h" > > +#include "qapi/error.h" > > +#include "qemu-common.h" > > +#include "cpu.h" > > +#include "hw/hw.h" > > +#include "hw/sysbus.h" > > +#include "hw/registerfields.h" > > +#include "hw/char/renesas_sci.h" > > +#include "qemu/error-report.h" > > + > > +/* SCI register map */ > > +REG8(SMR, 0) > > + FIELD(SMR, CKS, 0, 2) > > + FIELD(SMR, MP, 2, 1) > > + FIELD(SMR, STOP, 3, 1) > > + FIELD(SMR, PM, 4, 1) > > + FIELD(SMR, PE, 5, 1) > > + FIELD(SMR, CHR, 6, 1) > > + FIELD(SMR, CM, 7, 1) > > +REG8(BRR, 1) > > +REG8(SCR, 2) > > + FIELD(SCR, CKE, 0, 2) > > + FIELD(SCR, TEIE, 2, 1) > > + FIELD(SCR, MPIE, 3, 1) > > + FIELD(SCR, RE, 4, 1) > > + FIELD(SCR, TE, 5, 1) > > + FIELD(SCR, RIE, 6, 1) > > + FIELD(SCR, TIE, 7, 1) > > +REG8(TDR, 3) > > +REG8(SSR, 4) > > + FIELD(SSR, MPBT, 0, 1) > > + FIELD(SSR, MPB, 1, 1) > > + FIELD(SSR, TEND, 2, 1) > > + FIELD(SSR, ERR, 3, 3) > > + FIELD(SSR, PER, 3, 1) > > + FIELD(SSR, FER, 4, 1) > > + FIELD(SSR, ORER, 5, 1) > > + FIELD(SSR, RDRF, 6, 1) > > + FIELD(SSR, TDRE, 7, 1) > > +REG8(RDR, 5) > > +REG8(SCMR, 6) > > + FIELD(SCMR, SMIF, 0, 1) > > + FIELD(SCMR, SINV, 2, 1) > > + FIELD(SCMR, SDIR, 3, 1) > > + FIELD(SCMR, BCP2, 7, 1) > > +REG8(SEMR, 7) > > + FIELD(SEMR, ACS0, 0, 1) > > + FIELD(SEMR, ABCS, 4, 1) > > + > > +static int can_receive(void *opaque) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + if (sci->rx_next > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) { > > + return 0; > > + } else { > > + return FIELD_EX8(sci->scr, SCR, RE); > > + } > > +} > > + > > +static void receive(void *opaque, const uint8_t *buf, int size) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + sci->rx_next =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trti= me; > > + if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, ORER, 1); > > + if (FIELD_EX8(sci->scr, SCR, RIE)) { > > + qemu_set_irq(sci->irq[ERI], 1); > > + } > > + } else { > > + sci->rdr =3D buf[0]; > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, RDRF, 1); > > + if (FIELD_EX8(sci->scr, SCR, RIE)) { > > + qemu_irq_pulse(sci->irq[RXI]); > > + } > > + } > > +} > > + > > +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); > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TEND, 0); > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TDRE, 1); > > + qemu_set_irq(sci->irq[TEI], 0); > > + if (FIELD_EX8(sci->scr, SCR, TIE)) { > > + qemu_irq_pulse(sci->irq[TXI]); > > + } > > +} > > + > > +static void txend(void *opaque) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + if (!FIELD_EX8(sci->ssr, SSR, TDRE)) { > > + send_byte(sci); > > + } else { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TEND, 1); > > + if (FIELD_EX8(sci->scr, SCR, TEIE)) { > > + qemu_set_irq(sci->irq[TEI], 1); > > + } > > + } > > +} > > + > > +static void update_trtime(RSCIState *sci) > > +{ > > + /* char per bits */ > > + sci->trtime =3D 8 - FIELD_EX8(sci->smr, SMR, CHR); > > + sci->trtime +=3D FIELD_EX8(sci->smr, SMR, PE); > > + sci->trtime +=3D FIELD_EX8(sci->smr, SMR, STOP) + 1; > > + /* x bit transmit time (32 * divrate * brr) / base freq */ > > + sci->trtime *=3D 32 * sci->brr; > > + sci->trtime *=3D 1 << (2 * FIELD_EX8(sci->smr, SMR, CKS)); > > + sci->trtime *=3D NANOSECONDS_PER_SECOND; > > + sci->trtime /=3D sci->input_freq; > > +} > > + > > +#define IS_TR_ENABLED(scr) \ > > + (FIELD_EX8(scr, SCR, TE) || FIELD_EX8(scr, SCR, RE)) > > + > > +static void sci_write(void *opaque, hwaddr addr, uint64_t val, unsigne= d size) > > +{ > > + hwaddr offset =3D addr & 0x07; > > + RSCIState *sci =3D RSCI(opaque); > > + > > + switch (offset) { > > + case A_SMR: > > + if (!IS_TR_ENABLED(sci->scr)) { > > + sci->smr =3D val; > > + update_trtime(sci); > > + } > > + break; > > + case A_BRR: > > + if (!IS_TR_ENABLED(sci->scr)) { > > + sci->brr =3D val; > > + update_trtime(sci); > > + } > > + break; > > + case A_SCR: > > + sci->scr =3D val; > > + if (FIELD_EX8(sci->scr, SCR, TE)) { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TDRE, 1); > > + sci->ssr =3D 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, TEIE)) { > > + qemu_set_irq(sci->irq[TEI], 0); > > + } > > + if (!FIELD_EX8(sci->scr, SCR, RIE)) { > > + qemu_set_irq(sci->irq[ERI], 0); > > + } > > + break; > > + case A_TDR: > > + sci->tdr =3D val; > > + if (FIELD_EX8(sci->ssr, SSR, TEND)) { > > + send_byte(sci); > > + } else { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, TDRE, 0); > > + } > > + break; > > + case A_SSR: > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, MPBT, > > + FIELD_EX8(val, SSR, MPBT)); > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, ERR, > > + FIELD_EX8(val, SSR, ERR) & 0x07); > > + if (FIELD_EX8(sci->read_ssr, SSR, ERR) && > > + FIELD_EX8(sci->ssr, SSR, ERR) =3D=3D 0) { > > + qemu_set_irq(sci->irq[ERI], 0); > > + } > > + break; > > + case A_RDR: > > + qemu_log_mask(LOG_GUEST_ERROR, "reneas_sci: RDR is read only.\= n"); > > + break; > > + case A_SCMR: > > + sci->scmr =3D val; break; > > + case A_SEMR: /* SEMR */ > > + sci->semr =3D val; break; > > + default: > > + qemu_log_mask(LOG_UNIMP, > > + "renesas_sci: Register %08lx not implemented\n",= offset); > > + } > > +} > > + > > +static uint64_t sci_read(void *opaque, hwaddr addr, unsigned size) > > +{ > > + hwaddr offset =3D addr & 0x07; > > + RSCIState *sci =3D RSCI(opaque); > > + > > + switch (offset) { > > + case A_SMR: > > + return sci->smr; > > + case A_BRR: > > + return sci->brr; > > + case A_SCR: > > + return sci->scr; > > + case A_TDR: > > + return sci->tdr; > > + case A_SSR: > > + sci->read_ssr =3D sci->ssr; > > + return sci->ssr; > > + case A_RDR: > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, RDRF, 0); > > + return sci->rdr; > > + case A_SCMR: > > + return sci->scmr; > > + case A_SEMR: > > + return sci->semr; > > + default: > > + qemu_log_mask(LOG_UNIMP, > > + "renesas_sci: Register %08lx not implemented.\n"= , offset); > > + } > > + return -1; > > +} > > + > > +static const MemoryRegionOps sci_ops =3D { > > + .write =3D sci_write, > > + .read =3D sci_read, > > + .endianness =3D DEVICE_NATIVE_ENDIAN, > > + .impl =3D { > > + .max_access_size =3D 1, > > + }, > > +}; > > + > > +static void rsci_reset(DeviceState *dev) > > +{ > > + RSCIState *sci =3D RSCI(dev); > > + sci->smr =3D sci->scr =3D 0x00; > > + sci->brr =3D 0xff; > > + sci->tdr =3D 0xff; > > + sci->rdr =3D 0x00; > > + sci->ssr =3D 0x84; > > + sci->scmr =3D 0x00; > > + sci->semr =3D 0x00; > > + sci->rx_next =3D qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); > > +} > > + > > +static void sci_event(void *opaque, int event) > > +{ > > + RSCIState *sci =3D RSCI(opaque); > > + if (event =3D=3D CHR_EVENT_BREAK) { > > + sci->ssr =3D FIELD_DP8(sci->ssr, SSR, FER, 1); > > + printf("ssr %s %d %02x\n", __func__, __LINE__, sci->ssr); >=20 > stray debug printf Oh, removed it. > Otherwise: >=20 > Reviewed-by: Alex Benn=E9e >=20 > -- > Alex Benn=E9e >=20 --=20 Yosinori Sato