mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-24 10:32:02 -06:00
clock: Add ClockEvent parameter to callbacks
The Clock framework allows users to specify a callback which is called after the clock's period has been updated. Some users need to also have a callback which is called before the clock period is updated. As the first step in adding support for notifying Clock users on pre-update events, add an argument to the ClockCallback to specify what event is being notified, and add an argument to the various functions for registering a callback to specify which events are of interest to that callback. Note that the documentation update renders correct the previously incorrect claim in 'Adding a new clock' that callbacks "will be explained in a following section". Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Luc Michel <luc@lmichel.fr> Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210219144617.4782-2-peter.maydell@linaro.org
This commit is contained in:
parent
0436c55edf
commit
5ee0abed51
20 changed files with 161 additions and 58 deletions
|
@ -80,11 +80,12 @@ Adding clocks to a device must be done during the init method of the Device
|
||||||
instance.
|
instance.
|
||||||
|
|
||||||
To add an input clock to a device, the function ``qdev_init_clock_in()``
|
To add an input clock to a device, the function ``qdev_init_clock_in()``
|
||||||
must be used. It takes the name, a callback and an opaque parameter
|
must be used. It takes the name, a callback, an opaque parameter
|
||||||
for the callback (this will be explained in a following section).
|
for the callback and a mask of events when the callback should be
|
||||||
|
called (this will be explained in a following section).
|
||||||
Output is simpler; only the name is required. Typically::
|
Output is simpler; only the name is required. Typically::
|
||||||
|
|
||||||
qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev);
|
qdev_init_clock_in(DEVICE(dev), "clk_in", clk_in_callback, dev, ClockUpdate);
|
||||||
qdev_init_clock_out(DEVICE(dev), "clk_out");
|
qdev_init_clock_out(DEVICE(dev), "clk_out");
|
||||||
|
|
||||||
Both functions return the created Clock pointer, which should be saved in the
|
Both functions return the created Clock pointer, which should be saved in the
|
||||||
|
@ -113,7 +114,7 @@ output.
|
||||||
* callback for the input clock (see "Callback on input clock
|
* callback for the input clock (see "Callback on input clock
|
||||||
* change" section below for more information).
|
* change" section below for more information).
|
||||||
*/
|
*/
|
||||||
static void clk_in_callback(void *opaque);
|
static void clk_in_callback(void *opaque, ClockEvent event);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* static array describing clocks:
|
* static array describing clocks:
|
||||||
|
@ -124,7 +125,7 @@ output.
|
||||||
* the clk_out field of a MyDeviceState structure.
|
* the clk_out field of a MyDeviceState structure.
|
||||||
*/
|
*/
|
||||||
static const ClockPortInitArray mydev_clocks = {
|
static const ClockPortInitArray mydev_clocks = {
|
||||||
QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback),
|
QDEV_CLOCK_IN(MyDeviceState, clk_in, clk_in_callback, ClockUpdate),
|
||||||
QDEV_CLOCK_OUT(MyDeviceState, clk_out),
|
QDEV_CLOCK_OUT(MyDeviceState, clk_out),
|
||||||
QDEV_CLOCK_END
|
QDEV_CLOCK_END
|
||||||
};
|
};
|
||||||
|
@ -153,6 +154,40 @@ nothing else to do. This value will be propagated to other clocks when
|
||||||
connecting the clocks together and devices will fetch the right value during
|
connecting the clocks together and devices will fetch the right value during
|
||||||
the first reset.
|
the first reset.
|
||||||
|
|
||||||
|
Clock callbacks
|
||||||
|
---------------
|
||||||
|
|
||||||
|
You can give a clock a callback function in several ways:
|
||||||
|
|
||||||
|
* by passing it as an argument to ``qdev_init_clock_in()``
|
||||||
|
* as an argument to the ``QDEV_CLOCK_IN()`` macro initializing an
|
||||||
|
array to be passed to ``qdev_init_clocks()``
|
||||||
|
* by directly calling the ``clock_set_callback()`` function
|
||||||
|
|
||||||
|
The callback function must be of this type:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
typedef void ClockCallback(void *opaque, ClockEvent event);
|
||||||
|
|
||||||
|
The ``opaque`` argument is the pointer passed to ``qdev_init_clock_in()``
|
||||||
|
or ``clock_set_callback()``; for ``qdev_init_clocks()`` it is the
|
||||||
|
``dev`` device pointer.
|
||||||
|
|
||||||
|
The ``event`` argument specifies why the callback has been called.
|
||||||
|
When you register the callback you specify a mask of ClockEvent values
|
||||||
|
that you are interested in. The callback will only be called for those
|
||||||
|
events.
|
||||||
|
|
||||||
|
The events currently supported are:
|
||||||
|
|
||||||
|
* ``ClockUpdate`` : called after the input clock's period has changed
|
||||||
|
|
||||||
|
Note that a clock only has one callback: it is not possible to register
|
||||||
|
different functions for different events. You must register a single
|
||||||
|
callback which listens for all of the events you are interested in,
|
||||||
|
and use the ``event`` argument to identify which event has happened.
|
||||||
|
|
||||||
Retrieving clocks from a device
|
Retrieving clocks from a device
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
@ -231,7 +266,7 @@ object during device instance init. For example:
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback,
|
clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback,
|
||||||
dev);
|
dev, ClockUpdate);
|
||||||
/* set initial value to 10ns / 100MHz */
|
/* set initial value to 10ns / 100MHz */
|
||||||
clock_set_ns(clk, 10);
|
clock_set_ns(clk, 10);
|
||||||
|
|
||||||
|
@ -267,11 +302,12 @@ next lowest integer. This implies some inaccuracy due to the rounding,
|
||||||
so be cautious about using it in calculations.
|
so be cautious about using it in calculations.
|
||||||
|
|
||||||
It is also possible to register a callback on clock frequency changes.
|
It is also possible to register a callback on clock frequency changes.
|
||||||
Here is an example:
|
Here is an example, which assumes that ``clock_callback`` has been
|
||||||
|
specified as the callback for the ``ClockUpdate`` event:
|
||||||
|
|
||||||
.. code-block:: c
|
.. code-block:: c
|
||||||
|
|
||||||
void clock_callback(void *opaque) {
|
void clock_callback(void *opaque, ClockEvent event) {
|
||||||
MyDeviceState *s = (MyDeviceState *) opaque;
|
MyDeviceState *s = (MyDeviceState *) opaque;
|
||||||
/*
|
/*
|
||||||
* 'opaque' is the argument passed to qdev_init_clock_in();
|
* 'opaque' is the argument passed to qdev_init_clock_in();
|
||||||
|
|
|
@ -238,7 +238,7 @@ static void npcm7xx_adc_init(Object *obj)
|
||||||
memory_region_init_io(&s->iomem, obj, &npcm7xx_adc_ops, s,
|
memory_region_init_io(&s->iomem, obj, &npcm7xx_adc_ops, s,
|
||||||
TYPE_NPCM7XX_ADC, 4 * KiB);
|
TYPE_NPCM7XX_ADC, 4 * KiB);
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
|
s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
|
||||||
|
|
||||||
for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
|
for (i = 0; i < NPCM7XX_ADC_NUM_INPUTS; ++i) {
|
||||||
object_property_add_uint32_ptr(obj, "adci[*]",
|
object_property_add_uint32_ptr(obj, "adci[*]",
|
||||||
|
|
|
@ -230,9 +230,10 @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
|
||||||
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
|
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void armsse_mainclk_update(void *opaque)
|
static void armsse_mainclk_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
ARMSSE *s = ARM_SSE(opaque);
|
ARMSSE *s = ARM_SSE(opaque);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set system_clock_scale from our Clock input; this is what
|
* Set system_clock_scale from our Clock input; this is what
|
||||||
* controls the tick rate of the CPU SysTick timer.
|
* controls the tick rate of the CPU SysTick timer.
|
||||||
|
@ -251,8 +252,8 @@ static void armsse_init(Object *obj)
|
||||||
assert(info->num_cpus <= SSE_MAX_CPUS);
|
assert(info->num_cpus <= SSE_MAX_CPUS);
|
||||||
|
|
||||||
s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
|
s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
|
||||||
armsse_mainclk_update, s);
|
armsse_mainclk_update, s, ClockUpdate);
|
||||||
s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
|
s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
|
||||||
|
|
||||||
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
|
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
|
||||||
|
|
||||||
|
@ -1120,7 +1121,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
|
||||||
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
|
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
|
||||||
|
|
||||||
/* Set initial system_clock_scale from MAINCLK */
|
/* Set initial system_clock_scale from MAINCLK */
|
||||||
armsse_mainclk_update(s);
|
armsse_mainclk_update(s, ClockUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
|
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
|
||||||
|
|
|
@ -519,7 +519,7 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
|
||||||
uart_event, NULL, s, NULL, true);
|
uart_event, NULL, s, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cadence_uart_refclk_update(void *opaque)
|
static void cadence_uart_refclk_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
CadenceUARTState *s = opaque;
|
CadenceUARTState *s = opaque;
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ static void cadence_uart_init(Object *obj)
|
||||||
sysbus_init_irq(sbd, &s->irq);
|
sysbus_init_irq(sbd, &s->irq);
|
||||||
|
|
||||||
s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk",
|
s->refclk = qdev_init_clock_in(DEVICE(obj), "refclk",
|
||||||
cadence_uart_refclk_update, s);
|
cadence_uart_refclk_update, s, ClockUpdate);
|
||||||
/* initialize the frequency in case the clock remains unconnected */
|
/* initialize the frequency in case the clock remains unconnected */
|
||||||
clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
|
clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
|
||||||
|
|
||||||
|
|
|
@ -396,7 +396,7 @@ static void ibex_uart_write(void *opaque, hwaddr addr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ibex_uart_clk_update(void *opaque)
|
static void ibex_uart_clk_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
IbexUartState *s = opaque;
|
IbexUartState *s = opaque;
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ static void ibex_uart_init(Object *obj)
|
||||||
IbexUartState *s = IBEX_UART(obj);
|
IbexUartState *s = IBEX_UART(obj);
|
||||||
|
|
||||||
s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock",
|
s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock",
|
||||||
ibex_uart_clk_update, s);
|
ibex_uart_clk_update, s, ClockUpdate);
|
||||||
clock_set_hz(s->f_clk, IBEX_UART_CLOCK);
|
clock_set_hz(s->f_clk, IBEX_UART_CLOCK);
|
||||||
|
|
||||||
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
|
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
|
||||||
|
|
|
@ -309,7 +309,7 @@ static void pl011_event(void *opaque, QEMUChrEvent event)
|
||||||
pl011_put_fifo(opaque, 0x400);
|
pl011_put_fifo(opaque, 0x400);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pl011_clock_update(void *opaque)
|
static void pl011_clock_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
PL011State *s = PL011(opaque);
|
PL011State *s = PL011(opaque);
|
||||||
|
|
||||||
|
@ -378,7 +378,8 @@ static void pl011_init(Object *obj)
|
||||||
sysbus_init_irq(sbd, &s->irq[i]);
|
sysbus_init_irq(sbd, &s->irq[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s);
|
s->clk = qdev_init_clock_in(DEVICE(obj), "clk", pl011_clock_update, s,
|
||||||
|
ClockUpdate);
|
||||||
|
|
||||||
s->read_trigger = 1;
|
s->read_trigger = 1;
|
||||||
s->ifl = 0x12;
|
s->ifl = 0x12;
|
||||||
|
|
|
@ -39,15 +39,17 @@ Clock *clock_new(Object *parent, const char *name)
|
||||||
return clk;
|
return clk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque)
|
void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque,
|
||||||
|
unsigned int events)
|
||||||
{
|
{
|
||||||
clk->callback = cb;
|
clk->callback = cb;
|
||||||
clk->callback_opaque = opaque;
|
clk->callback_opaque = opaque;
|
||||||
|
clk->callback_events = events;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clock_clear_callback(Clock *clk)
|
void clock_clear_callback(Clock *clk)
|
||||||
{
|
{
|
||||||
clock_set_callback(clk, NULL, NULL);
|
clock_set_callback(clk, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool clock_set(Clock *clk, uint64_t period)
|
bool clock_set(Clock *clk, uint64_t period)
|
||||||
|
@ -62,6 +64,17 @@ bool clock_set(Clock *clk, uint64_t period)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clock_call_callback(Clock *clk, ClockEvent event)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Call the Clock's callback for this event, if it has one and
|
||||||
|
* is interested in this event.
|
||||||
|
*/
|
||||||
|
if (clk->callback && (clk->callback_events & event)) {
|
||||||
|
clk->callback(clk->callback_opaque, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void clock_propagate_period(Clock *clk, bool call_callbacks)
|
static void clock_propagate_period(Clock *clk, bool call_callbacks)
|
||||||
{
|
{
|
||||||
Clock *child;
|
Clock *child;
|
||||||
|
@ -72,8 +85,8 @@ static void clock_propagate_period(Clock *clk, bool call_callbacks)
|
||||||
trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
|
trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
|
||||||
CLOCK_PERIOD_TO_HZ(clk->period),
|
CLOCK_PERIOD_TO_HZ(clk->period),
|
||||||
call_callbacks);
|
call_callbacks);
|
||||||
if (call_callbacks && child->callback) {
|
if (call_callbacks) {
|
||||||
child->callback(child->callback_opaque);
|
clock_call_callback(child, ClockUpdate);
|
||||||
}
|
}
|
||||||
clock_propagate_period(child, call_callbacks);
|
clock_propagate_period(child, call_callbacks);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,8 @@ Clock *qdev_init_clock_out(DeviceState *dev, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
|
Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
|
||||||
ClockCallback *callback, void *opaque)
|
ClockCallback *callback, void *opaque,
|
||||||
|
unsigned int events)
|
||||||
{
|
{
|
||||||
NamedClockList *ncl;
|
NamedClockList *ncl;
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
|
||||||
ncl = qdev_init_clocklist(dev, name, false, NULL);
|
ncl = qdev_init_clocklist(dev, name, false, NULL);
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
clock_set_callback(ncl->clock, callback, opaque);
|
clock_set_callback(ncl->clock, callback, opaque, events);
|
||||||
}
|
}
|
||||||
return ncl->clock;
|
return ncl->clock;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +138,8 @@ void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks)
|
||||||
if (elem->is_output) {
|
if (elem->is_output) {
|
||||||
*clkp = qdev_init_clock_out(dev, elem->name);
|
*clkp = qdev_init_clock_out(dev, elem->name);
|
||||||
} else {
|
} else {
|
||||||
*clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev);
|
*clkp = qdev_init_clock_in(dev, elem->name, elem->callback, dev,
|
||||||
|
elem->callback_events);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ static void mips_cps_init(Object *obj)
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||||
MIPSCPSState *s = MIPS_CPS(obj);
|
MIPSCPSState *s = MIPS_CPS(obj);
|
||||||
|
|
||||||
s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL);
|
s->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, NULL, 0);
|
||||||
/*
|
/*
|
||||||
* Cover entire address space as there do not seem to be any
|
* Cover entire address space as there do not seem to be any
|
||||||
* constraints for the base address of CPC and GIC.
|
* constraints for the base address of CPC and GIC.
|
||||||
|
|
|
@ -107,7 +107,7 @@ static void pll_update(CprmanPllState *pll)
|
||||||
clock_update_hz(pll->out, freq);
|
clock_update_hz(pll->out, freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pll_xosc_update(void *opaque)
|
static void pll_xosc_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
pll_update(CPRMAN_PLL(opaque));
|
pll_update(CPRMAN_PLL(opaque));
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,8 @@ static void pll_init(Object *obj)
|
||||||
{
|
{
|
||||||
CprmanPllState *s = CPRMAN_PLL(obj);
|
CprmanPllState *s = CPRMAN_PLL(obj);
|
||||||
|
|
||||||
s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update, s);
|
s->xosc_in = qdev_init_clock_in(DEVICE(s), "xosc-in", pll_xosc_update,
|
||||||
|
s, ClockUpdate);
|
||||||
s->out = qdev_init_clock_out(DEVICE(s), "out");
|
s->out = qdev_init_clock_out(DEVICE(s), "out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +210,7 @@ static void pll_update_all_channels(BCM2835CprmanState *s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pll_channel_pll_in_update(void *opaque)
|
static void pll_channel_pll_in_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
pll_channel_update(CPRMAN_PLL_CHANNEL(opaque));
|
pll_channel_update(CPRMAN_PLL_CHANNEL(opaque));
|
||||||
}
|
}
|
||||||
|
@ -219,7 +220,8 @@ static void pll_channel_init(Object *obj)
|
||||||
CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);
|
CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);
|
||||||
|
|
||||||
s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in",
|
s->pll_in = qdev_init_clock_in(DEVICE(s), "pll-in",
|
||||||
pll_channel_pll_in_update, s);
|
pll_channel_pll_in_update, s,
|
||||||
|
ClockUpdate);
|
||||||
s->out = qdev_init_clock_out(DEVICE(s), "out");
|
s->out = qdev_init_clock_out(DEVICE(s), "out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +305,7 @@ static void clock_mux_update(CprmanClockMuxState *mux)
|
||||||
clock_update_hz(mux->out, freq);
|
clock_update_hz(mux->out, freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clock_mux_src_update(void *opaque)
|
static void clock_mux_src_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
CprmanClockMuxState **backref = opaque;
|
CprmanClockMuxState **backref = opaque;
|
||||||
CprmanClockMuxState *s = *backref;
|
CprmanClockMuxState *s = *backref;
|
||||||
|
@ -335,7 +337,8 @@ static void clock_mux_init(Object *obj)
|
||||||
s->backref[i] = s;
|
s->backref[i] = s;
|
||||||
s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
|
s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
|
||||||
clock_mux_src_update,
|
clock_mux_src_update,
|
||||||
&s->backref[i]);
|
&s->backref[i],
|
||||||
|
ClockUpdate);
|
||||||
g_free(name);
|
g_free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +383,7 @@ static void dsi0hsck_mux_update(CprmanDsi0HsckMuxState *s)
|
||||||
clock_update(s->out, clock_get(src));
|
clock_update(s->out, clock_get(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dsi0hsck_mux_in_update(void *opaque)
|
static void dsi0hsck_mux_in_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
dsi0hsck_mux_update(CPRMAN_DSI0HSCK_MUX(opaque));
|
dsi0hsck_mux_update(CPRMAN_DSI0HSCK_MUX(opaque));
|
||||||
}
|
}
|
||||||
|
@ -390,8 +393,10 @@ static void dsi0hsck_mux_init(Object *obj)
|
||||||
CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj);
|
CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj);
|
||||||
DeviceState *dev = DEVICE(obj);
|
DeviceState *dev = DEVICE(obj);
|
||||||
|
|
||||||
s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update, s);
|
s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update,
|
||||||
s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update, s);
|
s, ClockUpdate);
|
||||||
|
s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update,
|
||||||
|
s, ClockUpdate);
|
||||||
s->out = qdev_init_clock_out(DEVICE(s), "out");
|
s->out = qdev_init_clock_out(DEVICE(s), "out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,15 +586,26 @@ static const DividerInitInfo divider_init_info_list[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void npcm7xx_clk_update_pll_cb(void *opaque, ClockEvent event)
|
||||||
|
{
|
||||||
|
npcm7xx_clk_update_pll(opaque);
|
||||||
|
}
|
||||||
|
|
||||||
static void npcm7xx_clk_pll_init(Object *obj)
|
static void npcm7xx_clk_pll_init(Object *obj)
|
||||||
{
|
{
|
||||||
NPCM7xxClockPLLState *pll = NPCM7XX_CLOCK_PLL(obj);
|
NPCM7xxClockPLLState *pll = NPCM7XX_CLOCK_PLL(obj);
|
||||||
|
|
||||||
pll->clock_in = qdev_init_clock_in(DEVICE(pll), "clock-in",
|
pll->clock_in = qdev_init_clock_in(DEVICE(pll), "clock-in",
|
||||||
npcm7xx_clk_update_pll, pll);
|
npcm7xx_clk_update_pll_cb, pll,
|
||||||
|
ClockUpdate);
|
||||||
pll->clock_out = qdev_init_clock_out(DEVICE(pll), "clock-out");
|
pll->clock_out = qdev_init_clock_out(DEVICE(pll), "clock-out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void npcm7xx_clk_update_sel_cb(void *opaque, ClockEvent event)
|
||||||
|
{
|
||||||
|
npcm7xx_clk_update_sel(opaque);
|
||||||
|
}
|
||||||
|
|
||||||
static void npcm7xx_clk_sel_init(Object *obj)
|
static void npcm7xx_clk_sel_init(Object *obj)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -603,16 +614,23 @@ static void npcm7xx_clk_sel_init(Object *obj)
|
||||||
for (i = 0; i < NPCM7XX_CLK_SEL_MAX_INPUT; ++i) {
|
for (i = 0; i < NPCM7XX_CLK_SEL_MAX_INPUT; ++i) {
|
||||||
sel->clock_in[i] = qdev_init_clock_in(DEVICE(sel),
|
sel->clock_in[i] = qdev_init_clock_in(DEVICE(sel),
|
||||||
g_strdup_printf("clock-in[%d]", i),
|
g_strdup_printf("clock-in[%d]", i),
|
||||||
npcm7xx_clk_update_sel, sel);
|
npcm7xx_clk_update_sel_cb, sel, ClockUpdate);
|
||||||
}
|
}
|
||||||
sel->clock_out = qdev_init_clock_out(DEVICE(sel), "clock-out");
|
sel->clock_out = qdev_init_clock_out(DEVICE(sel), "clock-out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void npcm7xx_clk_update_divider_cb(void *opaque, ClockEvent event)
|
||||||
|
{
|
||||||
|
npcm7xx_clk_update_divider(opaque);
|
||||||
|
}
|
||||||
|
|
||||||
static void npcm7xx_clk_divider_init(Object *obj)
|
static void npcm7xx_clk_divider_init(Object *obj)
|
||||||
{
|
{
|
||||||
NPCM7xxClockDividerState *div = NPCM7XX_CLOCK_DIVIDER(obj);
|
NPCM7xxClockDividerState *div = NPCM7XX_CLOCK_DIVIDER(obj);
|
||||||
|
|
||||||
div->clock_in = qdev_init_clock_in(DEVICE(div), "clock-in",
|
div->clock_in = qdev_init_clock_in(DEVICE(div), "clock-in",
|
||||||
npcm7xx_clk_update_divider, div);
|
npcm7xx_clk_update_divider_cb,
|
||||||
|
div, ClockUpdate);
|
||||||
div->clock_out = qdev_init_clock_out(DEVICE(div), "clock-out");
|
div->clock_out = qdev_init_clock_out(DEVICE(div), "clock-out");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,7 +893,7 @@ static void npcm7xx_clk_init_clock_hierarchy(NPCM7xxCLKState *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL);
|
s->clkref = qdev_init_clock_in(DEVICE(s), "clkref", NULL, NULL, 0);
|
||||||
|
|
||||||
/* First pass: init all converter modules */
|
/* First pass: init all converter modules */
|
||||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(pll_init_info_list) != NPCM7XX_CLOCK_NR_PLLS);
|
QEMU_BUILD_BUG_ON(ARRAY_SIZE(pll_init_info_list) != NPCM7XX_CLOCK_NR_PLLS);
|
||||||
|
|
|
@ -493,7 +493,7 @@ static void npcm7xx_pwm_init(Object *obj)
|
||||||
memory_region_init_io(&s->iomem, obj, &npcm7xx_pwm_ops, s,
|
memory_region_init_io(&s->iomem, obj, &npcm7xx_pwm_ops, s,
|
||||||
TYPE_NPCM7XX_PWM, 4 * KiB);
|
TYPE_NPCM7XX_PWM, 4 * KiB);
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL);
|
s->clock = qdev_init_clock_in(DEVICE(s), "clock", NULL, NULL, 0);
|
||||||
|
|
||||||
for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
|
for (i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
|
||||||
object_property_add_uint32_ptr(obj, "freq[*]",
|
object_property_add_uint32_ptr(obj, "freq[*]",
|
||||||
|
|
|
@ -307,9 +307,10 @@ static void zynq_slcr_propagate_clocks(ZynqSLCRState *s)
|
||||||
clock_propagate(s->uart1_ref_clk);
|
clock_propagate(s->uart1_ref_clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void zynq_slcr_ps_clk_callback(void *opaque)
|
static void zynq_slcr_ps_clk_callback(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
ZynqSLCRState *s = (ZynqSLCRState *) opaque;
|
ZynqSLCRState *s = (ZynqSLCRState *) opaque;
|
||||||
|
|
||||||
zynq_slcr_compute_clocks(s);
|
zynq_slcr_compute_clocks(s);
|
||||||
zynq_slcr_propagate_clocks(s);
|
zynq_slcr_propagate_clocks(s);
|
||||||
}
|
}
|
||||||
|
@ -576,7 +577,7 @@ static const MemoryRegionOps slcr_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ClockPortInitArray zynq_slcr_clocks = {
|
static const ClockPortInitArray zynq_slcr_clocks = {
|
||||||
QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback),
|
QDEV_CLOCK_IN(ZynqSLCRState, ps_clk, zynq_slcr_ps_clk_callback, ClockUpdate),
|
||||||
QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk),
|
QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk),
|
||||||
QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk),
|
QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk),
|
||||||
QDEV_CLOCK_END
|
QDEV_CLOCK_END
|
||||||
|
|
|
@ -449,7 +449,7 @@ static void cmsdk_apb_dualtimer_reset(DeviceState *dev)
|
||||||
s->timeritop = 0;
|
s->timeritop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmsdk_apb_dualtimer_clk_update(void *opaque)
|
static void cmsdk_apb_dualtimer_clk_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
|
CMSDKAPBDualTimer *s = CMSDK_APB_DUALTIMER(opaque);
|
||||||
int i;
|
int i;
|
||||||
|
@ -478,7 +478,8 @@ static void cmsdk_apb_dualtimer_init(Object *obj)
|
||||||
sysbus_init_irq(sbd, &s->timermod[i].timerint);
|
sysbus_init_irq(sbd, &s->timermod[i].timerint);
|
||||||
}
|
}
|
||||||
s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
|
s->timclk = qdev_init_clock_in(DEVICE(s), "TIMCLK",
|
||||||
cmsdk_apb_dualtimer_clk_update, s);
|
cmsdk_apb_dualtimer_clk_update, s,
|
||||||
|
ClockUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
|
static void cmsdk_apb_dualtimer_realize(DeviceState *dev, Error **errp)
|
||||||
|
|
|
@ -204,7 +204,7 @@ static void cmsdk_apb_timer_reset(DeviceState *dev)
|
||||||
ptimer_transaction_commit(s->timer);
|
ptimer_transaction_commit(s->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmsdk_apb_timer_clk_update(void *opaque)
|
static void cmsdk_apb_timer_clk_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
|
CMSDKAPBTimer *s = CMSDK_APB_TIMER(opaque);
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ static void cmsdk_apb_timer_init(Object *obj)
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
sysbus_init_irq(sbd, &s->timerint);
|
sysbus_init_irq(sbd, &s->timerint);
|
||||||
s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
|
s->pclk = qdev_init_clock_in(DEVICE(s), "pclk",
|
||||||
cmsdk_apb_timer_clk_update, s);
|
cmsdk_apb_timer_clk_update, s, ClockUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
|
static void cmsdk_apb_timer_realize(DeviceState *dev, Error **errp)
|
||||||
|
|
|
@ -627,7 +627,7 @@ static void npcm7xx_timer_init(Object *obj)
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
qdev_init_gpio_out_named(dev, &w->reset_signal,
|
qdev_init_gpio_out_named(dev, &w->reset_signal,
|
||||||
NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 1);
|
NPCM7XX_WATCHDOG_RESET_GPIO_OUT, 1);
|
||||||
s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL);
|
s->clock = qdev_init_clock_in(dev, "clock", NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_npcm7xx_base_timer = {
|
static const VMStateDescription vmstate_npcm7xx_base_timer = {
|
||||||
|
|
|
@ -310,7 +310,7 @@ static void cmsdk_apb_watchdog_reset(DeviceState *dev)
|
||||||
ptimer_transaction_commit(s->timer);
|
ptimer_transaction_commit(s->timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmsdk_apb_watchdog_clk_update(void *opaque)
|
static void cmsdk_apb_watchdog_clk_update(void *opaque, ClockEvent event)
|
||||||
{
|
{
|
||||||
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
|
CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
|
||||||
|
|
||||||
|
@ -329,7 +329,8 @@ static void cmsdk_apb_watchdog_init(Object *obj)
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
sysbus_init_irq(sbd, &s->wdogint);
|
sysbus_init_irq(sbd, &s->wdogint);
|
||||||
s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
|
s->wdogclk = qdev_init_clock_in(DEVICE(s), "WDOGCLK",
|
||||||
cmsdk_apb_watchdog_clk_update, s);
|
cmsdk_apb_watchdog_clk_update, s,
|
||||||
|
ClockUpdate);
|
||||||
|
|
||||||
s->is_luminary = false;
|
s->is_luminary = false;
|
||||||
s->id = cmsdk_apb_watchdog_id;
|
s->id = cmsdk_apb_watchdog_id;
|
||||||
|
|
|
@ -22,7 +22,17 @@
|
||||||
#define TYPE_CLOCK "clock"
|
#define TYPE_CLOCK "clock"
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
|
OBJECT_DECLARE_SIMPLE_TYPE(Clock, CLOCK)
|
||||||
|
|
||||||
typedef void ClockCallback(void *opaque);
|
/*
|
||||||
|
* Argument to ClockCallback functions indicating why the callback
|
||||||
|
* has been called. A mask of these values logically ORed together
|
||||||
|
* is used to specify which events are interesting when the callback
|
||||||
|
* is registered, so these values must all be different bit values.
|
||||||
|
*/
|
||||||
|
typedef enum ClockEvent {
|
||||||
|
ClockUpdate = 1, /* Clock period has just updated */
|
||||||
|
} ClockEvent;
|
||||||
|
|
||||||
|
typedef void ClockCallback(void *opaque, ClockEvent event);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* clock store a value representing the clock's period in 2^-32ns unit.
|
* clock store a value representing the clock's period in 2^-32ns unit.
|
||||||
|
@ -50,6 +60,7 @@ typedef void ClockCallback(void *opaque);
|
||||||
* @canonical_path: clock path string cache (used for trace purpose)
|
* @canonical_path: clock path string cache (used for trace purpose)
|
||||||
* @callback: called when clock changes
|
* @callback: called when clock changes
|
||||||
* @callback_opaque: argument for @callback
|
* @callback_opaque: argument for @callback
|
||||||
|
* @callback_events: mask of events when callback should be called
|
||||||
* @source: source (or parent in clock tree) of the clock
|
* @source: source (or parent in clock tree) of the clock
|
||||||
* @children: list of clocks connected to this one (it is their source)
|
* @children: list of clocks connected to this one (it is their source)
|
||||||
* @sibling: structure used to form a clock list
|
* @sibling: structure used to form a clock list
|
||||||
|
@ -67,6 +78,7 @@ struct Clock {
|
||||||
char *canonical_path;
|
char *canonical_path;
|
||||||
ClockCallback *callback;
|
ClockCallback *callback;
|
||||||
void *callback_opaque;
|
void *callback_opaque;
|
||||||
|
unsigned int callback_events;
|
||||||
|
|
||||||
/* Clocks are organized in a clock tree */
|
/* Clocks are organized in a clock tree */
|
||||||
Clock *source;
|
Clock *source;
|
||||||
|
@ -114,10 +126,15 @@ Clock *clock_new(Object *parent, const char *name);
|
||||||
* @clk: the clock to register the callback into
|
* @clk: the clock to register the callback into
|
||||||
* @cb: the callback function
|
* @cb: the callback function
|
||||||
* @opaque: the argument to the callback
|
* @opaque: the argument to the callback
|
||||||
|
* @events: the events the callback should be called for
|
||||||
|
* (logical OR of ClockEvent enum values)
|
||||||
*
|
*
|
||||||
* Register a callback called on every clock update.
|
* Register a callback called on every clock update.
|
||||||
|
* Note that a clock has only one callback: you cannot register
|
||||||
|
* different callback functions for different events.
|
||||||
*/
|
*/
|
||||||
void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque);
|
void clock_set_callback(Clock *clk, ClockCallback *cb,
|
||||||
|
void *opaque, unsigned int events);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clock_clear_callback:
|
* clock_clear_callback:
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
* @name: the name of the clock (can't be NULL).
|
* @name: the name of the clock (can't be NULL).
|
||||||
* @callback: optional callback to be called on update or NULL.
|
* @callback: optional callback to be called on update or NULL.
|
||||||
* @opaque: argument for the callback
|
* @opaque: argument for the callback
|
||||||
|
* @events: the events the callback should be called for
|
||||||
|
* (logical OR of ClockEvent enum values)
|
||||||
* @returns: a pointer to the newly added clock
|
* @returns: a pointer to the newly added clock
|
||||||
*
|
*
|
||||||
* Add an input clock to device @dev as a clock named @name.
|
* Add an input clock to device @dev as a clock named @name.
|
||||||
|
@ -29,7 +31,8 @@
|
||||||
* The callback will be called with @opaque as opaque parameter.
|
* The callback will be called with @opaque as opaque parameter.
|
||||||
*/
|
*/
|
||||||
Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
|
Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
|
||||||
ClockCallback *callback, void *opaque);
|
ClockCallback *callback, void *opaque,
|
||||||
|
unsigned int events);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qdev_init_clock_out:
|
* qdev_init_clock_out:
|
||||||
|
@ -105,6 +108,7 @@ void qdev_finalize_clocklist(DeviceState *dev);
|
||||||
* @output: indicates whether the clock is input or output
|
* @output: indicates whether the clock is input or output
|
||||||
* @callback: for inputs, optional callback to be called on clock's update
|
* @callback: for inputs, optional callback to be called on clock's update
|
||||||
* with device as opaque
|
* with device as opaque
|
||||||
|
* @callback_events: mask of ClockEvent values for when callback is called
|
||||||
* @offset: optional offset to store the ClockIn or ClockOut pointer in device
|
* @offset: optional offset to store the ClockIn or ClockOut pointer in device
|
||||||
* state structure (0 means unused)
|
* state structure (0 means unused)
|
||||||
*/
|
*/
|
||||||
|
@ -112,6 +116,7 @@ struct ClockPortInitElem {
|
||||||
const char *name;
|
const char *name;
|
||||||
bool is_output;
|
bool is_output;
|
||||||
ClockCallback *callback;
|
ClockCallback *callback;
|
||||||
|
unsigned int callback_events;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,10 +124,11 @@ struct ClockPortInitElem {
|
||||||
(offsetof(devstate, field) + \
|
(offsetof(devstate, field) + \
|
||||||
type_check(Clock *, typeof_field(devstate, field)))
|
type_check(Clock *, typeof_field(devstate, field)))
|
||||||
|
|
||||||
#define QDEV_CLOCK(out_not_in, devstate, field, cb) { \
|
#define QDEV_CLOCK(out_not_in, devstate, field, cb, cbevents) { \
|
||||||
.name = (stringify(field)), \
|
.name = (stringify(field)), \
|
||||||
.is_output = out_not_in, \
|
.is_output = out_not_in, \
|
||||||
.callback = cb, \
|
.callback = cb, \
|
||||||
|
.callback_events = cbevents, \
|
||||||
.offset = clock_offset_value(devstate, field), \
|
.offset = clock_offset_value(devstate, field), \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,14 +139,15 @@ struct ClockPortInitElem {
|
||||||
* @field: a field in @_devstate (must be Clock*)
|
* @field: a field in @_devstate (must be Clock*)
|
||||||
* @callback: (for input only) callback (or NULL) to be called with the device
|
* @callback: (for input only) callback (or NULL) to be called with the device
|
||||||
* state as argument
|
* state as argument
|
||||||
|
* @cbevents: (for input only) ClockEvent mask for when callback is called
|
||||||
*
|
*
|
||||||
* The name of the clock will be derived from @field
|
* The name of the clock will be derived from @field
|
||||||
*/
|
*/
|
||||||
#define QDEV_CLOCK_IN(devstate, field, callback) \
|
#define QDEV_CLOCK_IN(devstate, field, callback, cbevents) \
|
||||||
QDEV_CLOCK(false, devstate, field, callback)
|
QDEV_CLOCK(false, devstate, field, callback, cbevents)
|
||||||
|
|
||||||
#define QDEV_CLOCK_OUT(devstate, field) \
|
#define QDEV_CLOCK_OUT(devstate, field) \
|
||||||
QDEV_CLOCK(true, devstate, field, NULL)
|
QDEV_CLOCK(true, devstate, field, NULL, 0)
|
||||||
|
|
||||||
#define QDEV_CLOCK_END { .name = NULL }
|
#define QDEV_CLOCK_END { .name = NULL }
|
||||||
|
|
||||||
|
|
|
@ -653,7 +653,7 @@ static void mips_cpu_initfn(Object *obj)
|
||||||
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
|
MIPSCPUClass *mcc = MIPS_CPU_GET_CLASS(obj);
|
||||||
|
|
||||||
cpu_set_cpustate_pointers(cpu);
|
cpu_set_cpustate_pointers(cpu);
|
||||||
cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu);
|
cpu->clock = qdev_init_clock_in(DEVICE(obj), "clk-in", NULL, cpu, 0);
|
||||||
env->cpu_model = mcc->cpu_def;
|
env->cpu_model = mcc->cpu_def;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue