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
``--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
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::

View File

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

View File

@ -56,6 +56,7 @@ the following architecture extensions:
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
- FEAT_PAN (Privileged access never)
- 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_PMULL (PMULL, PMULL2 instructions)
- FEAT_PMUv3p1 (PMU Extensions v3.1)

View File

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

View File

@ -6,7 +6,7 @@
notice and this notice are preserved. -->
<!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_cmask" bitsize="64"/>
<reg name="pauth_dmask_high" bitsize="64"/>

View File

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

View File

@ -38,6 +38,7 @@
#define AW_A10_EHCI_BASE 0x01c14000
#define AW_A10_OHCI_BASE 0x01c14400
#define AW_A10_SATA_BASE 0x01c18000
#define AW_A10_WDT_BASE 0x01c20c90
#define AW_A10_RTC_BASE 0x01c20d00
#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, "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)
@ -203,6 +206,10 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
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));
/* 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)

View File

@ -49,6 +49,7 @@ const hwaddr allwinner_h3_memmap[] = {
[AW_H3_DEV_OHCI3] = 0x01c1d400,
[AW_H3_DEV_CCU] = 0x01c20000,
[AW_H3_DEV_PIT] = 0x01c20c00,
[AW_H3_DEV_WDT] = 0x01c20ca0,
[AW_H3_DEV_UART0] = 0x01c28000,
[AW_H3_DEV_UART1] = 0x01c28400,
[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, "twi2", &s->i2c2, 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)
@ -453,6 +456,11 @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(SYS_BUS_DEVICE(&s->r_twi), 0,
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 */
for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
create_unimplemented_device(unimplemented[i].device_name,

View File

@ -326,7 +326,7 @@ static int mapline_size(const int *mapline)
/*
* 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)
{
@ -744,7 +744,7 @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
* - SDMA
* - 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"
* public datasheet which is very similar (implementing
* 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
*
* 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++) {
static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
FSL_IMX6UL_ENET1_ADDR,
@ -620,6 +636,10 @@ static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
static Property fsl_imx6ul_properties[] = {
DEFINE_PROP_UINT32("fec1-phy-num", FslIMX6ULState, phy_num[0], 0),
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(),
};

View File

@ -395,7 +395,23 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
/*
* 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++) {
static const hwaddr FSL_IMX7_ENETn_ADDR[FSL_IMX7_NUM_ETHS] = {
FSL_IMX7_ENET1_ADDR,
@ -601,6 +617,10 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
static Property fsl_imx7_properties[] = {
DEFINE_PROP_UINT32("fec1-phy-num", FslIMX7State, phy_num[0], 0),
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(),
};

View File

@ -41,6 +41,8 @@ static void mcimx6ul_evk_init(MachineState *machine)
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), "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);
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));
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);
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_INVALID 0x00000000
/* Commmands */
/* Commands */
#define MP_LCD_INST_SETPAGE0 0xB0
/* ... */
#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,
0xfffbd800, omap_findclk(s, "clk32-kHz"));
/* Register mappings not currenlty implemented:
/* Register mappings not currently implemented:
* MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310)
* MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310)
* 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, "core_l4_iclk"));
/* All register mappings (includin those not currenlty implemented):
/* All register mappings (including those not currently implemented):
* SystemControlMod 48000000 - 48000fff
* SystemControlL4 48001000 - 48001fff
* 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, 16, 1); /* Length */
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, size, 4); /* Discovery Range Length */
}

View File

