target-arm queue:

* hw/arm: Fix some typos in comments (most found by codespell)
  * exynos: Fix out-of-bounds access in exynos4210_gcomp_find debug printf
  * Orangepi-PC, Cubieboard: add Allwinner WDT watchdog emulation
  * tests/avocado: Add reboot tests to Cubieboard
  * hw/timer/imx_epit: Fix bugs in timer limit checking
  * target/arm: Remove KVM AArch32 CPU definitions
  * hw/arm/virt: Restrict Cortex-A7 check to TCG
  * target/arm: Initialize debug capabilities only once
  * target/arm: Implement FEAT_PAN3
  * docs/devel/kconfig.rst: Fix incorrect markup
  * target/arm: Report pauth information to gdb as 'pauth_v2'
  * mcimxd7-sabre, mcimx6ul-evk: Correctly model the way the PHY
    on the second ethernet device must be configured via the
    first one
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmRBDfkZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3rtLD/93hJ+CEUnATXx7Ic7g0EvN
 eXIMsgd80pd1gn4PKzP9lol6I40VDuozs9mb9jP6+Hc0tEoOua4KlIvyMlYy4wSx
 eJBqt/gx/N/V+jwVG8seY+ifLIzECMLMOQIRQqQoVk+scENuiJIXcJRH5A1eUWNb
 iV0QfJa1gQrKyyIG9vNfZ+cS+xy0bl0E9FlZ0ty3zeh0xBaMhUqnpraTVLISWelP
 OEovcIBEzvD/ngj+7F/xKBGgtSTZ1FuN5p/oOFDCH2Fihe2+wuw7B3Rc1SbHLG7n
 Wr4JZozdPbnudhrZgn+1A9SCFhH+B8k/QlKY2Qc+w+GrnC0JpJAmqtaF2aIaepPo
 kfbTUshDstIZ7MnCeAa+SWn2Exgrsn0Gv9nWdOrPgrvo0bqK6ceAhchi5nFmkkaJ
 MOy+Xx5GIAE91418wR8C2TlrTl58A81s15AYY1D7nZ0GeuZV5io7wPIAOWa14rOQ
 RdvQ/0rcZ+IkOFXz5Zj/L/Y/W4BpDyfuUVzLAah56zYkuV4im2cLt3YAOMFYZjjO
 6W1sdbAcuA5QFmO4v5VmcTU8t/B423QzcnssE6sbM0nazMh/i6kjzvJUhdJTQmi+
 lKjIe+MHutTgrbjrwemjiafk3dOpFpKtso/4C/dhP2UfDIcKuGXNpSYxCvoknO2j
 TWvxRvir/PC7gzUzA4CrwQ==
 =YUUL
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20230420' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * hw/arm: Fix some typos in comments (most found by codespell)
 * exynos: Fix out-of-bounds access in exynos4210_gcomp_find debug printf
 * Orangepi-PC, Cubieboard: add Allwinner WDT watchdog emulation
 * tests/avocado: Add reboot tests to Cubieboard
 * hw/timer/imx_epit: Fix bugs in timer limit checking
 * target/arm: Remove KVM AArch32 CPU definitions
 * hw/arm/virt: Restrict Cortex-A7 check to TCG
 * target/arm: Initialize debug capabilities only once
 * target/arm: Implement FEAT_PAN3
 * docs/devel/kconfig.rst: Fix incorrect markup
 * target/arm: Report pauth information to gdb as 'pauth_v2'
 * mcimxd7-sabre, mcimx6ul-evk: Correctly model the way the PHY
   on the second ethernet device must be configured via the
   first one

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmRBDfkZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3rtLD/93hJ+CEUnATXx7Ic7g0EvN
# eXIMsgd80pd1gn4PKzP9lol6I40VDuozs9mb9jP6+Hc0tEoOua4KlIvyMlYy4wSx
# eJBqt/gx/N/V+jwVG8seY+ifLIzECMLMOQIRQqQoVk+scENuiJIXcJRH5A1eUWNb
# iV0QfJa1gQrKyyIG9vNfZ+cS+xy0bl0E9FlZ0ty3zeh0xBaMhUqnpraTVLISWelP
# OEovcIBEzvD/ngj+7F/xKBGgtSTZ1FuN5p/oOFDCH2Fihe2+wuw7B3Rc1SbHLG7n
# Wr4JZozdPbnudhrZgn+1A9SCFhH+B8k/QlKY2Qc+w+GrnC0JpJAmqtaF2aIaepPo
# kfbTUshDstIZ7MnCeAa+SWn2Exgrsn0Gv9nWdOrPgrvo0bqK6ceAhchi5nFmkkaJ
# MOy+Xx5GIAE91418wR8C2TlrTl58A81s15AYY1D7nZ0GeuZV5io7wPIAOWa14rOQ
# RdvQ/0rcZ+IkOFXz5Zj/L/Y/W4BpDyfuUVzLAah56zYkuV4im2cLt3YAOMFYZjjO
# 6W1sdbAcuA5QFmO4v5VmcTU8t/B423QzcnssE6sbM0nazMh/i6kjzvJUhdJTQmi+
# lKjIe+MHutTgrbjrwemjiafk3dOpFpKtso/4C/dhP2UfDIcKuGXNpSYxCvoknO2j
# TWvxRvir/PC7gzUzA4CrwQ==
# =YUUL
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 20 Apr 2023 11:03:37 AM BST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]

* tag 'pull-target-arm-20230420' of https://git.linaro.org/people/pmaydell/qemu-arm: (21 commits)
  arm/mcimx7d-sabre: Set fec2-phy-connected property to false
  fsl-imx7: Add fec[12]-phy-connected properties
  arm/mcimx6ul-evk: Set fec1-phy-connected property to false
  fsl-imx6ul: Add fec[12]-phy-connected properties
  hw/net/imx_fec: Support two Ethernet interfaces connected to single MDIO bus
  target/arm: Report pauth information to gdb as 'pauth_v2'
  docs/devel/kconfig.rst: Fix incorrect markup
  target/arm: Implement FEAT_PAN3
  target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2
  target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort()
  target/arm: Initialize debug capabilities only once
  hw/arm/virt: Restrict Cortex-A7 check to TCG
  target/arm: Remove KVM AArch32 CPU definitions
  hw/timer/imx_epit: fix limit check
  hw/timer/imx_epit: don't shadow variable
  tests/avocado: Add reboot tests to Cubieboard
  hw/arm: Add WDT to Allwinner-H3 and Orangepi-PC
  hw/arm: Add WDT to Allwinner-A10 and Cubieboard
  hw/watchdog: Allwinner WDT emulation for system reset
  exynos: Fix out-of-bounds access in exynos4210_gcomp_find debug printf
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-04-21 09:21:17 +01:00
commit 29c343a463
43 changed files with 738 additions and 64 deletions

View File

@ -274,7 +274,7 @@ or commenting out lines in the second group.
It is also possible to run QEMU's configure script with the It is also possible to run QEMU's configure script with the
``--without-default-devices`` option. When this is done, everything defaults ``--without-default-devices`` option. When this is done, everything defaults
to ``n`` unless it is ``select``ed or explicitly switched on in the to ``n`` unless it is ``select``\ ed or explicitly switched on in the
``.mak`` files. In other words, ``default`` and ``imply`` directives ``.mak`` files. In other words, ``default`` and ``imply`` directives
are disabled. When QEMU is built with this option, the user will probably are disabled. When QEMU is built with this option, the user will probably
want to change some lines in the first group, for example like this:: want to change some lines in the first group, for example like this::

View File

@ -15,3 +15,4 @@ Emulated devices:
- USB controller - USB controller
- SATA controller - SATA controller
- TWI (I2C) controller - TWI (I2C) controller
- Watchdog timer

View File

