Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210129-1' into staging

target-arm queue:
 * Implement ID_PFR2
 * Conditionalize DBGDIDR
 * rename xlnx-zcu102.canbusN properties
 * provide powerdown/reset mechanism for secure firmware on 'virt' board
 * hw/misc: Fix arith overflow in NPCM7XX PWM module
 * target/arm: Replace magic value by MMU_DATA_LOAD definition
 * configure: fix preadv errors on Catalina macOS with new XCode
 * Various configure and other cleanups in preparation for iOS support
 * hvf: Add hypervisor entitlement to output binaries (needed for Big Sur)
 * Implement pvpanic-pci device
 * Convert the CMSDK timer devices to the Clock framework

# gpg: Signature made Fri 29 Jan 2021 16:08:02 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-20210129-1: (46 commits)
  hw/arm/stellaris: Remove board-creation reset of STELLARIS_SYS
  arm: Remove frq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
  arm: Don't set freq properties on CMSDK timer, dualtimer, watchdog, ARMSSE
  hw/arm/armsse: Use Clock to set system_clock_scale
  tests/qtest/cmsdk-apb-watchdog-test: Test clock changes
  hw/watchdog/cmsdk-apb-watchdog: Convert to use Clock input
  hw/timer/cmsdk-apb-dualtimer: Convert to use Clock input
  hw/timer/cmsdk-apb-timer: Convert to use Clock input
  hw/arm/stellaris: Create Clock input for watchdog
  hw/arm/stellaris: Convert SSYS to QOM device
  hw/arm/musca: Create and connect ARMSSE Clocks
  hw/arm/mps2-tz: Create and connect ARMSSE Clocks
  hw/arm/mps2: Create and connect SYSCLK Clock
  hw/arm/mps2: Inline CMSDK_APB_TIMER creation
  hw/arm/armsse: Wire up clocks
  hw/arm/armsse: Rename "MAINCLK" property to "MAINCLK_FRQ"
  hw/watchdog/cmsdk-apb-watchdog: Add Clock input
  hw/timer/cmsdk-apb-dualtimer: Add Clock input
  hw/timer/cmsdk-apb-timer: Add Clock input
  hw/timer/cmsdk-apb-timer: Rename CMSDKAPBTIMER struct to CMSDKAPBTimer
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2021-01-29 17:22:53 +00:00
52 changed files with 1436 additions and 319 deletions
+3
View File
@@ -581,12 +581,15 @@ F: include/hw/rtc/pl031.h
F: include/hw/arm/primecell.h
F: hw/timer/cmsdk-apb-timer.c
F: include/hw/timer/cmsdk-apb-timer.h
F: tests/qtest/cmsdk-apb-timer-test.c
F: hw/timer/cmsdk-apb-dualtimer.c
F: include/hw/timer/cmsdk-apb-dualtimer.h
F: tests/qtest/cmsdk-apb-dualtimer-test.c
F: hw/char/cmsdk-apb-uart.c
F: include/hw/char/cmsdk-apb-uart.h
F: hw/watchdog/cmsdk-apb-watchdog.c
F: include/hw/watchdog/cmsdk-apb-watchdog.h
F: tests/qtest/cmsdk-apb-watchdog-test.c
F: hw/misc/tz-ppc.c
F: include/hw/misc/tz-ppc.h
F: hw/misc/tz-mpc.c
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.hypervisor</key>
<true/>
</dict>
</plist>
Vendored
+45 -33
View File
@@ -238,6 +238,7 @@ cpu=""
iasl="iasl"
interp_prefix="/usr/gnemul/qemu-%M"
static="no"
cross_compile="no"
cross_prefix=""
audio_drv_list=""
block_drv_rw_whitelist=""
@@ -318,6 +319,7 @@ fdt="auto"
netmap="no"
sdl="auto"
sdl_image="auto"
coreaudio="auto"
virtiofsd="auto"
virtfs="auto"
libudev="auto"
@@ -469,6 +471,7 @@ for opt do
optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
case "$opt" in
--cross-prefix=*) cross_prefix="$optarg"
cross_compile="yes"
;;
--cc=*) CC="$optarg"
;;
@@ -622,13 +625,6 @@ fi
# the correct CPU with the --cpu option.
case $targetos in
Darwin)
# on Leopard most of the system is 32-bit, so we have to ask the kernel if we can
# run 64-bit userspace code.
# If the user didn't specify a CPU explicitly and the kernel says this is
# 64 bit hw, then assume x86_64. Otherwise fall through to the usual detection code.
if test -z "$cpu" && test "$(sysctl -n hw.optional.x86_64)" = "1"; then
cpu="x86_64"
fi
HOST_DSOSUF=".dylib"
;;
SunOS)
@@ -772,13 +768,8 @@ OpenBSD)
Darwin)
bsd="yes"
darwin="yes"
if [ "$cpu" = "x86_64" ] ; then
QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
fi
audio_drv_list="coreaudio try-sdl"
audio_drv_list="try-coreaudio try-sdl"
audio_possible_drivers="coreaudio sdl"
QEMU_LDFLAGS="-framework CoreFoundation -framework IOKit $QEMU_LDFLAGS"
# Disable attempts to use ObjectiveC features in os/object.h since they
# won't work when we're compiling with gcc as a C compiler.
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
@@ -1691,7 +1682,7 @@ $(echo Deprecated targets: $deprecated_targets_list | \
--target-list-exclude=LIST exclude a set of targets from the default target-list
Advanced options (experts only):
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
--cross-prefix=PREFIX use PREFIX for compile tools, PREFIX can be blank [$cross_prefix]
--cc=CC use C compiler CC [$cc]
--iasl=IASL use ACPI compiler IASL [$iasl]
--host-cc=CC use C compiler CC [$host_cc] for code run at
@@ -3145,6 +3136,24 @@ EOF
fi
fi
##########################################
# detect CoreAudio
if test "$coreaudio" != "no" ; then
coreaudio_libs="-framework CoreAudio"
cat > $TMPC << EOF
#include <CoreAudio/CoreAudio.h>
int main(void)
{
return (int)AudioGetCurrentHostTime();
}
EOF
if compile_prog "" "$coreaudio_libs" ; then
coreaudio=yes
else
coreaudio=no
fi
fi
##########################################
# Sound support libraries probe
@@ -3201,8 +3210,20 @@ for drv in $audio_drv_list; do
fi
;;
coreaudio)
coreaudio | try-coreaudio)
if test "$coreaudio" = "no"; then
if test "$drv" = "try-coreaudio"; then
audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio//')
else
error_exit "$drv check failed" \
"Make sure to have the $drv is available."
fi
else
coreaudio_libs="-framework CoreAudio"
if test "$drv" = "try-coreaudio"; then
audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-coreaudio/coreaudio/')
fi
fi
;;
dsound)
@@ -3531,19 +3552,6 @@ if compile_prog "" "" ; then
iovec=yes
fi
##########################################
# preadv probe
cat > $TMPC <<EOF
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
int main(void) { return preadv(0, 0, 0, 0); }
EOF
preadv=no
if compile_prog "" "" ; then
preadv=yes
fi
##########################################
# fdt probe
@@ -5748,9 +5756,6 @@ fi
if test "$iovec" = "yes" ; then
echo "CONFIG_IOVEC=y" >> $config_host_mak
fi
if test "$preadv" = "yes" ; then
echo "CONFIG_PREADV=y" >> $config_host_mak
fi
if test "$membarrier" = "yes" ; then
echo "CONFIG_MEMBARRIER=y" >> $config_host_mak
fi
@@ -6297,6 +6302,7 @@ echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
echo "[binaries]" >> $cross
echo "c = [$(meson_quote $cc)]" >> $cross
test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
echo "ar = [$(meson_quote $ar)]" >> $cross
echo "nm = [$(meson_quote $nm)]" >> $cross
echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
@@ -6306,7 +6312,7 @@ if has $sdl2_config; then
fi
echo "strip = [$(meson_quote $strip)]" >> $cross
echo "windres = [$(meson_quote $windres)]" >> $cross
if test -n "$cross_prefix"; then
if test "$cross_compile" = "yes"; then
cross_arg="--cross-file config-meson.cross"
echo "[host_machine]" >> $cross
if test "$mingw32" = "yes" ; then
@@ -6315,10 +6321,16 @@ if test -n "$cross_prefix"; then
if test "$linux" = "yes" ; then
echo "system = 'linux'" >> $cross
fi
if test "$darwin" = "yes" ; then
echo "system = 'darwin'" >> $cross
fi
case "$ARCH" in
i386|x86_64)
i386)
echo "cpu_family = 'x86'" >> $cross
;;
x86_64)
echo "cpu_family = 'x86_64'" >> $cross
;;
ppc64le)
echo "cpu_family = 'ppc64'" >> $cross
;;
+16
View File
@@ -235,6 +235,22 @@ object during device instance init. For example:
/* set initial value to 10ns / 100MHz */
clock_set_ns(clk, 10);
To enforce that the clock is wired up by the board code, you can
call ``clock_has_source()`` in your device's realize method:
.. code-block:: c
if (!clock_has_source(s->clk)) {
error_setg(errp, "MyDevice: clk input must be connected");
return;
}
Note that this only checks that the clock has been wired up; it is
still possible that the output clock connected to it is disabled
or has not yet been configured, in which case the period will be
zero. You should use the clock callback to find out when the clock
period changes.
Fetching clock frequency/period
-------------------------------
+1
View File
@@ -64,6 +64,7 @@ PCI devices (other than virtio):
1b36:000d PCI xhci usb host adapter
1b36:000f mdpy (mdev sample device), linux/samples/vfio-mdev/mdpy.c
1b36:0010 PCIe NVMe device (-device nvme)
1b36:0011 PCI PVPanic device (-device pvpanic-pci)
All these devices are documented in docs/specs.
+12 -1
View File
@@ -1,7 +1,7 @@
PVPANIC DEVICE
==============
pvpanic device is a simulated ISA device, through which a guest panic
pvpanic device is a simulated device, through which a guest panic
event is sent to qemu, and a QMP event is generated. This allows
management apps (e.g. libvirt) to be notified and respond to the event.
@@ -9,6 +9,9 @@ The management app has the option of waiting for GUEST_PANICKED events,
and/or polling for guest-panicked RunState, to learn when the pvpanic
device has fired a panic event.
The pvpanic device can be implemented as an ISA device (using IOPORT) or as a
PCI device.
ISA Interface
-------------
@@ -24,6 +27,14 @@ bit 1: a guest panic has happened and will be handled by the guest;
the host should record it or report it, but should not affect
the execution of the guest.
PCI Interface
-------------
The PCI interface is similar to the ISA interface except that it uses an MMIO
address space provided by its BAR0, 1 byte long. Any machine with a PCI bus
can enable a pvpanic device by adding '-device pvpanic-pci' to the command
line.
ACPI Interface
--------------
+2
View File
@@ -43,6 +43,8 @@ The virt board supports:
- Secure-World-only devices if the CPU has TrustZone:
- A second PL011 UART
- A second PL061 GPIO controller, with GPIO lines for triggering
a system reset or system poweroff
- A secure flash memory
- 16MB of secure RAM
+1
View File
@@ -17,6 +17,7 @@ config ARM_VIRT
select PL011 # UART
select PL031 # RTC
select PL061 # GPIO
select GPIO_PWR
select PLATFORM_BUS
select SMBIOS
select VIRTIO_MMIO
+33 -15
View File
@@ -21,6 +21,7 @@
#include "hw/arm/armsse.h"
#include "hw/arm/boot.h"
#include "hw/irq.h"
#include "hw/qdev-clock.h"
/* Format of the System Information block SYS_CONFIG register */
typedef enum SysConfigFormat {
@@ -47,7 +48,6 @@ static Property iotkit_properties[] = {
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
MemoryRegion *),
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
@@ -59,7 +59,6 @@ static Property armsse_properties[] = {
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
MemoryRegion *),
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
@@ -231,6 +230,16 @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
}
static void armsse_mainclk_update(void *opaque)
{
ARMSSE *s = ARM_SSE(opaque);
/*
* Set system_clock_scale from our Clock input; this is what
* controls the tick rate of the CPU SysTick timer.
*/
system_clock_scale = clock_ticks_to_ns(s->mainclk, 1);
}
static void armsse_init(Object *obj)
{
ARMSSE *s = ARM_SSE(obj);
@@ -241,6 +250,10 @@ static void armsse_init(Object *obj)
assert(info->sram_banks <= MAX_SRAM_BANKS);
assert(info->num_cpus <= SSE_MAX_CPUS);
s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK",
armsse_mainclk_update, s);
s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL);
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
for (i = 0; i < info->num_cpus; i++) {
@@ -447,9 +460,11 @@ static void armsse_realize(DeviceState *dev, Error **errp)
return;
}
if (!s->mainclk_frq) {
error_setg(errp, "MAINCLK property was not set");
return;
if (!clock_has_source(s->mainclk)) {
error_setg(errp, "MAINCLK clock was not connected");
}
if (!clock_has_source(s->s32kclk)) {
error_setg(errp, "S32KCLK clock was not connected");
}
assert(info->num_cpus <= SSE_MAX_CPUS);
@@ -710,7 +725,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
* it to the appropriate PPC port; then we can realize the PPC and
* map its upstream ends to the right place in the container.
*/
qdev_prop_set_uint32(DEVICE(&s->timer0), "pclk-frq", s->mainclk_frq);
qdev_connect_clock_in(DEVICE(&s->timer0), "pclk", s->mainclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer0), errp)) {
return;
}
@@ -720,7 +735,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
object_property_set_link(OBJECT(&s->apb_ppc0), "port[0]", OBJECT(mr),
&error_abort);
qdev_prop_set_uint32(DEVICE(&s->timer1), "pclk-frq", s->mainclk_frq);
qdev_connect_clock_in(DEVICE(&s->timer1), "pclk", s->mainclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer1), errp)) {
return;
}
@@ -730,7 +745,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
object_property_set_link(OBJECT(&s->apb_ppc0), "port[1]", OBJECT(mr),
&error_abort);
qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq);
qdev_connect_clock_in(DEVICE(&s->dualtimer), "TIMCLK", s->mainclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->dualtimer), errp)) {
return;
}
@@ -888,7 +903,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
/* Devices behind APB PPC1:
* 0x4002f000: S32K timer
*/
qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK);
qdev_connect_clock_in(DEVICE(&s->s32ktimer), "pclk", s->s32kclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32ktimer), errp)) {
return;
}
@@ -981,7 +996,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK);
qdev_connect_clock_in(DEVICE(&s->s32kwatchdog), "WDOGCLK", s->s32kclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->s32kwatchdog), errp)) {
return;
}
@@ -991,7 +1006,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
/* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
qdev_connect_clock_in(DEVICE(&s->nswatchdog), "WDOGCLK", s->mainclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->nswatchdog), errp)) {
return;
}
@@ -999,7 +1014,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
armsse_get_common_irq_in(s, 1));
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
qdev_connect_clock_in(DEVICE(&s->swatchdog), "WDOGCLK", s->mainclk);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->swatchdog), errp)) {
return;
}
@@ -1104,7 +1119,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
*/
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
/* Set initial system_clock_scale from MAINCLK */
armsse_mainclk_update(s);
}
static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
@@ -1127,9 +1143,11 @@ static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
static const VMStateDescription armsse_vmstate = {
.name = "iotkit",
.version_id = 1,
.minimum_version_id = 1,
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_CLOCK(mainclk, ARMSSE),
VMSTATE_CLOCK(s32kclk, ARMSSE),
VMSTATE_UINT32(nsccfg, ARMSSE),
VMSTATE_END_OF_LIST()
}
+13 -1
View File
@@ -62,6 +62,7 @@
#include "hw/net/lan9118.h"
#include "net/net.h"
#include "hw/core/split-irq.h"
#include "hw/qdev-clock.h"
#include "qom/object.h"
#define MPS2TZ_NUMIRQ 92
@@ -100,6 +101,8 @@ struct MPS2TZMachineState {
qemu_or_irq uart_irq_orgate;
DeviceState *lan9118;
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
Clock *sysclk;
Clock *s32kclk;
};
#define TYPE_MPS2TZ_MACHINE "mps2tz"
@@ -110,6 +113,8 @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
/* Main SYSCLK frequency in Hz */
#define SYSCLK_FRQ 20000000
/* Slow 32Khz S32KCLK frequency in Hz */
#define S32KCLK_FRQ (32 * 1000)
/* Create an alias of an entire original MemoryRegion @orig
* located at @base in the memory map.
@@ -396,13 +401,20 @@ static void mps2tz_common_init(MachineState *machine)
exit(EXIT_FAILURE);
}
/* These clocks don't need migration because they are fixed-frequency */
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
clock_set_hz(mms->sysclk, SYSCLK_FRQ);
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
object_initialize_child(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
mmc->armsse_type);
iotkitdev = DEVICE(&mms->iotkit);
object_property_set_link(OBJECT(&mms->iotkit), "memory",
OBJECT(system_memory), &error_abort);
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
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);
/*
+24 -4
View File
@@ -46,6 +46,7 @@
#include "hw/net/lan9118.h"
#include "net/net.h"
#include "hw/watchdog/cmsdk-apb-watchdog.h"
#include "hw/qdev-clock.h"
#include "qom/object.h"
typedef enum MPS2FPGAType {
@@ -83,6 +84,8 @@ struct MPS2MachineState {
/* CMSDK APB subsystem */
CMSDKAPBDualTimer dualtimer;
CMSDKAPBWatchdog watchdog;
CMSDKAPBTimer timer[2];
Clock *sysclk;
};
#define TYPE_MPS2_MACHINE "mps2"
@@ -139,6 +142,10 @@ static void mps2_common_init(MachineState *machine)
exit(EXIT_FAILURE);
}
/* This clock doesn't need migration because it is fixed-frequency */
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
clock_set_hz(mms->sysclk, SYSCLK_FRQ);
/* The FPGA images have an odd combination of different RAMs,
* because in hardware they are different implementations and
* connected to different buses, giving varying performance/size
@@ -330,18 +337,31 @@ static void mps2_common_init(MachineState *machine)
}
/* CMSDK APB subsystem */
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
for (i = 0; i < ARRAY_SIZE(mms->timer); i++) {
g_autofree char *name = g_strdup_printf("timer%d", i);
hwaddr base = 0x40000000 + i * 0x1000;
int irqno = 8 + i;
SysBusDevice *sbd;
object_initialize_child(OBJECT(mms), name, &mms->timer[i],
TYPE_CMSDK_APB_TIMER);
sbd = SYS_BUS_DEVICE(&mms->timer[i]);
qdev_connect_clock_in(DEVICE(&mms->timer[i]), "pclk", mms->sysclk);
sysbus_realize_and_unref(sbd, &error_fatal);
sysbus_mmio_map(sbd, 0, base);
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(armv7m, irqno));
}
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
TYPE_CMSDK_APB_DUALTIMER);
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->sysclk);
sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
qdev_get_gpio_in(armv7m, 10));
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
TYPE_CMSDK_APB_WATCHDOG);
qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->sysclk);
sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
qdev_get_gpio_in_named(armv7m, "NMI", 0));
+12 -1
View File
@@ -33,6 +33,7 @@
#include "hw/misc/tz-ppc.h"
#include "hw/misc/unimp.h"
#include "hw/rtc/pl031.h"
#include "hw/qdev-clock.h"
#include "qom/object.h"
#define MUSCA_NUMIRQ_MAX 96
@@ -82,6 +83,8 @@ struct MuscaMachineState {
UnimplementedDeviceState sdio;
UnimplementedDeviceState gpio;
UnimplementedDeviceState cryptoisland;
Clock *sysclk;
Clock *s32kclk;
};
#define TYPE_MUSCA_MACHINE "musca"
@@ -96,6 +99,8 @@ OBJECT_DECLARE_TYPE(MuscaMachineState, MuscaMachineClass, MUSCA_MACHINE)
* don't model that in our SSE-200 model yet.
*/
#define SYSCLK_FRQ 40000000
/* Slow 32Khz S32KCLK frequency in Hz */
#define S32KCLK_FRQ (32 * 1000)
static qemu_irq get_sse_irq_in(MuscaMachineState *mms, int irqno)
{
@@ -367,6 +372,11 @@ static void musca_init(MachineState *machine)
exit(1);
}
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
clock_set_hz(mms->sysclk, SYSCLK_FRQ);
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
object_initialize_child(OBJECT(machine), "sse-200", &mms->sse,
TYPE_SSE200);
ssedev = DEVICE(&mms->sse);
@@ -375,7 +385,8 @@ static void musca_init(MachineState *machine)
qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
qdev_connect_clock_in(ssedev, "MAINCLK", mms->sysclk);
qdev_connect_clock_in(ssedev, "S32KCLK", mms->s32kclk);
/*
* Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
* CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
+129 -41
View File
@@ -26,6 +26,7 @@
#include "hw/watchdog/cmsdk-apb-watchdog.h"
#include "migration/vmstate.h"
#include "hw/misc/unimp.h"
#include "hw/qdev-clock.h"
#include "cpu.h"
#include "qom/object.h"
@@ -357,7 +358,12 @@ static void stellaris_gptm_realize(DeviceState *dev, Error **errp)
/* System controller. */
typedef struct {
#define TYPE_STELLARIS_SYS "stellaris-sys"
OBJECT_DECLARE_SIMPLE_TYPE(ssys_state, STELLARIS_SYS)
struct ssys_state {
SysBusDevice parent_obj;
MemoryRegion iomem;
uint32_t pborctl;
uint32_t ldopctl;
@@ -371,11 +377,19 @@ typedef struct {
uint32_t dcgc[3];
uint32_t clkvclr;
uint32_t ldoarst;
qemu_irq irq;
Clock *sysclk;
/* Properties (all read-only registers) */
uint32_t user0;
uint32_t user1;
qemu_irq irq;
stellaris_board_info *board;
} ssys_state;
uint32_t did0;
uint32_t did1;
uint32_t dc0;
uint32_t dc1;
uint32_t dc2;
uint32_t dc3;
uint32_t dc4;
};
static void ssys_update(ssys_state *s)
{
@@ -430,7 +444,7 @@ static uint32_t pllcfg_fury[16] = {
static int ssys_board_class(const ssys_state *s)
{
uint32_t did0 = s->board->did0;
uint32_t did0 = s->did0;
switch (did0 & DID0_VER_MASK) {
case DID0_VER_0:
return DID0_CLASS_SANDSTORM;
@@ -456,19 +470,19 @@ static uint64_t ssys_read(void *opaque, hwaddr offset,
switch (offset) {
case 0x000: /* DID0 */
return s->board->did0;
return s->did0;
case 0x004: /* DID1 */
return s->board->did1;
return s->did1;
case 0x008: /* DC0 */
return s->board->dc0;
return s->dc0;
case 0x010: /* DC1 */
return s->board->dc1;
return s->dc1;
case 0x014: /* DC2 */
return s->board->dc2;
return s->dc2;
case 0x018: /* DC3 */
return s->board->dc3;
return s->dc3;
case 0x01c: /* DC4 */
return s->board->dc4;
return s->dc4;
case 0x030: /* PBORCTL */
return s->pborctl;
case 0x034: /* LDOPCTL */
@@ -543,15 +557,26 @@ static bool ssys_use_rcc2(ssys_state *s)
}
/*
* Caculate the sys. clock period in ms.
* Calculate the system clock period. We only want to propagate
* this change to the rest of the system if we're not being called
* from migration post-load.
*/
static void ssys_calculate_system_clock(ssys_state *s)
static void ssys_calculate_system_clock(ssys_state *s, bool propagate_clock)
{
/*
* SYSDIV field specifies divisor: 0 == /1, 1 == /2, etc. Input
* clock is 200MHz, which is a period of 5 ns. Dividing the clock
* frequency by X is the same as multiplying the period by X.
*/
if (ssys_use_rcc2(s)) {
system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
} else {
system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
}
clock_set_ns(s->sysclk, system_clock_scale);
if (propagate_clock) {
clock_propagate(s->sysclk);
}
}
static void ssys_write(void *opaque, hwaddr offset,
@@ -586,7 +611,7 @@ static void ssys_write(void *opaque, hwaddr offset,
s->int_status |= (1 << 6);
}
s->rcc = value;
ssys_calculate_system_clock(s);
ssys_calculate_system_clock(s, true);
break;
case 0x070: /* RCC2 */
if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
@@ -598,7 +623,7 @@ static void ssys_write(void *opaque, hwaddr offset,
s->int_status |= (1 << 6);
}
s->rcc2 = value;
ssys_calculate_system_clock(s);
ssys_calculate_system_clock(s, true);
break;
case 0x100: /* RCGC0 */
s->rcgc[0] = value;
@@ -646,9 +671,9 @@ static const MemoryRegionOps ssys_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void ssys_reset(void *opaque)
static void stellaris_sys_reset_enter(Object *obj, ResetType type)
{
ssys_state *s = (ssys_state *)opaque;
ssys_state *s = STELLARIS_SYS(obj);
s->pborctl = 0x7ffd;
s->rcc = 0x078e3ac0;
@@ -661,14 +686,25 @@ static void ssys_reset(void *opaque)
s->rcgc[0] = 1;
s->scgc[0] = 1;
s->dcgc[0] = 1;
ssys_calculate_system_clock(s);
}
static void stellaris_sys_reset_hold(Object *obj)
{
ssys_state *s = STELLARIS_SYS(obj);
/* OK to propagate clocks from the hold phase */
ssys_calculate_system_clock(s, true);
}
static void stellaris_sys_reset_exit(Object *obj)
{
}
static int stellaris_sys_post_load(void *opaque, int version_id)
{
ssys_state *s = opaque;
ssys_calculate_system_clock(s);
ssys_calculate_system_clock(s, false);
return 0;
}
@@ -691,30 +727,61 @@ static const VMStateDescription vmstate_stellaris_sys = {
VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
VMSTATE_UINT32(clkvclr, ssys_state),
VMSTATE_UINT32(ldoarst, ssys_state),
/* No field for sysclk -- handled in post-load instead */
VMSTATE_END_OF_LIST()
}
};
static int stellaris_sys_init(uint32_t base, qemu_irq irq,
stellaris_board_info * board,
uint8_t *macaddr)
static Property stellaris_sys_properties[] = {
DEFINE_PROP_UINT32("user0", ssys_state, user0, 0),
DEFINE_PROP_UINT32("user1", ssys_state, user1, 0),
DEFINE_PROP_UINT32("did0", ssys_state, did0, 0),
DEFINE_PROP_UINT32("did1", ssys_state, did1, 0),
DEFINE_PROP_UINT32("dc0", ssys_state, dc0, 0),
DEFINE_PROP_UINT32("dc1", ssys_state, dc1, 0),
DEFINE_PROP_UINT32("dc2", ssys_state, dc2, 0),
DEFINE_PROP_UINT32("dc3", ssys_state, dc3, 0),
DEFINE_PROP_UINT32("dc4", ssys_state, dc4, 0),
DEFINE_PROP_END_OF_LIST()
};
static void stellaris_sys_instance_init(Object *obj)
{
ssys_state *s;
ssys_state *s = STELLARIS_SYS(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
s = g_new0(ssys_state, 1);
s->irq = irq;
s->board = board;
/* Most devices come preprogrammed with a MAC address in the user data. */
s->user0 = macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16);
s->user1 = macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16);
memory_region_init_io(&s->iomem, NULL, &ssys_ops, s, "ssys", 0x00001000);
memory_region_add_subregion(get_system_memory(), base, &s->iomem);
ssys_reset(s);
vmstate_register(NULL, VMSTATE_INSTANCE_ID_ANY, &vmstate_stellaris_sys, s);
return 0;
memory_region_init_io(&s->iomem, obj, &ssys_ops, s, "ssys", 0x00001000);
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq);
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
}
static DeviceState *stellaris_sys_init(uint32_t base, qemu_irq irq,
stellaris_board_info *board,
uint8_t *macaddr)
{
DeviceState *dev = qdev_new(TYPE_STELLARIS_SYS);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
/* Most devices come preprogrammed with a MAC address in the user data. */
qdev_prop_set_uint32(dev, "user0",
macaddr[0] | (macaddr[1] << 8) | (macaddr[2] << 16));
qdev_prop_set_uint32(dev, "user1",
macaddr[3] | (macaddr[4] << 8) | (macaddr[5] << 16));
qdev_prop_set_uint32(dev, "did0", board->did0);
qdev_prop_set_uint32(dev, "did1", board->did1);
qdev_prop_set_uint32(dev, "dc0", board->dc0);
qdev_prop_set_uint32(dev, "dc1", board->dc1);
qdev_prop_set_uint32(dev, "dc2", board->dc2);
qdev_prop_set_uint32(dev, "dc3", board->dc3);
qdev_prop_set_uint32(dev, "dc4", board->dc4);
sysbus_realize_and_unref(sbd, &error_fatal);
sysbus_mmio_map(sbd, 0, base);
sysbus_connect_irq(sbd, 0, irq);
return dev;
}
/* I2C controller. */
@@ -1280,6 +1347,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
int flash_size;
I2CBus *i2c;
DeviceState *dev;
DeviceState *ssys_dev;
int i;
int j;
@@ -1330,16 +1398,15 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
}
}
stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
board, nd_table[0].macaddr.a);
ssys_dev = stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
board, nd_table[0].macaddr.a);
if (board->dc1 & (1 << 3)) { /* watchdog present */
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
/* system_clock_scale is valid now */
uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
qdev_connect_clock_in(dev, "WDOGCLK",
qdev_get_clock_out(ssys_dev, "SYSCLK"));
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev),
@@ -1553,11 +1620,32 @@ static const TypeInfo stellaris_adc_info = {
.class_init = stellaris_adc_class_init,
};
static void stellaris_sys_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
dc->vmsd = &vmstate_stellaris_sys;
rc->phases.enter = stellaris_sys_reset_enter;
rc->phases.hold = stellaris_sys_reset_hold;
rc->phases.exit = stellaris_sys_reset_exit;
device_class_set_props(dc, stellaris_sys_properties);
}
static const TypeInfo stellaris_sys_info = {
.name = TYPE_STELLARIS_SYS,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(ssys_state),
.instance_init = stellaris_sys_instance_init,
.class_init = stellaris_sys_class_init,
};
static void stellaris_register_types(void)
{
type_register_static(&stellaris_i2c_info);
type_register_static(&stellaris_gptm_info);
type_register_static(&stellaris_adc_info);
type_register_static(&stellaris_sys_info);
}
type_init(stellaris_register_types)
+90 -21
View File
@@ -153,6 +153,7 @@ static const MemMapEntry base_memmap[] = {
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
[VIRT_NVDIMM_ACPI] = { 0x09090000, NVDIMM_ACPI_IO_LEN},
[VIRT_PVTIME] = { 0x090a0000, 0x00010000 },
[VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 },
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
@@ -820,17 +821,80 @@ static void virt_powerdown_req(Notifier *n, void *opaque)
}
}
static void create_gpio(const VirtMachineState *vms)
static void create_gpio_keys(const VirtMachineState *vms,
DeviceState *pl061_dev,
uint32_t phandle)
{
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
qdev_get_gpio_in(pl061_dev, 3));
qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
"label", "GPIO Key Poweroff");
qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
KEY_POWER);
qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
"gpios", phandle, 3, 0);
}
#define SECURE_GPIO_POWEROFF 0
#define SECURE_GPIO_RESET 1
static void create_secure_gpio_pwr(const VirtMachineState *vms,
DeviceState *pl061_dev,
uint32_t phandle)
{
DeviceState *gpio_pwr_dev;
/* gpio-pwr */
gpio_pwr_dev = sysbus_create_simple("gpio-pwr", -1, NULL);
/* connect secure pl061 to gpio-pwr */
qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_RESET,
qdev_get_gpio_in_named(gpio_pwr_dev, "reset", 0));
qdev_connect_gpio_out(pl061_dev, SECURE_GPIO_POWEROFF,
qdev_get_gpio_in_named(gpio_pwr_dev, "shutdown", 0));
qemu_fdt_add_subnode(vms->fdt, "/gpio-poweroff");
qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "compatible",
"gpio-poweroff");
qemu_fdt_setprop_cells(vms->fdt, "/gpio-poweroff",
"gpios", phandle, SECURE_GPIO_POWEROFF, 0);
qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "status", "disabled");
qemu_fdt_setprop_string(vms->fdt, "/gpio-poweroff", "secure-status",
"okay");
qemu_fdt_add_subnode(vms->fdt, "/gpio-restart");
qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "compatible",
"gpio-restart");
qemu_fdt_setprop_cells(vms->fdt, "/gpio-restart",
"gpios", phandle, SECURE_GPIO_RESET, 0);
qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "status", "disabled");
qemu_fdt_setprop_string(vms->fdt, "/gpio-restart", "secure-status",
"okay");
}
static void create_gpio_devices(const VirtMachineState *vms, int gpio,
MemoryRegion *mem)
{
char *nodename;
DeviceState *pl061_dev;
hwaddr base = vms->memmap[VIRT_GPIO].base;
hwaddr size = vms->memmap[VIRT_GPIO].size;
int irq = vms->irqmap[VIRT_GPIO];
hwaddr base = vms->memmap[gpio].base;
hwaddr size = vms->memmap[gpio].size;
int irq = vms->irqmap[gpio];
const char compat[] = "arm,pl061\0arm,primecell";
SysBusDevice *s;
pl061_dev = sysbus_create_simple("pl061", base,
qdev_get_gpio_in(vms->gic, irq));
pl061_dev = qdev_new("pl061");
s = SYS_BUS_DEVICE(pl061_dev);
sysbus_realize_and_unref(s, &error_fatal);
memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
@@ -847,21 +911,19 @@ static void create_gpio(const VirtMachineState *vms)
qemu_fdt_setprop_string(vms->fdt, nodename, "clock-names", "apb_pclk");
qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle);
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
qdev_get_gpio_in(pl061_dev, 3));
qemu_fdt_add_subnode(vms->fdt, "/gpio-keys");
qemu_fdt_setprop_string(vms->fdt, "/gpio-keys", "compatible", "gpio-keys");
qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#size-cells", 0);
qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys", "#address-cells", 1);
qemu_fdt_add_subnode(vms->fdt, "/gpio-keys/poweroff");
qemu_fdt_setprop_string(vms->fdt, "/gpio-keys/poweroff",
"label", "GPIO Key Poweroff");
qemu_fdt_setprop_cell(vms->fdt, "/gpio-keys/poweroff", "linux,code",
KEY_POWER);
qemu_fdt_setprop_cells(vms->fdt, "/gpio-keys/poweroff",
"gpios", phandle, 3, 0);
if (gpio != VIRT_GPIO) {
/* Mark as not usable by the normal world */
qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled");
qemu_fdt_setprop_string(vms->fdt, nodename, "secure-status", "okay");
}
g_free(nodename);
/* Child gpio devices */
if (gpio == VIRT_GPIO) {
create_gpio_keys(vms, pl061_dev, phandle);
} else {
create_secure_gpio_pwr(vms, pl061_dev, phandle);
}
}
static void create_virtio_devices(const VirtMachineState *vms)
@@ -1990,7 +2052,11 @@ static void machvirt_init(MachineState *machine)
if (has_ged && aarch64 && firmware_loaded && virt_is_acpi_enabled(vms)) {
vms->acpi_dev = create_acpi_ged(vms);
} else {
create_gpio(vms);
create_gpio_devices(vms, VIRT_GPIO, sysmem);
}
if (vms->secure && !vmc->no_secure_gpio) {
create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem);
}
/* connect powerdown request */
@@ -2608,8 +2674,11 @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 0)
static void virt_machine_5_2_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_6_0_options(mc);
compat_props_add(mc->compat_props, hw_compat_5_2, hw_compat_5_2_len);
vmc->no_secure_gpio = true;
}
DEFINE_VIRT_MACHINE(5, 2)
+2 -2
View File
@@ -219,12 +219,12 @@ static void xlnx_zcu102_machine_instance_init(Object *obj)
s->secure = false;
/* Default to virt (EL2) being disabled */
s->virt = false;
object_property_add_link(obj, "xlnx-zcu102.canbus0", TYPE_CAN_BUS,
object_property_add_link(obj, "canbus0", TYPE_CAN_BUS,
(Object **)&s->canbus[0],
object_property_allow_set_link,
0);
object_property_add_link(obj, "xlnx-zcu102.canbus1", TYPE_CAN_BUS,
object_property_add_link(obj, "canbus1", TYPE_CAN_BUS,
(Object **)&s->canbus[1],
object_property_allow_set_link,
0);
+34
View File
@@ -15,6 +15,7 @@
#include "sysemu/qtest.h"
#include "block/aio.h"
#include "sysemu/cpus.h"
#include "hw/clock.h"
#define DELTA_ADJUST 1
#define DELTA_NO_ADJUST -1
@@ -348,6 +349,39 @@ void ptimer_set_period(ptimer_state *s, int64_t period)
}
}
/* Set counter increment interval from a Clock */
void ptimer_set_period_from_clock(ptimer_state *s, const Clock *clk,
unsigned int divisor)
{
/*
* The raw clock period is a 64-bit value in units of 2^-32 ns;
* put another way it's a 32.32 fixed-point ns value. Our internal
* representation of the period is 64.32 fixed point ns, so
* the conversion is simple.
*/
uint64_t raw_period = clock_get(clk);
uint64_t period_frac;
assert(s->in_transaction);
s->delta = ptimer_get_count(s);
s->period = extract64(raw_period, 32, 32);
period_frac = extract64(raw_period, 0, 32);
/*
* divisor specifies a possible frequency divisor between the
* clock and the timer, so it is a multiplier on the period.
* We do the multiply after splitting the raw period out into
* period and frac to avoid having to do a 32*64->96 multiply.
*/
s->period *= divisor;
period_frac *= divisor;
s->period += extract64(period_frac, 32, 32);
s->period_frac = (uint32_t)period_frac;
if (s->enabled) {
s->need_reload = true;
}
}
/* Set counter frequency in Hz. */
void ptimer_set_freq(ptimer_state *s, uint32_t freq)
{
+3
View File
@@ -8,5 +8,8 @@ config PL061
config GPIO_KEY
bool
config GPIO_PWR
bool
config SIFIVE_GPIO
bool
+70
View File
@@ -0,0 +1,70 @@
/*
* GPIO qemu power controller
*
* Copyright (c) 2020 Linaro Limited
*
* Author: Maxim Uvarov <maxim.uvarov@linaro.org>
*
* Virtual gpio driver which can be used on top of pl061
* to reboot and shutdown qemu virtual machine. One of use
* case is gpio driver for secure world application (ARM
* Trusted Firmware.).
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
/*
* QEMU interface:
* two named input GPIO lines:
* 'reset' : when asserted, trigger system reset
* 'shutdown' : when asserted, trigger system shutdown
*/
#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "sysemu/runstate.h"
#define TYPE_GPIOPWR "gpio-pwr"
OBJECT_DECLARE_SIMPLE_TYPE(GPIO_PWR_State, GPIOPWR)
struct GPIO_PWR_State {
SysBusDevice parent_obj;
};
static void gpio_pwr_reset(void *opaque, int n, int level)
{
if (level) {
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
}
}
static void gpio_pwr_shutdown(void *opaque, int n, int level)
{
if (level) {
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
}
}
static void gpio_pwr_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
qdev_init_gpio_in_named(dev, gpio_pwr_reset, "reset", 1);
qdev_init_gpio_in_named(dev, gpio_pwr_shutdown, "shutdown", 1);
}
static const TypeInfo gpio_pwr_info = {
.name = TYPE_GPIOPWR,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(GPIO_PWR_State),
.instance_init = gpio_pwr_init,
};
static void gpio_pwr_register_types(void)
{
type_register_static(&gpio_pwr_info);
}
type_init(gpio_pwr_register_types)
+1
View File
@@ -1,5 +1,6 @@
softmmu_ss.add(when: 'CONFIG_E500', if_true: files('mpc8xxx.c'))
softmmu_ss.add(when: 'CONFIG_GPIO_KEY', if_true: files('gpio_key.c'))
softmmu_ss.add(when: 'CONFIG_GPIO_PWR', if_true: files('gpio_pwr.c'))
softmmu_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
softmmu_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_gpio.c'))
+1 -1
View File
@@ -14,7 +14,7 @@ config PC
imply ISA_DEBUG
imply PARALLEL
imply PCI_DEVICES
imply PVPANIC
imply PVPANIC_ISA
imply QXL
imply SEV
imply SGA

Some files were not shown because too many files have changed in this diff Show More