qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
To: Michael Rolnik <mrolnik@gmail.com>, Fred Konrad <konrad@adacore.com>
Cc: "Alex Bennée" <alex.bennee@linaro.org>,
	"Joaquin de Andres" <me@xcancerberox.com.ar>,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"QEMU Developers" <qemu-devel@nongnu.org>,
	"Pavel Dovgalyuk" <pavel.dovgaluk@ispras.ru>
Subject: Re: [RFC 1/1] Implement AVR watchdog timer
Date: Sat, 15 May 2021 11:45:13 +0200	[thread overview]
Message-ID: <de5af4d1-ab78-3f6b-119f-dc3f8000f3c7@amsat.org> (raw)
In-Reply-To: <CAK4993iyo=FOE0x+tzQNWGexeHTOd+xpQAte+O9phXyMkFHJkQ@mail.gmail.com>

+Pavel/Alex

On 5/3/21 10:08 PM, Michael Rolnik wrote:
> Hi all,
> 
> I was about to make icount work. but, there is something I still don't
> understand. I have this code 
> 
> timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, avr_wdt_interrupt, s);
> 
> and then
> 
> void avr_wdt_interrupt(/* some arguments */) {
> #define MS2NS(n)        ((n) * 1000000ull)
>     timer_mod_ns(timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + MS2NS(15));
> }
> 
> when running with --icount shift=0, *avr_wdt_interrupt* is called about
> every 1K instructions, however it should have been called 15M
> instructions as shift=0 makes every instruction to be executed in 1
> virtual ns.
> 
> What am I doing wrong?
> 
> Thank you,
> Michael Rolnik
> 
> 
> On Mon, May 3, 2021 at 4:36 PM Michael Rolnik <mrolnik@gmail.com
> <mailto:mrolnik@gmail.com>> wrote:
> 
>     Hi Fred.
> 
>     1. thanks
>     2. It seems I have forgotten to set those flags.
>     3. 15ms is easy to test 8s will take 533 times longer, so in my case
>     3200 instructions which is totally incorrect. I don't understand why
>     as I program the timer in virtual nanoseconds and not host time.
>     4. I hope Richard could help with icount.
> 
>     best regards,
>     Michael Rolnik
> 
>     On Mon, May 3, 2021 at 4:15 PM Fred Konrad <konrad@adacore.com
>     <mailto:konrad@adacore.com>> wrote:
> 
> 
> 
>         Le 5/2/21 à 10:10 PM, Michael Rolnik a écrit :
>         > Signed-off-by: Michael Rolnik <mrolnik@gmail.com
>         <mailto:mrolnik@gmail.com>>
>         > ---
>         >   hw/avr/Kconfig                |   1 +
>         >   hw/avr/atmega.c               |  15 ++-
>         >   hw/avr/atmega.h               |   2 +
>         >   hw/watchdog/Kconfig           |   3 +
>         >   hw/watchdog/avr_wdt.c         | 190
>         ++++++++++++++++++++++++++++++++++
>         >   hw/watchdog/meson.build       |   2 +
>         >   hw/watchdog/trace-events      |   5 +
>         >   include/hw/watchdog/avr_wdt.h |  47 +++++++++
>         >   target/avr/cpu.c              |   3 +
>         >   target/avr/cpu.h              |   1 +
>         >   target/avr/helper.c           |   7 +-
>         >   11 files changed, 271 insertions(+), 5 deletions(-)
>         >   create mode 100644 hw/watchdog/avr_wdt.c
>         >   create mode 100644 include/hw/watchdog/avr_wdt.h
>         >
>         > diff --git a/hw/avr/Kconfig b/hw/avr/Kconfig
>         > index d31298c3cc..9939e4902f 100644
>         > --- a/hw/avr/Kconfig
>         > +++ b/hw/avr/Kconfig
>         > @@ -3,6 +3,7 @@ config AVR_ATMEGA_MCU
>         >       select AVR_TIMER16
>         >       select AVR_USART
>         >       select AVR_POWER
>         > +    select AVR_WDT
>         >   
>         >   config ARDUINO
>         >       select AVR_ATMEGA_MCU
>         > diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
>         > index 44c6afebbb..31ceb1c21c 100644
>         > --- a/hw/avr/atmega.c
>         > +++ b/hw/avr/atmega.c
>         > @@ -28,6 +28,7 @@ enum AtmegaPeripheral {
>         >       GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK, GPIOL,
>         >       USART0, USART1, USART2, USART3,
>         >       TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5,
>         > +    WDT,
>         >       PERIFMAX
>         >   };
>         >   
>         > @@ -75,6 +76,7 @@ static const peripheral_cfg
>         dev168_328[PERIFMAX] = {
>         >       [GPIOD]         = {  0x29 },
>         >       [GPIOC]         = {  0x26 },
>         >       [GPIOB]         = {  0x23 },
>         > +    [WDT]           = {  0x60 },
>         >   }, dev1280_2560[PERIFMAX] = {
>         >       [USART3]        = { 0x130, POWER1, 2 },
>         >       [TIMER5]        = { 0x120, POWER1, 5, 0x73, 0x3a, true },
>         > @@ -99,6 +101,7 @@ static const peripheral_cfg
>         dev168_328[PERIFMAX] = {
>         >       [GPIOC]         = {  0x26 },
>         >       [GPIOB]         = {  0x23 },
>         >       [GPIOA]         = {  0x20 },
>         > +    [WDT]           = {  0x60 },
>         >   };
>         >   
>         >   enum AtmegaIrq {
>         > @@ -118,6 +121,7 @@ enum AtmegaIrq {
>         >           TIMER4_COMPC_IRQ, TIMER4_OVF_IRQ,
>         >       TIMER5_CAPT_IRQ, TIMER5_COMPA_IRQ, TIMER5_COMPB_IRQ,
>         >           TIMER5_COMPC_IRQ, TIMER5_OVF_IRQ,
>         > +    WATCHDOG_TIMER_IRQ,
>         >       IRQ_COUNT
>         >   };
>         >   
>         > @@ -133,6 +137,7 @@ enum AtmegaIrq {
>         >   #define TIMER_OVF_IRQ(n)    (n * TIMER_IRQ_COUNT +
>         TIMER0_OVF_IRQ)
>         >   
>         >   static const uint8_t irq168_328[IRQ_COUNT] = {
>         > +    [WATCHDOG_TIMER_IRQ]    = 7,
>         >       [TIMER2_COMPA_IRQ]      = 8,
>         >       [TIMER2_COMPB_IRQ]      = 9,
>         >       [TIMER2_OVF_IRQ]        = 10,
>         > @@ -147,6 +152,7 @@ static const uint8_t irq168_328[IRQ_COUNT] = {
>         >       [USART0_DRE_IRQ]        = 20,
>         >       [USART0_TXC_IRQ]        = 21,
>         >   }, irq1280_2560[IRQ_COUNT] = {
>         > +    [WATCHDOG_TIMER_IRQ]    = 13,
>         >       [TIMER2_COMPA_IRQ]      = 14,
>         >       [TIMER2_COMPB_IRQ]      = 15,
>         >       [TIMER2_OVF_IRQ]        = 16,
>         > @@ -344,10 +350,17 @@ static void atmega_realize(DeviceState
>         *dev, Error **errp)
>         >           g_free(devname);
>         >       }
>         >   
>         > +    /* Watchdog Timer */
>         > +    object_initialize_child(OBJECT(dev), "wdt", &s->wdt,
>         TYPE_AVR_WDT);
>         > +    sysbus_realize(SYS_BUS_DEVICE(&s->wdt), &error_abort);
>         > +    sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0,
>         > +                    OFFSET_DATA + mc->dev[WDT].addr);
>         > +    qdev_connect_gpio_out_named(cpudev, "wdr", 0,
>         > +                    qdev_get_gpio_in_named(DEVICE(&s->wdt),
>         "wdr", 0));
>         > +
>         >       create_unimplemented_device("avr-twi",         
>         OFFSET_DATA + 0x0b8, 6);
>         >       create_unimplemented_device("avr-adc",         
>         OFFSET_DATA + 0x078, 8);
>         >       create_unimplemented_device("avr-ext-mem-ctrl",
>         OFFSET_DATA + 0x074, 2);
>         > -    create_unimplemented_device("avr-watchdog",   
>          OFFSET_DATA + 0x060, 1);
>         >       create_unimplemented_device("avr-spi",         
>         OFFSET_DATA + 0x04c, 3);
>         >       create_unimplemented_device("avr-eeprom",     
>          OFFSET_DATA + 0x03f, 3);
>         >   }
>         > diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
>         > index a99ee15c7e..60bbd44bdd 100644
>         > --- a/hw/avr/atmega.h
>         > +++ b/hw/avr/atmega.h
>         > @@ -13,6 +13,7 @@
>         >   
>         >   #include "hw/char/avr_usart.h"
>         >   #include "hw/timer/avr_timer16.h"
>         > +#include "hw/watchdog/avr_wdt.h"
>         >   #include "hw/misc/avr_power.h"
>         >   #include "target/avr/cpu.h"
>         >   #include "qom/object.h"
>         > @@ -45,6 +46,7 @@ struct AtmegaMcuState {
>         >       AVRMaskState pwr[POWER_MAX];
>         >       AVRUsartState usart[USART_MAX];
>         >       AVRTimer16State timer[TIMER_MAX];
>         > +    AVRWatchdogState wdt;
>         >       uint64_t xtal_freq_hz;
>         >   };
>         >   
>         > diff --git a/hw/watchdog/Kconfig b/hw/watchdog/Kconfig
>         > index 66e1d029e3..e0f89d2fe0 100644
>         > --- a/hw/watchdog/Kconfig
>         > +++ b/hw/watchdog/Kconfig
>         > @@ -20,3 +20,6 @@ config WDT_IMX2
>         >   
>         >   config WDT_SBSA
>         >       bool
>         > +
>         > +config AVR_WDT
>         > +    bool
>         > diff --git a/hw/watchdog/avr_wdt.c b/hw/watchdog/avr_wdt.c
>         > new file mode 100644
>         > index 0000000000..4ce1029a64
>         > --- /dev/null
>         > +++ b/hw/watchdog/avr_wdt.c
>         > @@ -0,0 +1,190 @@
>         > +/*
>         > + * AVR watchdog
>         > + *
>         > + * Copyright (c) 2018 Michael Rolnik
> 
>         2021?
> 
>         > + *
>         > + * This library is free software; you can redistribute it and/or
>         > + * modify it under the terms of the GNU Lesser General Public
>         > + * License as published by the Free Software Foundation; either
>         > + * version 2.1 of the License, or (at your option) any later
>         version.
>         > + *
>         > + * This library is distributed in the hope that it will be
>         useful,
>         > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>         > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>         the GNU
>         > + * Lesser General Public License for more details.
>         > + *
>         > + * You should have received a copy of the GNU Lesser General
>         Public
>         > + * License along with this library; if not, see
>         > + * <http://www.gnu.org/licenses/lgpl-2.1.html
>         <http://www.gnu.org/licenses/lgpl-2.1.html>>
>         > + */
>         > +
>         > +#include "qemu/osdep.h"
>         > +#include "qapi/error.h"
>         > +#include "qemu/log.h"
>         > +#include "hw/irq.h"
>         > +#include "hw/watchdog/avr_wdt.h"
>         > +#include "trace.h"
>         > +
>         > +/* Field masks */
>         > +#define WDTCSR_MASK_WDP0     0x01
>         > +#define WDTCSR_MASK_WDP1     0x02
>         > +#define WDTCSR_MASK_WDP2     0x04
>         > +#define WDTCSR_MASK_WDE      0x08
>         > +#define WDTCSR_MASK_WCE      0x10
>         > +#define WDTCSR_MASK_WDP3     0x20
>         > +#define WDTCSR_MASK_WDIE     0x40
>         > +#define WDTCSR_MASK_WDIF     0x80
>         > +
>         > +#define WDTCSR_SHFT_WDP0     0x00
>         > +#define WDTCSR_SHFT_WDP1     0x01
>         > +#define WDTCSR_SHFT_WDP2     0x02
>         > +#define WDTCSR_SHFT_WDE      0x03
>         > +#define WDTCSR_SHFT_WCE      0x04
>         > +#define WDTCSR_SHFT_WDP3     0x05
>         > +#define WDTCSR_SHFT_WDIE     0x06
>         > +#define WDTCSR_SHFT_WDIF     0x07
>         > +
>         > +/* Helper macros */
>         > +#define WDP0(csr)       ((csr & WDTCSR_MASK_WDP0) >>
>         WDTCSR_SHFT_WDP0)
>         > +#define WDP1(csr)       ((csr & WDTCSR_MASK_WDP1) >>
>         WDTCSR_SHFT_WDP1)
>         > +#define WDP2(csr)       ((csr & WDTCSR_MASK_WDP2) >>
>         WDTCSR_SHFT_WDP2)
>         > +#define WDP3(csr)       ((csr & WDTCSR_MASK_WDP3) >>
>         WDTCSR_SHFT_WDP3)
>         > +#define WDP(csr)        ((WDP3(csr) << 3) | (WDP2(csr) << 2) | \
>         > +                         (WDP1(csr) << 1) | (WDP0(csr) << 0))
>         > +#define WDIE(csr)       ((csr & WDTCSR_MASK_WDIE) >>
>         WDTCSR_SHFT_WDIE)
>         > +#define WDE(csr)        ((csr & WDTCSR_MASK_WDE) >>
>         WDTCSR_SHFT_WDE)
>         > +#define WCE(csr)        ((csr & WDTCSR_MASK_WCE) >>
>         WDTCSR_SHFT_WCE)
>         > +
>         > +#define DB_PRINT(fmt, args...) /* Nothing */
>         > +
>         > +#define MS2NS(n)        ((n) * 1000000ull)
>         > +
>         > +static void avr_wdt_reset_alarm(AVRWatchdogState *wdt)
>         > +{
>         > +    uint32_t csr = wdt->csr;
>         > +    int wdp = WDP(csr);
>         > +    assert(wdp <= 9);
> 
>         Maybe qemu_log(..) instead and pick a default value?
> 
>         > +
>         > +    if (WDIE(csr) == 0 && WDE(csr) == 0) {
>         > +        /* watchdog is stopped */
>         > +        return;
>         > +    }
>         > +
>         > +    timer_mod_ns(wdt->timer,
>         qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
>         > +            (MS2NS(15) << wdp));
>         > +}
>         > +
>         > +static void avr_wdt_interrupt(void *opaque)
>         > +{
>         > +    AVRWatchdogState *wdt = opaque;
>         > +    int8_t csr = wdt->csr;
>         > +
>         > +    if (WDE(csr) == 0 && WDIE(csr) == 0) {
>         > +        /* Stopped */
>         > +
>         > +    } else if (WDE(csr) == 0 && WDIE(csr) == 1) {
>         > +        /* Interrupt Mode */
>         > +        wdt->csr |= WDTCSR_MASK_WDIF;
>         > +        qemu_set_irq(wdt->irq, 1);
>         > +        trace_avr_wdt_interrupt();
>         > +    } else if (WDE(csr) == 1 && WDIE(csr) == 0) {
>         > +        /* System Reset Mode */
> 
>                 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> 
>         +/- setting the MCUSR, WDRF flags would be nice.
> 
>         > +    } else if (WDE(csr) == 1 && WDIE(csr) == 1) {
>         > +        /* Interrupt and System Reset Mode */
>         > +        wdt->csr |= WDTCSR_MASK_WDIF;
>         > +        qemu_set_irq(wdt->irq, 1);
>         > +        trace_avr_wdt_interrupt();
>         > +    }
>         > +
>         > +    avr_wdt_reset_alarm(wdt);
>         > +}
>         > +
>         > +static void avr_wdt_reset(DeviceState *dev)
>         > +{
>         > +    AVRWatchdogState *wdt = AVR_WDT(dev);
>         > +
>         > +    wdt->csr = 0;
>         > +    qemu_set_irq(wdt->irq, 0);
>         > +    avr_wdt_reset_alarm(wdt);
>         > +}
>         > +
>         > +static uint64_t avr_wdt_read(void *opaque, hwaddr offset,
>         unsigned size)
>         > +{
>         > +    assert(size == 1);
>         > +    AVRWatchdogState *wdt = opaque;
>         > +    uint8_t retval = wdt->csr;
>         > +
>         > +    trace_avr_wdt_read(offset, retval);
>         > +
>         > +    return (uint64_t)retval;
>         > +}
>         > +
>         > +static void avr_wdt_write(void *opaque, hwaddr offset,
>         > +                              uint64_t val64, unsigned size)
>         > +{
>         > +    assert(size == 1);
>         > +    AVRWatchdogState *wdt = opaque;
>         > +    uint8_t val8 = (uint8_t)val64;
>         > +
>         > +    trace_avr_wdt_write(offset, val8);
>         > +
>         > +    wdt->csr = val8;
>         > +    avr_wdt_reset_alarm(wdt);
>         > +}
>         > +
>         > +static const MemoryRegionOps avr_wdt_ops = {
>         > +    .read = avr_wdt_read,
>         > +    .write = avr_wdt_write,
>         > +    .endianness = DEVICE_NATIVE_ENDIAN,
>         > +    .impl = {.max_access_size = 1}
>         > +};
>         > +
>         > +static void avr_wdt_wdr(void *opaque, int irq, int level)
>         > +{
>         > +    AVRWatchdogState *wdt = AVR_WDT(opaque);
>         > +
>         > +    avr_wdt_reset_alarm(wdt);
>         > +}
>         > +
>         > +static void avr_wdt_init(Object *obj)
>         > +{
>         > +    AVRWatchdogState *s = AVR_WDT(obj);
>         > +
>         > +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
>         > +
>         > +    memory_region_init_io(&s->iomem, obj, &avr_wdt_ops,
>         > +                          s, "avr-wdt", 0xa);
>         > +
>         > +    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
>         > +    qdev_init_gpio_in_named(DEVICE(s), avr_wdt_wdr, "wdr", 1);
>         > +}
>         > +
>         > +static void avr_wdt_realize(DeviceState *dev, Error **errp)
>         > +{
>         > +    AVRWatchdogState *s = AVR_WDT(dev);
>         > +
>         > +    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>         avr_wdt_interrupt, s);
>         > +}
>         > +
>         > +static void avr_wdt_class_init(ObjectClass *klass, void *data)
>         > +{
>         > +    DeviceClass *dc = DEVICE_CLASS(klass);
>         > +
>         > +    dc->reset = avr_wdt_reset;
>         > +    dc->realize = avr_wdt_realize;
>         > +}
>         > +
>         > +static const TypeInfo avr_wdt_info = {
>         > +    .name          = TYPE_AVR_WDT,
>         > +    .parent        = TYPE_SYS_BUS_DEVICE,
>         > +    .instance_size = sizeof(AVRWatchdogState),
>         > +    .instance_init = avr_wdt_init,
>         > +    .class_init    = avr_wdt_class_init,
>         > +};
>         > +
>         > +static void avr_wdt_register_types(void)
>         > +{
>         > +    type_register_static(&avr_wdt_info);
>         > +}
>         > +
>         > +type_init(avr_wdt_register_types)
>         > diff --git a/hw/watchdog/meson.build b/hw/watchdog/meson.build
>         > index 054c403dea..8db2be8317 100644
>         > --- a/hw/watchdog/meson.build
>         > +++ b/hw/watchdog/meson.build
>         > @@ -6,3 +6,5 @@ softmmu_ss.add(when: 'CONFIG_WDT_DIAG288',
>         if_true: files('wdt_diag288.c'))
>         >   softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true:
>         files('wdt_aspeed.c'))
>         >   softmmu_ss.add(when: 'CONFIG_WDT_IMX2', if_true:
>         files('wdt_imx2.c'))
>         >   softmmu_ss.add(when: 'CONFIG_WDT_SBSA', if_true:
>         files('sbsa_gwdt.c'))
>         > +
>         > +specific_ss.add(when: 'CONFIG_AVR_WDT', if_true:
>         files('avr_wdt.c'))
>         > diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
>         > index 3124ca1f1b..ac14773179 100644
>         > --- a/hw/watchdog/trace-events
>         > +++ b/hw/watchdog/trace-events
>         > @@ -5,3 +5,8 @@ cmsdk_apb_watchdog_read(uint64_t offset,
>         uint64_t data, unsigned size) "CMSDK AP
>         >   cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data,
>         unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 "
>         data 0x%" PRIx64 " size %u"
>         >   cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
>         >   cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog:
>         lock %" PRIu32
>         > +
>         > +# avr_wdt.c
>         > +avr_wdt_read(uint8_t addr, uint8_t value) "wdt read addr:%u
>         value:%u"
>         > +avr_wdt_write(uint8_t addr, uint8_t value) "wdt write addr:%u
>         value:%u"
>         > +avr_wdt_interrupt(void) ""
>         > diff --git a/include/hw/watchdog/avr_wdt.h
>         b/include/hw/watchdog/avr_wdt.h
>         > new file mode 100644
>         > index 0000000000..2679e8f2a6
>         > --- /dev/null
>         > +++ b/include/hw/watchdog/avr_wdt.h
>         > @@ -0,0 +1,47 @@
>         > +/*
>         > + * AVR 16-bit timer
> 
>         AVR Watchdog?
> 
>         > + *
>         > + * Copyright (c) 2021 Michael Rolnik
>         > + *
>         > + * This library is free software; you can redistribute it and/or
>         > + * modify it under the terms of the GNU Lesser General Public
>         > + * License as published by the Free Software Foundation; either
>         > + * version 2.1 of the License, or (at your option) any later
>         version.
>         > + *
>         > + * This library is distributed in the hope that it will be
>         useful,
>         > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>         > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
>         the GNU
>         > + * Lesser General Public License for more details.
>         > + *
>         > + * You should have received a copy of the GNU Lesser General
>         Public
>         > + * License along with this library; if not, see
>         > + * <http://www.gnu.org/licenses/lgpl-2.1.html
>         <http://www.gnu.org/licenses/lgpl-2.1.html>>
>         > + */
>         > +
>         > +#ifndef HW_WATCHDOG_AVR_WDT_H
>         > +#define HW_WATCHDOG_AVR_WDT_H
>         > +
>         > +#include "hw/sysbus.h"
>         > +#include "qemu/timer.h"
>         > +#include "hw/hw.h"
>         > +#include "qom/object.h"
>         > +
>         > +#define TYPE_AVR_WDT "avr-wdt"
>         > +OBJECT_DECLARE_SIMPLE_TYPE(AVRWatchdogState, AVR_WDT)
>         > +
>         > +struct AVRWatchdogState {
>         > +    /* <private> */
>         > +    SysBusDevice parent_obj;
>         > +
>         > +    /* <public> */
>         > +    MemoryRegion iomem;
>         > +    MemoryRegion imsk_iomem;
>         > +    MemoryRegion ifr_iomem;
>         > +    QEMUTimer *timer;
>         > +    qemu_irq irq;
>         > +
>         > +    /* registers */
>         > +    uint8_t csr;
>         > +};
>         > +
>         > +#endif /* HW_WATCHDOG_AVR_WDT_H */
>         > diff --git a/target/avr/cpu.c b/target/avr/cpu.c
>         > index 0f4596932b..d5eb785833 100644
>         > --- a/target/avr/cpu.c
>         > +++ b/target/avr/cpu.c
>         > @@ -131,6 +131,9 @@ static void avr_cpu_initfn(Object *obj)
>         >       /* Set the number of interrupts supported by the CPU. */
>         >       qdev_init_gpio_in(DEVICE(cpu), avr_cpu_set_int,
>         >                         sizeof(cpu->env.intsrc) * 8);
>         > +
>         > +    /* register watchdog timer reset interrupt */
>         > +    qdev_init_gpio_out_named(DEVICE(cpu), &cpu->wdr, "wdr", 1);
>         >   }
>         >   
>         >   static ObjectClass *avr_cpu_class_by_name(const char *cpu_model)
>         > diff --git a/target/avr/cpu.h b/target/avr/cpu.h
>         > index d148e8c75a..f8f5641c8b 100644
>         > --- a/target/avr/cpu.h
>         > +++ b/target/avr/cpu.h
>         > @@ -152,6 +152,7 @@ typedef struct AVRCPU {
>         >   
>         >       CPUNegativeOffsetState neg;
>         >       CPUAVRState env;
>         > +    qemu_irq wdr; /* reset WDT */
>         >   } AVRCPU;
>         >   
>         >   extern const struct VMStateDescription vms_avr_cpu;
>         > diff --git a/target/avr/helper.c b/target/avr/helper.c
>         > index 35e1019594..dd88057e5f 100644
>         > --- a/target/avr/helper.c
>         > +++ b/target/avr/helper.c
>         > @@ -24,6 +24,7 @@
>         >   #include "exec/exec-all.h"
>         >   #include "exec/address-spaces.h"
>         >   #include "exec/helper-proto.h"
>         > +#include "hw/irq.h"
>         >   
>         >   bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
>         >   {
>         > @@ -188,11 +189,9 @@ void helper_break(CPUAVRState *env)
>         >   
>         >   void helper_wdr(CPUAVRState *env)
>         >   {
>         > -    CPUState *cs = env_cpu(env);
>         > +    AVRCPU *cpu = env_archcpu(env);
>         >   
>         > -    /* WD is not implemented yet, placeholder */
>         > -    cs->exception_index = EXCP_DEBUG;
>         > -    cpu_loop_exit(cs);
>         > +    qemu_set_irq(cpu->wdr, 1);
>         >   }
>         >   
>         >   /*
>         >
> 
>         Thanks!
> 
> 
> 
>     -- 
>     Best Regards,
>     Michael Rolnik
> 
> 
> 
> -- 
> Best Regards,
> Michael Rolnik


  reply	other threads:[~2021-05-15  9:47 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-02 20:10 [RFC 0/1] Implement AVR WDT (watchdog timer) Michael Rolnik
2021-05-02 20:10 ` Michael Rolnik
2021-05-03 13:06   ` Fred Konrad
2021-05-02 20:10 ` [RFC 1/1] Implement AVR watchdog timer Michael Rolnik
2021-05-03 13:15   ` Fred Konrad
2021-05-03 13:36     ` Michael Rolnik
2021-05-03 20:08       ` Michael Rolnik
2021-05-15  9:45         ` Philippe Mathieu-Daudé [this message]
2021-05-05 21:18 [RFC v1 0/1] Implement AVR WDT (watchdog timer) Michael Rolnik
2021-05-05 21:18 ` [RFC 1/1] Implement AVR watchdog timer Michael Rolnik
2021-05-13 12:27   ` Pavel Dovgalyuk
2021-05-14  7:20     ` Michael Rolnik

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=de5af4d1-ab78-3f6b-119f-dc3f8000f3c7@amsat.org \
    --to=f4bug@amsat.org \
    --cc=alex.bennee@linaro.org \
    --cc=konrad@adacore.com \
    --cc=me@xcancerberox.com.ar \
    --cc=mrolnik@gmail.com \
    --cc=pavel.dovgaluk@ispras.ru \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).