@ -56,6 +56,7 @@ the following architecture extensions:
- FEAT_MTE3 (MTE Asymmetric Fault Handling) - FEAT_MTE3 (MTE Asymmetric Fault Handling)
- FEAT_PAN (Privileged access never) - FEAT_PAN (Privileged access never)
- FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN) - FEAT_PAN2 (AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN)
- FEAT_PAN3 (Support for SCTLR_ELx.EPAN)
- FEAT_PAuth (Pointer authentication) - FEAT_PAuth (Pointer authentication)
- FEAT_PMULL (PMULL, PMULL2 instructions) - FEAT_PMULL (PMULL, PMULL2 instructions)
- FEAT_PMUv3p1 (PMU Extensions v3.1) - FEAT_PMUv3p1 (PMU Extensions v3.1)

View File

@ -26,6 +26,7 @@ The Orange Pi PC machine supports the following devices:
* System Control module * System Control module
* Security Identifier device * Security Identifier device
* TWI (I2C) * TWI (I2C)
* Watchdog timer
Limitations Limitations
""""""""""" """""""""""

View File

@ -6,7 +6,7 @@
notice and this notice are preserved. --> notice and this notice are preserved. -->
<!DOCTYPE feature SYSTEM "gdb-target.dtd"> <!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.aarch64.pauth"> <feature name="org.gnu.gdb.aarch64.pauth_v2">
<reg name="pauth_dmask" bitsize="64"/> <reg name="pauth_dmask" bitsize="64"/>
<reg name="pauth_cmask" bitsize="64"/> <reg name="pauth_cmask" bitsize="64"/>
<reg name="pauth_dmask_high" bitsize="64"/> <reg name="pauth_dmask_high" bitsize="64"/>

View File

@ -126,7 +126,7 @@ config OLIMEX_STM32_H405
config NSERIES config NSERIES
bool bool
select OMAP select OMAP
select TMP105 # tempature sensor select TMP105 # temperature sensor
select BLIZZARD # LCD/TV controller select BLIZZARD # LCD/TV controller
select ONENAND select ONENAND
select TSC210X # touchscreen/sensors/audio select TSC210X # touchscreen/sensors/audio
@ -325,6 +325,7 @@ config ALLWINNER_A10
select ALLWINNER_A10_PIC select ALLWINNER_A10_PIC
select ALLWINNER_A10_CCM select ALLWINNER_A10_CCM
select ALLWINNER_A10_DRAMC select ALLWINNER_A10_DRAMC
select ALLWINNER_WDT
select ALLWINNER_EMAC select ALLWINNER_EMAC
select ALLWINNER_I2C select ALLWINNER_I2C
select AXP209_PMU select AXP209_PMU
@ -336,6 +337,7 @@ config ALLWINNER_H3
select ALLWINNER_A10_PIT select ALLWINNER_A10_PIT
select ALLWINNER_SUN8I_EMAC select ALLWINNER_SUN8I_EMAC
select ALLWINNER_I2C select ALLWINNER_I2C
select ALLWINNER_WDT
select SERIAL select SERIAL
select ARM_TIMER select ARM_TIMER
select ARM_GIC select ARM_GIC

View File

@ -38,6 +38,7 @@
#define AW_A10_EHCI_BASE 0x01c14000 #define AW_A10_EHCI_BASE 0x01c14000
#define AW_A10_OHCI_BASE 0x01c14400 #define AW_A10_OHCI_BASE 0x01c14400
#define AW_A10_SATA_BASE 0x01c18000 #define AW_A10_SATA_BASE 0x01c18000
#define AW_A10_WDT_BASE 0x01c20c90
#define AW_A10_RTC_BASE 0x01c20d00 #define AW_A10_RTC_BASE 0x01c20d00
#define AW_A10_I2C0_BASE 0x01c2ac00 #define AW_A10_I2C0_BASE 0x01c2ac00
@ -92,6 +93,8 @@ static void aw_a10_init(Object *obj)
object_initialize_child(obj, "mmc0", &s->mmc0, TYPE_AW_SDHOST_SUN4I); object_initialize_child(obj, "mmc0", &s->mmc0, TYPE_AW_SDHOST_SUN4I);
object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN4I); object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN4I);
object_initialize_child(obj, "wdt", &s->wdt, TYPE_AW_WDT_SUN4I);
} }
static void aw_a10_realize(DeviceState *dev, Error **errp) static void aw_a10_realize(DeviceState *dev, Error **errp)
@ -203,6 +206,10 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal); sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, AW_A10_I2C0_BASE); sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, AW_A10_I2C0_BASE);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, qdev_get_gpio_in(dev, 7)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, qdev_get_gpio_in(dev, 7));
/* WDT */
sysbus_realize(SYS_BUS_DEVICE(&s->wdt), &error_fatal);
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->wdt), 0, AW_A10_WDT_BASE, 1);
} }
static void aw_a10_class_init(ObjectClass *oc, void *data) static void aw_a10_class_init(ObjectClass *oc, void *data)

View File

@ -49,6 +49,7 @@ const hwaddr allwinner_h3_memmap[] = {
[AW_H3_DEV_OHCI3] = 0x01c1d400, [AW_H3_DEV_OHCI3] = 0x01c1d400,
[AW_H3_DEV_CCU] = 0x01c20000, [AW_H3_DEV_CCU] = 0x01c20000,
[AW_H3_DEV_PIT] = 0x01c20c00, [AW_H3_DEV_PIT] = 0x01c20c00,
[AW_H3_DEV_WDT] = 0x01c20ca0,
[AW_H3_DEV_UART0] = 0x01c28000, [AW_H3_DEV_UART0] = 0x01c28000,
[AW_H3_DEV_UART1] = 0x01c28400, [AW_H3_DEV_UART1] = 0x01c28400,
[AW_H3_DEV_UART2] = 0x01c28800, [AW_H3_DEV_UART2] = 0x01c28800,
@ -234,6 +235,8 @@ static void allwinner_h3_init(Object *obj)
object_initialize_child(obj, "twi1", &s->i2c1, TYPE_AW_I2C_SUN6I); object_initialize_child(obj, "twi1", &s->i2c1, TYPE_AW_I2C_SUN6I);
object_initialize_child(obj, "twi2", &s->i2c2, TYPE_AW_I2C_SUN6I); object_initialize_child(obj, "twi2", &s->i2c2, TYPE_AW_I2C_SUN6I);
object_initialize_child(obj, "r_twi", &s->r_twi, TYPE_AW_I2C_SUN6I); object_initialize_child(obj, "r_twi", &s->r_twi, TYPE_AW_I2C_SUN6I);
object_initialize_child(obj, "wdt", &s->wdt, TYPE_AW_WDT_SUN6I);
} }
static void allwinner_h3_realize(DeviceState *dev, Error **errp) static void allwinner_h3_realize(DeviceState *dev, Error **errp)
@ -453,6 +456,11 @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->r_twi), 0, sysbus_connect_irq(SYS_BUS_DEVICE(&s->r_twi), 0,
qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_R_TWI)); qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_R_TWI));
/* WDT */
sysbus_realize(SYS_BUS_DEVICE(&s->wdt), &error_fatal);
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->wdt), 0,
s->memmap[AW_H3_DEV_WDT], 1);
/* Unimplemented devices */ /* Unimplemented devices */
for (i = 0; i < ARRAY_SIZE(unimplemented); i++) { for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
create_unimplemented_device(unimplemented[i].device_name, create_unimplemented_device(unimplemented[i].device_name,

View File

@ -326,7 +326,7 @@ static int mapline_size(const int *mapline)
/* /*
* Initialize board IRQs. * Initialize board IRQs.
* These IRQs contain splitted Int/External Combiner and External Gic IRQs. * These IRQs contain split Int/External Combiner and External Gic IRQs.
*/ */
static void exynos4210_init_board_irqs(Exynos4210State *s) static void exynos4210_init_board_irqs(Exynos4210State *s)
{ {
@ -744,7 +744,7 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
* - SDMA * - SDMA
* - ADMA2 * - ADMA2
* *
* As this part of the Exynos4210 is not publically available, * As this part of the Exynos4210 is not publicly available,
* we used the "HS-MMC Controller S3C2416X RISC Microprocessor" * we used the "HS-MMC Controller S3C2416X RISC Microprocessor"
* public datasheet which is very similar (implementing * public datasheet which is very similar (implementing
* MMC Specification Version 4.0 being the only difference noted) * MMC Specification Version 4.0 being the only difference noted)

View File

@ -407,7 +407,23 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
/* /*
* Ethernet * Ethernet
*
* We must use two loops since phy_connected affects the other interface
* and we have to set all properties before calling sysbus_realize().
*/ */
for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
s->phy_connected[i], &error_abort);
/*
* If the MDIO bus on this controller is not connected, assume the
* other controller provides support for it.
*/
if (!s->phy_connected[i]) {
object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
OBJECT(&s->eth[i]), &error_abort);
}
}
for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) { for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = { static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
FSL_IMX6UL_ENET1_ADDR, FSL_IMX6UL_ENET1_ADDR,
@ -620,6 +636,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
static Property fsl_imx6ul_properties[] = { static Property fsl_imx6ul_properties[] = {
DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0), DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1), DEFINE_PROP_UINT32("fec2-phy-num", FslIMX6ULState, phy_num[1], 1),
DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX6ULState, phy_connected[0],
true),
DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX6ULState, phy_connected[1],
true),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };

