mirror of https://gitee.com/openkylin/qemu.git
target-arm queue:
* util/oslib-posix : qemu_init_exec_dir implementation for Mac * target/arm: Last parts of neon decodetree conversion * hw/arm/virt: Add 5.0 HW compat props * hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status * mps2: Add CMSDK APB watchdog, FPGAIO block, S2I devices and I2C devices * mps2: Add some unimplemented-device stubs for audio and GPIO * mps2-tz: Use the ARM SBCon two-wire serial bus interface * target/arm: Check supported KVM features globally (not per vCPU) * tests/qtest/arm-cpu-features: Add feature setting tests * arm/virt: Add memory hot remove support -----BEGIN PGP SIGNATURE----- iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAl7x6bcZHHBldGVyLm1h eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3h3MD/sEBAvRiJVjGPwfeVrGV5+H IbPudvozkQMgGmv+yW3pkJp5wvpEwWH1fk9rVbjJq3WUCcJpNuITGTbU6LHtbKX/ v5K7d+flkKzeYCCa7zhi+3S9JhnLYH6AjCqjOr8pkKYcDrgQ9qSoU9RPCajn2PQt j8ricE85A77Q6CCnNuwnyOw3ed2rFpc09nt+63StddG98mRbvRbNOMyzZcPHcYHk MKda1W4kzIasHk4m+2ZV9NLgmgni6F/nPn/XRb80Qtqc2Y+PjQZrco9yny3JyV+0 blKYKwZ7OLjn+bQsjQ0iWBlJpK3q+2m2XEaCQaqtXpImh2vURtihUDCTOcQrwlPq CMCu/aL9msrCeT7+mmUJAZ1C01Gj/Hed1QZn6Y9GGtQPZlCC1RcKgTnqMaAhpBNb ZPnXqNWPYFDQIE8LKOIsDKQOeeKup8ORwHstoOPSjqqwsKf37IiX6QtITAZfCWEo 1UyPTfYLru+ar/N5C6CIzloTxIvfRpib8hL8OGhYCt+Tf8xWJKp2kvg7uEio4X4M b7cuO+2SKdE9NcZAlTgvUeGTvGUwe8F8vMMpJDzWQVrvrCFptICQclP0/3EMHJ88 YQkdlSjpvU5Ymlqockkuu2DaYFsENSjw1FhrQt/V34z8G64Kt80dPadAE2D7IW7d IjVQcdFJDEogryGOFKpfdA== =prKc -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20200623' into staging target-arm queue: * util/oslib-posix : qemu_init_exec_dir implementation for Mac * target/arm: Last parts of neon decodetree conversion * hw/arm/virt: Add 5.0 HW compat props * hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status * mps2: Add CMSDK APB watchdog, FPGAIO block, S2I devices and I2C devices * mps2: Add some unimplemented-device stubs for audio and GPIO * mps2-tz: Use the ARM SBCon two-wire serial bus interface * target/arm: Check supported KVM features globally (not per vCPU) * tests/qtest/arm-cpu-features: Add feature setting tests * arm/virt: Add memory hot remove support # gpg: Signature made Tue 23 Jun 2020 12:38:31 BST # 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-20200623: (42 commits) arm/virt: Add memory hot remove support tests/qtest/arm-cpu-features: Add feature setting tests target/arm: Check supported KVM features globally (not per vCPU) hw/arm/mps2-tz: Use the ARM SBCon two-wire serial bus interface hw/arm/mps2: Add audio I2S interface as unimplemented device hw/arm/mps2: Add I2C devices hw/arm/mps2: Add SPI devices hw/arm/mps2: Map the FPGA I/O block hw/arm/mps2: Add CMSDK AHB GPIO peripherals as unimplemented devices hw/arm/mps2: Add CMSDK APB watchdog device hw/arm/mps2: Rename CMSDK AHB peripheral region hw/arm/mps2: Document CMSDK/FPGA APB subsystem sections hw/arm: Use TYPE_VERSATILE_I2C instead of hardcoded string hw/i2c: Add header for ARM SBCon two-wire serial bus interface hw/i2c/versatile_i2c: Add SCL/SDA definitions hw/i2c/versatile_i2c: Add definitions for register addresses hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status target/arm: Remove dead code relating to SABA and UABA target/arm: Remove unnecessary gen_io_end() calls target/arm: Move some functions used only in translate-neon.inc.c to that file ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d4b78317b7
|
@ -842,6 +842,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
|
||||||
L: qemu-arm@nongnu.org
|
L: qemu-arm@nongnu.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: hw/*/versatile*
|
F: hw/*/versatile*
|
||||||
|
F: include/hw/i2c/arm_sbcon_i2c.h
|
||||||
F: hw/misc/arm_sysctl.c
|
F: hw/misc/arm_sysctl.c
|
||||||
F: docs/system/arm/versatile.rst
|
F: docs/system/arm/versatile.rst
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,33 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||||
|
DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
AcpiGedState *s = ACPI_GED(hotplug_dev);
|
||||||
|
|
||||||
|
if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
|
||||||
|
!(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) {
|
||||||
|
acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
|
||||||
|
} else {
|
||||||
|
error_setg(errp, "acpi: device unplug request for unsupported device"
|
||||||
|
" type: %s", object_get_typename(OBJECT(dev)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
|
||||||
|
DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
AcpiGedState *s = ACPI_GED(hotplug_dev);
|
||||||
|
|
||||||
|
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||||
|
acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
|
||||||
|
} else {
|
||||||
|
error_setg(errp, "acpi: device unplug for unsupported device"
|
||||||
|
" type: %s", object_get_typename(OBJECT(dev)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
|
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
|
||||||
{
|
{
|
||||||
AcpiGedState *s = ACPI_GED(adev);
|
AcpiGedState *s = ACPI_GED(adev);
|
||||||
|
@ -318,6 +345,8 @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
|
||||||
dc->vmsd = &vmstate_acpi_ged;
|
dc->vmsd = &vmstate_acpi_ged;
|
||||||
|
|
||||||
hc->plug = acpi_ged_device_plug_cb;
|
hc->plug = acpi_ged_device_plug_cb;
|
||||||
|
hc->unplug_request = acpi_ged_unplug_request_cb;
|
||||||
|
hc->unplug = acpi_ged_unplug_cb;
|
||||||
|
|
||||||
adevc->send_event = acpi_ged_send_event;
|
adevc->send_event = acpi_ged_send_event;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ config HIGHBANK
|
||||||
select ARM_TIMER # sp804
|
select ARM_TIMER # sp804
|
||||||
select ARM_V7M
|
select ARM_V7M
|
||||||
select PL011 # UART
|
select PL011 # UART
|
||||||
select PL022 # Serial port
|
select PL022 # SPI
|
||||||
select PL031 # RTC
|
select PL031 # RTC
|
||||||
select PL061 # GPIO
|
select PL061 # GPIO
|
||||||
select PL310 # cache controller
|
select PL310 # cache controller
|
||||||
|
@ -222,7 +222,7 @@ config STELLARIS
|
||||||
select CMSDK_APB_WATCHDOG
|
select CMSDK_APB_WATCHDOG
|
||||||
select I2C
|
select I2C
|
||||||
select PL011 # UART
|
select PL011 # UART
|
||||||
select PL022 # Serial port
|
select PL022 # SPI
|
||||||
select PL061 # GPIO
|
select PL061 # GPIO
|
||||||
select SSD0303 # OLED display
|
select SSD0303 # OLED display
|
||||||
select SSD0323 # OLED display
|
select SSD0323 # OLED display
|
||||||
|
@ -401,10 +401,12 @@ config MPS2
|
||||||
select MPS2_FPGAIO
|
select MPS2_FPGAIO
|
||||||
select MPS2_SCC
|
select MPS2_SCC
|
||||||
select OR_IRQ
|
select OR_IRQ
|
||||||
select PL022 # Serial port
|
select PL022 # SPI
|
||||||
select PL080 # DMA controller
|
select PL080 # DMA controller
|
||||||
select SPLIT_IRQ
|
select SPLIT_IRQ
|
||||||
select UNIMP
|
select UNIMP
|
||||||
|
select CMSDK_APB_WATCHDOG
|
||||||
|
select VERSATILE_I2C
|
||||||
|
|
||||||
config FSL_IMX7
|
config FSL_IMX7
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "hw/arm/armsse.h"
|
#include "hw/arm/armsse.h"
|
||||||
#include "hw/dma/pl080.h"
|
#include "hw/dma/pl080.h"
|
||||||
#include "hw/ssi/pl022.h"
|
#include "hw/ssi/pl022.h"
|
||||||
|
#include "hw/i2c/arm_sbcon_i2c.h"
|
||||||
#include "hw/net/lan9118.h"
|
#include "hw/net/lan9118.h"
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
#include "hw/core/split-irq.h"
|
#include "hw/core/split-irq.h"
|
||||||
|
@ -87,7 +88,7 @@ typedef struct {
|
||||||
TZPPC ppc[5];
|
TZPPC ppc[5];
|
||||||
TZMPC ssram_mpc[3];
|
TZMPC ssram_mpc[3];
|
||||||
PL022State spi[5];
|
PL022State spi[5];
|
||||||
UnimplementedDeviceState i2c[4];
|
ArmSbconI2CState i2c[4];
|
||||||
UnimplementedDeviceState i2s_audio;
|
UnimplementedDeviceState i2s_audio;
|
||||||
UnimplementedDeviceState gpio[4];
|
UnimplementedDeviceState gpio[4];
|
||||||
UnimplementedDeviceState gfx;
|
UnimplementedDeviceState gfx;
|
||||||
|
@ -365,6 +366,18 @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
|
||||||
return sysbus_mmio_get_region(s, 0);
|
return sysbus_mmio_get_region(s, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
|
||||||
|
const char *name, hwaddr size)
|
||||||
|
{
|
||||||
|
ArmSbconI2CState *i2c = opaque;
|
||||||
|
SysBusDevice *s;
|
||||||
|
|
||||||
|
object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
|
||||||
|
s = SYS_BUS_DEVICE(i2c);
|
||||||
|
sysbus_realize(s, &error_fatal);
|
||||||
|
return sysbus_mmio_get_region(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void mps2tz_common_init(MachineState *machine)
|
static void mps2tz_common_init(MachineState *machine)
|
||||||
{
|
{
|
||||||
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
|
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
|
||||||
|
@ -499,10 +512,10 @@ static void mps2tz_common_init(MachineState *machine)
|
||||||
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
|
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
|
||||||
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
|
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
|
||||||
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
|
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
|
||||||
{ "i2c0", make_unimp_dev, &mms->i2c[0], 0x40207000, 0x1000 },
|
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
|
||||||
{ "i2c1", make_unimp_dev, &mms->i2c[1], 0x40208000, 0x1000 },
|
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
|
||||||
{ "i2c2", make_unimp_dev, &mms->i2c[2], 0x4020c000, 0x1000 },
|
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
|
||||||
{ "i2c3", make_unimp_dev, &mms->i2c[3], 0x4020d000, 0x1000 },
|
{ "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
.name = "apb_ppcexp2",
|
.name = "apb_ppcexp2",
|
||||||
|
|
|
@ -38,8 +38,12 @@
|
||||||
#include "hw/timer/cmsdk-apb-timer.h"
|
#include "hw/timer/cmsdk-apb-timer.h"
|
||||||
#include "hw/timer/cmsdk-apb-dualtimer.h"
|
#include "hw/timer/cmsdk-apb-dualtimer.h"
|
||||||
#include "hw/misc/mps2-scc.h"
|
#include "hw/misc/mps2-scc.h"
|
||||||
|
#include "hw/misc/mps2-fpgaio.h"
|
||||||
|
#include "hw/ssi/pl022.h"
|
||||||
|
#include "hw/i2c/arm_sbcon_i2c.h"
|
||||||
#include "hw/net/lan9118.h"
|
#include "hw/net/lan9118.h"
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
|
#include "hw/watchdog/cmsdk-apb-watchdog.h"
|
||||||
|
|
||||||
typedef enum MPS2FPGAType {
|
typedef enum MPS2FPGAType {
|
||||||
FPGA_AN385,
|
FPGA_AN385,
|
||||||
|
@ -65,8 +69,12 @@ typedef struct {
|
||||||
MemoryRegion blockram_m2;
|
MemoryRegion blockram_m2;
|
||||||
MemoryRegion blockram_m3;
|
MemoryRegion blockram_m3;
|
||||||
MemoryRegion sram;
|
MemoryRegion sram;
|
||||||
|
/* FPGA APB subsystem */
|
||||||
MPS2SCC scc;
|
MPS2SCC scc;
|
||||||
|
MPS2FPGAIO fpgaio;
|
||||||
|
/* CMSDK APB subsystem */
|
||||||
CMSDKAPBDualTimer dualtimer;
|
CMSDKAPBDualTimer dualtimer;
|
||||||
|
CMSDKAPBWatchdog watchdog;
|
||||||
} MPS2MachineState;
|
} MPS2MachineState;
|
||||||
|
|
||||||
#define TYPE_MPS2_MACHINE "mps2"
|
#define TYPE_MPS2_MACHINE "mps2"
|
||||||
|
@ -111,6 +119,7 @@ static void mps2_common_init(MachineState *machine)
|
||||||
MemoryRegion *system_memory = get_system_memory();
|
MemoryRegion *system_memory = get_system_memory();
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||||
DeviceState *armv7m, *sccdev;
|
DeviceState *armv7m, *sccdev;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
|
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
|
||||||
error_report("This board can only be used with CPU %s",
|
error_report("This board can only be used with CPU %s",
|
||||||
|
@ -210,10 +219,11 @@ static void mps2_common_init(MachineState *machine)
|
||||||
*/
|
*/
|
||||||
create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
|
create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
|
||||||
0x40000000, 0x00010000);
|
0x40000000, 0x00010000);
|
||||||
create_unimplemented_device("CMSDK peripheral region @0x40010000",
|
create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
|
||||||
0x40010000, 0x00010000);
|
0x40010000, 0x00010000);
|
||||||
create_unimplemented_device("Extra peripheral region @0x40020000",
|
create_unimplemented_device("Extra peripheral region @0x40020000",
|
||||||
0x40020000, 0x00010000);
|
0x40020000, 0x00010000);
|
||||||
|
|
||||||
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
|
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
|
||||||
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
|
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
|
||||||
|
|
||||||
|
@ -225,7 +235,6 @@ static void mps2_common_init(MachineState *machine)
|
||||||
*/
|
*/
|
||||||
Object *orgate;
|
Object *orgate;
|
||||||
DeviceState *orgate_dev;
|
DeviceState *orgate_dev;
|
||||||
int i;
|
|
||||||
|
|
||||||
orgate = object_new(TYPE_OR_IRQ);
|
orgate = object_new(TYPE_OR_IRQ);
|
||||||
object_property_set_int(orgate, 6, "num-lines", &error_fatal);
|
object_property_set_int(orgate, 6, "num-lines", &error_fatal);
|
||||||
|
@ -262,7 +271,6 @@ static void mps2_common_init(MachineState *machine)
|
||||||
*/
|
*/
|
||||||
Object *orgate;
|
Object *orgate;
|
||||||
DeviceState *orgate_dev;
|
DeviceState *orgate_dev;
|
||||||
int i;
|
|
||||||
|
|
||||||
orgate = object_new(TYPE_OR_IRQ);
|
orgate = object_new(TYPE_OR_IRQ);
|
||||||
object_property_set_int(orgate, 10, "num-lines", &error_fatal);
|
object_property_set_int(orgate, 10, "num-lines", &error_fatal);
|
||||||
|
@ -298,10 +306,15 @@ static void mps2_common_init(MachineState *machine)
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
|
||||||
|
0x40012000, 0x40013000};
|
||||||
|
create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CMSDK APB subsystem */
|
||||||
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
|
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);
|
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
|
||||||
|
|
||||||
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
|
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
|
||||||
TYPE_CMSDK_APB_DUALTIMER);
|
TYPE_CMSDK_APB_DUALTIMER);
|
||||||
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
|
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
|
||||||
|
@ -309,7 +322,15 @@ static void mps2_common_init(MachineState *machine)
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
|
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
|
||||||
qdev_get_gpio_in(armv7m, 10));
|
qdev_get_gpio_in(armv7m, 10));
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
|
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);
|
||||||
|
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));
|
||||||
|
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0x40008000);
|
||||||
|
|
||||||
|
/* FPGA APB subsystem */
|
||||||
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
|
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
|
||||||
sccdev = DEVICE(&mms->scc);
|
sccdev = DEVICE(&mms->scc);
|
||||||
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
|
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
|
||||||
|
@ -317,6 +338,42 @@ static void mps2_common_init(MachineState *machine)
|
||||||
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
|
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
|
||||||
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
|
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
|
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
|
||||||
|
object_initialize_child(OBJECT(mms), "fpgaio",
|
||||||
|
&mms->fpgaio, TYPE_MPS2_FPGAIO);
|
||||||
|
qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
|
||||||
|
sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
|
||||||
|
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
|
||||||
|
sysbus_create_simple(TYPE_PL022, 0x40025000, /* External ADC */
|
||||||
|
qdev_get_gpio_in(armv7m, 22));
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
static const int spi_irqno[] = {11, 24};
|
||||||
|
static const hwaddr spibase[] = {0x40020000, /* APB */
|
||||||
|
0x40021000, /* LCD */
|
||||||
|
0x40026000, /* Shield0 */
|
||||||
|
0x40027000}; /* Shield1 */
|
||||||
|
DeviceState *orgate_dev;
|
||||||
|
Object *orgate;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
orgate = object_new(TYPE_OR_IRQ);
|
||||||
|
object_property_set_int(orgate, 2, "num-lines", &error_fatal);
|
||||||
|
orgate_dev = DEVICE(orgate);
|
||||||
|
qdev_realize(orgate_dev, NULL, &error_fatal);
|
||||||
|
qdev_connect_gpio_out(orgate_dev, 0,
|
||||||
|
qdev_get_gpio_in(armv7m, spi_irqno[i]));
|
||||||
|
for (j = 0; j < 2; j++) {
|
||||||
|
sysbus_create_simple(TYPE_PL022, spibase[2 * i + j],
|
||||||
|
qdev_get_gpio_in(orgate_dev, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
static const hwaddr i2cbase[] = {0x40022000, /* Touch */
|
||||||
|
0x40023000, /* Audio */
|
||||||
|
0x40029000, /* Shield0 */
|
||||||
|
0x4002a000}; /* Shield1 */
|
||||||
|
sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
|
||||||
|
}
|
||||||
|
create_unimplemented_device("i2s", 0x40024000, 0x400);
|
||||||
|
|
||||||
/* In hardware this is a LAN9220; the LAN9118 is software compatible
|
/* In hardware this is a LAN9220; the LAN9118 is software compatible
|
||||||
* except that it doesn't support the checksum-offload feature.
|
* except that it doesn't support the checksum-offload feature.
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "hw/cpu/a9mpcore.h"
|
#include "hw/cpu/a9mpcore.h"
|
||||||
#include "hw/intc/realview_gic.h"
|
#include "hw/intc/realview_gic.h"
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
|
#include "hw/i2c/arm_sbcon_i2c.h"
|
||||||
|
|
||||||
#define SMP_BOOT_ADDR 0xe0000000
|
#define SMP_BOOT_ADDR 0xe0000000
|
||||||
#define SMP_BOOTREG_ADDR 0x10000030
|
#define SMP_BOOTREG_ADDR 0x10000030
|
||||||
|
@ -282,7 +283,7 @@ static void realview_init(MachineState *machine,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
|
dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
|
||||||
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
||||||
i2c_create_slave(i2c, "ds1338", 0x68);
|
i2c_create_slave(i2c, "ds1338", 0x68);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
#include "hw/i2c/i2c.h"
|
#include "hw/i2c/i2c.h"
|
||||||
|
#include "hw/i2c/arm_sbcon_i2c.h"
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
@ -314,7 +315,7 @@ static void versatile_init(MachineState *machine, int board_id)
|
||||||
/* Add PL031 Real Time Clock. */
|
/* Add PL031 Real Time Clock. */
|
||||||
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
|
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
|
||||||
|
|
||||||
dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
|
dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
|
||||||
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
||||||
i2c_create_slave(i2c, "ds1338", 0x68);
|
i2c_create_slave(i2c, "ds1338", 0x68);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "hw/char/pl011.h"
|
#include "hw/char/pl011.h"
|
||||||
#include "hw/cpu/a9mpcore.h"
|
#include "hw/cpu/a9mpcore.h"
|
||||||
#include "hw/cpu/a15mpcore.h"
|
#include "hw/cpu/a15mpcore.h"
|
||||||
|
#include "hw/i2c/arm_sbcon_i2c.h"
|
||||||
|
|
||||||
#define VEXPRESS_BOARD_ID 0x8e0
|
#define VEXPRESS_BOARD_ID 0x8e0
|
||||||
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
|
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
|
||||||
|
@ -640,7 +641,7 @@ static void vexpress_common_init(MachineState *machine)
|
||||||
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
|
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
|
||||||
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
|
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
|
||||||
|
|
||||||
dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
|
dev = sysbus_create_simple(TYPE_VERSATILE_I2C, map[VE_SERIALDVI], NULL);
|
||||||
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
|
||||||
i2c_create_slave(i2c, "sii9022", 0x39);
|
i2c_create_slave(i2c, "sii9022", 0x39);
|
||||||
|
|
||||||
|
|
|
@ -2177,11 +2177,68 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev,
|
||||||
|
DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
if (!vms->acpi_dev) {
|
||||||
|
error_setg(&local_err,
|
||||||
|
"memory hotplug is not enabled: missing acpi-ged device");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
|
||||||
|
error_setg(&local_err,
|
||||||
|
"nvdimm device hot unplug is not supported yet.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
hotplug_handler_unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev,
|
||||||
|
&local_err);
|
||||||
|
out:
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virt_dimm_unplug(HotplugHandler *hotplug_dev,
|
||||||
|
DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
hotplug_handler_unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pc_dimm_unplug(PC_DIMM(dev), MACHINE(vms));
|
||||||
|
qdev_unrealize(dev);
|
||||||
|
|
||||||
|
out:
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
}
|
||||||
|
|
||||||
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||||
DeviceState *dev, Error **errp)
|
DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
error_setg(errp, "device unplug request for unsupported device"
|
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||||
" type: %s", object_get_typename(OBJECT(dev)));
|
virt_dimm_unplug_request(hotplug_dev, dev, errp);
|
||||||
|
} else {
|
||||||
|
error_setg(errp, "device unplug request for unsupported device"
|
||||||
|
" type: %s", object_get_typename(OBJECT(dev)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
|
||||||
|
DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||||
|
virt_dimm_unplug(hotplug_dev, dev, errp);
|
||||||
|
} else {
|
||||||
|
error_setg(errp, "virt: device unplug for unsupported device"
|
||||||
|
" type: %s", object_get_typename(OBJECT(dev)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
|
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
|
||||||
|
@ -2262,6 +2319,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
||||||
hc->pre_plug = virt_machine_device_pre_plug_cb;
|
hc->pre_plug = virt_machine_device_pre_plug_cb;
|
||||||
hc->plug = virt_machine_device_plug_cb;
|
hc->plug = virt_machine_device_plug_cb;
|
||||||
hc->unplug_request = virt_machine_device_unplug_request_cb;
|
hc->unplug_request = virt_machine_device_unplug_request_cb;
|
||||||
|
hc->unplug = virt_machine_device_unplug_cb;
|
||||||
mc->numa_mem_supported = true;
|
mc->numa_mem_supported = true;
|
||||||
mc->nvdimm_supported = true;
|
mc->nvdimm_supported = true;
|
||||||
mc->auto_enable_numa_with_memhp = true;
|
mc->auto_enable_numa_with_memhp = true;
|
||||||
|
@ -2375,6 +2433,7 @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
|
||||||
static void virt_machine_5_0_options(MachineClass *mc)
|
static void virt_machine_5_0_options(MachineClass *mc)
|
||||||
{
|
{
|
||||||
virt_machine_5_1_options(mc);
|
virt_machine_5_1_options(mc);
|
||||||
|
compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
|
||||||
}
|
}
|
||||||
DEFINE_VIRT_MACHINE(5, 0)
|
DEFINE_VIRT_MACHINE(5, 0)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* ARM Versatile I2C controller
|
* ARM SBCon two-wire serial bus interface (I2C bitbang)
|
||||||
|
* a.k.a. ARM Versatile I2C controller
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2007 CodeSourcery.
|
* Copyright (c) 2006-2007 CodeSourcery.
|
||||||
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
|
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
|
||||||
|
@ -22,32 +23,33 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/i2c/arm_sbcon_i2c.h"
|
||||||
#include "hw/i2c/bitbang_i2c.h"
|
#include "hw/registerfields.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
|
|
||||||
#define TYPE_VERSATILE_I2C "versatile_i2c"
|
|
||||||
#define VERSATILE_I2C(obj) \
|
#define VERSATILE_I2C(obj) \
|
||||||
OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
|
OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
|
||||||
|
|
||||||
typedef struct VersatileI2CState {
|
typedef ArmSbconI2CState VersatileI2CState;
|
||||||
SysBusDevice parent_obj;
|
|
||||||
|
|
||||||
MemoryRegion iomem;
|
|
||||||
bitbang_i2c_interface bitbang;
|
REG32(CONTROL_GET, 0)
|
||||||
int out;
|
REG32(CONTROL_SET, 0)
|
||||||
int in;
|
REG32(CONTROL_CLR, 4)
|
||||||
} VersatileI2CState;
|
|
||||||
|
#define SCL BIT(0)
|
||||||
|
#define SDA BIT(1)
|
||||||
|
|
||||||
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
|
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
|
||||||
unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
VersatileI2CState *s = (VersatileI2CState *)opaque;
|
VersatileI2CState *s = (VersatileI2CState *)opaque;
|
||||||
|
|
||||||
if (offset == 0) {
|
switch (offset) {
|
||||||
|
case A_CONTROL_SET:
|
||||||
return (s->out & 1) | (s->in << 1);
|
return (s->out & 1) | (s->in << 1);
|
||||||
} else {
|
default:
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
"%s: Bad offset 0x%x\n", __func__, (int)offset);
|
"%s: Bad offset 0x%x\n", __func__, (int)offset);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -60,18 +62,18 @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
|
||||||
VersatileI2CState *s = (VersatileI2CState *)opaque;
|
VersatileI2CState *s = (VersatileI2CState *)opaque;
|
||||||
|
|
||||||
switch (offset) {
|
switch (offset) {
|
||||||
case 0:
|
case A_CONTROL_SET:
|
||||||
s->out |= value & 3;
|
s->out |= value & 3;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case A_CONTROL_CLR:
|
||||||
s->out &= ~value;
|
s->out &= ~value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qemu_log_mask(LOG_GUEST_ERROR,
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
"%s: Bad offset 0x%x\n", __func__, (int)offset);
|
"%s: Bad offset 0x%x\n", __func__, (int)offset);
|
||||||
}
|
}
|
||||||
bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
|
bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & SCL) != 0);
|
||||||
s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
|
s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & SDA) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps versatile_i2c_ops = {
|
static const MemoryRegionOps versatile_i2c_ops = {
|
||||||
|
@ -90,7 +92,7 @@ static void versatile_i2c_init(Object *obj)
|
||||||
bus = i2c_init_bus(dev, "i2c");
|
bus = i2c_init_bus(dev, "i2c");
|
||||||
bitbang_i2c_init(&s->bitbang, bus);
|
bitbang_i2c_init(&s->bitbang, bus);
|
||||||
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
|
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
|
||||||
"versatile_i2c", 0x1000);
|
"arm_sbcon_i2c", 0x1000);
|
||||||
sysbus_init_mmio(sbd, &s->iomem);
|
sysbus_init_mmio(sbd, &s->iomem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,6 +225,7 @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
|
||||||
break;
|
break;
|
||||||
case A_WDOGLOCK:
|
case A_WDOGLOCK:
|
||||||
s->lock = (value != WDOG_UNLOCK_VALUE);
|
s->lock = (value != WDOG_UNLOCK_VALUE);
|
||||||
|
trace_cmsdk_apb_watchdog_lock(s->lock);
|
||||||
break;
|
break;
|
||||||
case A_WDOGITCR:
|
case A_WDOGITCR:
|
||||||
if (s->is_luminary) {
|
if (s->is_luminary) {
|
||||||
|
|
|
@ -4,3 +4,4 @@
|
||||||
cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
||||||
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
||||||
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
|
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
|
||||||
|
cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* ARM SBCon two-wire serial bus interface (I2C bitbang)
|
||||||
|
* a.k.a.
|
||||||
|
* ARM Versatile I2C controller
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006-2007 CodeSourcery.
|
||||||
|
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
|
||||||
|
* Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
#ifndef HW_I2C_ARM_SBCON_H
|
||||||
|
#define HW_I2C_ARM_SBCON_H
|
||||||
|
|
||||||
|
#include "hw/sysbus.h"
|
||||||
|
#include "hw/i2c/bitbang_i2c.h"
|
||||||
|
|
||||||
|
#define TYPE_VERSATILE_I2C "versatile_i2c"
|
||||||
|
#define TYPE_ARM_SBCON_I2C TYPE_VERSATILE_I2C
|
||||||
|
|
||||||
|
#define ARM_SBCON_I2C(obj) \
|
||||||
|
OBJECT_CHECK(ArmSbconI2CState, (obj), TYPE_ARM_SBCON_I2C)
|
||||||
|
|
||||||
|
typedef struct ArmSbconI2CState {
|
||||||
|
/*< private >*/
|
||||||
|
SysBusDevice parent_obj;
|
||||||
|
/*< public >*/
|
||||||
|
|
||||||
|
MemoryRegion iomem;
|
||||||
|
bitbang_i2c_interface bitbang;
|
||||||
|
int out;
|
||||||
|
int in;
|
||||||
|
} ArmSbconI2CState;
|
||||||
|
|
||||||
|
#endif /* HW_I2C_ARM_SBCON_H */
|
|
@ -1108,7 +1108,7 @@ static void arm_set_pmu(Object *obj, bool value, Error **errp)
|
||||||
ARMCPU *cpu = ARM_CPU(obj);
|
ARMCPU *cpu = ARM_CPU(obj);
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) {
|
if (kvm_enabled() && !kvm_arm_pmu_supported()) {
|
||||||
error_setg(errp, "'pmu' feature not supported by KVM on this host");
|
error_setg(errp, "'pmu' feature not supported by KVM on this host");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2334,7 +2334,7 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
|
||||||
* migration or KVM state synchronization. (Typically this is for "registers"
|
* migration or KVM state synchronization. (Typically this is for "registers"
|
||||||
* which are actually used as instructions for cache maintenance and so on.)
|
* which are actually used as instructions for cache maintenance and so on.)
|
||||||
* IO indicates that this register does I/O and therefore its accesses
|
* IO indicates that this register does I/O and therefore its accesses
|
||||||
* need to be surrounded by gen_io_start()/gen_io_end(). In particular,
|
* need to be marked with gen_io_start() and also end the TB. In particular,
|
||||||
* registers which implement clocks or timers require this.
|
* registers which implement clocks or timers require this.
|
||||||
* RAISES_EXC is for when the read or write hook might raise an exception;
|
* RAISES_EXC is for when the read or write hook might raise an exception;
|
||||||
* the generated code will synchronize the CPU state before calling the hook
|
* the generated code will synchronize the CPU state before calling the hook
|
||||||
|
|
|
@ -266,7 +266,7 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
|
||||||
|
|
||||||
/* Collect the set of vector lengths supported by KVM. */
|
/* Collect the set of vector lengths supported by KVM. */
|
||||||
bitmap_zero(kvm_supported, ARM_MAX_VQ);
|
bitmap_zero(kvm_supported, ARM_MAX_VQ);
|
||||||
if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
|
if (kvm_enabled() && kvm_arm_sve_supported()) {
|
||||||
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
|
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
|
||||||
} else if (kvm_enabled()) {
|
} else if (kvm_enabled()) {
|
||||||
assert(!cpu_isar_feature(aa64_sve, cpu));
|
assert(!cpu_isar_feature(aa64_sve, cpu));
|
||||||
|
@ -473,7 +473,7 @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
|
if (kvm_enabled() && !kvm_arm_sve_supported()) {
|
||||||
error_setg(errp, "cannot set sve-max-vq");
|
error_setg(errp, "cannot set sve-max-vq");
|
||||||
error_append_hint(errp, "SVE not supported by KVM on this host\n");
|
error_append_hint(errp, "SVE not supported by KVM on this host\n");
|
||||||
return;
|
return;
|
||||||
|
@ -519,7 +519,7 @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
|
if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
|
||||||
error_setg(errp, "cannot enable %s", name);
|
error_setg(errp, "cannot enable %s", name);
|
||||||
error_append_hint(errp, "SVE not supported by KVM on this host\n");
|
error_append_hint(errp, "SVE not supported by KVM on this host\n");
|
||||||
return;
|
return;
|
||||||
|
@ -556,7 +556,7 @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
|
if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
|
||||||
error_setg(errp, "'sve' feature not supported by KVM on this host");
|
error_setg(errp, "'sve' feature not supported by KVM on this host");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -751,7 +751,7 @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
|
||||||
* uniform execution state like do_interrupt.
|
* uniform execution state like do_interrupt.
|
||||||
*/
|
*/
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
|
if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
|
||||||
error_setg(errp, "'aarch64' feature cannot be disabled "
|
error_setg(errp, "'aarch64' feature cannot be disabled "
|
||||||
"unless KVM is enabled and 32-bit EL1 "
|
"unless KVM is enabled and 32-bit EL1 "
|
||||||
"is supported");
|
"is supported");
|
||||||
|
|
|
@ -208,9 +208,9 @@ void kvm_arm_add_vcpu_properties(Object *obj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kvm_arm_pmu_supported(CPUState *cpu)
|
bool kvm_arm_pmu_supported(void)
|
||||||
{
|
{
|
||||||
return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
|
return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
|
||||||
}
|
}
|
||||||
|
|
||||||
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
|
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
|
||||||
|
|
|
@ -652,18 +652,14 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kvm_arm_aarch32_supported(CPUState *cpu)
|
bool kvm_arm_aarch32_supported(void)
|
||||||
{
|
{
|
||||||
KVMState *s = KVM_STATE(current_accel());
|
return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
|
||||||
|
|
||||||
return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kvm_arm_sve_supported(CPUState *cpu)
|
bool kvm_arm_sve_supported(void)
|
||||||
{
|
{
|
||||||
KVMState *s = KVM_STATE(current_accel());
|
return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
|
||||||
|
|
||||||
return kvm_check_extension(s, KVM_CAP_ARM_SVE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
|
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
|
||||||
|
@ -798,7 +794,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||||
env->features &= ~(1ULL << ARM_FEATURE_PMU);
|
env->features &= ~(1ULL << ARM_FEATURE_PMU);
|
||||||
}
|
}
|
||||||
if (cpu_isar_feature(aa64_sve, cpu)) {
|
if (cpu_isar_feature(aa64_sve, cpu)) {
|
||||||
assert(kvm_arm_sve_supported(cs));
|
assert(kvm_arm_sve_supported());
|
||||||
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
|
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,29 +269,26 @@ void kvm_arm_add_vcpu_properties(Object *obj);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvm_arm_aarch32_supported:
|
* kvm_arm_aarch32_supported:
|
||||||
* @cs: CPUState
|
|
||||||
*
|
*
|
||||||
* Returns: true if the KVM VCPU can enable AArch32 mode
|
* Returns: true if KVM can enable AArch32 mode
|
||||||
* and false otherwise.
|
* and false otherwise.
|
||||||
*/
|
*/
|
||||||
bool kvm_arm_aarch32_supported(CPUState *cs);
|
bool kvm_arm_aarch32_supported(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvm_arm_pmu_supported:
|
* kvm_arm_pmu_supported:
|
||||||
* @cs: CPUState
|
|
||||||
*
|
*
|
||||||
* Returns: true if the KVM VCPU can enable its PMU
|
* Returns: true if KVM can enable the PMU
|
||||||
* and false otherwise.
|
* and false otherwise.
|
||||||
*/
|
*/
|
||||||
bool kvm_arm_pmu_supported(CPUState *cs);
|
bool kvm_arm_pmu_supported(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvm_arm_sve_supported:
|
* kvm_arm_sve_supported:
|
||||||
* @cs: CPUState
|
|
||||||
*
|
*
|
||||||
* Returns true if the KVM VCPU can enable SVE and false otherwise.
|
* Returns true if KVM can enable SVE and false otherwise.
|
||||||
*/
|
*/
|
||||||
bool kvm_arm_sve_supported(CPUState *cs);
|
bool kvm_arm_sve_supported(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvm_arm_get_max_vm_ipa_size:
|
* kvm_arm_get_max_vm_ipa_size:
|
||||||
|
@ -359,17 +356,17 @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
|
||||||
|
|
||||||
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
|
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
|
||||||
|
|
||||||
static inline bool kvm_arm_aarch32_supported(CPUState *cs)
|
static inline bool kvm_arm_aarch32_supported(void)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool kvm_arm_pmu_supported(CPUState *cs)
|
static inline bool kvm_arm_pmu_supported(void)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool kvm_arm_sve_supported(CPUState *cs)
|
static inline bool kvm_arm_sve_supported(void)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -429,6 +429,112 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
|
||||||
vm=%vm_dp vd=%vd_dp size=1
|
vm=%vm_dp vd=%vd_dp size=1
|
||||||
VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
|
VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
|
||||||
vm=%vm_dp vd=%vd_dp size=2
|
vm=%vm_dp vd=%vd_dp size=2
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
# 2-reg-misc grouping:
|
||||||
|
# 1111 001 11 D 11 size:2 opc1:2 Vd:4 0 opc2:4 q:1 M 0 Vm:4
|
||||||
|
##################################################################
|
||||||
|
|
||||||
|
&2misc vd vm q size
|
||||||
|
|
||||||
|
@2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
|
||||||
|
&2misc vm=%vm_dp vd=%vd_dp
|
||||||
|
@2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
|
||||||
|
&2misc vm=%vm_dp vd=%vd_dp q=0
|
||||||
|
@2misc_q1 .... ... .. . .. size:2 .. .... . .... . . . .... \
|
||||||
|
&2misc vm=%vm_dp vd=%vd_dp q=1
|
||||||
|
|
||||||
|
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
|
||||||
|
VREV32 1111 001 11 . 11 .. 00 .... 0 0001 . . 0 .... @2misc
|
||||||
|
VREV16 1111 001 11 . 11 .. 00 .... 0 0010 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
|
||||||
|
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
|
||||||
|
|
||||||
|
AESE 1111 001 11 . 11 .. 00 .... 0 0110 0 . 0 .... @2misc_q1
|
||||||
|
AESD 1111 001 11 . 11 .. 00 .... 0 0110 1 . 0 .... @2misc_q1
|
||||||
|
AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
|
||||||
|
AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
|
||||||
|
|
||||||
|
VCLS 1111 001 11 . 11 .. 00 .... 0 1000 . . 0 .... @2misc
|
||||||
|
VCLZ 1111 001 11 . 11 .. 00 .... 0 1001 . . 0 .... @2misc
|
||||||
|
VCNT 1111 001 11 . 11 .. 00 .... 0 1010 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
|
||||||
|
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VQABS 1111 001 11 . 11 .. 00 .... 0 1110 . . 0 .... @2misc
|
||||||
|
VQNEG 1111 001 11 . 11 .. 00 .... 0 1111 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
|
||||||
|
VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
|
||||||
|
VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
|
||||||
|
VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
|
||||||
|
VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
|
||||||
|
|
||||||
|
SHA1H 1111 001 11 . 11 .. 01 .... 0 0101 1 . 0 .... @2misc_q1
|
||||||
|
|
||||||
|
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
|
||||||
|
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VCGT0_F 1111 001 11 . 11 .. 01 .... 0 1000 . . 0 .... @2misc
|
||||||
|
VCGE0_F 1111 001 11 . 11 .. 01 .... 0 1001 . . 0 .... @2misc
|
||||||
|
VCEQ0_F 1111 001 11 . 11 .. 01 .... 0 1010 . . 0 .... @2misc
|
||||||
|
VCLE0_F 1111 001 11 . 11 .. 01 .... 0 1011 . . 0 .... @2misc
|
||||||
|
VCLT0_F 1111 001 11 . 11 .. 01 .... 0 1100 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
|
||||||
|
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
|
||||||
|
VTRN 1111 001 11 . 11 .. 10 .... 0 0001 . . 0 .... @2misc
|
||||||
|
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
|
||||||
|
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VMOVN 1111 001 11 . 11 .. 10 .... 0 0100 0 . 0 .... @2misc_q0
|
||||||
|
# VQMOVUN: unsigned result (source is always signed)
|
||||||
|
VQMOVUN 1111 001 11 . 11 .. 10 .... 0 0100 1 . 0 .... @2misc_q0
|
||||||
|
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
|
||||||
|
VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
|
||||||
|
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
|
||||||
|
|
||||||
|
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
|
||||||
|
|
||||||
|
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
|
||||||
|
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
|
||||||
|
|
||||||
|
VRINTN 1111 001 11 . 11 .. 10 .... 0 1000 . . 0 .... @2misc
|
||||||
|
VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
|
||||||
|
VRINTA 1111 001 11 . 11 .. 10 .... 0 1010 . . 0 .... @2misc
|
||||||
|
VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
|
||||||
|
|
||||||
|
VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
|
||||||
|
|
||||||
|
VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VCVTAS 1111 001 11 . 11 .. 11 .... 0 0000 . . 0 .... @2misc
|
||||||
|
VCVTAU 1111 001 11 . 11 .. 11 .... 0 0001 . . 0 .... @2misc
|
||||||
|
VCVTNS 1111 001 11 . 11 .. 11 .... 0 0010 . . 0 .... @2misc
|
||||||
|
VCVTNU 1111 001 11 . 11 .. 11 .... 0 0011 . . 0 .... @2misc
|
||||||
|
VCVTPS 1111 001 11 . 11 .. 11 .... 0 0100 . . 0 .... @2misc
|
||||||
|
VCVTPU 1111 001 11 . 11 .. 11 .... 0 0101 . . 0 .... @2misc
|
||||||
|
VCVTMS 1111 001 11 . 11 .. 11 .... 0 0110 . . 0 .... @2misc
|
||||||
|
VCVTMU 1111 001 11 . 11 .. 11 .... 0 0111 . . 0 .... @2misc
|
||||||
|
|
||||||
|
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
|
||||||
|
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
|
||||||
|
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
|
||||||
|
VRSQRTE_F 1111 001 11 . 11 .. 11 .... 0 1011 . . 0 .... @2misc
|
||||||
|
VCVT_FS 1111 001 11 . 11 .. 11 .... 0 1100 . . 0 .... @2misc
|
||||||
|
VCVT_FU 1111 001 11 . 11 .. 11 .... 0 1101 . . 0 .... @2misc
|
||||||
|
VCVT_SF 1111 001 11 . 11 .. 11 .... 0 1110 . . 0 .... @2misc
|
||||||
|
VCVT_UF 1111 001 11 . 11 .. 11 .... 0 1111 . . 0 .... @2misc
|
||||||
]
|
]
|
||||||
|
|
||||||
# Subgroup for size != 0b11
|
# Subgroup for size != 0b11
|
||||||
|
|
|
@ -9534,7 +9534,7 @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
|
||||||
TCGv_i64 tcg_op = tcg_temp_new_i64();
|
TCGv_i64 tcg_op = tcg_temp_new_i64();
|
||||||
TCGv_i64 tcg_zero = tcg_const_i64(0);
|
TCGv_i64 tcg_zero = tcg_const_i64(0);
|
||||||
TCGv_i64 tcg_res = tcg_temp_new_i64();
|
TCGv_i64 tcg_res = tcg_temp_new_i64();
|
||||||
NeonGenTwoDoubleOPFn *genfn;
|
NeonGenTwoDoubleOpFn *genfn;
|
||||||
bool swap = false;
|
bool swap = false;
|
||||||
int pass;
|
int pass;
|
||||||
|
|
||||||
|
@ -9576,7 +9576,7 @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
|
||||||
TCGv_i32 tcg_op = tcg_temp_new_i32();
|
TCGv_i32 tcg_op = tcg_temp_new_i32();
|
||||||
TCGv_i32 tcg_zero = tcg_const_i32(0);
|
TCGv_i32 tcg_zero = tcg_const_i32(0);
|
||||||
TCGv_i32 tcg_res = tcg_temp_new_i32();
|
TCGv_i32 tcg_res = tcg_temp_new_i32();
|
||||||
NeonGenTwoSingleOPFn *genfn;
|
NeonGenTwoSingleOpFn *genfn;
|
||||||
bool swap = false;
|
bool swap = false;
|
||||||
int pass, maxpasses;
|
int pass, maxpasses;
|
||||||
|
|
||||||
|
@ -11370,18 +11370,6 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
|
||||||
genfn(tcg_res, tcg_op1, tcg_op2);
|
genfn(tcg_res, tcg_op1, tcg_op2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode == 0xf) {
|
|
||||||
/* SABA, UABA: accumulating ops */
|
|
||||||
static NeonGenTwoOpFn * const fns[3] = {
|
|
||||||
gen_helper_neon_add_u8,
|
|
||||||
gen_helper_neon_add_u16,
|
|
||||||
tcg_gen_add_i32,
|
|
||||||
};
|
|
||||||
|
|
||||||
read_vec_element_i32(s, tcg_op1, rd, pass, MO_32);
|
|
||||||
fns[size](tcg_res, tcg_op1, tcg_res);
|
|
||||||
}
|
|
||||||
|
|
||||||
write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
|
write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
|
||||||
|
|
||||||
tcg_temp_free_i32(tcg_res);
|
tcg_temp_free_i32(tcg_res);
|
||||||
|
@ -11917,8 +11905,8 @@ static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
|
||||||
} else {
|
} else {
|
||||||
for (pass = 0; pass < maxpass; pass++) {
|
for (pass = 0; pass < maxpass; pass++) {
|
||||||
TCGv_i64 tcg_op = tcg_temp_new_i64();
|
TCGv_i64 tcg_op = tcg_temp_new_i64();
|
||||||
NeonGenOneOpFn *genfn;
|
NeonGenOne64OpFn *genfn;
|
||||||
static NeonGenOneOpFn * const fns[2][2] = {
|
static NeonGenOne64OpFn * const fns[2][2] = {
|
||||||
{ gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 },
|
{ gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 },
|
||||||
{ gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 },
|
{ gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 },
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -119,15 +119,14 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
|
||||||
if (s->v7m_lspact) {
|
if (s->v7m_lspact) {
|
||||||
/*
|
/*
|
||||||
* Lazy state saving affects external memory and also the NVIC,
|
* Lazy state saving affects external memory and also the NVIC,
|
||||||
* so we must mark it as an IO operation for icount.
|
* so we must mark it as an IO operation for icount (and cause
|
||||||
|
* this to be the last insn in the TB).
|
||||||
*/
|
*/
|
||||||
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
|
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
|
||||||
|
s->base.is_jmp = DISAS_UPDATE;
|
||||||
gen_io_start();
|
gen_io_start();
|
||||||
}
|
}
|
||||||
gen_helper_v7m_preserve_fp_state(cpu_env);
|
gen_helper_v7m_preserve_fp_state(cpu_env);
|
||||||
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
|
|
||||||
gen_io_end();
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* If the preserve_fp_state helper doesn't throw an exception
|
* If the preserve_fp_state helper doesn't throw an exception
|
||||||
* then it will clear LSPACT; we don't need to repeat this for
|
* then it will clear LSPACT; we don't need to repeat this for
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -363,6 +363,7 @@ typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
|
||||||
uint32_t, uint32_t, uint32_t);
|
uint32_t, uint32_t, uint32_t);
|
||||||
|
|
||||||
/* Function prototype for gen_ functions for calling Neon helpers */
|
/* Function prototype for gen_ functions for calling Neon helpers */
|
||||||
|
typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
|
||||||
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
|
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
|
||||||
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
|
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
|
||||||
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
|
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
|
||||||
|
@ -372,9 +373,10 @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
|
||||||
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
|
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
|
||||||
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
|
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
|
||||||
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
|
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
|
||||||
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
|
typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
|
||||||
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
|
typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
|
||||||
typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
|
typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
|
||||||
|
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
|
||||||
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
|
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
|
||||||
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
|
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
|
||||||
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
|
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
|
||||||
|
|
|
@ -159,16 +159,35 @@ static bool resp_get_feature(QDict *resp, const char *feature)
|
||||||
qobject_unref(_resp); \
|
qobject_unref(_resp); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define assert_feature(qts, cpu_type, feature, expected_value) \
|
#define resp_assert_feature(resp, feature, expected_value) \
|
||||||
({ \
|
({ \
|
||||||
QDict *_resp, *_props; \
|
QDict *_props; \
|
||||||
\
|
\
|
||||||
_resp = do_query_no_props(qts, cpu_type); \
|
|
||||||
g_assert(_resp); \
|
g_assert(_resp); \
|
||||||
g_assert(resp_has_props(_resp)); \
|
g_assert(resp_has_props(_resp)); \
|
||||||
_props = resp_get_props(_resp); \
|
_props = resp_get_props(_resp); \
|
||||||
g_assert(qdict_get(_props, feature)); \
|
g_assert(qdict_get(_props, feature)); \
|
||||||
g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
|
g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define assert_feature(qts, cpu_type, feature, expected_value) \
|
||||||
|
({ \
|
||||||
|
QDict *_resp; \
|
||||||
|
\
|
||||||
|
_resp = do_query_no_props(qts, cpu_type); \
|
||||||
|
g_assert(_resp); \
|
||||||
|
resp_assert_feature(_resp, feature, expected_value); \
|
||||||
|
qobject_unref(_resp); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define assert_set_feature(qts, cpu_type, feature, value) \
|
||||||
|
({ \
|
||||||
|
const char *_fmt = (value) ? "{ %s: true }" : "{ %s: false }"; \
|
||||||
|
QDict *_resp; \
|
||||||
|
\
|
||||||
|
_resp = do_query(qts, cpu_type, _fmt, feature); \
|
||||||
|
g_assert(_resp); \
|
||||||
|
resp_assert_feature(_resp, feature, value); \
|
||||||
qobject_unref(_resp); \
|
qobject_unref(_resp); \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -424,10 +443,14 @@ static void test_query_cpu_model_expansion(const void *data)
|
||||||
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
|
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
|
||||||
|
|
||||||
/* Test expected feature presence/absence for some cpu types */
|
/* Test expected feature presence/absence for some cpu types */
|
||||||
assert_has_feature_enabled(qts, "max", "pmu");
|
|
||||||
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
|
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
|
||||||
assert_has_not_feature(qts, "cortex-a15", "aarch64");
|
assert_has_not_feature(qts, "cortex-a15", "aarch64");
|
||||||
|
|
||||||
|
/* Enabling and disabling pmu should always work. */
|
||||||
|
assert_has_feature_enabled(qts, "max", "pmu");
|
||||||
|
assert_set_feature(qts, "max", "pmu", false);
|
||||||
|
assert_set_feature(qts, "max", "pmu", true);
|
||||||
|
|
||||||
assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
|
assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
|
||||||
|
|
||||||
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
||||||
|
@ -464,7 +487,10 @@ static void test_query_cpu_model_expansion_kvm(const void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enabling and disabling kvm-no-adjvtime should always work. */
|
||||||
assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
|
assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
|
||||||
|
assert_set_feature(qts, "host", "kvm-no-adjvtime", true);
|
||||||
|
assert_set_feature(qts, "host", "kvm-no-adjvtime", false);
|
||||||
|
|
||||||
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
if (g_str_equal(qtest_get_arch(), "aarch64")) {
|
||||||
bool kvm_supports_sve;
|
bool kvm_supports_sve;
|
||||||
|
@ -475,7 +501,11 @@ static void test_query_cpu_model_expansion_kvm(const void *data)
|
||||||
char *error;
|
char *error;
|
||||||
|
|
||||||
assert_has_feature_enabled(qts, "host", "aarch64");
|
assert_has_feature_enabled(qts, "host", "aarch64");
|
||||||
|
|
||||||
|
/* Enabling and disabling pmu should always work. */
|
||||||
assert_has_feature_enabled(qts, "host", "pmu");
|
assert_has_feature_enabled(qts, "host", "pmu");
|
||||||
|
assert_set_feature(qts, "host", "pmu", false);
|
||||||
|
assert_set_feature(qts, "host", "pmu", true);
|
||||||
|
|
||||||
assert_error(qts, "cortex-a15",
|
assert_error(qts, "cortex-a15",
|
||||||
"We cannot guarantee the CPU type 'cortex-a15' works "
|
"We cannot guarantee the CPU type 'cortex-a15' works "
|
||||||
|
|
|
@ -57,6 +57,10 @@
|
||||||
#include <lwp.h>
|
#include <lwp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "qemu/mmap-alloc.h"
|
#include "qemu/mmap-alloc.h"
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_STACK_USAGE
|
#ifdef CONFIG_DEBUG_STACK_USAGE
|
||||||
|
@ -375,6 +379,17 @@ void qemu_init_exec_dir(const char *argv0)
|
||||||
p = buf;
|
p = buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
{
|
||||||
|
char fpath[PATH_MAX];
|
||||||
|
uint32_t len = sizeof(fpath);
|
||||||
|
if (_NSGetExecutablePath(fpath, &len) == 0) {
|
||||||
|
p = realpath(fpath, buf);
|
||||||
|
if (!p) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
/* If we don't have any way of figuring out the actual executable
|
/* If we don't have any way of figuring out the actual executable
|
||||||
location then try argv[0]. */
|
location then try argv[0]. */
|
||||||
|
|
Loading…
Reference in New Issue