@ -204,7 +204,9 @@ static const int a15irqmap[] = {
};
static const char *valid_cpus[] = {
#ifdef CONFIG_TCG
ARM_CPU_TYPE_NAME("cortex-a7"),
#endif
ARM_CPU_TYPE_NAME("cortex-a15"),
ARM_CPU_TYPE_NAME("cortex-a35"),
ARM_CPU_TYPE_NAME("cortex-a53"),
@ -2052,7 +2054,7 @@ static void machvirt_init(MachineState *machine)
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
* 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);
/* 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(),
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 phy = reg / 32;
if (phy != s->phy_num) {
trace_imx_phy_read_num(phy, s->phy_num);
if (!s->phy_connected) {
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;
switch (reg) {
@ -343,11 +351,19 @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
{
uint32_t phy = reg / 32;
if (phy != s->phy_num) {
trace_imx_phy_write_num(phy, s->phy_num);
if (!s->phy_connected) {
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;
trace_imx_phy_write(val, phy, reg);
@ -1327,6 +1343,9 @@ static Property imx_eth_properties[] = {
DEFINE_NIC_PROPERTIES(IMXFECState, conf),
DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
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(),
};

View File

@ -480,11 +480,14 @@ static int32_t exynos4210_gcomp_find(Exynos4210MCTState *s)
res = min_comp_i;
}
DPRINTF("found comparator %d: comp 0x%llx distance 0x%llx, gfrc 0x%llx\n",
res,
s->g_timer.reg.comp[res],
distance_min,
gfrc);
if (res >= 0) {
DPRINTF("found comparator %d: "
"comp 0x%llx distance 0x%llx, gfrc 0x%llx\n",
res,
s->g_timer.reg.comp[res],
distance_min,
gfrc);
}
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
* current round.
*/
bool is_oneshot = (limit >= s->cmp);
is_oneshot = (limit < s->cmp);
if (counter >= s->cmp) {
/* The compare timer fires in the current round. */
counter -= s->cmp;

View File

@ -20,3 +20,7 @@ config WDT_IMX2
config WDT_SBSA
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(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_WDT_IB6300ESB', if_true: files('wdt_i6300esb.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.
# 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_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"

View File

@ -13,6 +13,7 @@
#include "hw/misc/allwinner-a10-ccm.h"
#include "hw/misc/allwinner-a10-dramc.h"
#include "hw/i2c/allwinner-i2c.h"
#include "hw/watchdog/allwinner-wdt.h"
#include "sysemu/block-backend.h"
#include "target/arm/cpu.h"
@ -41,6 +42,7 @@ struct AwA10State {
AwSdHostState mmc0;
AWI2CState i2c0;
AwRtcState rtc;
AwWdtState wdt;
MemoryRegion sram_a;
EHCISysBusState ehci[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/rtc/allwinner-rtc.h"
#include "hw/i2c/allwinner-i2c.h"
#include "hw/watchdog/allwinner-wdt.h"
#include "target/arm/cpu.h"
#include "sysemu/block-backend.h"
@ -96,7 +97,8 @@ enum {
AW_H3_DEV_RTC,
AW_H3_DEV_CPUCFG,
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 */
@ -141,6 +143,7 @@ struct AwH3State {
AWI2CState r_twi;
AwSun8iEmacState emac;
AwRtcState rtc;
AwWdtState wdt;
GICState gic;
MemoryRegion sram_a1;
MemoryRegion sram_a2;

View File

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

View File

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

View File

@ -270,6 +270,8 @@ struct IMXFECState {
uint32_t phy_int;
uint32_t phy_int_mask;
uint32_t phy_num;
bool phy_connected;
struct IMXFECState *phy_consumer;
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;
}
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)
{
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, HPDS, 1); /* FEAT_HPDS */
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, ETS, 1); /* FEAT_ETS */
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_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
cpu->midr = 0x410fc075;
cpu->reset_fpsid = 0x41023075;
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_EL3);
set_feature(&cpu->env, ARM_FEATURE_PMU);
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
/* r4p0 cpu, not requiring expensive tlb flush errata */
cpu->midr = 0x414fc0f0;
cpu->revidr = 0x0;

View File

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

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_wp(i) (&g_array_index(hw_watchpoints, HWWatchpoint, i))
/**
* 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)
void kvm_arm_init_debug(KVMState *s)
{
have_guest_debug = kvm_check_extension(cs->kvm_state,
have_guest_debug = kvm_check_extension(s,
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,
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,
sizeof(HWBreakpoint), max_hw_bps);
return;
@ -920,8 +912,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
}
cpu->mp_affinity = mpidr & ARM64_AFFINITY_MASK;
kvm_arm_init_debug(cs);
/* Check whether user space can specify guest syndrome value */
kvm_arm_init_serror_injection(cs);

View File

@ -18,6 +18,14 @@
#define KVM_ARM_VGIC_V2 (1 << 0)
#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:
* @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,
int ap, int ns, int xn, int pxn)
{
ARMCPU *cpu = env_archcpu(env);
bool is_user = regime_is_user(env, mmu_idx);
int prot_rw, user_rw;
bool have_wxn;
@ -958,8 +959,19 @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
if (is_user) {
prot_rw = user_rw;
} 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)) {
/* 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;
} else {
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,
ARMMMUFaultInfo *fi,
unsigned int target_el,
bool same_el, bool ea,
bool s1ptw, bool is_write,
bool same_el, bool is_write,
int fsc)
{
uint32_t syn;
/*
* ISV is only set for data aborts routed to EL2 and
* never for stage-1 page table walks faulting on stage 2.
* ISV is only set for stage-2 data aborts routed to EL2 and
* 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.
* 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:
* ISS encoding for an exception from a Data Abort, the
* 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,
ea, 0, s1ptw, is_write, fsc);
fi->ea, 0, fi->s1ptw, is_write, fsc);
} else {
/*
* 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,
0, 0, 0, 0, 0,
ea, 0, s1ptw, is_write, fsc,
fi->ea, 0, fi->s1ptw, is_write, fsc,
true);
/* Merge the runtime syndrome with the template syndrome. */
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);
exc = EXCP_PREFETCH_ABORT;
} else {
syn = merge_syn_data_abort(env->exception.syndrome, target_el,
same_el, fi->ea, fi->s1ptw,
access_type == MMU_DATA_STORE,
syn = merge_syn_data_abort(env->exception.syndrome, fi, target_el,
same_el, access_type == MMU_DATA_STORE,
fsc);
if (access_type == MMU_DATA_STORE
&& arm_feature(env, ARM_FEATURE_V6)) {

View File

@ -581,7 +581,10 @@ class BootLinuxConsole(LinuxKernelTest):
'Allwinner sun4i/sun5i')
exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
'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):
"""
@ -625,7 +628,10 @@ class BootLinuxConsole(LinuxKernelTest):
'Allwinner sun4i/sun5i')
exec_command_and_wait_for_pattern(self, 'cat /proc/partitions',
'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')
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',
'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')
def test_arm_quanta_gsj(self):