View File

@ -395,7 +395,23 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
/* /*
* Ethernet * Ethernet
*
* We must use two loops since phy_connected affects the other interface
* and we have to set all properties before calling sysbus_realize().
*/ */
for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
object_property_set_bool(OBJECT(&s->eth[i]), "phy-connected",
s->phy_connected[i], &error_abort);
/*
* If the MDIO bus on this controller is not connected, assume the
* other controller provides support for it.
*/
if (!s->phy_connected[i]) {
object_property_set_link(OBJECT(&s->eth[1 - i]), "phy-consumer",
OBJECT(&s->eth[i]), &error_abort);
}
}
for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) { for (i = 0; i < FSL_IMX7_NUM_ETHS; i++) {
static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = { static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
FSL_IMX7_ENET1_ADDR, FSL_IMX7_ENET1_ADDR,
@ -601,6 +617,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
static Property fsl_imx7_properties[] = { static Property fsl_imx7_properties[] = {
DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0), DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0),
DEFINE_PROP_UINT32("fec2-phy-num", FslIMX7State, phy_num[1], 1), DEFINE_PROP_UINT32("fec2-phy-num", FslIMX7State, phy_num[1], 1),
DEFINE_PROP_BOOL("fec1-phy-connected", FslIMX7State, phy_connected[0],
true),
DEFINE_PROP_BOOL("fec2-phy-connected", FslIMX7State, phy_connected[1],
true),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };

View File

@ -41,6 +41,8 @@ static void mcimx6ul_evk_init(MachineState *machine)
object_property_add_child(OBJECT(machine), "soc", OBJECT(s)); object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
object_property_set_uint(OBJECT(s), "fec1-phy-num", 2, &error_fatal); object_property_set_uint(OBJECT(s), "fec1-phy-num", 2, &error_fatal);
object_property_set_uint(OBJECT(s), "fec2-phy-num", 1, &error_fatal); object_property_set_uint(OBJECT(s), "fec2-phy-num", 1, &error_fatal);
object_property_set_bool(OBJECT(s), "fec1-phy-connected", false,
&error_fatal);
qdev_realize(DEVICE(s), NULL, &error_fatal); qdev_realize(DEVICE(s), NULL, &error_fatal);
memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_MMDC_ADDR, memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_MMDC_ADDR,

View File

@ -41,6 +41,8 @@ static void mcimx7d_sabre_init(MachineState *machine)
s = FSL_IMX7(object_new(TYPE_FSL_IMX7)); s = FSL_IMX7(object_new(TYPE_FSL_IMX7));
object_property_add_child(OBJECT(machine), "soc", OBJECT(s)); object_property_add_child(OBJECT(machine), "soc", OBJECT(s));
object_property_set_bool(OBJECT(s), "fec2-phy-connected", false,
&error_fatal);
qdev_realize(DEVICE(s), NULL, &error_fatal); qdev_realize(DEVICE(s), NULL, &error_fatal);
memory_region_add_subregion(get_system_memory(), FSL_IMX7_MMDC_ADDR, memory_region_add_subregion(get_system_memory(), FSL_IMX7_MMDC_ADDR,

View File

@ -100,7 +100,7 @@
#define MP_LCD_SPI_CMD 0x00104011 #define MP_LCD_SPI_CMD 0x00104011
#define MP_LCD_SPI_INVALID 0x00000000 #define MP_LCD_SPI_INVALID 0x00000000
/* Commmands */ /* Commands */
#define MP_LCD_INST_SETPAGE0 0xB0 #define MP_LCD_INST_SETPAGE0 0xB0
/* ... */ /* ... */
#define MP_LCD_INST_SETPAGE7 0xB7 #define MP_LCD_INST_SETPAGE7 0xB7

View File

@ -4057,7 +4057,7 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *dram,
s->led[1] = omap_lpg_init(system_memory, s->led[1] = omap_lpg_init(system_memory,
0xfffbd800, omap_findclk(s, "clk32-kHz")); 0xfffbd800, omap_findclk(s, "clk32-kHz"));
/* Register mappings not currenlty implemented: /* Register mappings not currently implemented:
* MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310) * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
* MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310) * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310)
* USB W2FC fffb4000 - fffb47ff * USB W2FC fffb4000 - fffb47ff

View File

@ -2523,7 +2523,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sdram,
omap_findclk(s, "func_96m_clk"), omap_findclk(s, "func_96m_clk"),
omap_findclk(s, "core_l4_iclk")); omap_findclk(s, "core_l4_iclk"));
/* All register mappings (includin those not currenlty implemented): /* All register mappings (including those not currently implemented):
* SystemControlMod 48000000 - 48000fff * SystemControlMod 48000000 - 48000fff
* SystemControlL4 48001000 - 48001fff * SystemControlL4 48001000 - 48001fff
* 32kHz Timer Mod 48004000 - 48004fff * 32kHz Timer Mod 48004000 - 48004fff

View File

@ -694,7 +694,7 @@ static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size)
build_append_int_noprefix(table_data, 0xE, 1); /* Type */ build_append_int_noprefix(table_data, 0xE, 1); /* Type */
build_append_int_noprefix(table_data, 16, 1); /* Length */ build_append_int_noprefix(table_data, 16, 1); /* Length */
build_append_int_noprefix(table_data, 0, 2); /* Reserved */ build_append_int_noprefix(table_data, 0, 2); /* Reserved */
/* Discovery Range Base Addres */ /* Discovery Range Base Address */
build_append_int_noprefix(table_data, base, 8); build_append_int_noprefix(table_data, base, 8);
build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */ build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */
} }

View File

@ -204,7 +204,9 @@ static const int a15irqmap[] = {
}; };
static const char *valid_cpus[] = { static const char *valid_cpus[] = {
#ifdef CONFIG_TCG
ARM_CPU_TYPE_NAME("cortex-a7"), ARM_CPU_TYPE_NAME("cortex-a7"),
#endif
ARM_CPU_TYPE_NAME("cortex-a15"), ARM_CPU_TYPE_NAME("cortex-a15"),
ARM_CPU_TYPE_NAME("cortex-a35"), ARM_CPU_TYPE_NAME("cortex-a35"),
ARM_CPU_TYPE_NAME("cortex-a53"), ARM_CPU_TYPE_NAME("cortex-a53"),
@ -2052,7 +2054,7 @@ static void machvirt_init(MachineState *machine)
int pa_bits; int pa_bits;
/* /*
* Instanciate a temporary CPU object to find out about what * Instantiate a temporary CPU object to find out about what
* we are about to deal with. Once this is done, get rid of * we are about to deal with. Once this is done, get rid of
* the object. * the object.
*/ */

View File

@ -659,7 +659,7 @@ static void versal_virt_init(MachineState *machine)
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz); fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
/* Make the APU cpu address space visible to virtio and other /* Make the APU cpu address space visible to virtio and other
* modules unaware of muliple address-spaces. */ * modules unaware of multiple address-spaces. */
memory_region_add_subregion_overlap(get_system_memory(), memory_region_add_subregion_overlap(get_system_memory(),
0, &s->soc.fpd.apu.mr, 0); 0, &s->soc.fpd.apu.mr, 0);

View File

@ -282,11 +282,19 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
uint32_t val; uint32_t val;
uint32_t phy = reg / 32; uint32_t phy = reg / 32;
if (phy != s->phy_num) { if (!s->phy_connected) {
trace_imx_phy_read_num(phy, s->phy_num);
return 0xffff; return 0xffff;
} }
if (phy != s->phy_num) {
if (s->phy_consumer && phy == s->phy_consumer->phy_num) {
s = s->phy_consumer;
} else {
trace_imx_phy_read_num(phy, s->phy_num);
return 0xffff;
}
}
reg %= 32; reg %= 32;
switch (reg) { switch (reg) {
@ -343,11 +351,19 @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
{ {
uint32_t phy = reg / 32; uint32_t phy = reg / 32;
if (phy != s->phy_num) { if (!s->phy_connected) {
trace_imx_phy_write_num(phy, s->phy_num);
return; return;
} }
if (phy != s->phy_num) {
if (s->phy_consumer && phy == s->phy_consumer->phy_num) {
s = s->phy_consumer;
} else {
trace_imx_phy_write_num(phy, s->phy_num);
return;
}
}
reg %= 32; reg %= 32;
trace_imx_phy_write(val, phy, reg); trace_imx_phy_write(val, phy, reg);
@ -1327,6 +1343,9 @@ static Property imx_eth_properties[] = {
DEFINE_NIC_PROPERTIES(IMXFECState, conf), DEFINE_NIC_PROPERTIES(IMXFECState, conf),
DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1), DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
DEFINE_PROP_UINT32("phy-num", IMXFECState, phy_num, 0), DEFINE_PROP_UINT32("phy-num", IMXFECState, phy_num, 0),
DEFINE_PROP_BOOL("phy-connected", IMXFECState, phy_connected, true),
DEFINE_PROP_LINK("phy-consumer", IMXFECState, phy_consumer, TYPE_IMX_FEC,
IMXFECState *),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };

View File

@ -480,11 +480,14 @@ static int32_t exynos4210_gcomp_find(Exynos4210MCTState *s)
res = min_comp_i; res = min_comp_i;
} }
DPRINTF("found comparator %d: comp 0x%llx distance 0x%llx, gfrc 0x%llx\n", if (res >= 0) {
res, DPRINTF("found comparator %d: "
s->g_timer.reg.comp[res], "comp 0x%llx distance 0x%llx, gfrc 0x%llx\n",
distance_min, res,
gfrc); s->g_timer.reg.comp[res],
distance_min,
gfrc);
}
return res; return res;
} }

View File

@ -179,7 +179,7 @@ static void imx_epit_update_compare_timer(IMXEPITState *s)
* the compare value. Otherwise it may fire at most once in the * the compare value. Otherwise it may fire at most once in the
* current round. * current round.
*/ */
bool is_oneshot = (limit >= s->cmp); is_oneshot = (limit < s->cmp);
if (counter >= s->cmp) { if (counter >= s->cmp) {
/* The compare timer fires in the current round. */ /* The compare timer fires in the current round. */
counter -= s->cmp; counter -= s->cmp;

View File

@ -20,3 +20,7 @@ config WDT_IMX2
config WDT_SBSA config WDT_SBSA
bool bool
config ALLWINNER_WDT
bool
select PTIMER

416
hw/watchdog/allwinner-wdt.c Normal file
View File

@ -0,0 +1,416 @@
/*
* Allwinner Watchdog emulation
*
* Copyright (C) 2023 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
*
* This file is derived from Allwinner RTC,
* by Niek Linnenbank.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/units.h"
#include "qemu/module.h"
#include "trace.h"
#include "hw/sysbus.h"
#include "hw/registerfields.h"
#include "hw/watchdog/allwinner-wdt.h"
#include "sysemu/watchdog.h"
#include "migration/vmstate.h"
/* WDT registers */
enum {
REG_IRQ_EN = 0, /* Watchdog interrupt enable */
REG_IRQ_STA, /* Watchdog interrupt status */
REG_CTRL, /* Watchdog control register */
REG_CFG, /* Watchdog configuration register */
REG_MODE, /* Watchdog mode register */
};
/* Universal WDT register flags */
#define WDT_RESTART_MASK (1 << 0)
#define WDT_EN_MASK (1 << 0)
/* sun4i specific WDT register flags */
#define RST_EN_SUN4I_MASK (1 << 1)
#define INTV_VALUE_SUN4I_SHIFT (3)
#define INTV_VALUE_SUN4I_MASK (0xfu << INTV_VALUE_SUN4I_SHIFT)
/* sun6i specific WDT register flags */
#define RST_EN_SUN6I_MASK (1 << 0)
#define KEY_FIELD_SUN6I_SHIFT (1)
#define KEY_FIELD_SUN6I_MASK (0xfffu << KEY_FIELD_SUN6I_SHIFT)
#define KEY_FIELD_SUN6I (0xA57u)
#define INTV_VALUE_SUN6I_SHIFT (4)
#define INTV_VALUE_SUN6I_MASK (0xfu << INTV_VALUE_SUN6I_SHIFT)
/* Map of INTV_VALUE to 0.5s units. */
static const uint8_t allwinner_wdt_count_map[] = {
1,
2,
4,
6,
8,
10,
12,
16,
20,
24,
28,
32
};
/* WDT sun4i register map (offset to name) */
const uint8_t allwinner_wdt_sun4i_regmap[] = {
[0x0000] = REG_CTRL,
[0x0004] = REG_MODE,
};
/* WDT sun6i register map (offset to name) */
const uint8_t allwinner_wdt_sun6i_regmap[] = {
[0x0000] = REG_IRQ_EN,
[0x0004] = REG_IRQ_STA,
[0x0010] = REG_CTRL,
[0x0014] = REG_CFG,
[0x0018] = REG_MODE,
};
static bool allwinner_wdt_sun4i_read(AwWdtState *s, uint32_t offset)
{
/* no sun4i specific registers currently implemented */
return false;
}
static bool allwinner_wdt_sun4i_write(AwWdtState *s, uint32_t offset,
uint32_t data)
{
/* no sun4i specific registers currently implemented */
return false;
}
static bool allwinner_wdt_sun4i_can_reset_system(AwWdtState *s)
{
if (s->regs[REG_MODE] & RST_EN_SUN4I_MASK) {
return true;
} else {
return false;
}
}
static bool allwinner_wdt_sun4i_is_key_valid(AwWdtState *s, uint32_t val)
{
/* sun4i has no key */
return true;
}
static uint8_t allwinner_wdt_sun4i_get_intv_value(AwWdtState *s)
{
return ((s->regs[REG_MODE] & INTV_VALUE_SUN4I_MASK) >>
INTV_VALUE_SUN4I_SHIFT);
}
static bool allwinner_wdt_sun6i_read(AwWdtState *s, uint32_t offset)
{
const AwWdtClass *c = AW_WDT_GET_CLASS(s);
switch (c->regmap[offset]) {
case REG_IRQ_EN:
case REG_IRQ_STA:
case REG_CFG:
return true;
default:
break;
}
return false;
}
static bool allwinner_wdt_sun6i_write(AwWdtState *s, uint32_t offset,
uint32_t data)
{
const AwWdtClass *c = AW_WDT_GET_CLASS(s);
switch (c->regmap[offset]) {
case REG_IRQ_EN:
case REG_IRQ_STA:
case REG_CFG:
return true;
default:
break;
}
return false;
}
static bool allwinner_wdt_sun6i_can_reset_system(AwWdtState *s)
{
if (s->regs[REG_CFG] & RST_EN_SUN6I_MASK) {
return true;
} else {
return false;
}
}
static bool allwinner_wdt_sun6i_is_key_valid(AwWdtState *s, uint32_t val)
{
uint16_t key = (val & KEY_FIELD_SUN6I_MASK) >> KEY_FIELD_SUN6I_SHIFT;
return (key == KEY_FIELD_SUN6I);
}
static uint8_t allwinner_wdt_sun6i_get_intv_value(AwWdtState *s)
{
return ((s->regs[REG_MODE] & INTV_VALUE_SUN6I_MASK) >>
INTV_VALUE_SUN6I_SHIFT);
}
static void allwinner_wdt_update_timer(AwWdtState *s)
{
const AwWdtClass *c = AW_WDT_GET_CLASS(s);
uint8_t count = c->get_intv_value(s);
ptimer_transaction_begin(s->timer);
ptimer_stop(s->timer);
/* Use map to convert. */
if (count < sizeof(allwinner_wdt_count_map)) {
ptimer_set_count(s->timer, allwinner_wdt_count_map[count]);
} else {
qemu_log_mask(LOG_GUEST_ERROR, "%s: incorrect INTV_VALUE 0x%02x\n",
__func__, count);
}
ptimer_run(s->timer, 1);
ptimer_transaction_commit(s->timer);
trace_allwinner_wdt_update_timer(count);
}
static uint64_t allwinner_wdt_read(void *opaque, hwaddr offset,
unsigned size)
{
AwWdtState *s = AW_WDT(opaque);
const AwWdtClass *c = AW_WDT_GET_CLASS(s);
uint64_t r;
if (offset >= c->regmap_size) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
__func__, (uint32_t)offset);
return 0;
}
switch (c->regmap[offset]) {
case REG_CTRL:
case REG_MODE:
r = s->regs[c->regmap[offset]];
break;
default:
if (!c->read(s, offset)) {
qemu_log_mask(LOG_UNIMP, "%s: unimplemented register 0x%04x\n",
__func__, (uint32_t)offset);
return 0;
}
r = s->regs[c->regmap[offset]];
break;
}
trace_allwinner_wdt_read(offset, r, size);
return r;
}
static void allwinner_wdt_write(void *opaque, hwaddr offset,
uint64_t val, unsigned size)
{
AwWdtState *s = AW_WDT(opaque);
const AwWdtClass *c = AW_WDT_GET_CLASS(s);
uint32_t old_val;
if (offset >= c->regmap_size) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
__func__, (uint32_t)offset);
return;
}
trace_allwinner_wdt_write(offset, val, size);
switch (c->regmap[offset]) {
case REG_CTRL:
if (c->is_key_valid(s, val)) {
if (val & WDT_RESTART_MASK) {
/* Kick timer */
allwinner_wdt_update_timer(s);
}
}
break;
case REG_MODE:
old_val = s->regs[REG_MODE];
s->regs[REG_MODE] = (uint32_t)val;
/* Check for rising edge on WDOG_MODE_EN */
if ((s->regs[REG_MODE] & ~old_val) & WDT_EN_MASK) {
allwinner_wdt_update_timer(s);
}
break;
default:
if (!c->write(s, offset, val)) {
qemu_log_mask(LOG_UNIMP, "%s: unimplemented register 0x%04x\n",
__func__, (uint32_t)offset);
}
s->regs[c->regmap[offset]] = (uint32_t)val;
break;
}
}
static const MemoryRegionOps allwinner_wdt_ops = {
.read = allwinner_wdt_read,
.write = allwinner_wdt_write,
.endianness = DEVICE_NATIVE_ENDIAN,
.valid = {
.min_access_size = 4,
.max_access_size = 4,
},
.impl.min_access_size = 4,
};
static void allwinner_wdt_expired(void *opaque)
{
AwWdtState *s = AW_WDT(opaque);
const AwWdtClass *c = AW_WDT_GET_CLASS(s);
bool enabled = s->regs[REG_MODE] & WDT_EN_MASK;
bool reset_enabled = c->can_reset_system(s);
trace_allwinner_wdt_expired(enabled, reset_enabled);
/* Perform watchdog action if watchdog is enabled and can trigger reset */
if (enabled && reset_enabled) {
watchdog_perform_action();
}
}
static void allwinner_wdt_reset_enter(Object *obj, ResetType type)
{
AwWdtState *s = AW_WDT(obj);
trace_allwinner_wdt_reset_enter();
/* Clear registers */
memset(s->regs, 0, sizeof(s->regs));
}
static const VMStateDescription allwinner_wdt_vmstate = {
.name = "allwinner-wdt",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_PTIMER(timer, AwWdtState),
VMSTATE_UINT32_ARRAY(regs, AwWdtState, AW_WDT_REGS_NUM),
VMSTATE_END_OF_LIST()
}
};
static void allwinner_wdt_init(Object *obj)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
AwWdtState *s = AW_WDT(obj);
const AwWdtClass *c = AW_WDT_GET_CLASS(s);
/* Memory mapping */
memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_wdt_ops, s,
TYPE_AW_WDT, c->regmap_size * 4);
sysbus_init_mmio(sbd, &s->iomem);
}
static void allwinner_wdt_realize(DeviceState *dev, Error **errp)
{
AwWdtState *s = AW_WDT(dev);
s->timer = ptimer_init(allwinner_wdt_expired, s,
PTIMER_POLICY_NO_IMMEDIATE_TRIGGER |
PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
ptimer_transaction_begin(s->timer);
/* Set to 2Hz (0.5s period); other periods are multiples of 0.5s. */
ptimer_set_freq(s->timer, 2);
ptimer_set_limit(s->timer, 0xff, 1);
ptimer_transaction_commit(s->timer);
}
static void allwinner_wdt_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ResettableClass *rc = RESETTABLE_CLASS(klass);
rc->phases.enter = allwinner_wdt_reset_enter;
dc->realize = allwinner_wdt_realize;
dc->vmsd = &allwinner_wdt_vmstate;
}
static void allwinner_wdt_sun4i_class_init(ObjectClass *klass, void *data)
{
AwWdtClass *awc = AW_WDT_CLASS(klass);
awc->regmap = allwinner_wdt_sun4i_regmap;
awc->regmap_size = sizeof(allwinner_wdt_sun4i_regmap);
awc->read = allwinner_wdt_sun4i_read;
awc->write = allwinner_wdt_sun4i_write;
awc->can_reset_system = allwinner_wdt_sun4i_can_reset_system;
awc->is_key_valid = allwinner_wdt_sun4i_is_key_valid;
awc->get_intv_value = allwinner_wdt_sun4i_get_intv_value;
}
static void allwinner_wdt_sun6i_class_init(ObjectClass *klass, void *data)
{
AwWdtClass *awc = AW_WDT_CLASS(klass);
awc->regmap = allwinner_wdt_sun6i_regmap;
awc->regmap_size = sizeof(allwinner_wdt_sun6i_regmap);
awc->read = allwinner_wdt_sun6i_read;
awc->write = allwinner_wdt_sun6i_write;
awc->can_reset_system = allwinner_wdt_sun6i_can_reset_system;
awc->is_key_valid = allwinner_wdt_sun6i_is_key_valid;
awc->get_intv_value = allwinner_wdt_sun6i_get_intv_value;
}
static const TypeInfo allwinner_wdt_info = {
.name = TYPE_AW_WDT,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_init = allwinner_wdt_init,
.instance_size = sizeof(AwWdtState),
.class_init = allwinner_wdt_class_init,
.class_size = sizeof(AwWdtClass),
.abstract = true,
};
static const TypeInfo allwinner_wdt_sun4i_info = {
.name = TYPE_AW_WDT_SUN4I,
.parent = TYPE_AW_WDT,
.class_init = allwinner_wdt_sun4i_class_init,
};
static const TypeInfo allwinner_wdt_sun6i_info = {
.name = TYPE_AW_WDT_SUN6I,
.parent = TYPE_AW_WDT,
.class_init = allwinner_wdt_sun6i_class_init,
};
static void allwinner_wdt_register(void)
{
type_register_static(&allwinner_wdt_info);
type_register_static(&allwinner_wdt_sun4i_info);
type_register_static(&allwinner_wdt_sun6i_info);
}
type_init(allwinner_wdt_register)

