From: Igor Mammedov <imammedo@redhat.com>
To: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
Cc: "Sarah Harris" <S.E.Harris@kent.ac.uk>,
"Thomas Huth" <huth@tuxfamily.org>,
"Joaquin de Andres" <me@xcancerberox.com.ar>,
"Richard Henderson" <richard.henderson@linaro.org>,
qemu-devel@nongnu.org,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Michael Rolnik" <mrolnik@gmail.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Pavel Dovgalyuk" <dovgaluk@ispras.ru>,
"Aleksandar Markovic" <aleksandar.m.mail@gmail.com>
Subject: Re: [RFC PATCH 06/10] hw/avr: Add ATmega microcontrollers
Date: Fri, 20 Dec 2019 11:09:17 +0100 [thread overview]
Message-ID: <20191220110917.3fccb284@redhat.com> (raw)
In-Reply-To: <20191128015030.27543-7-f4bug@amsat.org>
On Thu, 28 Nov 2019 02:50:26 +0100
Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> Add famous ATmega MCUs:
>
> - middle range: ATmega168 and ATmega328
> - high range: ATmega1280 and ATmega2560
>
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> hw/avr/atmega.h | 58 +++++++
> hw/avr/atmega.c | 379 +++++++++++++++++++++++++++++++++++++++++++
> hw/avr/Makefile.objs | 1 +
> 3 files changed, 438 insertions(+)
> create mode 100644 hw/avr/atmega.h
> create mode 100644 hw/avr/atmega.c
>
> diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
> new file mode 100644
> index 0000000000..d22d90a962
> --- /dev/null
> +++ b/hw/avr/atmega.h
> @@ -0,0 +1,58 @@
> +/*
> + * QEMU ATmega MCU
> + *
> + * Copyright (c) 2019 Philippe Mathieu-Daudé
> + *
> + * This work is licensed under the terms of the GNU GPLv2 or later.
> + * See the COPYING file in the top-level directory.
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef HW_AVR_ATMEGA_H
> +#define HW_AVR_ATMEGA_H
> +
> +#include "hw/char/avr_usart.h"
> +#include "hw/char/avr_usart.h"
> +#include "hw/timer/avr_timer16.h"
> +#include "hw/misc/avr_mask.h"
> +#include "target/avr/cpu.h"
> +
> +#define TYPE_ATMEGA "ATmega"
> +#define TYPE_ATMEGA168 "ATmega168"
> +#define TYPE_ATMEGA328 "ATmega328"
> +#define TYPE_ATMEGA1280 "ATmega1280"
> +#define TYPE_ATMEGA2560 "ATmega2560"
> +#define ATMEGA(obj) OBJECT_CHECK(AtmegaState, (obj), TYPE_ATMEGA)
> +
> +#define USART_MAX 4
> +#define TIMER_MAX 6
> +
> +typedef struct AtmegaState {
> + /*< private >*/
> + SysBusDevice parent_obj;
> + /*< public >*/
> +
> + AVRCPU cpu;
> + MemoryRegion flash;
> + MemoryRegion eeprom;
> + MemoryRegion sram;
> + DeviceState *io;
> + AVRMaskState pwr[2];
> + AVRUsartState usart[USART_MAX];
> + AVRTimer16State timer[TIMER_MAX];
> + uint64_t xtal_freq_hz;
> +} AtmegaState;
> +
> +typedef struct AtmegaInfo AtmegaInfo;
> +
> +typedef struct AtmegaClass {
> + SysBusDeviceClass parent_class;
> + const AtmegaInfo *info;
> +} AtmegaClass;
> +
> +#define ATMEGA_CLASS(klass) \
> + OBJECT_CLASS_CHECK(AtmegaClass, (klass), TYPE_ATMEGA)
> +#define ATMEGA_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(AtmegaClass, (obj), TYPE_ATMEGA)
> +
> +#endif /* HW_AVR_ATMEGA_H */
> diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
> new file mode 100644
> index 0000000000..1f1b1246ef
> --- /dev/null
> +++ b/hw/avr/atmega.c
> @@ -0,0 +1,379 @@
> +/*
> + * QEMU ATmega MCU
> + *
> + * Copyright (c) 2019 Philippe Mathieu-Daudé
> + *
> + * This work is licensed under the terms of the GNU GPLv2 or later.
> + * See the COPYING file in the top-level directory.
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/module.h"
> +#include "qemu/units.h"
> +#include "qapi/error.h"
> +#include "exec/memory.h"
> +#include "exec/address-spaces.h"
> +#include "sysemu/sysemu.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "hw/boards.h" /* FIXME memory_region_allocate_system_memory for sram */
> +#include "hw/misc/unimp.h"
> +#include "atmega.h"
> +
> +enum AtmegaIrq {
> + USART0_RXC_IRQ, USART0_DRE_IRQ, USART0_TXC_IRQ,
> + USART1_RXC_IRQ, USART1_DRE_IRQ, USART1_TXC_IRQ,
> + USART2_RXC_IRQ, USART2_DRE_IRQ, USART2_TXC_IRQ,
> + USART3_RXC_IRQ, USART3_DRE_IRQ, USART3_TXC_IRQ,
> + TIMER0_CAPT_IRQ, TIMER0_COMPA_IRQ, TIMER0_COMPB_IRQ,
> + TIMER0_COMPC_IRQ, TIMER0_OVF_IRQ,
> + TIMER1_CAPT_IRQ, TIMER1_COMPA_IRQ, TIMER1_COMPB_IRQ,
> + TIMER1_COMPC_IRQ, TIMER1_OVF_IRQ,
> + TIMER2_CAPT_IRQ, TIMER2_COMPA_IRQ, TIMER2_COMPB_IRQ,
> + TIMER2_COMPC_IRQ, TIMER2_OVF_IRQ,
> + TIMER3_CAPT_IRQ, TIMER3_COMPA_IRQ, TIMER3_COMPB_IRQ,
> + TIMER3_COMPC_IRQ, TIMER3_OVF_IRQ,
> + TIMER4_CAPT_IRQ, TIMER4_COMPA_IRQ, TIMER4_COMPB_IRQ,
> + TIMER4_COMPC_IRQ, TIMER4_OVF_IRQ,
> + TIMER5_CAPT_IRQ, TIMER5_COMPA_IRQ, TIMER5_COMPB_IRQ,
> + TIMER5_COMPC_IRQ, TIMER5_OVF_IRQ,
> +};
> +#define IRQ_MAX 64
> +
> +#define USART_RXC_IRQ(n) (3 * n + USART0_RXC_IRQ)
> +#define USART_DRE_IRQ(n) (3 * n + USART0_DRE_IRQ)
> +#define USART_TXC_IRQ(n) (3 * n + USART0_TXC_IRQ)
> +#define TIMER_CAPT_IRQ(n) (5 * n + TIMER0_CAPT_IRQ)
> +#define TIMER_COMPA_IRQ(n) (5 * n + TIMER0_COMPA_IRQ)
> +#define TIMER_COMPB_IRQ(n) (5 * n + TIMER0_COMPB_IRQ)
> +#define TIMER_COMPC_IRQ(n) (5 * n + TIMER0_COMPC_IRQ)
> +#define TIMER_OVF_IRQ(n) (5 * n + TIMER0_OVF_IRQ)
> +
> +static const uint8_t irq168_328[IRQ_MAX] = {
> + [TIMER2_COMPA_IRQ] = 8,
> + [TIMER2_COMPB_IRQ] = 9,
> + [TIMER2_OVF_IRQ] = 10,
> + [TIMER1_CAPT_IRQ] = 11,
> + [TIMER1_COMPA_IRQ] = 12,
> + [TIMER1_COMPB_IRQ] = 13,
> + [TIMER1_OVF_IRQ] = 14,
> + [TIMER0_COMPA_IRQ] = 15,
> + [TIMER0_COMPB_IRQ] = 16,
> + [TIMER0_OVF_IRQ] = 17,
> + [USART0_RXC_IRQ] = 19,
> + [USART0_DRE_IRQ] = 20,
> + [USART0_TXC_IRQ] = 21,
> +}, irq1280_2560[IRQ_MAX] = {
> + [TIMER2_COMPA_IRQ] = 14,
> + [TIMER2_COMPB_IRQ] = 15,
> + [TIMER2_OVF_IRQ] = 16,
> + [TIMER1_CAPT_IRQ] = 17,
> + [TIMER1_COMPA_IRQ] = 18,
> + [TIMER1_COMPB_IRQ] = 19,
> + [TIMER1_COMPC_IRQ] = 20,
> + [TIMER1_OVF_IRQ] = 21,
> + [TIMER0_COMPA_IRQ] = 22,
> + [TIMER0_COMPB_IRQ] = 23,
> + [TIMER0_OVF_IRQ] = 24,
> + [USART0_RXC_IRQ] = 26,
> + [USART0_DRE_IRQ] = 27,
> + [USART0_TXC_IRQ] = 28,
> + [TIMER3_CAPT_IRQ] = 32,
> + [TIMER3_COMPA_IRQ] = 33,
> + [TIMER3_COMPB_IRQ] = 34,
> + [TIMER3_COMPC_IRQ] = 35,
> + [TIMER3_OVF_IRQ] = 36,
> + [USART1_RXC_IRQ] = 37,
> + [USART1_DRE_IRQ] = 38,
> + [USART1_TXC_IRQ] = 39,
> + [USART2_RXC_IRQ] = 52,
> + [USART2_DRE_IRQ] = 53,
> + [USART2_TXC_IRQ] = 54,
> + [USART3_RXC_IRQ] = 55,
> + [USART3_DRE_IRQ] = 56,
> + [USART3_TXC_IRQ] = 57,
> +};
> +
> +enum AtmegaPeripheralAddress {
> + USART0, USART1, USART2, USART3,
> + TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5,
> + DEV_MAX
> +};
> +
> +#define USART_ADDR(n) (n + USART0)
> +#define TIMER_ADDR(n) (n + TIMER0)
> +
> +typedef struct {
> + uint16_t addr;
> + uint16_t prr_addr;
> + uint8_t prr_bit;
> + /* timer specific */
> + uint16_t intmask_addr;
> + uint16_t intflag_addr;
> + bool is_timer16;
> +} peripheral_cfg;
> +
> +static const peripheral_cfg dev168_328[DEV_MAX] = {
> + [TIMER0] = { 0x24, 0x64, 5, 0x6e, 0x35, false },
> + [TIMER1] = { 0x80, 0x64, 3, 0x6f, 0x36, true },
> + [TIMER2] = { 0xb0, 0x64, 6, 0x70, 0x37, false },
> + [USART0] = { 0xc0, 0x64, 1 },
> +}, dev1280_2560[DEV_MAX] = {
> + [TIMER0] = { 0x24, 0x64, 5, 0x6e, 0x35, false },
> + [TIMER1] = { 0x80, 0x64, 3, 0x6f, 0x36, true },
> + [TIMER3] = { 0x90, 0x65, 3, 0x71, 0x38, true },
> + [TIMER4] = { 0xa0, 0x65, 4, 0x72, 0x39, true },
> + [TIMER2] = { 0xb0, 0x64, 6, 0x70, 0x37, false },
> + [USART0] = { 0xc0, 0x64, 1 },
> + [USART1] = { 0xc8, 0x65, 0 },
> + [USART2] = { 0xd0, 0x65, 1 },
> + [TIMER5] = { 0x120, 0x65, 5, 0x73, 0x3a, true },
> + [USART3] = { 0x130, 0x65, 2 },
> +};
> +
> +struct AtmegaInfo {
> + const char *uc_name;
> + const char *cpu_type;
> + size_t flash_size;
> + size_t eeprom_size;
> + size_t sram_size;
> + size_t io_size;
> + size_t uart_count;
> + size_t timer_count;
> + size_t gpio_count;
> + size_t adc_count;
> + const uint8_t *irq;
> + const peripheral_cfg *dev;
> +};
> +
> +static const AtmegaInfo atmega_mcu[] = {
> + {
> + .uc_name = TYPE_ATMEGA168,
> + .cpu_type = AVR_CPU_TYPE_NAME("avr5"),
> + .flash_size = 16 * KiB,
> + .eeprom_size = 512,
> + .sram_size = 1 * KiB,
> + .io_size = 256,
> + .uart_count = 1,
> + .gpio_count = 23,
> + .adc_count = 6,
> + .irq = irq168_328,
> + .dev = dev168_328,
> + },
> + {
> + .uc_name = TYPE_ATMEGA328,
> + .cpu_type = AVR_CPU_TYPE_NAME("avr5"),
> + .flash_size = 32 * KiB,
> + .eeprom_size = 1 * KiB,
> + .sram_size = 2 * KiB,
> + .io_size = 256,
> + .uart_count = 1,
> + .timer_count = 3,
> + .gpio_count = 23,
> + .adc_count = 6,
> + .irq = irq168_328,
> + .dev = dev168_328,
> + },
> + {
> + .uc_name = TYPE_ATMEGA1280,
> + .cpu_type = AVR_CPU_TYPE_NAME("avr6"),
> + .flash_size = 128 * KiB,
> + .eeprom_size = 4 * KiB,
> + .sram_size = 8 * KiB,
> + .io_size = 512,
> + .uart_count = 4,
> + .timer_count = 6,
> + .gpio_count = 86,
> + .adc_count = 16,
> + .irq = irq1280_2560,
> + .dev = dev1280_2560,
> + },
> + {
> + .uc_name = TYPE_ATMEGA2560,
> + .cpu_type = AVR_CPU_TYPE_NAME("avr6"),
> + .flash_size = 256 * KiB,
> + .eeprom_size = 4 * KiB,
> + .sram_size = 8 * KiB,
> + .io_size = 512,
> + .uart_count = 4,
> + .timer_count = 6,
> + .gpio_count = 54,
> + .adc_count = 16,
> + .irq = irq1280_2560,
> + .dev = dev1280_2560,
> + },
> +};
> +
> +static void connect_nonnull_irq(SysBusDevice *sbd, DeviceState *dev,
> + int n, int irq)
> +{
> + if (irq) {
> + sysbus_connect_irq(sbd, n, qdev_get_gpio_in(dev, irq));
> + }
> +}
> +
> +static void connect_pr_irq(AtmegaState *s, const AtmegaInfo *info,
> + DeviceState *dev, int index)
> +{
> + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pwr[info->dev[index].prr_addr & 1]),
> + info->dev[index].prr_bit,
> + qdev_get_gpio_in(dev, 0));
> +}
> +
> +static void atmega_realize(DeviceState *dev, Error **errp)
> +{
> + AtmegaState *s = ATMEGA(dev);
> + AtmegaClass *bc = ATMEGA_GET_CLASS(dev);
> + const AtmegaInfo *info = bc->info;
> + DeviceState *cpudev;
> + SysBusDevice *sbd;
> + Error *err = NULL;
> + char *devname;
> + size_t i;
> +
> + if (!s->xtal_freq_hz) {
> + error_setg(errp, "\"xtal-frequency-hz\" property must be provided.");
> + return;
> + }
> +
> + /* CPU */
> + object_initialize_child(OBJECT(dev), "cpu", &s->cpu, sizeof(s->cpu),
> + info->cpu_type, &err, NULL);
> + if (err) {
> + error_propagate(errp, err);
> + return;
> + }
> + object_property_set_bool(OBJECT(&s->cpu), true, "realized", &error_abort);
> + cpudev = DEVICE(&s->cpu);
> +
> + /* SRAM */
> + memory_region_allocate_system_memory(&s->sram, OBJECT(dev),
> + "sram", info->sram_size);
with main RAM conversion to hostmem backend, this API will go away
and RAM memory region will be allocated by generic machine code
and shall be treated as backend. Users would be able to access it
via MachineState::ram memory region.
Meanwhile I'd suggest to move this line to arduino_machine_init()
and pass it to MCU as a link property.
Also use MachineState::ram_size and add check that it matches mc->default_ram_size.
Ex: https://github.com/imammedo/qemu/commit/241c65d506ccba1e0239a2bc0632d7dc9c3517c1
> + memory_region_add_subregion(get_system_memory(),
> + OFFSET_DATA + 0x200, &s->sram);
> +
> + /* Flash */
> + memory_region_init_rom(&s->flash, OBJECT(dev),
> + "flash", info->flash_size, &error_fatal);
> + memory_region_add_subregion(get_system_memory(), OFFSET_CODE, &s->flash);
> +
> + /* I/O */
> + s->io = qdev_create(NULL, TYPE_UNIMPLEMENTED_DEVICE);
> + qdev_prop_set_string(s->io, "name", "I/O");
> + qdev_prop_set_uint64(s->io, "size", info->io_size);
> + qdev_init_nofail(s->io);
> + sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->io), 0, OFFSET_DATA, -1234);
> +
> + /* Power */
> + for (i = 0; i < ARRAY_SIZE(s->pwr); i++) {
> + devname = g_strdup_printf("pwr%zu", i);
> + object_initialize_child(OBJECT(dev), devname,
> + &s->pwr[i], sizeof(s->pwr[i]),
> + TYPE_AVR_MASK, &error_abort, NULL);
> + object_property_set_bool(OBJECT(&s->pwr[i]), true, "realized",
> + &error_abort);
> + sysbus_mmio_map(SYS_BUS_DEVICE(&s->pwr[i]), 0, OFFSET_DATA + 0x64 + i);
> + g_free(devname);
> + }
> +
> + /* USART */
> + for (i = 0; i < info->uart_count; i++) {
> + devname = g_strdup_printf("usart%zu", i);
> + object_initialize_child(OBJECT(dev), devname,
> + &s->usart[i], sizeof(s->usart[i]),
> + TYPE_AVR_USART, &error_abort, NULL);
> + qdev_prop_set_chr(DEVICE(&s->usart[i]), "chardev", serial_hd(i));
> + object_property_set_bool(OBJECT(&s->usart[i]), true, "realized",
> + &error_abort);
> + sbd = SYS_BUS_DEVICE(&s->usart[i]);
> + sysbus_mmio_map(sbd, 0, OFFSET_DATA + info->dev[USART_ADDR(i)].addr);
> + connect_nonnull_irq(sbd, cpudev, 0, info->irq[USART_RXC_IRQ(i)]);
> + connect_nonnull_irq(sbd, cpudev, 1, info->irq[USART_DRE_IRQ(i)]);
> + connect_nonnull_irq(sbd, cpudev, 2, info->irq[USART_TXC_IRQ(i)]);
> + connect_pr_irq(s, info, DEVICE(&s->usart[i]), 0);
> + g_free(devname);
> + }
> +
> + /* Timer */
> + for (i = 0; i < info->timer_count; i++) {
> + int idx = TIMER_ADDR(i);
> + if (!info->dev[idx].is_timer16) {
> + create_unimplemented_device("avr-timer8",
> + OFFSET_DATA + info->dev[idx].addr, 7);
> + create_unimplemented_device("avr-timer8-intmask",
> + OFFSET_DATA
> + + info->dev[idx].intmask_addr, 1);
> + create_unimplemented_device("avr-timer8-intflag",
> + OFFSET_DATA
> + + info->dev[idx].intflag_addr, 1);
> + continue;
> + }
> + devname = g_strdup_printf("timer%zu", i);
> + object_initialize_child(OBJECT(dev), devname,
> + &s->timer[i], sizeof(s->timer[i]),
> + TYPE_AVR_TIMER16, &error_abort, NULL);
> + object_property_set_uint(OBJECT(&s->timer[i]), s->xtal_freq_hz,
> + "cpu-frequency-hz", &error_abort);
> + object_property_set_bool(OBJECT(&s->timer[i]), true, "realized",
> + &error_abort);
> + sbd = SYS_BUS_DEVICE(&s->timer[i]);
> + sysbus_mmio_map(sbd, 0, OFFSET_DATA + info->dev[idx].addr);
> + sysbus_mmio_map(sbd, 1, OFFSET_DATA + info->dev[idx].intmask_addr);
> + sysbus_mmio_map(sbd, 2, OFFSET_DATA + info->dev[idx].intflag_addr);
> + connect_nonnull_irq(sbd, cpudev, 0, info->irq[TIMER_CAPT_IRQ(i)]);
> + connect_nonnull_irq(sbd, cpudev, 1, info->irq[TIMER_COMPA_IRQ(i)]);
> + connect_nonnull_irq(sbd, cpudev, 2, info->irq[TIMER_COMPB_IRQ(i)]);
> + connect_nonnull_irq(sbd, cpudev, 3, info->irq[TIMER_COMPC_IRQ(i)]);
> + connect_nonnull_irq(sbd, cpudev, 4, info->irq[TIMER_OVF_IRQ(i)]);
> + connect_pr_irq(s, info, DEVICE(&s->timer[i]), 0);
> + g_free(devname);
> + }
> +}
> +
> +static Property atmega_props[] = {
> + DEFINE_PROP_UINT64("xtal-frequency-hz", AtmegaState,
> + xtal_freq_hz, 0),
> + DEFINE_PROP_END_OF_LIST()
> +};
> +
> +static void atmega_class_init(ObjectClass *oc, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(oc);
> + AtmegaClass *bc = ATMEGA_CLASS(oc);
> +
> + bc->info = data;
> + dc->realize = atmega_realize;
> + dc->props = atmega_props;
> + /* Reason: Mapped at fixed location on the system bus */
> + dc->user_creatable = false;
> +}
> +
> +static const TypeInfo atmega_type_info = {
> + .name = TYPE_ATMEGA,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(AtmegaState),
> + .class_size = sizeof(AtmegaClass),
> + .abstract = true,
> +};
> +
> +static void atmega_register_types(void)
> +{
> + size_t i;
> +
> + type_register_static(&atmega_type_info);
> + for (i = 0; i < ARRAY_SIZE(atmega_mcu); i++) {
> + assert(atmega_mcu[i].io_size <= 0x200);
> + assert(atmega_mcu[i].uart_count <= USART_MAX);
> + assert(atmega_mcu[i].timer_count <= TIMER_MAX);
> + TypeInfo ti = {
> + .name = atmega_mcu[i].uc_name,
> + .parent = TYPE_ATMEGA,
> + .class_init = atmega_class_init,
> + .class_data = (void *) &atmega_mcu[i],
> + };
> + type_register(&ti);
> + }
> +}
> +
> +type_init(atmega_register_types)
> diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
> index 626b7064b3..4b6b911820 100644
> --- a/hw/avr/Makefile.objs
> +++ b/hw/avr/Makefile.objs
> @@ -1 +1,2 @@
> obj-y += sample.o
> +obj-y += atmega.o
next prev parent reply other threads:[~2019-12-20 10:12 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-28 1:50 [RFC PATCH 00/10] hw/avr: Introduce the Arduino board Philippe Mathieu-Daudé
2019-11-28 1:50 ` [NOTFORMERGE PATCH 01/10] hw/avr: Kludge to fix build failure Philippe Mathieu-Daudé
2019-11-28 1:50 ` [PATCH 02/10] target/avr: Remove unused include Philippe Mathieu-Daudé
2019-11-28 1:50 ` [PATCH 03/10] target/avr: Add missing definitions Philippe Mathieu-Daudé
2019-11-28 1:50 ` [NOTFORMERGE PATCH 04/10] target/avr: Fix IRQ count Philippe Mathieu-Daudé
2019-11-28 1:50 ` [RFC PATCH 05/10] hw/char/avr: Reduce USART I/O size Philippe Mathieu-Daudé
2019-11-28 1:50 ` [RFC PATCH 06/10] hw/avr: Add ATmega microcontrollers Philippe Mathieu-Daudé
2019-11-28 1:55 ` Philippe Mathieu-Daudé
2019-11-28 9:28 ` Aleksandar Markovic
2019-11-28 9:48 ` dovgaluk
2019-11-28 10:20 ` Aleksandar Markovic
2019-11-28 11:08 ` dovgaluk
2019-11-28 11:25 ` Aleksandar Markovic
2019-11-28 11:12 ` Philippe Mathieu-Daudé
2019-11-28 11:36 ` Philippe Mathieu-Daudé
2019-12-20 10:09 ` Igor Mammedov [this message]
2019-12-20 12:58 ` Philippe Mathieu-Daudé
2019-12-20 15:03 ` Igor Mammedov
2019-11-28 1:50 ` [RFC PATCH 07/10] hw/avr: Add few Arduino boards Philippe Mathieu-Daudé
2019-12-20 10:01 ` Igor Mammedov
2019-11-28 1:50 ` [PATCH 08/10] tests/acceptance: Keep multilines comment consistent with other tests Philippe Mathieu-Daudé
2019-11-28 1:50 ` [RFC PATCH 09/10] tests/acceptance: Use the ATmega2560 board Philippe Mathieu-Daudé
2019-11-28 1:50 ` [NOTFORMERGE PATCH 10/10] hw/avr: Remove the 'sample' board Philippe Mathieu-Daudé
2019-11-28 10:30 ` [RFC PATCH 00/10] hw/avr: Introduce the Arduino board 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=20191220110917.3fccb284@redhat.com \
--to=imammedo@redhat.com \
--cc=S.E.Harris@kent.ac.uk \
--cc=aleksandar.m.mail@gmail.com \
--cc=dovgaluk@ispras.ru \
--cc=f4bug@amsat.org \
--cc=huth@tuxfamily.org \
--cc=marcandre.lureau@redhat.com \
--cc=me@xcancerberox.com.ar \
--cc=mrolnik@gmail.com \
--cc=pbonzini@redhat.com \
--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).