mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210310' into staging
target-arm queue: * Add new mps3-an547 board * target/arm: Restrict v7A TCG cpus to TCG accel * Implement a Xilinx CSU DMA model * hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt() # gpg: Signature made Wed 10 Mar 2021 13:56:20 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20210310: (54 commits) hw/timer/renesas_tmr: Fix use of uninitialized data in read_tcnt() hw/timer/renesas_tmr: Prefix constants for CSS values with CSS_ hw/ssi: xilinx_spips: Remove DMA related dead codes from zynqmp_spips hw/ssi: xilinx_spips: Clean up coding convention issues hw/arm: xlnx-zynqmp: Connect a Xilinx CSU DMA module for QSPI hw/arm: xlnx-zynqmp: Clean up coding convention issues hw/dma: Implement a Xilinx CSU DMA model target/arm: Restrict v7A TCG cpus to TCG accel tests/qtest/sse-timer-test: Test counter scaling changes tests/qtest/sse-timer-test: Test the system timer tests/qtest/sse-timer-test: Add simple test of the SSE counter docs/system/arm/mps2.rst: Document the new mps3-an547 board hw/arm/mps2-tz: Add new mps3-an547 board hw/arm/mps2-tz: Make initsvtor0 setting board-specific hw/arm/mps2-tz: Support running APB peripherals on different clock hw/misc/mps2-scc: Implement changes for AN547 hw/misc/mps2-fpgaio: Support AN547 DBGCTRL register hw/misc/mps2-fpgaio: Fold counters subsection into main vmstate hw/arm/mps2-tz: Make UART overflow IRQ board-specific hw/arm/armsse: Add SSE-300 support ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -747,10 +747,17 @@ F: hw/misc/iotkit-sysctl.c
|
||||
F: include/hw/misc/iotkit-sysctl.h
|
||||
F: hw/misc/iotkit-sysinfo.c
|
||||
F: include/hw/misc/iotkit-sysinfo.h
|
||||
F: hw/misc/armsse-cpu-pwrctrl.c
|
||||
F: include/hw/misc/armsse-cpu-pwrctrl.h
|
||||
F: hw/misc/armsse-cpuid.c
|
||||
F: include/hw/misc/armsse-cpuid.h
|
||||
F: hw/misc/armsse-mhu.c
|
||||
F: include/hw/misc/armsse-mhu.h
|
||||
F: hw/timer/sse-counter.c
|
||||
F: include/hw/timer/sse-counter.h
|
||||
F: hw/timer/sse-timer.c
|
||||
F: include/hw/timer/sse-timer.h
|
||||
F: tests/qtest/sse-timer-test.c
|
||||
F: docs/system/arm/mps2.rst
|
||||
|
||||
Musca
|
||||
|
||||
+63
-8
@@ -80,11 +80,12 @@ Adding clocks to a device must be done during the init method of the Device
|
||||
instance.
|
||||
|
||||
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
|
||||
for the callback (this will be explained in a following section).
|
||||
must be used. It takes the name, a callback, an opaque parameter
|
||||
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::
|
||||
|
||||
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");
|
||||
|
||||
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
|
||||
* 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:
|
||||
@@ -124,7 +125,7 @@ output.
|
||||
* the clk_out field of a MyDeviceState structure.
|
||||
*/
|
||||
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_END
|
||||
};
|
||||
@@ -153,6 +154,47 @@ 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
|
||||
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:
|
||||
|
||||
* ``ClockPreUpdate`` : called when the input clock's period is about to
|
||||
update. This is useful if the device needs to do some action for
|
||||
which it needs to know the old value of the clock period. During
|
||||
this callback, Clock API functions like ``clock_get()`` or
|
||||
``clock_ticks_to_ns()`` will use the old period.
|
||||
* ``ClockUpdate`` : called after the input clock's period has changed.
|
||||
During this callback, Clock API functions like ``clock_ticks_to_ns()``
|
||||
will use the new period.
|
||||
|
||||
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
|
||||
-------------------------------
|
||||
|
||||
@@ -231,7 +273,7 @@ object during device instance init. For example:
|
||||
.. code-block:: c
|
||||
|
||||
clk = qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback,
|
||||
dev);
|
||||
dev, ClockUpdate);
|
||||
/* set initial value to 10ns / 100MHz */
|
||||
clock_set_ns(clk, 10);
|
||||
|
||||
@@ -267,11 +309,12 @@ next lowest integer. This implies some inaccuracy due to the rounding,
|
||||
so be cautious about using it in calculations.
|
||||
|
||||
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
|
||||
|
||||
void clock_callback(void *opaque) {
|
||||
void clock_callback(void *opaque, ClockEvent event) {
|
||||
MyDeviceState *s = (MyDeviceState *) opaque;
|
||||
/*
|
||||
* 'opaque' is the argument passed to qdev_init_clock_in();
|
||||
@@ -317,6 +360,18 @@ rather than simply passing it to a QEMUTimer function like
|
||||
``timer_mod_ns()`` then you should be careful to avoid overflow
|
||||
in those calculations, of course.)
|
||||
|
||||
Obtaining tick counts
|
||||
---------------------
|
||||
|
||||
For calculations where you need to know the number of ticks in
|
||||
a given duration, use ``clock_ns_to_ticks()``. This function handles
|
||||
possible non-whole-number-of-nanoseconds periods and avoids
|
||||
potential rounding errors. It will return '0' if the clock is stopped
|
||||
(i.e. it has period zero). If the inputs imply a tick count that
|
||||
overflows a 64-bit value (a very long duration for a clock with a
|
||||
very short period) the output value is truncated, so effectively
|
||||
the 64-bit output wraps around.
|
||||
|
||||
Changing a clock period
|
||||
-----------------------
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
|
||||
=========================================================================================================================================
|
||||
Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
|
||||
=========================================================================================================================================================
|
||||
|
||||
These board models all use Arm M-profile CPUs.
|
||||
|
||||
@@ -27,6 +27,8 @@ QEMU models the following FPGA images:
|
||||
Dual Cortex-M33 as documented in Arm Application Note AN521
|
||||
``mps3-an524``
|
||||
Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
|
||||
``mps3-an547``
|
||||
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
|
||||
|
||||
Differences between QEMU and real hardware:
|
||||
|
||||
|
||||
@@ -238,7 +238,7 @@ static void npcm7xx_adc_init(Object *obj)
|
||||
memory_region_init_io(&s->iomem, obj, &npcm7xx_adc_ops, s,
|
||||
TYPE_NPCM7XX_ADC, 4 * KiB);
|
||||
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) {
|
||||
object_property_add_uint32_ptr(obj, "adci[*]",
|
||||
|
||||
+4
-6
@@ -353,6 +353,7 @@ config XLNX_ZYNQMP_ARM
|
||||
select SSI_M25P80
|
||||
select XILINX_AXI
|
||||
select XILINX_SPIPS
|
||||
select XLNX_CSU_DMA
|
||||
select XLNX_ZYNQMP
|
||||
select XLNX_ZDMA
|
||||
|
||||
@@ -505,6 +506,7 @@ config ARM11MPCORE
|
||||
config ARMSSE
|
||||
bool
|
||||
select ARM_V7M
|
||||
select ARMSSE_CPU_PWRCTRL
|
||||
select ARMSSE_CPUID
|
||||
select ARMSSE_MHU
|
||||
select CMSDK_APB_TIMER
|
||||
@@ -520,9 +522,5 @@ config ARMSSE
|
||||
select TZ_MSC
|
||||
select TZ_PPC
|
||||
select UNIMP
|
||||
|
||||
config ARMSSE_CPUID
|
||||
bool
|
||||
|
||||
config ARMSSE_MHU
|
||||
bool
|
||||
select SSE_COUNTER
|
||||
select SSE_TIMER
|
||||
|
||||
+752
-256
File diff suppressed because it is too large
Load Diff
+164
-4
@@ -17,6 +17,7 @@
|
||||
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
|
||||
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
|
||||
* "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
|
||||
* "mps2-an547" -- Single Cortex-M55 as documented in Application Note AN547
|
||||
*
|
||||
* Links to the TRM for the board itself and to the various Application
|
||||
* Notes which document the FPGA images can be found here:
|
||||
@@ -30,6 +31,8 @@
|
||||
* https://developer.arm.com/documentation/dai0521/latest/
|
||||
* Application Note AN524:
|
||||
* https://developer.arm.com/documentation/dai0524/latest/
|
||||
* Application Note AN547:
|
||||
* https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
|
||||
*
|
||||
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
|
||||
* (ARM ECM0601256) for the details of some of the device layout:
|
||||
@@ -37,6 +40,8 @@
|
||||
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
|
||||
* most of the device layout:
|
||||
* https://developer.arm.com/documentation/101104/latest/
|
||||
* and the AN547 uses the SSE-300, whose layout is in the SSE-300 TRM:
|
||||
* https://developer.arm.com/documentation/101773/latest/
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
@@ -68,13 +73,14 @@
|
||||
#include "hw/qdev-clock.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define MPS2TZ_NUMIRQ_MAX 95
|
||||
#define MPS2TZ_RAM_MAX 4
|
||||
#define MPS2TZ_NUMIRQ_MAX 96
|
||||
#define MPS2TZ_RAM_MAX 5
|
||||
|
||||
typedef enum MPS2TZFPGAType {
|
||||
FPGA_AN505,
|
||||
FPGA_AN521,
|
||||
FPGA_AN524,
|
||||
FPGA_AN547,
|
||||
} MPS2TZFPGAType;
|
||||
|
||||
/*
|
||||
@@ -106,11 +112,15 @@ struct MPS2TZMachineClass {
|
||||
MPS2TZFPGAType fpga_type;
|
||||
uint32_t scc_id;
|
||||
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
|
||||
uint32_t apb_periph_frq; /* APB peripheral frequency in Hz */
|
||||
uint32_t len_oscclk;
|
||||
const uint32_t *oscclk;
|
||||
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
|
||||
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
|
||||
bool fpgaio_has_dbgctrl; /* Does FPGAIO have DBGCTRL register? */
|
||||
int numirq; /* Number of external interrupts */
|
||||
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
|
||||
uint32_t init_svtor; /* init-svtor setting for SSE */
|
||||
const RAMInfo *raminfo;
|
||||
const char *armsse_type;
|
||||
};
|
||||
@@ -149,6 +159,7 @@ struct MPS2TZMachineState {
|
||||
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
|
||||
#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
|
||||
#define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
|
||||
#define TYPE_MPS3TZ_AN547_MACHINE MACHINE_TYPE_NAME("mps3-an547")
|
||||
|
||||
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
|
||||
|
||||
@@ -248,6 +259,49 @@ static const RAMInfo an524_raminfo[] = { {
|
||||
},
|
||||
};
|
||||
|
||||
static const RAMInfo an547_raminfo[] = { {
|
||||
.name = "itcm",
|
||||
.base = 0x00000000,
|
||||
.size = 512 * KiB,
|
||||
.mpc = -1,
|
||||
.mrindex = 0,
|
||||
}, {
|
||||
.name = "sram",
|
||||
.base = 0x01000000,
|
||||
.size = 2 * MiB,
|
||||
.mpc = 0,
|
||||
.mrindex = 1,
|
||||
}, {
|
||||
.name = "dtcm",
|
||||
.base = 0x20000000,
|
||||
.size = 4 * 128 * KiB,
|
||||
.mpc = -1,
|
||||
.mrindex = 2,
|
||||
}, {
|
||||
.name = "sram 2",
|
||||
.base = 0x21000000,
|
||||
.size = 4 * MiB,
|
||||
.mpc = -1,
|
||||
.mrindex = 3,
|
||||
}, {
|
||||
/* We don't model QSPI flash yet; for now expose it as simple ROM */
|
||||
.name = "QSPI",
|
||||
.base = 0x28000000,
|
||||
.size = 8 * MiB,
|
||||
.mpc = 1,
|
||||
.mrindex = 4,
|
||||
.flags = IS_ROM,
|
||||
}, {
|
||||
.name = "DDR",
|
||||
.base = 0x60000000,
|
||||
.size = MPS3_DDR_SIZE,
|
||||
.mpc = 2,
|
||||
.mrindex = -1,
|
||||
}, {
|
||||
.name = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
|
||||
{
|
||||
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
|
||||
@@ -377,7 +431,7 @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
|
||||
|
||||
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
|
||||
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
|
||||
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
|
||||
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->apb_periph_frq);
|
||||
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
|
||||
s = SYS_BUS_DEVICE(uart);
|
||||
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
|
||||
@@ -421,6 +475,7 @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
|
||||
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
|
||||
qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
|
||||
qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
|
||||
qdev_prop_set_bit(DEVICE(fpgaio), "has-dbgctrl", mmc->fpgaio_has_dbgctrl);
|
||||
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
|
||||
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
|
||||
}
|
||||
@@ -696,6 +751,7 @@ static void mps2tz_common_init(MachineState *machine)
|
||||
object_property_set_link(OBJECT(&mms->iotkit), "memory",
|
||||
OBJECT(system_memory), &error_abort);
|
||||
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
|
||||
qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
|
||||
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
|
||||
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
|
||||
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
|
||||
@@ -770,7 +826,7 @@ static void mps2tz_common_init(MachineState *machine)
|
||||
&error_fatal);
|
||||
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
|
||||
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
|
||||
get_sse_irq_in(mms, 47));
|
||||
get_sse_irq_in(mms, mmc->uart_overflow_irq));
|
||||
|
||||
/* Most of the devices in the FPGA are behind Peripheral Protection
|
||||
* Controllers. The required order for initializing things is:
|
||||
@@ -887,6 +943,55 @@ static void mps2tz_common_init(MachineState *machine)
|
||||
},
|
||||
};
|
||||
|
||||
const PPCInfo an547_ppcs[] = { {
|
||||
.name = "apb_ppcexp0",
|
||||
.ports = {
|
||||
{ "ssram-mpc", make_mpc, &mms->mpc[0], 0x57000000, 0x1000 },
|
||||
{ "qspi-mpc", make_mpc, &mms->mpc[1], 0x57001000, 0x1000 },
|
||||
{ "ddr-mpc", make_mpc, &mms->mpc[2], 0x57002000, 0x1000 },
|
||||
},
|
||||
}, {
|
||||
.name = "apb_ppcexp1",
|
||||
.ports = {
|
||||
{ "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000 },
|
||||
{ "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000 },
|
||||
{ "spi0", make_spi, &mms->spi[0], 0x49202000, 0x1000, { 53 } },
|
||||
{ "spi1", make_spi, &mms->spi[1], 0x49203000, 0x1000, { 54 } },
|
||||
{ "spi2", make_spi, &mms->spi[2], 0x49204000, 0x1000, { 55 } },
|
||||
{ "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000 },
|
||||
{ "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000 },
|
||||
{ /* port 7 reserved */ },
|
||||
{ "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000 },
|
||||
},
|
||||
}, {
|
||||
.name = "apb_ppcexp2",
|
||||
.ports = {
|
||||
{ "scc", make_scc, &mms->scc, 0x49300000, 0x1000 },
|
||||
{ "i2s-audio", make_unimp_dev, &mms->i2s_audio, 0x49301000, 0x1000 },
|
||||
{ "fpgaio", make_fpgaio, &mms->fpgaio, 0x49302000, 0x1000 },
|
||||
{ "uart0", make_uart, &mms->uart[0], 0x49303000, 0x1000, { 33, 34, 43 } },
|
||||
{ "uart1", make_uart, &mms->uart[1], 0x49304000, 0x1000, { 35, 36, 44 } },
|
||||
{ "uart2", make_uart, &mms->uart[2], 0x49305000, 0x1000, { 37, 38, 45 } },
|
||||
{ "uart3", make_uart, &mms->uart[3], 0x49306000, 0x1000, { 39, 40, 46 } },
|
||||
{ "uart4", make_uart, &mms->uart[4], 0x49307000, 0x1000, { 41, 42, 47 } },
|
||||
{ "uart5", make_uart, &mms->uart[5], 0x49308000, 0x1000, { 125, 126, 127 } },
|
||||
|
||||
{ /* port 9 reserved */ },
|
||||
{ "clcd", make_unimp_dev, &mms->cldc, 0x4930a000, 0x1000 },
|
||||
{ "rtc", make_rtc, &mms->rtc, 0x4930b000, 0x1000 },
|
||||
},
|
||||
}, {
|
||||
.name = "ahb_ppcexp0",
|
||||
.ports = {
|
||||
{ "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
|
||||
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
|
||||
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
|
||||
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
|
||||
{ "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
switch (mmc->fpga_type) {
|
||||
case FPGA_AN505:
|
||||
case FPGA_AN521:
|
||||
@@ -897,6 +1002,10 @@ static void mps2tz_common_init(MachineState *machine)
|
||||
ppcs = an524_ppcs;
|
||||
num_ppcs = ARRAY_SIZE(an524_ppcs);
|
||||
break;
|
||||
case FPGA_AN547:
|
||||
ppcs = an547_ppcs;
|
||||
num_ppcs = ARRAY_SIZE(an547_ppcs);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@@ -975,6 +1084,11 @@ static void mps2tz_common_init(MachineState *machine)
|
||||
|
||||
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
|
||||
|
||||
if (mmc->fpga_type == FPGA_AN547) {
|
||||
create_unimplemented_device("U55 timing adapter 0", 0x48102000, 0x1000);
|
||||
create_unimplemented_device("U55 timing adapter 1", 0x48103000, 0x1000);
|
||||
}
|
||||
|
||||
create_non_mpc_ram(mms);
|
||||
|
||||
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
|
||||
@@ -1041,11 +1155,15 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
|
||||
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
|
||||
mmc->scc_id = 0x41045050;
|
||||
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
|
||||
mmc->apb_periph_frq = mmc->sysclk_frq;
|
||||
mmc->oscclk = an505_oscclk;
|
||||
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
|
||||
mmc->fpgaio_num_leds = 2;
|
||||
mmc->fpgaio_has_switches = false;
|
||||
mmc->fpgaio_has_dbgctrl = false;
|
||||
mmc->numirq = 92;
|
||||
mmc->uart_overflow_irq = 47;
|
||||
mmc->init_svtor = 0x10000000;
|
||||
mmc->raminfo = an505_raminfo;
|
||||
mmc->armsse_type = TYPE_IOTKIT;
|
||||
mps2tz_set_default_ram_info(mmc);
|
||||
@@ -1064,11 +1182,15 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
|
||||
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
|
||||
mmc->scc_id = 0x41045210;
|
||||
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
|
||||
mmc->apb_periph_frq = mmc->sysclk_frq;
|
||||
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
|
||||
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
|
||||
mmc->fpgaio_num_leds = 2;
|
||||
mmc->fpgaio_has_switches = false;
|
||||
mmc->fpgaio_has_dbgctrl = false;
|
||||
mmc->numirq = 92;
|
||||
mmc->uart_overflow_irq = 47;
|
||||
mmc->init_svtor = 0x10000000;
|
||||
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
|
||||
mmc->armsse_type = TYPE_SSE200;
|
||||
mps2tz_set_default_ram_info(mmc);
|
||||
@@ -1087,16 +1209,47 @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
|
||||
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
|
||||
mmc->scc_id = 0x41045240;
|
||||
mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
|
||||
mmc->apb_periph_frq = mmc->sysclk_frq;
|
||||
mmc->oscclk = an524_oscclk;
|
||||
mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
|
||||
mmc->fpgaio_num_leds = 10;
|
||||
mmc->fpgaio_has_switches = true;
|
||||
mmc->fpgaio_has_dbgctrl = false;
|
||||
mmc->numirq = 95;
|
||||
mmc->uart_overflow_irq = 47;
|
||||
mmc->init_svtor = 0x10000000;
|
||||
mmc->raminfo = an524_raminfo;
|
||||
mmc->armsse_type = TYPE_SSE200;
|
||||
mps2tz_set_default_ram_info(mmc);
|
||||
}
|
||||
|
||||
static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
|
||||
|
||||
mc->desc = "ARM MPS3 with AN547 FPGA image for Cortex-M55";
|
||||
mc->default_cpus = 1;
|
||||
mc->min_cpus = mc->default_cpus;
|
||||
mc->max_cpus = mc->default_cpus;
|
||||
mmc->fpga_type = FPGA_AN547;
|
||||
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m55");
|
||||
mmc->scc_id = 0x41055470;
|
||||
mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
|
||||
mmc->apb_periph_frq = 25 * 1000 * 1000; /* 25MHz */
|
||||
mmc->oscclk = an524_oscclk; /* same as AN524 */
|
||||
mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
|
||||
mmc->fpgaio_num_leds = 10;
|
||||
mmc->fpgaio_has_switches = true;
|
||||
mmc->fpgaio_has_dbgctrl = true;
|
||||
mmc->numirq = 96;
|
||||
mmc->uart_overflow_irq = 48;
|
||||
mmc->init_svtor = 0x00000000;
|
||||
mmc->raminfo = an547_raminfo;
|
||||
mmc->armsse_type = TYPE_SSE300;
|
||||
mps2tz_set_default_ram_info(mmc);
|
||||
}
|
||||
|
||||
static const TypeInfo mps2tz_info = {
|
||||
.name = TYPE_MPS2TZ_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
@@ -1128,12 +1281,19 @@ static const TypeInfo mps3tz_an524_info = {
|
||||
.class_init = mps3tz_an524_class_init,
|
||||
};
|
||||
|
||||
static const TypeInfo mps3tz_an547_info = {
|
||||
.name = TYPE_MPS3TZ_AN547_MACHINE,
|
||||
.parent = TYPE_MPS2TZ_MACHINE,
|
||||
.class_init = mps3tz_an547_class_init,
|
||||
};
|
||||
|
||||
static void mps2tz_machine_init(void)
|
||||
{
|
||||
type_register_static(&mps2tz_info);
|
||||
type_register_static(&mps2tz_an505_info);
|
||||
type_register_static(&mps2tz_an521_info);
|
||||
type_register_static(&mps3tz_an524_info);
|
||||
type_register_static(&mps3tz_an547_info);
|
||||
}
|
||||
|
||||
type_init(mps2tz_machine_init);
|
||||
|
||||
+18
-3
@@ -50,6 +50,7 @@
|
||||
#define QSPI_ADDR 0xff0f0000
|
||||
#define LQSPI_ADDR 0xc0000000
|
||||
#define QSPI_IRQ 15
|
||||
#define QSPI_DMA_ADDR 0xff0f0800
|
||||
|
||||
#define DP_ADDR 0xfd4a0000
|
||||
#define DP_IRQ 113
|
||||
@@ -284,6 +285,8 @@ static void xlnx_zynqmp_init(Object *obj)
|
||||
for (i = 0; i < XLNX_ZYNQMP_NUM_ADMA_CH; i++) {
|
||||
object_initialize_child(obj, "adma[*]", &s->adma[i], TYPE_XLNX_ZDMA);
|
||||
}
|
||||
|
||||
object_initialize_child(obj, "qspi-dma", &s->qspi_dma, TYPE_XLNX_CSU_DMA);
|
||||
}
|
||||
|
||||
static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
||||
@@ -301,11 +304,13 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
ram_size = memory_region_size(s->ddr_ram);
|
||||
|
||||
/* Create the DDR Memory Regions. User friendly checks should happen at
|
||||
/*
|
||||
* Create the DDR Memory Regions. User friendly checks should happen at
|
||||
* the board level
|
||||
*/
|
||||
if (ram_size > XLNX_ZYNQMP_MAX_LOW_RAM_SIZE) {
|
||||
/* The RAM size is above the maximum available for the low DDR.
|
||||
/*
|
||||
* The RAM size is above the maximum available for the low DDR.
|
||||
* Create the high DDR memory region as well.
|
||||
*/
|
||||
assert(ram_size <= XLNX_ZYNQMP_MAX_RAM_SIZE);
|
||||
@@ -521,7 +526,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sdhci[i]);
|
||||
Object *sdhci = OBJECT(&s->sdhci[i]);
|
||||
|
||||
/* Compatible with:
|
||||
/*
|
||||
* Compatible with:
|
||||
* - SD Host Controller Specification Version 3.00
|
||||
* - SDIO Specification Version 3.0
|
||||
* - eMMC Specification Version 4.51
|
||||
@@ -635,6 +641,15 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->adma[i]), 0,
|
||||
gic_spi[adma_ch_intr[i]]);
|
||||
}
|
||||
|
||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->qspi_dma), errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi_dma), 0, QSPI_DMA_ADDR);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi_dma), 0, gic_spi[QSPI_IRQ]);
|
||||
object_property_set_link(OBJECT(&s->qspi), "stream-connected-dma",
|
||||
OBJECT(&s->qspi_dma), errp);
|
||||
}
|
||||
|
||||
static Property xlnx_zynqmp_props[] = {
|
||||
|
||||
@@ -519,7 +519,7 @@ static void cadence_uart_realize(DeviceState *dev, Error **errp)
|
||||
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;
|
||||
|
||||
@@ -537,7 +537,7 @@ static void cadence_uart_init(Object *obj)
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
|
||||
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 */
|
||||
clock_set_hz(s->refclk, UART_DEFAULT_REF_CLK);
|
||||
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
@@ -466,7 +466,7 @@ static void ibex_uart_init(Object *obj)
|
||||
IbexUartState *s = IBEX_UART(obj);
|
||||
|
||||
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);
|
||||
|
||||
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
|
||||
|
||||
+3
-2
@@ -309,7 +309,7 @@ static void pl011_event(void *opaque, QEMUChrEvent event)
|
||||
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);
|
||||
|
||||
@@ -378,7 +378,8 @@ static void pl011_init(Object *obj)
|
||||
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->ifl = 0x12;
|
||||
|
||||
+20
-4
@@ -39,15 +39,17 @@ Clock *clock_new(Object *parent, const char *name)
|
||||
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_opaque = opaque;
|
||||
clk->callback_events = events;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -62,18 +64,32 @@ bool clock_set(Clock *clk, uint64_t period)
|
||||
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)
|
||||
{
|
||||
Clock *child;
|
||||
|
||||
QLIST_FOREACH(child, &clk->children, sibling) {
|
||||
if (child->period != clk->period) {
|
||||
if (call_callbacks) {
|
||||
clock_call_callback(child, ClockPreUpdate);
|
||||
}
|
||||
child->period = clk->period;
|
||||
trace_clock_update(CLOCK_PATH(child), CLOCK_PATH(clk),
|
||||
CLOCK_PERIOD_TO_HZ(clk->period),
|
||||
call_callbacks);
|
||||
if (call_callbacks && child->callback) {
|
||||
child->callback(child->callback_opaque);
|
||||
if (call_callbacks) {
|
||||
clock_call_callback(child, ClockUpdate);
|
||||
}
|
||||
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,
|
||||
ClockCallback *callback, void *opaque)
|
||||
ClockCallback *callback, void *opaque,
|
||||
unsigned int events)
|
||||
{
|
||||
NamedClockList *ncl;
|
||||
|
||||
@@ -120,7 +121,7 @@ Clock *qdev_init_clock_in(DeviceState *dev, const char *name,
|
||||
ncl = qdev_init_clocklist(dev, name, false, NULL);
|
||||
|
||||
if (callback) {
|
||||
clock_set_callback(ncl->clock, callback, opaque);
|
||||
clock_set_callback(ncl->clock, callback, opaque, events);
|
||||
}
|
||||
return ncl->clock;
|
||||
}
|
||||
@@ -137,7 +138,8 @@ void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks)
|
||||
if (elem->is_output) {
|
||||
*clkp = qdev_init_clock_out(dev, elem->name);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,3 +26,7 @@ config STP2000
|
||||
|
||||
config SIFIVE_PDMA
|
||||
bool
|
||||
|
||||
config XLNX_CSU_DMA
|
||||
bool
|
||||
select REGISTER
|
||||
|
||||
@@ -14,3 +14,4 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_dma.c', 'soc_dma.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_dma.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_dma.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_SIFIVE_PDMA', if_true: files('sifive_pdma.c'))
|
||||
softmmu_ss.add(when: 'CONFIG_XLNX_CSU_DMA', if_true: files('xlnx_csu_dma.c'))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -39,7 +39,7 @@ static void mips_cps_init(Object *obj)
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(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
|
||||
* constraints for the base address of CPC and GIC.
|
||||
|
||||
@@ -2,6 +2,15 @@ config APPLESMC
|
||||
bool
|
||||
depends on ISA_BUS
|
||||
|
||||
config ARMSSE_CPUID
|
||||
bool
|
||||
|
||||
config ARMSSE_MHU
|
||||
bool
|
||||
|
||||
config ARMSSE_CPU_PWRCTRL
|
||||
bool
|
||||
|
||||
config MAX111X
|
||||
bool
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Arm SSE CPU PWRCTRL register block
|
||||
*
|
||||
* Copyright (c) 2021 Linaro Limited
|
||||
* Written by Peter Maydell
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a model of the "CPU<N>_PWRCTRL block" which is part of the
|
||||
* Arm Corstone SSE-300 Example Subsystem and documented in
|
||||
* https://developer.arm.com/documentation/101773/0000
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/module.h"
|
||||
#include "trace.h"
|
||||
#include "qapi/error.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/registerfields.h"
|
||||
#include "hw/misc/armsse-cpu-pwrctrl.h"
|
||||
|
||||
REG32(CPUPWRCFG, 0x0)
|
||||
REG32(PID4, 0xfd0)
|
||||
REG32(PID5, 0xfd4)
|
||||
REG32(PID6, 0xfd8)
|
||||
REG32(PID7, 0xfdc)
|
||||
REG32(PID0, 0xfe0)
|
||||
REG32(PID1, 0xfe4)
|
||||
REG32(PID2, 0xfe8)
|
||||
REG32(PID3, 0xfec)
|
||||
REG32(CID0, 0xff0)
|
||||
REG32(CID1, 0xff4)
|
||||
REG32(CID2, 0xff8)
|
||||
REG32(CID3, 0xffc)
|
||||
|
||||
/* PID/CID values */
|
||||
static const int cpu_pwrctrl_id[] = {
|
||||
0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
|
||||
0x5a, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
|
||||
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
|
||||
};
|
||||
|
||||
static uint64_t pwrctrl_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
|
||||
uint64_t r;
|
||||
|
||||
switch (offset) {
|
||||
case A_CPUPWRCFG:
|
||||
r = s->cpupwrcfg;
|
||||
break;
|
||||
case A_PID4 ... A_CID3:
|
||||
r = cpu_pwrctrl_id[(offset - A_PID4) / 4];
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"SSE CPU_PWRCTRL read: bad offset %x\n", (int)offset);
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
trace_armsse_cpu_pwrctrl_read(offset, r, size);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void pwrctrl_write(void *opaque, hwaddr offset,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
|
||||
|
||||
trace_armsse_cpu_pwrctrl_write(offset, value, size);
|
||||
|
||||
switch (offset) {
|
||||
case A_CPUPWRCFG:
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"SSE CPU_PWRCTRL: CPUPWRCFG unimplemented\n");
|
||||
s->cpupwrcfg = value;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"SSE CPU_PWRCTRL write: bad offset 0x%x\n", (int)offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const MemoryRegionOps pwrctrl_ops = {
|
||||
.read = pwrctrl_read,
|
||||
.write = pwrctrl_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.impl.min_access_size = 4,
|
||||
.impl.max_access_size = 4,
|
||||
.valid.min_access_size = 4,
|
||||
.valid.max_access_size = 4,
|
||||
};
|
||||
|
||||
static void pwrctrl_reset(DeviceState *dev)
|
||||
{
|
||||
ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(dev);
|
||||
|
||||
s->cpupwrcfg = 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription pwrctrl_vmstate = {
|
||||
.name = "armsse-cpu-pwrctrl",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32(cpupwrcfg, ARMSSECPUPwrCtrl),
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
};
|
||||
|
||||
static void pwrctrl_init(Object *obj)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||
ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(obj);
|
||||
|
||||
memory_region_init_io(&s->iomem, obj, &pwrctrl_ops,
|
||||
s, "armsse-cpu-pwrctrl", 0x1000);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
static void pwrctrl_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
dc->reset = pwrctrl_reset;
|
||||
dc->vmsd = &pwrctrl_vmstate;
|
||||
}
|
||||
|
||||
static const TypeInfo pwrctrl_info = {
|
||||
.name = TYPE_ARMSSE_CPU_PWRCTRL,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(ARMSSECPUPwrCtrl),
|
||||
.instance_init = pwrctrl_init,
|
||||
.class_init = pwrctrl_class_init,
|
||||
};
|
||||
|
||||
static void pwrctrl_register_types(void)
|
||||
{
|
||||
type_register_static(&pwrctrl_info);
|
||||
}
|
||||
|
||||
type_init(pwrctrl_register_types);
|
||||
@@ -107,7 +107,7 @@ static void pll_update(CprmanPllState *pll)
|
||||
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));
|
||||
}
|
||||
@@ -116,7 +116,8 @@ static void pll_init(Object *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");
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
@@ -219,7 +220,8 @@ static void pll_channel_init(Object *obj)
|
||||
CprmanPllChannelState *s = CPRMAN_PLL_CHANNEL(obj);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -303,7 +305,7 @@ static void clock_mux_update(CprmanClockMuxState *mux)
|
||||
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 *s = *backref;
|
||||
@@ -335,7 +337,8 @@ static void clock_mux_init(Object *obj)
|
||||
s->backref[i] = s;
|
||||
s->srcs[i] = qdev_init_clock_in(DEVICE(s), name,
|
||||
clock_mux_src_update,
|
||||
&s->backref[i]);
|
||||
&s->backref[i],
|
||||
ClockUpdate);
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
@@ -380,7 +383,7 @@ static void dsi0hsck_mux_update(CprmanDsi0HsckMuxState *s)
|
||||
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));
|
||||
}
|
||||
@@ -390,8 +393,10 @@ static void dsi0hsck_mux_init(Object *obj)
|
||||
CprmanDsi0HsckMuxState *s = CPRMAN_DSI0HSCK_MUX(obj);
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
|
||||
s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update, s);
|
||||
s->plld_in = qdev_init_clock_in(dev, "plld-in", dsi0hsck_mux_in_update, s);
|
||||
s->plla_in = qdev_init_clock_in(dev, "plla-in", dsi0hsck_mux_in_update,
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user