View File

@ -1,4 +1,5 @@
softmmu_ss.add(files('watchdog.c')) softmmu_ss.add(files('watchdog.c'))
softmmu_ss.add(when: 'CONFIG_ALLWINNER_WDT', if_true: files('allwinner-wdt.c'))
softmmu_ss.add(when: 'CONFIG_CMSDK_APB_WATCHDOG', if_true: files('cmsdk-apb-watchdog.c')) softmmu_ss.add(when: 'CONFIG_CMSDK_APB_WATCHDOG', if_true: files('cmsdk-apb-watchdog.c'))
softmmu_ss.add(when: 'CONFIG_WDT_IB6300ESB', if_true: files('wdt_i6300esb.c')) softmmu_ss.add(when: 'CONFIG_WDT_IB6300ESB', if_true: files('wdt_i6300esb.c'))
softmmu_ss.add(when: 'CONFIG_WDT_IB700', if_true: files('wdt_ib700.c')) softmmu_ss.add(when: 'CONFIG_WDT_IB700', if_true: files('wdt_ib700.c'))

View File

@ -1,5 +1,12 @@
# See docs/devel/tracing.rst for syntax documentation. # See docs/devel/tracing.rst for syntax documentation.
# allwinner-wdt.c
allwinner_wdt_read(uint64_t offset, uint64_t data, unsigned size) "Allwinner watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
allwinner_wdt_write(uint64_t offset, uint64_t data, unsigned size) "Allwinner watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
allwinner_wdt_reset_enter(void) "Allwinner watchdog: reset"
allwinner_wdt_update_timer(uint8_t count) "Allwinner watchdog: count %" PRIu8
allwinner_wdt_expired(bool enabled, bool reset_enabled) "Allwinner watchdog: enabled %u reset_enabled %u"
# cmsdk-apb-watchdog.c # cmsdk-apb-watchdog.c
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"

