:p
atchew
Login
Hi; here's the first target-arm pullreq for the 8.1 cycle. Nothing particularly huge in here, just the various things that had accumulated during the freeze. thanks -- PMM The following changes since commit 2d82c32b2ceaca3dc3da5e36e10976f34bfcb598: Open 8.1 development tree (2023-04-20 10:05:25 +0100) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230420 for you to fetch changes up to 1ed1f338520cda0574b7e04f5e8e85e049740548: arm/mcimx7d-sabre: Set fec2-phy-connected property to false (2023-04-20 10:46:43 +0100) ---------------------------------------------------------------- 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 ---------------------------------------------------------------- Akihiko Odaki (1): target/arm: Initialize debug capabilities only once Axel Heider (2): hw/timer/imx_epit: don't shadow variable hw/timer/imx_epit: fix limit check Feng Jiang (1): exynos: Fix out-of-bounds access in exynos4210_gcomp_find debug printf Guenter Roeck (5): hw/net/imx_fec: Support two Ethernet interfaces connected to single MDIO bus fsl-imx6ul: Add fec[12]-phy-connected properties arm/mcimx6ul-evk: Set fec1-phy-connected property to false fsl-imx7: Add fec[12]-phy-connected properties arm/mcimx7d-sabre: Set fec2-phy-connected property to false Peter Maydell (5): target/arm: Pass ARMMMUFaultInfo to merge_syn_data_abort() target/arm: Don't set ISV when reporting stage 1 faults in ESR_EL2 target/arm: Implement FEAT_PAN3 docs/devel/kconfig.rst: Fix incorrect markup target/arm: Report pauth information to gdb as 'pauth_v2' Philippe Mathieu-Daudé (2): target/arm: Remove KVM AArch32 CPU definitions hw/arm/virt: Restrict Cortex-A7 check to TCG Stefan Weil (1): hw/arm: Fix some typos in comments (most found by codespell) Strahinja Jankovic (4): hw/watchdog: Allwinner WDT emulation for system reset hw/arm: Add WDT to Allwinner-A10 and Cubieboard hw/arm: Add WDT to Allwinner-H3 and Orangepi-PC tests/avocado: Add reboot tests to Cubieboard docs/devel/kconfig.rst | 2 +- docs/system/arm/cubieboard.rst | 1 + docs/system/arm/emulation.rst | 1 + docs/system/arm/orangepi.rst | 1 + include/hw/arm/allwinner-a10.h | 2 + include/hw/arm/allwinner-h3.h | 5 +- include/hw/arm/fsl-imx6ul.h | 1 + include/hw/arm/fsl-imx7.h | 1 + include/hw/net/imx_fec.h | 2 + include/hw/watchdog/allwinner-wdt.h | 123 +++++++++++ target/arm/cpu.h | 5 + target/arm/kvm-consts.h | 9 +- target/arm/kvm_arm.h | 8 + hw/arm/allwinner-a10.c | 7 + hw/arm/allwinner-h3.c | 8 + hw/arm/exynos4210.c | 4 +- hw/arm/fsl-imx6ul.c | 20 ++ hw/arm/fsl-imx7.c | 20 ++ hw/arm/mcimx6ul-evk.c | 2 + hw/arm/mcimx7d-sabre.c | 2 + hw/arm/musicpal.c | 2 +- hw/arm/omap1.c | 2 +- hw/arm/omap2.c | 2 +- hw/arm/virt-acpi-build.c | 2 +- hw/arm/virt.c | 4 +- hw/arm/xlnx-versal-virt.c | 2 +- hw/net/imx_fec.c | 27 ++- hw/timer/exynos4210_mct.c | 13 +- hw/timer/imx_epit.c | 2 +- hw/watchdog/allwinner-wdt.c | 416 ++++++++++++++++++++++++++++++++++++ target/arm/cpu64.c | 2 +- target/arm/cpu_tcg.c | 2 - target/arm/gdbstub.c | 9 +- target/arm/kvm.c | 2 + target/arm/kvm64.c | 18 +- target/arm/ptw.c | 14 +- target/arm/tcg/tlb_helper.c | 26 ++- gdb-xml/aarch64-pauth.xml | 2 +- hw/arm/Kconfig | 4 +- hw/watchdog/Kconfig | 4 + hw/watchdog/meson.build | 1 + hw/watchdog/trace-events | 7 + tests/avocado/boot_linux_console.py | 15 +- 43 files changed, 738 insertions(+), 64 deletions(-) create mode 100644 include/hw/watchdog/allwinner-wdt.h create mode 100644 hw/watchdog/allwinner-wdt.c
From: Stefan Weil <sw@weilnetz.de> Signed-off-by: Stefan Weil <sw@weilnetz.de> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230409200526.1156456-1-sw@weilnetz.de Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/exynos4210.c | 4 ++-- hw/arm/musicpal.c | 2 +- hw/arm/omap1.c | 2 +- hw/arm/omap2.c | 2 +- hw/arm/virt-acpi-build.c | 2 +- hw/arm/virt.c | 2 +- hw/arm/xlnx-versal-virt.c | 2 +- hw/arm/Kconfig | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -XXX,XX +XXX,XX @@ 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) { @@ -XXX,XX +XXX,XX @@ 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) diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -XXX,XX +XXX,XX @@ #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 diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -XXX,XX +XXX,XX @@ 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 diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -XXX,XX +XXX,XX @@ 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 diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -XXX,XX +XXX,XX @@ 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 */ } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -XXX,XX +XXX,XX @@ 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. */ diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/xlnx-versal-virt.c +++ b/hw/arm/xlnx-versal-virt.c @@ -XXX,XX +XXX,XX @@ 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); diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -XXX,XX +XXX,XX @@ 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 -- 2.34.1
From: Feng Jiang <jiangfeng@kylinos.cn> One of the debug printfs in exynos4210_gcomp_find() will access outside the 's->g_timer.reg.comp[]' array if there was no active comparator and 'res' is -1. Add a conditional to avoid this. This doesn't happen in normal use because the debug printfs are by default not compiled in. Signed-off-by: Feng Jiang <jiangfeng@kylinos.cn> Message-id: 20230404074506.112615-1-jiangfeng@kylinos.cn Reviewed-by: Peter Maydell <peter.maydell@linaro.org> [PMM: Adjusted commit message to clarify that the overrun only happens if you've enabled debug printfs] Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/exynos4210_mct.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/exynos4210_mct.c +++ b/hw/timer/exynos4210_mct.c @@ -XXX,XX +XXX,XX @@ 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; } -- 2.34.1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com> This patch adds basic support for Allwinner WDT. Both sun4i and sun6i variants are supported. However, interrupt generation is not supported, so WDT can be used only to trigger system reset. Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com> Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com> Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com> Message-id: 20230326202256.22980-2-strahinja.p.jankovic@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/watchdog/allwinner-wdt.h | 123 ++++++++ hw/watchdog/allwinner-wdt.c | 416 ++++++++++++++++++++++++++++ hw/watchdog/Kconfig | 4 + hw/watchdog/meson.build | 1 + hw/watchdog/trace-events | 7 + 5 files changed, 551 insertions(+) create mode 100644 include/hw/watchdog/allwinner-wdt.h create mode 100644 hw/watchdog/allwinner-wdt.c diff --git a/include/hw/watchdog/allwinner-wdt.h b/include/hw/watchdog/allwinner-wdt.h new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/include/hw/watchdog/allwinner-wdt.h @@ -XXX,XX +XXX,XX @@ +/* + * 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 */ diff --git a/hw/watchdog/allwinner-wdt.c b/hw/watchdog/allwinner-wdt.c new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/hw/watchdog/allwinner-wdt.c @@ -XXX,XX +XXX,XX @@ +/* + * 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) diff --git a/hw/watchdog/Kconfig b/hw/watchdog/Kconfig index XXXXXXX..XXXXXXX 100644 --- a/hw/watchdog/Kconfig +++ b/hw/watchdog/Kconfig @@ -XXX,XX +XXX,XX @@ config WDT_IMX2 config WDT_SBSA bool + +config ALLWINNER_WDT + bool + select PTIMER diff --git a/hw/watchdog/meson.build b/hw/watchdog/meson.build index XXXXXXX..XXXXXXX 100644 --- a/hw/watchdog/meson.build +++ b/hw/watchdog/meson.build @@ -XXX,XX +XXX,XX @@ 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')) diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events index XXXXXXX..XXXXXXX 100644 --- a/hw/watchdog/trace-events +++ b/hw/watchdog/trace-events @@ -XXX,XX +XXX,XX @@ # 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" -- 2.34.1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com> This patch adds WDT to Allwinner-A10 and Cubieboard. WDT is added as an overlay to the Timer module memory map. Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com> Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com> Message-id: 20230326202256.22980-3-strahinja.p.jankovic@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- docs/system/arm/cubieboard.rst | 1 + include/hw/arm/allwinner-a10.h | 2 ++ hw/arm/allwinner-a10.c | 7 +++++++ hw/arm/Kconfig | 1 + 4 files changed, 11 insertions(+) diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/cubieboard.rst +++ b/docs/system/arm/cubieboard.rst @@ -XXX,XX +XXX,XX @@ Emulated devices: - USB controller - SATA controller - TWI (I2C) controller +- Watchdog timer diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -XXX,XX +XXX,XX @@ #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" @@ -XXX,XX +XXX,XX @@ 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]; diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -XXX,XX +XXX,XX @@ #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 @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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) diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -XXX,XX +XXX,XX @@ 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 -- 2.34.1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com> This patch adds WDT to Allwinner-H3 and Orangepi-PC. WDT is added as an overlay to the Timer module memory area. Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com> Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com> Message-id: 20230326202256.22980-4-strahinja.p.jankovic@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- docs/system/arm/orangepi.rst | 1 + include/hw/arm/allwinner-h3.h | 5 ++++- hw/arm/allwinner-h3.c | 8 ++++++++ hw/arm/Kconfig | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/orangepi.rst +++ b/docs/system/arm/orangepi.rst @@ -XXX,XX +XXX,XX @@ The Orange Pi PC machine supports the following devices: * System Control module * Security Identifier device * TWI (I2C) + * Watchdog timer Limitations """"""""""" diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/allwinner-h3.h +++ b/include/hw/arm/allwinner-h3.h @@ -XXX,XX +XXX,XX @@ #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" @@ -XXX,XX +XXX,XX @@ 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 */ @@ -XXX,XX +XXX,XX @@ struct AwH3State { AWI2CState r_twi; AwSun8iEmacState emac; AwRtcState rtc; + AwWdtState wdt; GICState gic; MemoryRegion sram_a1; MemoryRegion sram_a2; diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/allwinner-h3.c +++ b/hw/arm/allwinner-h3.c @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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) @@ -XXX,XX +XXX,XX @@ 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, diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -XXX,XX +XXX,XX @@ 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 -- 2.34.1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com> Cubieboard tests end with comment "reboot not functioning; omit test". Fix this so reboot is done at the end of each test. Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com> Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com> Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com> Message-id: 20230326202256.22980-5-strahinja.p.jankovic@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- tests/avocado/boot_linux_console.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py index XXXXXXX..XXXXXXX 100644 --- a/tests/avocado/boot_linux_console.py +++ b/tests/avocado/boot_linux_console.py @@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self): '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): """ @@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self): '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): @@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_openwrt_22_03_2(self): 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): -- 2.34.1
From: Axel Heider <axel.heider@hensoldt.net> Fix issue reported by Coverity. Signed-off-by: Axel Heider <axel.heider@hensoldt.net> Message-id: 168070611775.20412.2883242077302841473-1@git.sr.ht Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/imx_epit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/imx_epit.c +++ b/hw/timer/imx_epit.c @@ -XXX,XX +XXX,XX @@ 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; -- 2.34.1
From: Axel Heider <axel.heider@hensoldt.net> Fix the limit check. If the limit is less than the compare value, the timer can never reach this value, thus it will never fire. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1491 Signed-off-by: Axel Heider <axel.heider@hensoldt.net> Message-id: 168070611775.20412.2883242077302841473-2@git.sr.ht Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/imx_epit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/imx_epit.c +++ b/hw/timer/imx_epit.c @@ -XXX,XX +XXX,XX @@ static void imx_epit_update_compare_timer(IMXEPITState *s) * the compare value. Otherwise it may fire at most once in the * current round. */ - 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; -- 2.34.1
From: Philippe Mathieu-Daudé <philmd@linaro.org> Missed in commit 80485d88f9 ("target/arm: Restrict v7A TCG cpus to TCG accel"). Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230405100848.76145-2-philmd@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/kvm-consts.h | 9 +++------ target/arm/cpu_tcg.c | 2 -- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm-consts.h +++ b/target/arm/kvm-consts.h @@ -XXX,XX +XXX,XX @@ 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 diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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; -- 2.34.1
From: Philippe Mathieu-Daudé <philmd@linaro.org> The Cortex-A7 core is only available when TCG is enabled (see commit 80485d88f9 "target/arm: Restrict v7A TCG cpus to TCG accel"). Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230405100848.76145-3-philmd@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/virt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -XXX,XX +XXX,XX @@ 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"), -- 2.34.1
From: Akihiko Odaki <akihiko.odaki@daynix.com> kvm_arm_init_debug() used to be called several times on a SMP system as kvm_arch_init_vcpu() calls it. Move the call to kvm_arch_init() to make sure it will be called only once; otherwise it will overwrite pointers to memory allocated with the previous call and leak it. Fixes: e4482ab7e3 ("target-arm: kvm - add support for HW assisted debug") Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Message-id: 20230405153644.25300-1-akihiko.odaki@daynix.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/kvm_arm.h | 8 ++++++++ target/arm/kvm.c | 2 ++ target/arm/kvm64.c | 18 ++++-------------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -XXX,XX +XXX,XX @@ #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 diff --git a/target/arm/kvm.c b/target/arm/kvm.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s) } } + kvm_arm_init_debug(s); + return ret; } diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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); -- 2.34.1
We already pass merge_syn_data_abort() two fields from the ARMMMUFaultInfo struct, and we're about to want to use a third field. Refactor to just pass a pointer to the fault info. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230331145045.2584941-2-peter.maydell@linaro.org --- target/arm/tcg/tlb_helper.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn, * ISS encoding for an exception from a Data Abort, the * ISV field. */ - if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) { + if (!(template_syn & ARM_EL_ISV) || target_el != 2 || fi->s1ptw) { 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 @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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)) { -- 2.34.1
The syndrome value reported to ESR_EL2 should only contain the detailed instruction syndrome information when the fault has been caused by a stage 2 abort, not when the fault was a stage 1 abort (i.e. caused by execution at EL2). We were getting this wrong and reporting the detailed ISV information all the time. Fix the bug by checking fi->stage2. Add a TODO comment noting the cases where we'll have to come back and revisit this when we implement FEAT_LS64 and friends. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230331145045.2584941-3-peter.maydell@linaro.org --- target/arm/tcg/tlb_helper.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn, 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 @@ -XXX,XX +XXX,XX @@ 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 || fi->s1ptw) { + if (!(template_syn & ARM_EL_ISV) || target_el != 2 + || fi->s1ptw || !fi->stage2) { syn = syn_data_abort_no_iss(same_el, 0, fi->ea, 0, fi->s1ptw, is_write, fsc); } else { -- 2.34.1
FEAT_PAN3 adds an EPAN bit to SCTLR_EL1 and SCTLR_EL2, which allows the PAN bit to make memory non-privileged-read/write if it is user-executable as well as if it is user-read/write. Implement this feature and enable it in the AArch64 'max' CPU. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230331145045.2584941-4-peter.maydell@linaro.org --- docs/system/arm/emulation.rst | 1 + target/arm/cpu.h | 5 +++++ target/arm/cpu64.c | 2 +- target/arm/ptw.c | 14 +++++++++++++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/arm/emulation.rst +++ b/docs/system/arm/emulation.rst @@ -XXX,XX +XXX,XX @@ 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) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -XXX,XX +XXX,XX @@ 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; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -XXX,XX +XXX,XX @@ 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 */ diff --git a/target/arm/ptw.c b/target/arm/ptw.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -XXX,XX +XXX,XX @@ 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; @@ -XXX,XX +XXX,XX @@ 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); -- 2.34.1
In rST markup syntax, the inline markup (*italics*, **bold** and ``monospaced``) must be separated from the surrending text by non-word characters, otherwise it is not interpreted as markup. To force interpretation as markup in the middle of a word, you need to use a backslash-escaped space (which will not appear as a space in the output). Fix a missing backslash-space in this file, which meant that the `` after "select" was output literally and the monospacing was incorrectly extended all the way to the end of the next monospaced word. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-id: 20230411105424.3994585-1-peter.maydell@linaro.org --- docs/devel/kconfig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/devel/kconfig.rst b/docs/devel/kconfig.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/devel/kconfig.rst +++ b/docs/devel/kconfig.rst @@ -XXX,XX +XXX,XX @@ 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:: -- 2.34.1
So that we can avoid the "older gdb crashes" problem described in commit 5787d17a42f7af4 and which caused us to disable reporting pauth information via the gdbstub, newer gdb is going to implement support for recognizing the pauth information via a new feature name: org.gnu.gdb.aarch64.pauth_v2 Older gdb won't recognize this feature name, so we can re-enable the pauth support under the new name without risking them crashing. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20230406150827.3322670-1-peter.maydell@linaro.org --- target/arm/gdbstub.c | 9 ++++----- gdb-xml/aarch64-pauth.xml | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/gdbstub.c +++ b/target/arm/gdbstub.c @@ -XXX,XX +XXX,XX @@ 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)) { diff --git a/gdb-xml/aarch64-pauth.xml b/gdb-xml/aarch64-pauth.xml index XXXXXXX..XXXXXXX 100644 --- a/gdb-xml/aarch64-pauth.xml +++ b/gdb-xml/aarch64-pauth.xml @@ -XXX,XX +XXX,XX @@ 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"/> -- 2.34.1
From: Guenter Roeck <linux@roeck-us.net> The SOC on i.MX6UL and i.MX7 has 2 Ethernet interfaces. The PHY on each may be connected to separate MDIO busses, or both may be connected on the same MDIO bus using different PHY addresses. Commit 461c51ad4275 ("Add a phy-num property to the i.MX FEC emulator") added support for specifying PHY addresses, but it did not provide support for linking the second PHY on a given MDIO bus to the other Ethernet interface. To be able to support two PHY instances on a single MDIO bus, two properties are needed: First, there needs to be a flag indicating if the MDIO bus on a given Ethernet interface is connected. If not, attempts to read from this bus must always return 0xffff. Implement this property as phy-connected. Second, if the MDIO bus on an interface is active, it needs a link to the consumer interface to be able to provide PHY access for it. Implement this property as phy-consumer. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Message-id: 20230315145248.1639364-2-linux@roeck-us.net Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/net/imx_fec.h | 2 ++ hw/net/imx_fec.c | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/net/imx_fec.h +++ b/include/hw/net/imx_fec.h @@ -XXX,XX +XXX,XX @@ 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; diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/imx_fec.c +++ b/hw/net/imx_fec.c @@ -XXX,XX +XXX,XX @@ 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) { @@ -XXX,XX +XXX,XX @@ 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); @@ -XXX,XX +XXX,XX @@ 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(), }; -- 2.34.1
From: Guenter Roeck <linux@roeck-us.net> Add fec[12]-phy-connected properties and use it to set phy-connected and phy-consumer properties for imx_fec. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Message-id: 20230315145248.1639364-3-linux@roeck-us.net Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/arm/fsl-imx6ul.h | 1 + hw/arm/fsl-imx6ul.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/fsl-imx6ul.h +++ b/include/hw/arm/fsl-imx6ul.h @@ -XXX,XX +XXX,XX @@ struct FslIMX6ULState { MemoryRegion ocram_alias; uint32_t phy_num[FSL_IMX6UL_NUM_ETHS]; + bool phy_connected[FSL_IMX6UL_NUM_ETHS]; }; enum FslIMX6ULMemoryMap { diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/fsl-imx6ul.c +++ b/hw/arm/fsl-imx6ul.c @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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(), }; -- 2.34.1
From: Guenter Roeck <linux@roeck-us.net> On mcimx6ul-evk, the MDIO bus is connected to the second Ethernet interface. Set fec1-phy-connected to false to reflect this. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Message-id: 20230315145248.1639364-4-linux@roeck-us.net Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/mcimx6ul-evk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/mcimx6ul-evk.c +++ b/hw/arm/mcimx6ul-evk.c @@ -XXX,XX +XXX,XX @@ 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, -- 2.34.1
From: Guenter Roeck <linux@roeck-us.net> Add fec[12]-phy-connected properties and use it to set phy-connected and phy-consumer properties for imx_fec. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Message-id: 20230315145248.1639364-5-linux@roeck-us.net Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/arm/fsl-imx7.h | 1 + hw/arm/fsl-imx7.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/fsl-imx7.h +++ b/include/hw/arm/fsl-imx7.h @@ -XXX,XX +XXX,XX @@ 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 { diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/fsl-imx7.c +++ b/hw/arm/fsl-imx7.c @@ -XXX,XX +XXX,XX @@ 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, @@ -XXX,XX +XXX,XX @@ 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(), }; -- 2.34.1
From: Guenter Roeck <linux@roeck-us.net> On mcimx7d-sabre, the MDIO bus is connected to the first Ethernet interface. Set fec2-phy-connected to false to reflect this. Signed-off-by: Guenter Roeck <linux@roeck-us.net> Message-id: 20230315145248.1639364-6-linux@roeck-us.net Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/mcimx7d-sabre.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/mcimx7d-sabre.c +++ b/hw/arm/mcimx7d-sabre.c @@ -XXX,XX +XXX,XX @@ 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, -- 2.34.1
v3->v4: Windows headers define an INT type which clashed with an enum value name in arm_gicv3_its.c... The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5: Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913-3 for you to fetch changes up to 28e987a7e7edaa3ca7feeac65edca26145df8814: hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 21:01:08 +0100) ---------------------------------------------------------------- target-arm queue: * mark MPS2/MPS3 board-internal i2c buses as 'full' so that command line user-created devices are not plugged into them * Take an exception if PSTATE.IL is set * Support an emulated ITS in the virt board * Add support for kudo-bmc board * Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM * cadence_uart: Fix clock handling issues that prevented u-boot from running ---------------------------------------------------------------- Bin Meng (6): hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase hw/char: cadence_uart: Disable transmit when input clock is disabled hw/char: cadence_uart: Move clock/reset check to uart_can_receive() hw/char: cadence_uart: Convert to memop_with_attrs() ops hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}() hw/char: cadence_uart: Log a guest error when device is unclocked or in reset Chris Rauer (1): hw/arm: Add support for kudo-bmc board. Marc Zyngier (1): hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM Peter Maydell (5): target/arm: Take an exception if PSTATE.IL is set qdev: Support marking individual buses as 'full' hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full' hw/arm/mps2.c: Mark internal-only I2C buses as 'full' Richard Henderson (1): target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn Shashi Mallela (9): hw/intc: GICv3 ITS initial framework hw/intc: GICv3 ITS register definitions added hw/intc: GICv3 ITS command queue framework hw/intc: GICv3 ITS Command processing hw/intc: GICv3 ITS Feature enablement hw/intc: GICv3 redistributor ITS processing tests/data/acpi/virt: Add IORT files for ITS hw/arm/virt: add ITS support in virt GIC tests/data/acpi/virt: Update IORT files for ITS docs/system/arm/nuvoton.rst | 1 + hw/intc/gicv3_internal.h | 188 ++++- include/hw/arm/virt.h | 2 + include/hw/intc/arm_gicv3_common.h | 13 + include/hw/intc/arm_gicv3_its_common.h | 32 +- include/hw/qdev-core.h | 24 + target/arm/cpu.h | 1 + target/arm/kvm_arm.h | 4 +- target/arm/syndrome.h | 5 + target/arm/translate.h | 2 + hw/arm/mps2-tz.c | 92 ++- hw/arm/mps2.c | 12 +- hw/arm/npcm7xx_boards.c | 34 + hw/arm/virt.c | 29 +- hw/char/cadence_uart.c | 61 +- hw/intc/arm_gicv3.c | 14 + hw/intc/arm_gicv3_common.c | 13 + hw/intc/arm_gicv3_cpuif.c | 7 +- hw/intc/arm_gicv3_dist.c | 5 +- hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 7 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/arm_gicv3_redist.c | 153 +++- hw/misc/zynq_slcr.c | 31 +- softmmu/qdev-monitor.c | 7 +- target/arm/helper-a64.c | 1 + target/arm/helper.c | 8 + target/arm/kvm.c | 7 +- target/arm/translate-a64.c | 255 +++--- target/arm/translate.c | 21 + hw/intc/meson.build | 1 + tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes 35 files changed, 2144 insertions(+), 210 deletions(-) create mode 100644 hw/intc/arm_gicv3_its.c create mode 100644 tests/data/acpi/virt/IORT create mode 100644 tests/data/acpi/virt/IORT.memhp create mode 100644 tests/data/acpi/virt/IORT.numamem create mode 100644 tests/data/acpi/virt/IORT.pxb