All of lore.kernel.org
 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 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.