View File

@ -13,6 +13,7 @@
#include "hw/misc/allwinner-a10-ccm.h" #include "hw/misc/allwinner-a10-ccm.h"
#include "hw/misc/allwinner-a10-dramc.h" #include "hw/misc/allwinner-a10-dramc.h"
#include "hw/i2c/allwinner-i2c.h" #include "hw/i2c/allwinner-i2c.h"
#include "hw/watchdog/allwinner-wdt.h"
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
#include "target/arm/cpu.h" #include "target/arm/cpu.h"
@ -41,6 +42,7 @@ struct AwA10State {
AwSdHostState mmc0; AwSdHostState mmc0;
AWI2CState i2c0; AWI2CState i2c0;
AwRtcState rtc; AwRtcState rtc;
AwWdtState wdt;
MemoryRegion sram_a; MemoryRegion sram_a;
EHCISysBusState ehci[AW_A10_NUM_USB]; EHCISysBusState ehci[AW_A10_NUM_USB];
OHCISysBusState ohci[AW_A10_NUM_USB]; OHCISysBusState ohci[AW_A10_NUM_USB];

View File

@ -48,6 +48,7 @@
#include "hw/net/allwinner-sun8i-emac.h" #include "hw/net/allwinner-sun8i-emac.h"
#include "hw/rtc/allwinner-rtc.h" #include "hw/rtc/allwinner-rtc.h"
#include "hw/i2c/allwinner-i2c.h" #include "hw/i2c/allwinner-i2c.h"
#include "hw/watchdog/allwinner-wdt.h"
#include "target/arm/cpu.h" #include "target/arm/cpu.h"
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
@ -96,7 +97,8 @@ enum {
AW_H3_DEV_RTC, AW_H3_DEV_RTC,
AW_H3_DEV_CPUCFG, AW_H3_DEV_CPUCFG,
AW_H3_DEV_R_TWI, AW_H3_DEV_R_TWI,
AW_H3_DEV_SDRAM AW_H3_DEV_SDRAM,
AW_H3_DEV_WDT
}; };
/** Total number of CPU cores in the H3 SoC */ /** Total number of CPU cores in the H3 SoC */
@ -141,6 +143,7 @@ struct AwH3State {
AWI2CState r_twi; AWI2CState r_twi;
AwSun8iEmacState emac; AwSun8iEmacState emac;
AwRtcState rtc; AwRtcState rtc;
AwWdtState wdt;
GICState gic; GICState gic;
MemoryRegion sram_a1; MemoryRegion sram_a1;
MemoryRegion sram_a2; MemoryRegion sram_a2;

View File

@ -89,6 +89,7 @@ struct FslIMX6ULState {
MemoryRegion ocram_alias; MemoryRegion ocram_alias;
uint32_t phy_num[FSL_IMX6UL_NUM_ETHS]; uint32_t phy_num[FSL_IMX6UL_NUM_ETHS];
bool phy_connected[FSL_IMX6UL_NUM_ETHS];
}; };
enum FslIMX6ULMemoryMap { enum FslIMX6ULMemoryMap {

View File

@ -82,6 +82,7 @@ struct FslIMX7State {
ChipideaState usb[FSL_IMX7_NUM_USBS]; ChipideaState usb[FSL_IMX7_NUM_USBS];
DesignwarePCIEHost pcie; DesignwarePCIEHost pcie;
uint32_t phy_num[FSL_IMX7_NUM_ETHS]; uint32_t phy_num[FSL_IMX7_NUM_ETHS];
bool phy_connected[FSL_IMX7_NUM_ETHS];
}; };
enum FslIMX7MemoryMap { enum FslIMX7MemoryMap {

View File

@ -270,6 +270,8 @@ struct IMXFECState {
uint32_t phy_int; uint32_t phy_int;
uint32_t phy_int_mask; uint32_t phy_int_mask;
uint32_t phy_num; uint32_t phy_num;
bool phy_connected;
struct IMXFECState *phy_consumer;
bool is_fec; bool is_fec;

View File

@ -0,0 +1,123 @@
/*
* Allwinner Watchdog emulation
*
* Copyright (C) 2023 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
*
* This file is derived from Allwinner RTC,
* by Niek Linnenbank.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HW_WATCHDOG_ALLWINNER_WDT_H
#define HW_WATCHDOG_ALLWINNER_WDT_H
#include "qom/object.h"
#include "hw/ptimer.h"
#include "hw/sysbus.h"
/*
* This is a model of the Allwinner watchdog.
* Since watchdog registers belong to the timer module (and are shared with the
* RTC module), the interrupt line from watchdog is not handled right now.
* In QEMU, we just wire up the watchdog reset to watchdog_perform_action(),
* at least for the moment.
*/
#define TYPE_AW_WDT "allwinner-wdt"
/** Allwinner WDT sun4i family (A10, A12), also sun7i (A20) */
#define TYPE_AW_WDT_SUN4I TYPE_AW_WDT "-sun4i"
/** Allwinner WDT sun6i family and newer (A31, H2+, H3, etc) */
#define TYPE_AW_WDT_SUN6I TYPE_AW_WDT "-sun6i"
/** Number of WDT registers */
#define AW_WDT_REGS_NUM (5)
OBJECT_DECLARE_TYPE(AwWdtState, AwWdtClass, AW_WDT)
/**
* Allwinner WDT object instance state.
*/
struct AwWdtState {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
MemoryRegion iomem;
struct ptimer_state *timer;
uint32_t regs[AW_WDT_REGS_NUM];
};
/**
* Allwinner WDT class-level struct.
*
* This struct is filled by each sunxi device specific code
* such that the generic code can use this struct to support
* all devices.
*/
struct AwWdtClass {
/*< private >*/
SysBusDeviceClass parent_class;
/*< public >*/
/** Defines device specific register map */
const uint8_t *regmap;
/** Size of the regmap in bytes */
size_t regmap_size;
/**
* Read device specific register
*
* @offset: register offset to read
* @return true if register read successful, false otherwise
*/
bool (*read)(AwWdtState *s, uint32_t offset);
/**
* Write device specific register
*
* @offset: register offset to write
* @data: value to set in register
* @return true if register write successful, false otherwise
*/
bool (*write)(AwWdtState *s, uint32_t offset, uint32_t data);
/**
* Check if watchdog can generate system reset
*
* @return true if watchdog can generate system reset
*/
bool (*can_reset_system)(AwWdtState *s);
/**
* Check if provided key is valid
*
* @value: value written to register
* @return true if key is valid, false otherwise
*/
bool (*is_key_valid)(AwWdtState *s, uint32_t val);
/**
* Get current INTV_VALUE setting
*
* @return current INTV_VALUE (0-15)
*/
uint8_t (*get_intv_value)(AwWdtState *s);
};
#endif /* HW_WATCHDOG_ALLWINNER_WDT_H */

View File

@ -3823,6 +3823,11 @@ static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2; return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
} }
static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id)
{
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3;
}
static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id) static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
{ {
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0; return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;

View File

@ -1302,7 +1302,7 @@ static void aarch64_max_initfn(Object *obj)
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */ t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1); /* FEAT_VHE */
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* FEAT_HPDS */
t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); /* FEAT_LOR */
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* FEAT_PAN2 */ t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 3); /* FEAT_PAN3 */
t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* FEAT_XNX */
t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */ t = FIELD_DP64(t, ID_AA64MMFR1, ETS, 1); /* FEAT_ETS */
t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */ t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1); /* FEAT_HCX */

