* [PATCH-for-6.1] hw/avr/atmega: Convert to QDev Clock API
@ 2021-04-09 11:25 Philippe Mathieu-Daudé
2021-04-09 11:33 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 2+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-04-09 11:25 UTC (permalink / raw)
To: qemu-devel
Cc: Luc Michel, Joaquin de Andres, Michael Rolnik,
Philippe Mathieu-Daudé
Create the oscillator object on the board, and propagate its
clock to the ATMega MCU. Wire this clock to the timers.
Properties are remplaced by clocks.
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
Based-on: <20210409062401.2350436-1-f4bug@amsat.org>
TODO: Add corresponding vmstates for migration,
but these devices don't have any, so keep
this for later.
---
hw/avr/atmega.h | 3 ++-
include/hw/timer/avr_timer16.h | 4 +++-
hw/avr/arduino.c | 8 ++++++--
hw/avr/atmega.c | 20 +++++++++++---------
hw/timer/avr_timer16.c | 20 ++++++++++++--------
5 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
index a99ee15c7e1..12e856386b6 100644
--- a/hw/avr/atmega.h
+++ b/hw/avr/atmega.h
@@ -11,6 +11,7 @@
#ifndef HW_AVR_ATMEGA_H
#define HW_AVR_ATMEGA_H
+#include "hw/clock.h"
#include "hw/char/avr_usart.h"
#include "hw/timer/avr_timer16.h"
#include "hw/misc/avr_power.h"
@@ -41,11 +42,11 @@ struct AtmegaMcuState {
MemoryRegion flash;
MemoryRegion eeprom;
MemoryRegion sram;
+ Clock *xtal_clkin;
DeviceState *io;
AVRMaskState pwr[POWER_MAX];
AVRUsartState usart[USART_MAX];
AVRTimer16State timer[TIMER_MAX];
- uint64_t xtal_freq_hz;
};
#endif /* HW_AVR_ATMEGA_H */
diff --git a/include/hw/timer/avr_timer16.h b/include/hw/timer/avr_timer16.h
index 05362543378..86dc9e98d95 100644
--- a/include/hw/timer/avr_timer16.h
+++ b/include/hw/timer/avr_timer16.h
@@ -28,6 +28,7 @@
#ifndef HW_TIMER_AVR_TIMER16_H
#define HW_TIMER_AVR_TIMER16_H
+#include "hw/clock.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "hw/hw.h"
@@ -84,7 +85,8 @@ struct AVRTimer16State {
uint8_t ifr;
uint8_t id;
- uint64_t cpu_freq_hz;
+ Clock *io_clkin;
+
uint64_t freq_hz;
uint64_t period_ns;
uint64_t reset_time_ns;
diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c
index 3ff31492fa6..71e69823c07 100644
--- a/hw/avr/arduino.c
+++ b/hw/avr/arduino.c
@@ -12,7 +12,9 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "hw/clock.h"
#include "hw/boards.h"
+#include "hw/qdev-clock.h"
#include "atmega.h"
#include "boot.h"
#include "qom/object.h"
@@ -21,6 +23,7 @@ struct ArduinoMachineState {
/*< private >*/
MachineState parent_obj;
/*< public >*/
+ Clock *xtal;
AtmegaMcuState mcu;
};
typedef struct ArduinoMachineState ArduinoMachineState;
@@ -44,9 +47,10 @@ static void arduino_machine_init(MachineState *machine)
ArduinoMachineClass *amc = ARDUINO_MACHINE_GET_CLASS(machine);
ArduinoMachineState *ams = ARDUINO_MACHINE(machine);
+ ams->xtal = machine_create_constant_clock(machine, "osc", amc->xtal_hz);
+
object_initialize_child(OBJECT(machine), "mcu", &ams->mcu, amc->mcu_type);
- object_property_set_uint(OBJECT(&ams->mcu), "xtal-frequency-hz",
- amc->xtal_hz, &error_abort);
+ qdev_connect_clock_in(DEVICE(&ams->mcu), "osc-in", ams->xtal);
sysbus_realize(SYS_BUS_DEVICE(&ams->mcu), &error_abort);
if (machine->firmware) {
diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
index 44c6afebbb6..b8a11965435 100644
--- a/hw/avr/atmega.c
+++ b/hw/avr/atmega.c
@@ -15,6 +15,7 @@
#include "exec/memory.h"
#include "exec/address-spaces.h"
#include "sysemu/sysemu.h"
+#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "qom/object.h"
@@ -216,6 +217,14 @@ static void connect_power_reduction_gpio(AtmegaMcuState *s,
qdev_get_gpio_in(cpu, 0));
}
+static void atmega_init(Object *obj)
+{
+ AtmegaMcuState *s = ATMEGA_MCU(obj);
+
+ s->xtal_clkin = qdev_init_clock_in(DEVICE(obj), "osc-in",
+ NULL, NULL, ClockUpdate);
+}
+
static void atmega_realize(DeviceState *dev, Error **errp)
{
AtmegaMcuState *s = ATMEGA_MCU(dev);
@@ -227,11 +236,6 @@ static void atmega_realize(DeviceState *dev, Error **errp)
assert(mc->io_size <= 0x200);
- 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, mc->cpu_type);
object_property_set_bool(OBJECT(&s->cpu), "realized", true, &error_abort);
@@ -328,8 +332,7 @@ static void atmega_realize(DeviceState *dev, Error **errp)
devname = g_strdup_printf("timer%zu", i);
object_initialize_child(OBJECT(dev), devname, &s->timer[i],
TYPE_AVR_TIMER16);
- object_property_set_uint(OBJECT(&s->timer[i]), "cpu-frequency-hz",
- s->xtal_freq_hz, &error_abort);
+ qdev_connect_clock_in(DEVICE(&s->timer[i]), "io-clk", s->xtal_clkin);
sbd = SYS_BUS_DEVICE(&s->timer[i]);
sysbus_realize(sbd, &error_abort);
sysbus_mmio_map(sbd, 0, OFFSET_DATA + mc->dev[idx].addr);
@@ -353,8 +356,6 @@ static void atmega_realize(DeviceState *dev, Error **errp)
}
static Property atmega_props[] = {
- DEFINE_PROP_UINT64("xtal-frequency-hz", AtmegaMcuState,
- xtal_freq_hz, 0),
DEFINE_PROP_END_OF_LIST()
};
@@ -449,6 +450,7 @@ static const TypeInfo atmega_mcu_types[] = {
.name = TYPE_ATMEGA_MCU,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AtmegaMcuState),
+ .instance_init = atmega_init,
.class_size = sizeof(AtmegaMcuClass),
.class_init = atmega_class_init,
.abstract = true,
diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c
index c48555da525..7092023d616 100644
--- a/hw/timer/avr_timer16.c
+++ b/hw/timer/avr_timer16.c
@@ -35,6 +35,7 @@
#include "qapi/error.h"
#include "qemu/log.h"
#include "hw/irq.h"
+#include "hw/qdev-clock.h"
#include "hw/qdev-properties.h"
#include "hw/timer/avr_timer16.h"
#include "trace.h"
@@ -167,7 +168,7 @@ static void avr_timer16_clksrc_update(AVRTimer16State *t16)
break;
}
if (divider) {
- t16->freq_hz = t16->cpu_freq_hz / divider;
+ t16->freq_hz = clock_get_hz(t16->io_clkin) / divider;
t16->period_ns = NANOSECONDS_PER_SECOND / t16->freq_hz;
trace_avr_timer16_clksrc_update(t16->freq_hz, t16->period_ns,
(uint64_t)(1e6 / t16->freq_hz));
@@ -544,8 +545,6 @@ static const MemoryRegionOps avr_timer16_ifr_ops = {
static Property avr_timer16_properties[] = {
DEFINE_PROP_UINT8("id", struct AVRTimer16State, id, 0),
- DEFINE_PROP_UINT64("cpu-frequency-hz", struct AVRTimer16State,
- cpu_freq_hz, 0),
DEFINE_PROP_END_OF_LIST(),
};
@@ -560,10 +559,20 @@ static void avr_timer16_pr(void *opaque, int irq, int level)
}
}
+static void avr_timer16_clock_update(void *opaque, ClockEvent event)
+{
+ AVRTimer16State *s = opaque;
+
+ avr_timer16_clksrc_update(s);
+}
+
static void avr_timer16_init(Object *obj)
{
AVRTimer16State *s = AVR_TIMER16(obj);
+ s->io_clkin = qdev_init_clock_in(DEVICE(obj), "io-clk",
+ avr_timer16_clock_update, s, ClockUpdate);
+
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->capt_irq);
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compa_irq);
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compb_irq);
@@ -587,11 +596,6 @@ static void avr_timer16_realize(DeviceState *dev, Error **errp)
{
AVRTimer16State *s = AVR_TIMER16(dev);
- if (s->cpu_freq_hz == 0) {
- error_setg(errp, "AVR timer16: cpu-frequency-hz property must be set");
- return;
- }
-
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, avr_timer16_interrupt, s);
s->enabled = true;
}
--
2.26.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH-for-6.1] hw/avr/atmega: Convert to QDev Clock API
2021-04-09 11:25 [PATCH-for-6.1] hw/avr/atmega: Convert to QDev Clock API Philippe Mathieu-Daudé
@ 2021-04-09 11:33 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 2+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-04-09 11:33 UTC (permalink / raw)
To: qemu-devel; +Cc: Michael Rolnik, Joaquin de Andres, Luc Michel
On 4/9/21 1:25 PM, Philippe Mathieu-Daudé wrote:
> Create the oscillator object on the board, and propagate its
> clock to the ATMega MCU. Wire this clock to the timers.
>
> Properties are remplaced by clocks.
>
> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> Based-on: <20210409062401.2350436-1-f4bug@amsat.org>
>
> TODO: Add corresponding vmstates for migration,
> but these devices don't have any, so keep
> this for later.
> ---
> hw/avr/atmega.h | 3 ++-
> include/hw/timer/avr_timer16.h | 4 +++-
> hw/avr/arduino.c | 8 ++++++--
> hw/avr/atmega.c | 20 +++++++++++---------
> hw/timer/avr_timer16.c | 20 ++++++++++++--------
> 5 files changed, 34 insertions(+), 21 deletions(-)
>
> diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
> index a99ee15c7e1..12e856386b6 100644
> --- a/hw/avr/atmega.h
> +++ b/hw/avr/atmega.h
> @@ -11,6 +11,7 @@
> #ifndef HW_AVR_ATMEGA_H
> #define HW_AVR_ATMEGA_H
>
> +#include "hw/clock.h"
> #include "hw/char/avr_usart.h"
> #include "hw/timer/avr_timer16.h"
> #include "hw/misc/avr_power.h"
> @@ -41,11 +42,11 @@ struct AtmegaMcuState {
> MemoryRegion flash;
> MemoryRegion eeprom;
> MemoryRegion sram;
> + Clock *xtal_clkin;
> DeviceState *io;
> AVRMaskState pwr[POWER_MAX];
> AVRUsartState usart[USART_MAX];
> AVRTimer16State timer[TIMER_MAX];
> - uint64_t xtal_freq_hz;
> };
>
> #endif /* HW_AVR_ATMEGA_H */
> diff --git a/include/hw/timer/avr_timer16.h b/include/hw/timer/avr_timer16.h
> index 05362543378..86dc9e98d95 100644
> --- a/include/hw/timer/avr_timer16.h
> +++ b/include/hw/timer/avr_timer16.h
> @@ -28,6 +28,7 @@
> #ifndef HW_TIMER_AVR_TIMER16_H
> #define HW_TIMER_AVR_TIMER16_H
>
> +#include "hw/clock.h"
> #include "hw/sysbus.h"
> #include "qemu/timer.h"
> #include "hw/hw.h"
> @@ -84,7 +85,8 @@ struct AVRTimer16State {
> uint8_t ifr;
>
> uint8_t id;
> - uint64_t cpu_freq_hz;
> + Clock *io_clkin;
> +
> uint64_t freq_hz;
> uint64_t period_ns;
> uint64_t reset_time_ns;
> diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c
> index 3ff31492fa6..71e69823c07 100644
> --- a/hw/avr/arduino.c
> +++ b/hw/avr/arduino.c
> @@ -12,7 +12,9 @@
>
> #include "qemu/osdep.h"
> #include "qapi/error.h"
> +#include "hw/clock.h"
> #include "hw/boards.h"
> +#include "hw/qdev-clock.h"
> #include "atmega.h"
> #include "boot.h"
> #include "qom/object.h"
> @@ -21,6 +23,7 @@ struct ArduinoMachineState {
> /*< private >*/
> MachineState parent_obj;
> /*< public >*/
> + Clock *xtal;
> AtmegaMcuState mcu;
> };
> typedef struct ArduinoMachineState ArduinoMachineState;
> @@ -44,9 +47,10 @@ static void arduino_machine_init(MachineState *machine)
> ArduinoMachineClass *amc = ARDUINO_MACHINE_GET_CLASS(machine);
> ArduinoMachineState *ams = ARDUINO_MACHINE(machine);
>
> + ams->xtal = machine_create_constant_clock(machine, "osc", amc->xtal_hz);
> +
> object_initialize_child(OBJECT(machine), "mcu", &ams->mcu, amc->mcu_type);
> - object_property_set_uint(OBJECT(&ams->mcu), "xtal-frequency-hz",
> - amc->xtal_hz, &error_abort);
> + qdev_connect_clock_in(DEVICE(&ams->mcu), "osc-in", ams->xtal);
> sysbus_realize(SYS_BUS_DEVICE(&ams->mcu), &error_abort);
>
> if (machine->firmware) {
> diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
> index 44c6afebbb6..b8a11965435 100644
> --- a/hw/avr/atmega.c
> +++ b/hw/avr/atmega.c
> @@ -15,6 +15,7 @@
> #include "exec/memory.h"
> #include "exec/address-spaces.h"
> #include "sysemu/sysemu.h"
> +#include "hw/qdev-clock.h"
> #include "hw/qdev-properties.h"
> #include "hw/sysbus.h"
> #include "qom/object.h"
> @@ -216,6 +217,14 @@ static void connect_power_reduction_gpio(AtmegaMcuState *s,
> qdev_get_gpio_in(cpu, 0));
> }
>
> +static void atmega_init(Object *obj)
> +{
> + AtmegaMcuState *s = ATMEGA_MCU(obj);
> +
> + s->xtal_clkin = qdev_init_clock_in(DEVICE(obj), "osc-in",
> + NULL, NULL, ClockUpdate);
> +}
> +
> static void atmega_realize(DeviceState *dev, Error **errp)
> {
> AtmegaMcuState *s = ATMEGA_MCU(dev);
> @@ -227,11 +236,6 @@ static void atmega_realize(DeviceState *dev, Error **errp)
>
> assert(mc->io_size <= 0x200);
>
> - 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, mc->cpu_type);
> object_property_set_bool(OBJECT(&s->cpu), "realized", true, &error_abort);
> @@ -328,8 +332,7 @@ static void atmega_realize(DeviceState *dev, Error **errp)
> devname = g_strdup_printf("timer%zu", i);
> object_initialize_child(OBJECT(dev), devname, &s->timer[i],
> TYPE_AVR_TIMER16);
I forgot to commit this hunk:
+ /*
+ * Since we do not model the Clock Distribution system,
+ * directly connect the external clock to I/O clock.
+ */
> - object_property_set_uint(OBJECT(&s->timer[i]), "cpu-frequency-hz",
> - s->xtal_freq_hz, &error_abort);
> + qdev_connect_clock_in(DEVICE(&s->timer[i]), "io-clk", s->xtal_clkin);
> sbd = SYS_BUS_DEVICE(&s->timer[i]);
> sysbus_realize(sbd, &error_abort);
> sysbus_mmio_map(sbd, 0, OFFSET_DATA + mc->dev[idx].addr);
> @@ -353,8 +356,6 @@ static void atmega_realize(DeviceState *dev, Error **errp)
> }
>
> static Property atmega_props[] = {
> - DEFINE_PROP_UINT64("xtal-frequency-hz", AtmegaMcuState,
> - xtal_freq_hz, 0),
> DEFINE_PROP_END_OF_LIST()
> };
>
> @@ -449,6 +450,7 @@ static const TypeInfo atmega_mcu_types[] = {
> .name = TYPE_ATMEGA_MCU,
> .parent = TYPE_SYS_BUS_DEVICE,
> .instance_size = sizeof(AtmegaMcuState),
> + .instance_init = atmega_init,
> .class_size = sizeof(AtmegaMcuClass),
> .class_init = atmega_class_init,
> .abstract = true,
> diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c
> index c48555da525..7092023d616 100644
> --- a/hw/timer/avr_timer16.c
> +++ b/hw/timer/avr_timer16.c
> @@ -35,6 +35,7 @@
> #include "qapi/error.h"
> #include "qemu/log.h"
> #include "hw/irq.h"
> +#include "hw/qdev-clock.h"
> #include "hw/qdev-properties.h"
> #include "hw/timer/avr_timer16.h"
> #include "trace.h"
> @@ -167,7 +168,7 @@ static void avr_timer16_clksrc_update(AVRTimer16State *t16)
> break;
> }
> if (divider) {
> - t16->freq_hz = t16->cpu_freq_hz / divider;
> + t16->freq_hz = clock_get_hz(t16->io_clkin) / divider;
> t16->period_ns = NANOSECONDS_PER_SECOND / t16->freq_hz;
> trace_avr_timer16_clksrc_update(t16->freq_hz, t16->period_ns,
> (uint64_t)(1e6 / t16->freq_hz));
> @@ -544,8 +545,6 @@ static const MemoryRegionOps avr_timer16_ifr_ops = {
>
> static Property avr_timer16_properties[] = {
> DEFINE_PROP_UINT8("id", struct AVRTimer16State, id, 0),
> - DEFINE_PROP_UINT64("cpu-frequency-hz", struct AVRTimer16State,
> - cpu_freq_hz, 0),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> @@ -560,10 +559,20 @@ static void avr_timer16_pr(void *opaque, int irq, int level)
> }
> }
>
> +static void avr_timer16_clock_update(void *opaque, ClockEvent event)
> +{
> + AVRTimer16State *s = opaque;
> +
> + avr_timer16_clksrc_update(s);
> +}
> +
> static void avr_timer16_init(Object *obj)
> {
> AVRTimer16State *s = AVR_TIMER16(obj);
>
> + s->io_clkin = qdev_init_clock_in(DEVICE(obj), "io-clk",
> + avr_timer16_clock_update, s, ClockUpdate);
> +
> sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->capt_irq);
> sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compa_irq);
> sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compb_irq);
> @@ -587,11 +596,6 @@ static void avr_timer16_realize(DeviceState *dev, Error **errp)
> {
> AVRTimer16State *s = AVR_TIMER16(dev);
>
> - if (s->cpu_freq_hz == 0) {
> - error_setg(errp, "AVR timer16: cpu-frequency-hz property must be set");
> - return;
> - }
> -
> s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, avr_timer16_interrupt, s);
> s->enabled = true;
> }
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-04-09 11:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-09 11:25 [PATCH-for-6.1] hw/avr/atmega: Convert to QDev Clock API Philippe Mathieu-Daudé
2021-04-09 11:33 ` Philippe Mathieu-Daudé
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).