From: Yoshinori Sato <ysato@users.sourceforge.jp>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: qemu-devel@nongnu.org, peter.maydell@linaro.org,
richard.henderson@linaro.org
Subject: Re: [Qemu-devel] [PATCH RFC v8 08/12] hw/char: RX62N serical communication interface (SCI)
Date: Mon, 06 May 2019 01:07:32 +0900 [thread overview]
Message-ID: <87o94g51h7.wl-ysato@users.sourceforge.jp> (raw)
In-Reply-To: <87o94j4l6j.fsf@zen.linaroharston>
On Sat, 04 May 2019 00:22:44 +0900,
Alex Bennée wrote:
>
>
> Yoshinori Sato <ysato@users.sourceforge.jp> writes:
>
>
> nit: typo in subject (serical->serial)
>
> > This module supported only non FIFO type.
> > Hardware manual.
> > https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf
> >
> > Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> > ---
> > 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_sci.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 = 0,
> > + RXI = 1,
> > + TXI = 2,
> > + TEI = 3,
> > + SCI_NR_IRQ = 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 modify 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 WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> > + * more details.
> > + *
> > + * You should have received a copy of the GNU General Public License along with
> > + * this program. If not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#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 = 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 = RSCI(opaque);
> > + sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime;
> > + if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) {
> > + 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->ssr = 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 = 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)) {
> > + qemu_irq_pulse(sci->irq[TXI]);
> > + }
> > +}
> > +
> > +static void txend(void *opaque)
> > +{
> > + RSCIState *sci = RSCI(opaque);
> > + if (!FIELD_EX8(sci->ssr, SSR, TDRE)) {
> > + send_byte(sci);
> > + } else {
> > + sci->ssr = 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 = 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;
> > +}
> > +
> > +#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, unsigned size)
> > +{
> > + hwaddr offset = addr & 0x07;
> > + RSCIState *sci = RSCI(opaque);
> > +
> > + switch (offset) {
> > + case A_SMR:
> > + if (!IS_TR_ENABLED(sci->scr)) {
> > + sci->smr = val;
> > + update_trtime(sci);
> > + }
> > + break;
> > + case A_BRR:
> > + if (!IS_TR_ENABLED(sci->scr)) {
> > + sci->brr = val;
> > + update_trtime(sci);
> > + }
> > + 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, 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 = val;
> > + if (FIELD_EX8(sci->ssr, SSR, TEND)) {
> > + send_byte(sci);
> > + } else {
> > + sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0);
> > + }
> > + break;
> > + case A_SSR:
> > + sci->ssr = FIELD_DP8(sci->ssr, SSR, MPBT,
> > + FIELD_EX8(val, SSR, MPBT));
> > + sci->ssr = 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) == 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 = val; break;
> > + case A_SEMR: /* SEMR */
> > + sci->semr = 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 = addr & 0x07;
> > + RSCIState *sci = 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 = sci->ssr;
> > + return sci->ssr;
> > + case A_RDR:
> > + sci->ssr = 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 = {
> > + .write = sci_write,
> > + .read = sci_read,
> > + .endianness = DEVICE_NATIVE_ENDIAN,
> > + .impl = {
> > + .max_access_size = 1,
> > + },
> > +};
> > +
> > +static void rsci_reset(DeviceState *dev)
> > +{
> > + RSCIState *sci = RSCI(dev);
> > + sci->smr = sci->scr = 0x00;
> > + sci->brr = 0xff;
> > + sci->tdr = 0xff;
> > + sci->rdr = 0x00;
> > + sci->ssr = 0x84;
> > + sci->scmr = 0x00;
> > + sci->semr = 0x00;
> > + sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > +}
> > +
> > +static void sci_event(void *opaque, int event)
> > +{
> > + RSCIState *sci = RSCI(opaque);
> > + if (event == CHR_EVENT_BREAK) {
> > + sci->ssr = FIELD_DP8(sci->ssr, SSR, FER, 1);
> > + printf("ssr %s %d %02x\n", __func__, __LINE__, sci->ssr);
>
> stray debug printf
Oh, removed it.
> Otherwise:
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
>
> --
> Alex Bennée
>
--
Yosinori Sato
WARNING: multiple messages have this Message-ID (diff)
From: Yoshinori Sato <ysato@users.sourceforge.jp>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: peter.maydell@linaro.org, richard.henderson@linaro.org,
qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH RFC v8 08/12] hw/char: RX62N serical communication interface (SCI)
Date: Mon, 06 May 2019 01:07:32 +0900 [thread overview]
Message-ID: <87o94g51h7.wl-ysato@users.sourceforge.jp> (raw)
Message-ID: <20190505160732.ZT3Qw9o3pR7Ry6zaBQwChyxBsX6aBYc4A_uBfdZboDQ@z> (raw)
In-Reply-To: <87o94j4l6j.fsf@zen.linaroharston>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="UTF-8", Size: 11526 bytes --]
On Sat, 04 May 2019 00:22:44 +0900,
Alex Bennée wrote:
>
>
> Yoshinori Sato <ysato@users.sourceforge.jp> writes:
>
>
> nit: typo in subject (serical->serial)
>
> > This module supported only non FIFO type.
> > Hardware manual.
> > https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf
> >
> > Signed-off-by: Yoshinori Sato <ysato@users.sourceforge.jp>
> > ---
> > 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_sci.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 = 0,
> > + RXI = 1,
> > + TXI = 2,
> > + TEI = 3,
> > + SCI_NR_IRQ = 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 modify 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 WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> > + * more details.
> > + *
> > + * You should have received a copy of the GNU General Public License along with
> > + * this program. If not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#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 = 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 = RSCI(opaque);
> > + sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime;
> > + if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) {
> > + 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->ssr = 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 = 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)) {
> > + qemu_irq_pulse(sci->irq[TXI]);
> > + }
> > +}
> > +
> > +static void txend(void *opaque)
> > +{
> > + RSCIState *sci = RSCI(opaque);
> > + if (!FIELD_EX8(sci->ssr, SSR, TDRE)) {
> > + send_byte(sci);
> > + } else {
> > + sci->ssr = 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 = 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;
> > +}
> > +
> > +#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, unsigned size)
> > +{
> > + hwaddr offset = addr & 0x07;
> > + RSCIState *sci = RSCI(opaque);
> > +
> > + switch (offset) {
> > + case A_SMR:
> > + if (!IS_TR_ENABLED(sci->scr)) {
> > + sci->smr = val;
> > + update_trtime(sci);
> > + }
> > + break;
> > + case A_BRR:
> > + if (!IS_TR_ENABLED(sci->scr)) {
> > + sci->brr = val;
> > + update_trtime(sci);
> > + }
> > + 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, 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 = val;
> > + if (FIELD_EX8(sci->ssr, SSR, TEND)) {
> > + send_byte(sci);
> > + } else {
> > + sci->ssr = FIELD_DP8(sci->ssr, SSR, TDRE, 0);
> > + }
> > + break;
> > + case A_SSR:
> > + sci->ssr = FIELD_DP8(sci->ssr, SSR, MPBT,
> > + FIELD_EX8(val, SSR, MPBT));
> > + sci->ssr = 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) == 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 = val; break;
> > + case A_SEMR: /* SEMR */
> > + sci->semr = 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 = addr & 0x07;
> > + RSCIState *sci = 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 = sci->ssr;
> > + return sci->ssr;
> > + case A_RDR:
> > + sci->ssr = 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 = {
> > + .write = sci_write,
> > + .read = sci_read,
> > + .endianness = DEVICE_NATIVE_ENDIAN,
> > + .impl = {
> > + .max_access_size = 1,
> > + },
> > +};
> > +
> > +static void rsci_reset(DeviceState *dev)
> > +{
> > + RSCIState *sci = RSCI(dev);
> > + sci->smr = sci->scr = 0x00;
> > + sci->brr = 0xff;
> > + sci->tdr = 0xff;
> > + sci->rdr = 0x00;
> > + sci->ssr = 0x84;
> > + sci->scmr = 0x00;
> > + sci->semr = 0x00;
> > + sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > +}
> > +
> > +static void sci_event(void *opaque, int event)
> > +{
> > + RSCIState *sci = RSCI(opaque);
> > + if (event == CHR_EVENT_BREAK) {
> > + sci->ssr = FIELD_DP8(sci->ssr, SSR, FER, 1);
> > + printf("ssr %s %d %02x\n", __func__, __LINE__, sci->ssr);
>
> stray debug printf
Oh, removed it.
> Otherwise:
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
>
> --
> Alex Bennée
>
--
Yosinori Sato
next prev parent reply other threads:[~2019-05-05 16:07 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-02 14:33 [Qemu-devel] [PATCH RFC v8 00/12] Add RX archtecture support Yoshinori Sato
2019-05-02 14:33 ` Yoshinori Sato
2019-05-02 14:33 ` [Qemu-devel] [PATCH RFC v8 01/12] target/rx: TCG translation Yoshinori Sato
2019-05-02 14:33 ` Yoshinori Sato
2019-05-03 18:43 ` Richard Henderson
2019-05-05 16:07 ` Yoshinori Sato
2019-05-05 16:07 ` Yoshinori Sato
2019-05-02 14:33 ` [Qemu-devel] [PATCH RFC v8 02/12] target/rx: TCG helper Yoshinori Sato
2019-05-02 14:33 ` Yoshinori Sato
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 03/12] target/rx: CPU definition Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 15:45 ` Alex Bennée
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 04/12] target/rx: RX disassembler Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 15:54 ` Alex Bennée
2019-05-03 18:37 ` Richard Henderson
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 05/12] target/rx: Miscellaneous files Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 16:06 ` Alex Bennée
2019-05-05 16:06 ` Yoshinori Sato
2019-05-05 16:06 ` Yoshinori Sato
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 06/12] hw/intc: RX62N interrupt controller (ICUa) Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 15:01 ` Alex Bennée
2019-05-03 15:50 ` Alex Bennée
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 07/12] hw/timer: RX62N internal timer modules Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 15:20 ` Alex Bennée
2019-05-05 16:06 ` Yoshinori Sato
2019-05-05 16:06 ` Yoshinori Sato
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 08/12] hw/char: RX62N serical communication interface (SCI) Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 15:22 ` Alex Bennée
2019-05-05 16:07 ` Yoshinori Sato [this message]
2019-05-05 16:07 ` Yoshinori Sato
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 09/12] hw/rx: RX Target hardware definition Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 15:38 ` Alex Bennée
2019-05-05 16:07 ` Yoshinori Sato
2019-05-05 16:07 ` Yoshinori Sato
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 10/12] Add rx-softmmu Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 11/12] MAINTAINERS: Add RX Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-02 14:34 ` [Qemu-devel] [PATCH RFC v8 12/12] hw/registerfields.h: Add 8bit and 16bit register macros Yoshinori Sato
2019-05-02 14:34 ` Yoshinori Sato
2019-05-03 15:27 ` Alex Bennée
2019-05-03 18:39 ` Richard Henderson
2019-05-05 21:18 ` Alex Bennée
2019-05-05 21:18 ` Alex Bennée
2019-05-05 16:07 ` Yoshinori Sato
2019-05-05 16:07 ` Yoshinori Sato
2019-05-03 16:11 ` [Qemu-devel] [PATCH RFC v8 00/12] Add RX archtecture support Alex Bennée
2019-05-05 16:07 ` Yoshinori Sato
2019-05-05 16:07 ` Yoshinori Sato
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87o94g51h7.wl-ysato@users.sourceforge.jp \
--to=ysato@users.sourceforge.jp \
--cc=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.