View File

@ -546,7 +546,6 @@ static void cortex_a7_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL2); set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU); set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
cpu->midr = 0x410fc075; cpu->midr = 0x410fc075;
cpu->reset_fpsid = 0x41023075; cpu->reset_fpsid = 0x41023075;
cpu->isar.mvfr0 = 0x10110222; cpu->isar.mvfr0 = 0x10110222;
@ -595,7 +594,6 @@ static void cortex_a15_initfn(Object *obj)
set_feature(&cpu->env, ARM_FEATURE_EL2); set_feature(&cpu->env, ARM_FEATURE_EL2);
set_feature(&cpu->env, ARM_FEATURE_EL3); set_feature(&cpu->env, ARM_FEATURE_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU); set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
/* r4p0 cpu, not requiring expensive tlb flush errata */ /* r4p0 cpu, not requiring expensive tlb flush errata */
cpu->midr = 0x414fc0f0; cpu->midr = 0x414fc0f0;
cpu->revidr = 0x0; cpu->revidr = 0x0;

View File

@ -521,18 +521,17 @@ void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
aarch64_gdb_set_fpu_reg, aarch64_gdb_set_fpu_reg,
34, "aarch64-fpu.xml", 0); 34, "aarch64-fpu.xml", 0);
} }
#if 0
/* /*
* GDB versions 9 through 12 have a bug which means they will * Note that we report pauth information via the feature name
* crash if they see this XML from QEMU; disable it for the 8.0 * org.gnu.gdb.aarch64.pauth_v2, not org.gnu.gdb.aarch64.pauth.
* release, pending a better solution. * GDB versions 9 through 12 have a bug where they will crash
* if they see the latter XML from QEMU.
*/ */
if (isar_feature_aa64_pauth(&cpu->isar)) { if (isar_feature_aa64_pauth(&cpu->isar)) {
gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg, gdb_register_coprocessor(cs, aarch64_gdb_get_pauth_reg,
aarch64_gdb_set_pauth_reg, aarch64_gdb_set_pauth_reg,
4, "aarch64-pauth.xml", 0); 4, "aarch64-pauth.xml", 0);
} }
#endif
#endif #endif
} else { } else {
if (arm_feature(env, ARM_FEATURE_NEON)) { if (arm_feature(env, ARM_FEATURE_NEON)) {

View File

@ -124,13 +124,10 @@ MISMATCH_CHECK(QEMU_PSCI_RET_INTERNAL_FAILURE, PSCI_RET_INTERNAL_FAILURE);
MISMATCH_CHECK(QEMU_PSCI_RET_NOT_PRESENT, PSCI_RET_NOT_PRESENT); MISMATCH_CHECK(QEMU_PSCI_RET_NOT_PRESENT, PSCI_RET_NOT_PRESENT);
MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED); MISMATCH_CHECK(QEMU_PSCI_RET_DISABLED, PSCI_RET_DISABLED);
/* Note that KVM uses overlapping values for AArch32 and AArch64 /*
* target CPU numbers. AArch32 targets: * Note that KVM uses overlapping values for AArch32 and AArch64
* target CPU numbers. AArch64 targets:
*/ */
#define QEMU_KVM_ARM_TARGET_CORTEX_A15 0
#define QEMU_KVM_ARM_TARGET_CORTEX_A7 1
/* AArch64 targets: */
#define QEMU_KVM_ARM_TARGET_AEM_V8 0 #define QEMU_KVM_ARM_TARGET_AEM_V8 0
#define QEMU_KVM_ARM_TARGET_FOUNDATION_V8 1 #define QEMU_KVM_ARM_TARGET_FOUNDATION_V8 1
#define QEMU_KVM_ARM_TARGET_CORTEX_A57 2 #define QEMU_KVM_ARM_TARGET_CORTEX_A57 2

View File

@ -280,6 +280,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
} }
} }
kvm_arm_init_debug(s);
return ret; return ret;
} }

