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 07/12] hw/timer: RX62N internal timer modules
Date: Mon, 06 May 2019 01:06:58 +0900 [thread overview]
Message-ID: <87sgts51i5.wl-ysato@users.sourceforge.jp> (raw)
In-Reply-To: <87pnoz4l9s.fsf@zen.linaroharston>
On Sat, 04 May 2019 00:20:47 +0900,
Alex Bennée wrote:
>
>
> Yoshinori Sato <ysato@users.sourceforge.jp> writes:
>
> > renesas_tmr: 8bit timer modules.
> > renesas_cmt: 16bit compare match timer modules.
> > This part use many renesas's CPU.
> > 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/timer/renesas_cmt.h | 33 +++
> > include/hw/timer/renesas_tmr.h | 46 +++++
> > hw/timer/renesas_cmt.c | 277 +++++++++++++++++++++++++
> > hw/timer/renesas_tmr.c | 458 +++++++++++++++++++++++++++++++++++++++++
> > hw/timer/Kconfig | 6 +
> > hw/timer/Makefile.objs | 3 +
> > 6 files changed, 823 insertions(+)
> > create mode 100644 include/hw/timer/renesas_cmt.h
> > create mode 100644 include/hw/timer/renesas_tmr.h
> > create mode 100644 hw/timer/renesas_cmt.c
> > create mode 100644 hw/timer/renesas_tmr.c
> >
> > diff --git a/include/hw/timer/renesas_cmt.h b/include/hw/timer/renesas_cmt.h
> > new file mode 100644
> > index 0000000000..7e393d7ad3
> > --- /dev/null
> > +++ b/include/hw/timer/renesas_cmt.h
> > @@ -0,0 +1,33 @@
> > +/*
> > + * Renesas Compare-match timer Object
> > + *
> > + * Copyright (c) 2019 Yoshinori Sato
> > + *
> > + * This code is licensed under the GPL version 2 or later.
> > + *
> > + */
> > +
> > +#ifndef HW_RENESAS_CMT_H
> > +#define HW_RENESAS_CMT_H
> > +
> > +#include "hw/sysbus.h"
> > +
> > +#define TYPE_RENESAS_CMT "renesas-cmt"
> > +#define RCMT(obj) OBJECT_CHECK(RCMTState, (obj), TYPE_RENESAS_CMT)
> > +
> > +typedef struct RCMTState {
> > + SysBusDevice parent_obj;
> > +
> > + uint64_t input_freq;
> > + MemoryRegion memory;
> > +
> > + uint16_t cmstr;
> > + uint16_t cmcr[2];
> > + uint16_t cmcnt[2];
> > + uint16_t cmcor[2];
> > + int64_t tick[2];
> > + qemu_irq cmi[2];
> > + QEMUTimer *timer[2];
> > +} RCMTState;
> > +
> > +#endif
> > diff --git a/include/hw/timer/renesas_tmr.h b/include/hw/timer/renesas_tmr.h
> > new file mode 100644
> > index 0000000000..718d9dc4ff
> > --- /dev/null
> > +++ b/include/hw/timer/renesas_tmr.h
> > @@ -0,0 +1,46 @@
> > +/*
> > + * Renesas 8bit timer Object
> > + *
> > + * Copyright (c) 2018 Yoshinori Sato
> > + *
> > + * This code is licensed under the GPL version 2 or later.
> > + *
> > + */
> > +
> > +#ifndef HW_RENESAS_TMR_H
> > +#define HW_RENESAS_TMR_H
> > +
> > +#include "hw/sysbus.h"
> > +
> > +#define TYPE_RENESAS_TMR "renesas-tmr"
> > +#define RTMR(obj) OBJECT_CHECK(RTMRState, (obj), TYPE_RENESAS_TMR)
> > +
> > +enum timer_event {cmia = 0,
> > + cmib = 1,
> > + ovi = 2,
> > + none = 3,
> > + TMR_NR_EVENTS = 4};
> > +enum {CH = 2};
> > +typedef struct RTMRState {
> > + SysBusDevice parent_obj;
> > +
> > + uint64_t input_freq;
> > + MemoryRegion memory;
> > +
> > + uint8_t tcnt[CH];
> > + uint8_t tcora[CH];
> > + uint8_t tcorb[CH];
> > + uint8_t tcr[CH];
> > + uint8_t tccr[CH];
> > + uint8_t tcor[CH];
> > + uint8_t tcsr[CH];
> > + int64_t tick;
> > + int64_t div_round[CH];
> > + enum timer_event next[CH];
> > + qemu_irq cmia[CH];
> > + qemu_irq cmib[CH];
> > + qemu_irq ovi[CH];
> > + QEMUTimer *timer[CH];
> > +} RTMRState;
> > +
> > +#endif
> > diff --git a/hw/timer/renesas_cmt.c b/hw/timer/renesas_cmt.c
> > new file mode 100644
> > index 0000000000..b82250dbc2
> > --- /dev/null
> > +++ b/hw/timer/renesas_cmt.c
> > @@ -0,0 +1,277 @@
> > +/*
> > + * Renesas 16bit Compare-match timer
> > + *
> > + * 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-common.h"
> > +#include "qemu/log.h"
> > +#include "qapi/error.h"
> > +#include "qemu/timer.h"
> > +#include "cpu.h"
> > +#include "hw/hw.h"
> > +#include "hw/sysbus.h"
> > +#include "hw/registerfields.h"
> > +#include "hw/timer/renesas_cmt.h"
> > +#include "qemu/error-report.h"
> > +
> > +/*
> > + * +0 CMSTR - common control
> > + * +2 CMCR - ch0
> > + * +4 CMCNT - ch0
> > + * +6 CMCOR - ch0
> > + * +8 CMCR - ch1
> > + * +10 CMCNT - ch1
> > + * +12 CMCOR - ch1
> > + * If we think that the address of CH 0 has an offset of +2,
> > + * we can treat it with the same address as CH 1, so define it like that.
> > + */
> > +REG16(CMSTR, 0)
> > + FIELD(CMSTR, STR0, 0, 1)
> > + FIELD(CMSTR, STR1, 1, 1)
> > + FIELD(CMSTR, STR, 0, 2)
> > +/* This addeess is channel offset */
> > +REG16(CMCR, 0)
> > + FIELD(CMCR, CKS, 0, 2)
> > + FIELD(CMCR, CMIE, 6, 1)
> > +REG16(CMCNT, 2)
> > +REG16(CMCOR, 4)
> > +
> > +static void update_events(RCMTState *cmt, int ch)
> > +{
> > + int64_t next_time;
> > +
> > + if ((cmt->cmstr & (1 << ch)) == 0) {
> > + /* count disable, so not happened next event. */
> > + return ;
> > + }
> > + next_time = cmt->cmcor[ch] - cmt->cmcnt[ch];
> > + next_time *= NANOSECONDS_PER_SECOND;
> > + next_time /= cmt->input_freq;
> > + /*
> > + * CKS -> div rate
> > + * 0 -> 8 (1 << 3)
> > + * 1 -> 32 (1 << 5)
> > + * 2 -> 128 (1 << 7)
> > + * 3 -> 512 (1 << 9)
> > + */
> > + next_time *= 1 << (3 + FIELD_EX16(cmt->cmcr[ch], CMCR, CKS) * 2);
> > + next_time += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > + timer_mod(cmt->timer[ch], next_time);
> > +}
> > +
> > +static int64_t read_cmcnt(RCMTState *cmt, int ch)
> > +{
> > + int64_t delta, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > +
> > + if (cmt->cmstr & (1 << ch)) {
> > + delta = (now - cmt->tick[ch]);
> > + delta /= NANOSECONDS_PER_SECOND;
> > + delta /= cmt->input_freq;
> > + delta /= 1 << (3 + FIELD_EX16(cmt->cmcr[ch], CMCR, CKS) * 2);
> > + cmt->tick[ch] = now;
> > + return cmt->cmcnt[ch] + delta;
> > + } else {
> > + return cmt->cmcnt[ch];
> > + }
> > +}
> > +
> > +static uint64_t cmt_read(void *opaque, hwaddr addr, unsigned size)
> > +{
> > + hwaddr offset = addr & 0x0f;
> > + RCMTState *cmt = opaque;
> > + int ch = offset / 0x08;
> > + uint64_t ret;
> > +
> > + if (offset == A_CMSTR) {
> > + ret = 0;
> > + ret = FIELD_DP16(ret, CMSTR, STR,
> > + FIELD_EX16(cmt->cmstr, CMSTR, STR));
> > + return ret;
> > + } else {
> > + offset &= 0x07;
> > + if (ch == 0) {
> > + offset -= 0x02;
> > + }
> > + switch (offset) {
> > + case A_CMCR:
> > + ret = 0;
> > + ret = FIELD_DP16(ret, CMCR, CKS,
> > + FIELD_EX16(cmt->cmstr, CMCR, CKS));
> > + ret = FIELD_DP16(ret, CMCR, CMIE,
> > + FIELD_EX16(cmt->cmstr, CMCR, CMIE));
> > + return ret;
> > + case A_CMCNT:
> > + return read_cmcnt(cmt, ch);
> > + case A_CMCOR:
> > + return cmt->cmcor[ch];
> > + }
> > + }
> > + qemu_log_mask(LOG_UNIMP,
> > + "renesas_cmt: Register %08lx not implemented\n",
> > + offset);
> > + return 0xffffffffffffffffUL;
> > +}
> > +
> > +static void start_stop(RCMTState *cmt, int ch, int st)
> > +{
> > + if (st) {
> > + update_events(cmt, ch);
> > + } else {
> > + timer_del(cmt->timer[ch]);
> > + }
> > +}
> > +
> > +static void cmt_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
> > +{
> > + hwaddr offset = addr & 0x0f;
> > + RCMTState *cmt = opaque;
> > + int ch = offset / 0x08;
> > +
> > + if (offset == A_CMSTR) {
> > + cmt->cmstr = FIELD_EX16(val, CMSTR, STR);
> > + start_stop(cmt, 0, FIELD_EX16(cmt->cmstr, CMSTR, STR0));
> > + start_stop(cmt, 1, FIELD_EX16(cmt->cmstr, CMSTR, STR1));
> > + } else {
> > + offset &= 0x07;
> > + if (ch == 0) {
> > + offset -= 0x02;
> > + }
> > + switch (offset) {
> > + case A_CMCR:
> > + cmt->cmcr[ch] = FIELD_DP16(cmt->cmcr[ch], CMCR, CKS,
> > + FIELD_EX16(val, CMCR, CKS));
> > + cmt->cmcr[ch] = FIELD_DP16(cmt->cmcr[ch], CMCR, CMIE,
> > + FIELD_EX16(val, CMCR, CMIE));
> > + break;
> > + case 2:
> > + cmt->cmcnt[ch] = val;
> > + break;
> > + case 4:
> > + cmt->cmcor[ch] = val;
> > + break;
> > + default:
> > + qemu_log_mask(LOG_UNIMP,
> > + "renesas_cmt: Register %08lx not implemented\n",
> > + offset);
> > + return;
> > + }
> > + if (FIELD_EX16(cmt->cmstr, CMSTR, STR) & (1 << ch)) {
> > + update_events(cmt, ch);
> > + }
> > + }
> > +}
> > +
> > +static const MemoryRegionOps cmt_ops = {
> > + .write = cmt_write,
> > + .read = cmt_read,
> > + .endianness = DEVICE_NATIVE_ENDIAN,
> > + .impl = {
> > + .min_access_size = 2,
> > + .max_access_size = 2,
> > + },
> > +};
> > +
> > +static void timer_events(RCMTState *cmt, int ch)
> > +{
> > + cmt->cmcnt[ch] = 0;
> > + cmt->tick[ch] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > + update_events(cmt, ch);
> > + if (FIELD_EX16(cmt->cmcr[ch], CMCR, CMIE)) {
> > + qemu_irq_pulse(cmt->cmi[ch]);
> > + }
> > +}
> > +
> > +static void timer_event0(void *opaque)
> > +{
> > + RCMTState *cmt = opaque;
> > +
> > + timer_events(cmt, 0);
> > +}
> > +
> > +static void timer_event1(void *opaque)
> > +{
> > + RCMTState *cmt = opaque;
> > +
> > + timer_events(cmt, 1);
> > +}
>
> I guess there is enough shared state RCMTState that you couldn't have an
> array of channel structures and just pass that when you setup the
> timers:
>
> > +static void rcmt_init(Object *obj)
> > +{
> <snip>
> > + cmt->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, timer_event0, cmt);
> > + cmt->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, timer_event1,
> > cmt);
>
> here?
Yes.
The shared part is only access from the CPU,
so I don't think there will be a conflict in the timer's event.
If problems occur, fix it to manage with one timer.
> Anyway:
>
> 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 07/12] hw/timer: RX62N internal timer modules
Date: Mon, 06 May 2019 01:06:58 +0900 [thread overview]
Message-ID: <87sgts51i5.wl-ysato@users.sourceforge.jp> (raw)
Message-ID: <20190505160658.H4o6VpcP6mSrCKxSZ9TkIYbjsZvAWaOLvZiSH08qLn0@z> (raw)
In-Reply-To: <87pnoz4l9s.fsf@zen.linaroharston>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="UTF-8", Size: 11512 bytes --]
On Sat, 04 May 2019 00:20:47 +0900,
Alex Bennée wrote:
>
>
> Yoshinori Sato <ysato@users.sourceforge.jp> writes:
>
> > renesas_tmr: 8bit timer modules.
> > renesas_cmt: 16bit compare match timer modules.
> > This part use many renesas's CPU.
> > 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/timer/renesas_cmt.h | 33 +++
> > include/hw/timer/renesas_tmr.h | 46 +++++
> > hw/timer/renesas_cmt.c | 277 +++++++++++++++++++++++++
> > hw/timer/renesas_tmr.c | 458 +++++++++++++++++++++++++++++++++++++++++
> > hw/timer/Kconfig | 6 +
> > hw/timer/Makefile.objs | 3 +
> > 6 files changed, 823 insertions(+)
> > create mode 100644 include/hw/timer/renesas_cmt.h
> > create mode 100644 include/hw/timer/renesas_tmr.h
> > create mode 100644 hw/timer/renesas_cmt.c
> > create mode 100644 hw/timer/renesas_tmr.c
> >
> > diff --git a/include/hw/timer/renesas_cmt.h b/include/hw/timer/renesas_cmt.h
> > new file mode 100644
> > index 0000000000..7e393d7ad3
> > --- /dev/null
> > +++ b/include/hw/timer/renesas_cmt.h
> > @@ -0,0 +1,33 @@
> > +/*
> > + * Renesas Compare-match timer Object
> > + *
> > + * Copyright (c) 2019 Yoshinori Sato
> > + *
> > + * This code is licensed under the GPL version 2 or later.
> > + *
> > + */
> > +
> > +#ifndef HW_RENESAS_CMT_H
> > +#define HW_RENESAS_CMT_H
> > +
> > +#include "hw/sysbus.h"
> > +
> > +#define TYPE_RENESAS_CMT "renesas-cmt"
> > +#define RCMT(obj) OBJECT_CHECK(RCMTState, (obj), TYPE_RENESAS_CMT)
> > +
> > +typedef struct RCMTState {
> > + SysBusDevice parent_obj;
> > +
> > + uint64_t input_freq;
> > + MemoryRegion memory;
> > +
> > + uint16_t cmstr;
> > + uint16_t cmcr[2];
> > + uint16_t cmcnt[2];
> > + uint16_t cmcor[2];
> > + int64_t tick[2];
> > + qemu_irq cmi[2];
> > + QEMUTimer *timer[2];
> > +} RCMTState;
> > +
> > +#endif
> > diff --git a/include/hw/timer/renesas_tmr.h b/include/hw/timer/renesas_tmr.h
> > new file mode 100644
> > index 0000000000..718d9dc4ff
> > --- /dev/null
> > +++ b/include/hw/timer/renesas_tmr.h
> > @@ -0,0 +1,46 @@
> > +/*
> > + * Renesas 8bit timer Object
> > + *
> > + * Copyright (c) 2018 Yoshinori Sato
> > + *
> > + * This code is licensed under the GPL version 2 or later.
> > + *
> > + */
> > +
> > +#ifndef HW_RENESAS_TMR_H
> > +#define HW_RENESAS_TMR_H
> > +
> > +#include "hw/sysbus.h"
> > +
> > +#define TYPE_RENESAS_TMR "renesas-tmr"
> > +#define RTMR(obj) OBJECT_CHECK(RTMRState, (obj), TYPE_RENESAS_TMR)
> > +
> > +enum timer_event {cmia = 0,
> > + cmib = 1,
> > + ovi = 2,
> > + none = 3,
> > + TMR_NR_EVENTS = 4};
> > +enum {CH = 2};
> > +typedef struct RTMRState {
> > + SysBusDevice parent_obj;
> > +
> > + uint64_t input_freq;
> > + MemoryRegion memory;
> > +
> > + uint8_t tcnt[CH];
> > + uint8_t tcora[CH];
> > + uint8_t tcorb[CH];
> > + uint8_t tcr[CH];
> > + uint8_t tccr[CH];
> > + uint8_t tcor[CH];
> > + uint8_t tcsr[CH];
> > + int64_t tick;
> > + int64_t div_round[CH];
> > + enum timer_event next[CH];
> > + qemu_irq cmia[CH];
> > + qemu_irq cmib[CH];
> > + qemu_irq ovi[CH];
> > + QEMUTimer *timer[CH];
> > +} RTMRState;
> > +
> > +#endif
> > diff --git a/hw/timer/renesas_cmt.c b/hw/timer/renesas_cmt.c
> > new file mode 100644
> > index 0000000000..b82250dbc2
> > --- /dev/null
> > +++ b/hw/timer/renesas_cmt.c
> > @@ -0,0 +1,277 @@
> > +/*
> > + * Renesas 16bit Compare-match timer
> > + *
> > + * 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-common.h"
> > +#include "qemu/log.h"
> > +#include "qapi/error.h"
> > +#include "qemu/timer.h"
> > +#include "cpu.h"
> > +#include "hw/hw.h"
> > +#include "hw/sysbus.h"
> > +#include "hw/registerfields.h"
> > +#include "hw/timer/renesas_cmt.h"
> > +#include "qemu/error-report.h"
> > +
> > +/*
> > + * +0 CMSTR - common control
> > + * +2 CMCR - ch0
> > + * +4 CMCNT - ch0
> > + * +6 CMCOR - ch0
> > + * +8 CMCR - ch1
> > + * +10 CMCNT - ch1
> > + * +12 CMCOR - ch1
> > + * If we think that the address of CH 0 has an offset of +2,
> > + * we can treat it with the same address as CH 1, so define it like that.
> > + */
> > +REG16(CMSTR, 0)
> > + FIELD(CMSTR, STR0, 0, 1)
> > + FIELD(CMSTR, STR1, 1, 1)
> > + FIELD(CMSTR, STR, 0, 2)
> > +/* This addeess is channel offset */
> > +REG16(CMCR, 0)
> > + FIELD(CMCR, CKS, 0, 2)
> > + FIELD(CMCR, CMIE, 6, 1)
> > +REG16(CMCNT, 2)
> > +REG16(CMCOR, 4)
> > +
> > +static void update_events(RCMTState *cmt, int ch)
> > +{
> > + int64_t next_time;
> > +
> > + if ((cmt->cmstr & (1 << ch)) == 0) {
> > + /* count disable, so not happened next event. */
> > + return ;
> > + }
> > + next_time = cmt->cmcor[ch] - cmt->cmcnt[ch];
> > + next_time *= NANOSECONDS_PER_SECOND;
> > + next_time /= cmt->input_freq;
> > + /*
> > + * CKS -> div rate
> > + * 0 -> 8 (1 << 3)
> > + * 1 -> 32 (1 << 5)
> > + * 2 -> 128 (1 << 7)
> > + * 3 -> 512 (1 << 9)
> > + */
> > + next_time *= 1 << (3 + FIELD_EX16(cmt->cmcr[ch], CMCR, CKS) * 2);
> > + next_time += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > + timer_mod(cmt->timer[ch], next_time);
> > +}
> > +
> > +static int64_t read_cmcnt(RCMTState *cmt, int ch)
> > +{
> > + int64_t delta, now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > +
> > + if (cmt->cmstr & (1 << ch)) {
> > + delta = (now - cmt->tick[ch]);
> > + delta /= NANOSECONDS_PER_SECOND;
> > + delta /= cmt->input_freq;
> > + delta /= 1 << (3 + FIELD_EX16(cmt->cmcr[ch], CMCR, CKS) * 2);
> > + cmt->tick[ch] = now;
> > + return cmt->cmcnt[ch] + delta;
> > + } else {
> > + return cmt->cmcnt[ch];
> > + }
> > +}
> > +
> > +static uint64_t cmt_read(void *opaque, hwaddr addr, unsigned size)
> > +{
> > + hwaddr offset = addr & 0x0f;
> > + RCMTState *cmt = opaque;
> > + int ch = offset / 0x08;
> > + uint64_t ret;
> > +
> > + if (offset == A_CMSTR) {
> > + ret = 0;
> > + ret = FIELD_DP16(ret, CMSTR, STR,
> > + FIELD_EX16(cmt->cmstr, CMSTR, STR));
> > + return ret;
> > + } else {
> > + offset &= 0x07;
> > + if (ch == 0) {
> > + offset -= 0x02;
> > + }
> > + switch (offset) {
> > + case A_CMCR:
> > + ret = 0;
> > + ret = FIELD_DP16(ret, CMCR, CKS,
> > + FIELD_EX16(cmt->cmstr, CMCR, CKS));
> > + ret = FIELD_DP16(ret, CMCR, CMIE,
> > + FIELD_EX16(cmt->cmstr, CMCR, CMIE));
> > + return ret;
> > + case A_CMCNT:
> > + return read_cmcnt(cmt, ch);
> > + case A_CMCOR:
> > + return cmt->cmcor[ch];
> > + }
> > + }
> > + qemu_log_mask(LOG_UNIMP,
> > + "renesas_cmt: Register %08lx not implemented\n",
> > + offset);
> > + return 0xffffffffffffffffUL;
> > +}
> > +
> > +static void start_stop(RCMTState *cmt, int ch, int st)
> > +{
> > + if (st) {
> > + update_events(cmt, ch);
> > + } else {
> > + timer_del(cmt->timer[ch]);
> > + }
> > +}
> > +
> > +static void cmt_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
> > +{
> > + hwaddr offset = addr & 0x0f;
> > + RCMTState *cmt = opaque;
> > + int ch = offset / 0x08;
> > +
> > + if (offset == A_CMSTR) {
> > + cmt->cmstr = FIELD_EX16(val, CMSTR, STR);
> > + start_stop(cmt, 0, FIELD_EX16(cmt->cmstr, CMSTR, STR0));
> > + start_stop(cmt, 1, FIELD_EX16(cmt->cmstr, CMSTR, STR1));
> > + } else {
> > + offset &= 0x07;
> > + if (ch == 0) {
> > + offset -= 0x02;
> > + }
> > + switch (offset) {
> > + case A_CMCR:
> > + cmt->cmcr[ch] = FIELD_DP16(cmt->cmcr[ch], CMCR, CKS,
> > + FIELD_EX16(val, CMCR, CKS));
> > + cmt->cmcr[ch] = FIELD_DP16(cmt->cmcr[ch], CMCR, CMIE,
> > + FIELD_EX16(val, CMCR, CMIE));
> > + break;
> > + case 2:
> > + cmt->cmcnt[ch] = val;
> > + break;
> > + case 4:
> > + cmt->cmcor[ch] = val;
> > + break;
> > + default:
> > + qemu_log_mask(LOG_UNIMP,
> > + "renesas_cmt: Register %08lx not implemented\n",
> > + offset);
> > + return;
> > + }
> > + if (FIELD_EX16(cmt->cmstr, CMSTR, STR) & (1 << ch)) {
> > + update_events(cmt, ch);
> > + }
> > + }
> > +}
> > +
> > +static const MemoryRegionOps cmt_ops = {
> > + .write = cmt_write,
> > + .read = cmt_read,
> > + .endianness = DEVICE_NATIVE_ENDIAN,
> > + .impl = {
> > + .min_access_size = 2,
> > + .max_access_size = 2,
> > + },
> > +};
> > +
> > +static void timer_events(RCMTState *cmt, int ch)
> > +{
> > + cmt->cmcnt[ch] = 0;
> > + cmt->tick[ch] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
> > + update_events(cmt, ch);
> > + if (FIELD_EX16(cmt->cmcr[ch], CMCR, CMIE)) {
> > + qemu_irq_pulse(cmt->cmi[ch]);
> > + }
> > +}
> > +
> > +static void timer_event0(void *opaque)
> > +{
> > + RCMTState *cmt = opaque;
> > +
> > + timer_events(cmt, 0);
> > +}
> > +
> > +static void timer_event1(void *opaque)
> > +{
> > + RCMTState *cmt = opaque;
> > +
> > + timer_events(cmt, 1);
> > +}
>
> I guess there is enough shared state RCMTState that you couldn't have an
> array of channel structures and just pass that when you setup the
> timers:
>
> > +static void rcmt_init(Object *obj)
> > +{
> <snip>
> > + cmt->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, timer_event0, cmt);
> > + cmt->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, timer_event1,
> > cmt);
>
> here?
Yes.
The shared part is only access from the CPU,
so I don't think there will be a conflict in the timer's event.
If problems occur, fix it to manage with one timer.
> Anyway:
>
> 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 [this message]
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
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=87sgts51i5.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.