View File

@ -74,24 +74,16 @@ GArray *hw_breakpoints, *hw_watchpoints;
#define get_hw_bp(i) (&g_array_index(hw_breakpoints, HWBreakpoint, i)) #define get_hw_bp(i) (&g_array_index(hw_breakpoints, HWBreakpoint, i))
#define get_hw_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i)) #define get_hw_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i))
/** void kvm_arm_init_debug(KVMState *s)
* kvm_arm_init_debug() - check for guest debug capabilities
* @cs: CPUState
*
* kvm_check_extension returns the number of debug registers we have
* or 0 if we have none.
*
*/
static void kvm_arm_init_debug(CPUState *cs)
{ {
have_guest_debug = kvm_check_extension(cs->kvm_state, have_guest_debug = kvm_check_extension(s,
KVM_CAP_SET_GUEST_DEBUG); KVM_CAP_SET_GUEST_DEBUG);
max_hw_wps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_WPS); max_hw_wps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_WPS);
hw_watchpoints = g_array_sized_new(true, true, hw_watchpoints = g_array_sized_new(true, true,
sizeof(HWWatchpoint), max_hw_wps); sizeof(HWWatchpoint), max_hw_wps);
max_hw_bps = kvm_check_extension(cs->kvm_state, KVM_CAP_GUEST_DEBUG_HW_BPS); max_hw_bps = kvm_check_extension(s, KVM_CAP_GUEST_DEBUG_HW_BPS);
hw_breakpoints = g_array_sized_new(true, true, hw_breakpoints = g_array_sized_new(true, true,
sizeof(HWBreakpoint), max_hw_bps); sizeof(HWBreakpoint), max_hw_bps);
return; return;
@ -920,8 +912,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
} }
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK; cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
kvm_arm_init_debug(cs);
/* Check whether user space can specify guest syndrome value */ /* Check whether user space can specify guest syndrome value */
kvm_arm_init_serror_injection(cs); kvm_arm_init_serror_injection(cs);

View File

@ -18,6 +18,14 @@
#define KVM_ARM_VGIC_V2 (1 << 0) #define KVM_ARM_VGIC_V2 (1 << 0)
#define KVM_ARM_VGIC_V3 (1 << 1) #define KVM_ARM_VGIC_V3 (1 << 1)
/**
* kvm_arm_init_debug() - initialize guest debug capabilities
* @s: KVMState
*
* Should be called only once before using guest debug capabilities.
*/
void kvm_arm_init_debug(KVMState *s);
/** /**
* kvm_arm_vcpu_init: * kvm_arm_vcpu_init:
* @cs: CPUState * @cs: CPUState

View File

@ -947,6 +947,7 @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64, static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
int ap, int ns, int xn, int pxn) int ap, int ns, int xn, int pxn)
{ {
ARMCPU *cpu = env_archcpu(env);
bool is_user = regime_is_user(env, mmu_idx); bool is_user = regime_is_user(env, mmu_idx);
int prot_rw, user_rw; int prot_rw, user_rw;
bool have_wxn; bool have_wxn;
@ -958,8 +959,19 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
if (is_user) { if (is_user) {
prot_rw = user_rw; prot_rw = user_rw;
} else { } else {
/*
* PAN controls can forbid data accesses but don't affect insn fetch.
* Plain PAN forbids data accesses if EL0 has data permissions;
* PAN3 forbids data accesses if EL0 has either data or exec perms.
* Note that for AArch64 the 'user can exec' case is exactly !xn.
* We make the IMPDEF choices that SCR_EL3.SIF and Realm EL2&0
* do not affect EPAN.
*/
if (user_rw && regime_is_pan(env, mmu_idx)) { if (user_rw && regime_is_pan(env, mmu_idx)) {
/* PAN forbids data accesses but doesn't affect insn fetch */ prot_rw = 0;
} else if (cpu_isar_feature(aa64_pan3, cpu) && is_aa64 &&
regime_is_pan(env, mmu_idx) &&
(regime_sctlr(env, mmu_idx) & SCTLR_EPAN) && !xn) {
prot_rw = 0; prot_rw = 0;
} else { } else {
prot_rw = simple_ap_to_rw_prot_is_user(ap, false); prot_rw = simple_ap_to_rw_prot_is_user(ap, false);

View File

@ -24,16 +24,17 @@ bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
} }
static inline uint32_t merge_syn_data_abort(uint32_t template_syn, static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
ARMMMUFaultInfo *fi,
unsigned int target_el, unsigned int target_el,
bool same_el, bool ea, bool same_el, bool is_write,
bool s1ptw, bool is_write,
int fsc) int fsc)
{ {
uint32_t syn; uint32_t syn;
/* /*
* ISV is only set for data aborts routed to EL2 and * ISV is only set for stage-2 data aborts routed to EL2 and
* never for stage-1 page table walks faulting on stage 2. * never for stage-1 page table walks faulting on stage 2
* or for stage-1 faults.
* *
* Furthermore, ISV is only set for certain kinds of load/stores. * Furthermore, ISV is only set for certain kinds of load/stores.
* If the template syndrome does not have ISV set, we should leave * If the template syndrome does not have ISV set, we should leave
@ -42,10 +43,16 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
* See ARMv8 specs, D7-1974: * See ARMv8 specs, D7-1974:
* ISS encoding for an exception from a Data Abort, the * ISS encoding for an exception from a Data Abort, the
* ISV field. * ISV field.
*
* TODO: FEAT_LS64/FEAT_LS64_V/FEAT_SL64_ACCDATA: Translation,
* Access Flag, and Permission faults caused by LD64B, ST64B,
* ST64BV, or ST64BV0 insns report syndrome info even for stage-1
* faults and regardless of the target EL.
*/ */
if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) { if (!(template_syn & ARM_EL_ISV) || target_el != 2
|| fi->s1ptw || !fi->stage2) {
syn = syn_data_abort_no_iss(same_el, 0, syn = syn_data_abort_no_iss(same_el, 0,
ea, 0, s1ptw, is_write, fsc); fi->ea, 0, fi->s1ptw, is_write, fsc);
} else { } else {
/* /*
* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template * Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
@ -54,7 +61,7 @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
*/ */
syn = syn_data_abort_with_iss(same_el, syn = syn_data_abort_with_iss(same_el,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
ea, 0, s1ptw, is_write, fsc, fi->ea, 0, fi->s1ptw, is_write, fsc,
true); true);
/* Merge the runtime syndrome with the template syndrome. */ /* Merge the runtime syndrome with the template syndrome. */
syn |= template_syn; syn |= template_syn;
@ -117,9 +124,8 @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc); syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
exc = EXCP_PREFETCH_ABORT; exc = EXCP_PREFETCH_ABORT;
} else { } else {
syn = merge_syn_data_abort(env->exception.syndrome, target_el, syn = merge_syn_data_abort(env->exception.syndrome, fi, target_el,
same_el, fi->ea, fi->s1ptw, same_el, access_type == MMU_DATA_STORE,
access_type == MMU_DATA_STORE,
fsc); fsc);
if (access_type == MMU_DATA_STORE if (access_type == MMU_DATA_STORE
&& arm_feature(env, ARM_FEATURE_V6)) { && arm_feature(env, ARM_FEATURE_V6)) {

View File

@ -581,7 +581,10 @@ class BootLinuxConsole(LinuxKernelTest):
'Allwinner sun4i/sun5i') 'Allwinner sun4i/sun5i')
exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
'system-control@1c00000') 'system-control@1c00000')
# cubieboard's reboot is not functioning; omit reboot test. exec_command_and_wait_for_pattern(self, 'reboot',
'reboot: Restarting system')
# Wait for VM to shut down gracefully
self.vm.wait()
def test_arm_cubieboard_sata(self): def test_arm_cubieboard_sata(self):
""" """
@ -625,7 +628,10 @@ class BootLinuxConsole(LinuxKernelTest):
'Allwinner sun4i/sun5i') 'Allwinner sun4i/sun5i')
exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', exec_command_and_wait_for_pattern(self, 'cat /proc/partitions',
'sda') 'sda')
# cubieboard's reboot is not functioning; omit reboot test. exec_command_and_wait_for_pattern(self, 'reboot',
'reboot: Restarting system')
# Wait for VM to shut down gracefully
self.vm.wait()
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
def test_arm_cubieboard_openwrt_22_03_2(self): def test_arm_cubieboard_openwrt_22_03_2(self):
@ -672,7 +678,10 @@ class BootLinuxConsole(LinuxKernelTest):
exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
'Allwinner sun4i/sun5i') 'Allwinner sun4i/sun5i')
# cubieboard's reboot is not functioning; omit reboot test. exec_command_and_wait_for_pattern(self, 'reboot',
'reboot: Restarting system')
# Wait for VM to shut down gracefully
self.vm.wait()
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout') @skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
def test_arm_quanta_gsj(self): def test_arm_quanta_gsj(self):