diff options
91 files changed, 2888 insertions, 1372 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 1d2003a9a1..025b5d2271 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -633,6 +633,7 @@ F: include/hw/*/allwinner* F: hw/arm/cubieboard.c F: docs/system/arm/cubieboard.rst F: hw/misc/axp209.c +F: tests/functional/test_arm_cubieboard.py Allwinner-h3 M: Niek Linnenbank <nieklinnenbank@gmail.com> @@ -720,6 +721,7 @@ S: Odd Fixes F: hw/*/exynos* F: include/hw/*/exynos* F: docs/system/arm/exynos.rst +F: tests/functional/test_arm_smdkc210.py Calxeda Highbank M: Rob Herring <robh@kernel.org> @@ -1025,6 +1027,7 @@ F: hw/display/dpcd.c F: include/hw/display/dpcd.h F: docs/system/arm/xlnx-versal-virt.rst F: docs/system/arm/xlnx-zcu102.rst +F: tests/functional/test_aarch64_xlnx_versal.py Xilinx Versal OSPI M: Francisco Iglesias <francisco.iglesias@amd.com> @@ -1115,6 +1118,7 @@ L: qemu-arm@nongnu.org S: Maintained F: hw/arm/msf2-som.c F: docs/system/arm/emcraft-sf2.rst +F: tests/functional/test_arm_emcraft_sf2.py ASPEED BMCs M: Cédric Le Goater <clg@kaod.org> @@ -1643,7 +1647,7 @@ F: hw/pci-host/sh_pci.c F: hw/timer/sh_timer.c F: include/hw/sh4/sh_intc.h F: include/hw/timer/tmu012.h -F: tests/functional/test_sh4_r2d.py +F: tests/functional/test_sh4*_r2d.py F: tests/functional/test_sh4_tuxrun.py SPARC Machines diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index d8dc29d0a4..267892b62f 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -263,14 +263,6 @@ images are not available, OpenWRT dropped support in 2019, U-Boot in 2017, Linux also is dropping support in 2024. It is time to let go of this ancient hardware and focus on newer CPUs and platforms. -Arm ``tacoma-bmc`` machine (since 9.1) -'''''''''''''''''''''''''''''''''''''''' - -The ``tacoma-bmc`` machine was a board including an AST2600 SoC based -BMC and a witherspoon like OpenPOWER system. It was used for bring up -of the AST2600 SoC in labs. It can be easily replaced by the -``rainier-bmc`` machine which is a real product. - Big-Endian variants of MicroBlaze ``petalogix-ml605`` and ``xlnx-zynqmp-pmu`` machines (since 9.2) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst index ee6455aeee..9bebee795c 100644 --- a/docs/about/removed-features.rst +++ b/docs/about/removed-features.rst @@ -1019,6 +1019,16 @@ Aspeed ``swift-bmc`` machine (removed in 7.0) This machine was removed because it was unused. Alternative AST2500 based OpenPOWER machines are ``witherspoon-bmc`` and ``romulus-bmc``. +Aspeed ``tacoma-bmc`` machine (removed in 10.0) +''''''''''''''''''''''''''''''''''''''''''''''' + +The ``tacoma-bmc`` machine was removed because it didn't bring much +compared to the ``rainier-bmc`` machine. Also, the ``tacoma-bmc`` was +a board used for bring up of the AST2600 SoC that never left the +labs. It can be easily replaced by the ``rainier-bmc`` machine, which +was the actual final product, or by the ``ast2600-evb`` with some +tweaks. + ppc ``taihu`` machine (removed in 7.2) ''''''''''''''''''''''''''''''''''''''''''''' diff --git a/docs/conf.py b/docs/conf.py index c11a6ead8a..164a8ee8b2 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -186,7 +186,7 @@ html_js_files = [ ] html_context = { - "display_gitlab": True, + "source_url_prefix": "https://gitlab.com/qemu-project/qemu/-/blob/master/docs/", "gitlab_user": "qemu-project", "gitlab_repo": "qemu", "gitlab_version": "master", diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst index d17fe7a4fc..fa4aa28eef 100644 --- a/docs/system/arm/aspeed.rst +++ b/docs/system/arm/aspeed.rst @@ -32,7 +32,6 @@ AST2500 SoC based machines : AST2600 SoC based machines : - ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7) -- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC - ``rainier-bmc`` IBM Rainier POWER10 BMC - ``fuji-bmc`` Facebook Fuji BMC - ``bletchley-bmc`` Facebook Bletchley BMC diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h index 51c94b0116..95ee4da9bd 100644 --- a/hw/9pfs/9p-util.h +++ b/hw/9pfs/9p-util.h @@ -177,20 +177,27 @@ again: return -1; } - if (close_if_special_file(fd) < 0) { - return -1; - } - - serrno = errno; - /* O_NONBLOCK was only needed to open the file. Let's drop it. We don't - * do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat() - * ignored it anyway. - */ + /* Only if O_PATH is not set ... */ if (!(flags & O_PATH_9P_UTIL)) { + /* + * Prevent I/O on special files (device files, etc.) on host side, + * however it is safe and required to allow opening them with O_PATH, + * as this is limited to (required) path based operations only. + */ + if (close_if_special_file(fd) < 0) { + return -1; + } + + serrno = errno; + /* + * O_NONBLOCK was only needed to open the file. Let's drop it. We don't + * do that with O_PATH since fcntl(F_SETFL) isn't supported, and + * openat() ignored it anyway. + */ ret = fcntl(fd, F_SETFL, flags); assert(!ret); + errno = serrno; } - errno = serrno; return fd; } diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 6ca145362c..556498f2a0 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -185,10 +185,6 @@ struct AspeedMachineState { #define AST2700_EVB_HW_STRAP2 0x00000003 #endif -/* Tacoma hardware value */ -#define TACOMA_BMC_HW_STRAP1 0x00000000 -#define TACOMA_BMC_HW_STRAP2 0x00000040 - /* Rainier hardware value: (QEMU prototype) */ #define RAINIER_BMC_HW_STRAP1 (0x00422016 | SCU_AST2600_HW_STRAP_BOOT_SRC_EMMC) #define RAINIER_BMC_HW_STRAP2 0x80000848 @@ -1425,26 +1421,6 @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data) aspeed_machine_ast2600_class_emmc_init(oc); }; -static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); - - mc->desc = "OpenPOWER Tacoma BMC (Cortex-A7)"; - amc->soc_name = "ast2600-a3"; - amc->hw_strap1 = TACOMA_BMC_HW_STRAP1; - amc->hw_strap2 = TACOMA_BMC_HW_STRAP2; - amc->fmc_model = "mx66l1g45g"; - amc->spi_model = "mx66l1g45g"; - amc->num_cs = 2; - amc->macs_mask = ASPEED_MAC2_ON; - amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */ - mc->default_ram_size = 1 * GiB; - aspeed_machine_class_init_cpus_defaults(mc); - - mc->deprecation_reason = "Please use the similar 'rainier-bmc' machine"; -}; - static void aspeed_machine_g220a_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1767,10 +1743,6 @@ static const TypeInfo aspeed_machine_types[] = { .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_yosemitev2_class_init, }, { - .name = MACHINE_TYPE_NAME("tacoma-bmc"), - .parent = TYPE_ASPEED_MACHINE, - .class_init = aspeed_machine_tacoma_class_init, - }, { .name = MACHINE_TYPE_NAME("tiogapass-bmc"), .parent = TYPE_ASPEED_MACHINE, .class_init = aspeed_machine_tiogapass_class_init, diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c index ecc81ecc79..3c1b419945 100644 --- a/hw/arm/aspeed_ast2400.c +++ b/hw/arm/aspeed_ast2400.c @@ -224,7 +224,8 @@ static void aspeed_ast2400_soc_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname); object_initialize_child(obj, "gpio", &s->gpio, typename); - object_initialize_child(obj, "sdc", &s->sdhci, TYPE_ASPEED_SDHCI); + snprintf(typename, sizeof(typename), "aspeed.sdhci-%s", socname); + object_initialize_child(obj, "sdc", &s->sdhci, typename); object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort); diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index be3eb70cdd..b5703bd064 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -236,8 +236,8 @@ static void aspeed_soc_ast2600_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.gpio-%s-1_8v", socname); object_initialize_child(obj, "gpio_1_8v", &s->gpio_1_8v, typename); - object_initialize_child(obj, "sd-controller", &s->sdhci, - TYPE_ASPEED_SDHCI); + snprintf(typename, sizeof(typename), "aspeed.sdhci-%s", socname); + object_initialize_child(obj, "sd-controller", &s->sdhci, typename); object_property_set_int(OBJECT(&s->sdhci), "num-slots", 2, &error_abort); @@ -247,8 +247,7 @@ static void aspeed_soc_ast2600_init(Object *obj) &s->sdhci.slots[i], TYPE_SYSBUS_SDHCI); } - object_initialize_child(obj, "emmc-controller", &s->emmc, - TYPE_ASPEED_SDHCI); + object_initialize_child(obj, "emmc-controller", &s->emmc, typename); object_property_set_int(OBJECT(&s->emmc), "num-slots", 1, &error_abort); @@ -541,7 +540,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp) if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) { return; } - aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0, sc->memmap[ASPEED_DEV_GPIO]); + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->gpio), 0, + sc->memmap[ASPEED_DEV_GPIO]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0, aspeed_soc_get_irq(s, ASPEED_DEV_GPIO)); diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index 63d1fcb086..23571584b2 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -65,6 +65,7 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = { [ASPEED_DEV_I2C] = 0x14C0F000, [ASPEED_DEV_GPIO] = 0x14C0B000, [ASPEED_DEV_RTC] = 0x12C0F000, + [ASPEED_DEV_SDHCI] = 0x14080000, }; #define AST2700_MAX_IRQ 256 @@ -113,6 +114,7 @@ static const int aspeed_soc_ast2700_irqmap[] = { [ASPEED_DEV_KCS] = 128, [ASPEED_DEV_DP] = 28, [ASPEED_DEV_I3C] = 131, + [ASPEED_DEV_SDHCI] = 133, }; /* GICINT 128 */ @@ -158,6 +160,7 @@ static const int aspeed_soc_ast2700_gic132_intcmap[] = { /* GICINT 133 */ static const int aspeed_soc_ast2700_gic133_intcmap[] = { + [ASPEED_DEV_SDHCI] = 1, [ASPEED_DEV_PECI] = 4, }; @@ -380,6 +383,20 @@ static void aspeed_soc_ast2700_init(Object *obj) object_initialize_child(obj, "gpio", &s->gpio, typename); object_initialize_child(obj, "rtc", &s->rtc, TYPE_ASPEED_RTC); + + snprintf(typename, sizeof(typename), "aspeed.sdhci-%s", socname); + object_initialize_child(obj, "sd-controller", &s->sdhci, typename); + object_property_set_int(OBJECT(&s->sdhci), "num-slots", 1, &error_abort); + + /* Init sd card slot class here so that they're under the correct parent */ + object_initialize_child(obj, "sd-controller.sdhci", + &s->sdhci.slots[0], TYPE_SYSBUS_SDHCI); + + object_initialize_child(obj, "emmc-controller", &s->emmc, typename); + object_property_set_int(OBJECT(&s->emmc), "num-slots", 1, &error_abort); + + object_initialize_child(obj, "emmc-controller.sdhci", &s->emmc.slots[0], + TYPE_SYSBUS_SDHCI); } /* @@ -681,6 +698,24 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->rtc), 0, aspeed_soc_get_irq(s, ASPEED_DEV_RTC)); + /* SDHCI */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->sdhci), errp)) { + return; + } + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->sdhci), 0, + sc->memmap[ASPEED_DEV_SDHCI]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0, + aspeed_soc_get_irq(s, ASPEED_DEV_SDHCI)); + + /* eMMC */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->emmc), errp)) { + return; + } + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->emmc), 0, + sc->memmap[ASPEED_DEV_EMMC]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->emmc), 0, + aspeed_soc_get_irq(s, ASPEED_DEV_EMMC)); + create_unimplemented_device("ast2700.dpmcu", 0x11000000, 0x40000); create_unimplemented_device("ast2700.iomem0", 0x12000000, 0x01000000); create_unimplemented_device("ast2700.iomem1", 0x14000000, 0x01000000); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 1a381e9a2b..3bd9dd0f86 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -3353,10 +3353,17 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); +static void virt_machine_10_0_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(10, 0) + static void virt_machine_9_2_options(MachineClass *mc) { + virt_machine_10_0_options(mc); + compat_props_add(mc->compat_props, hw_compat_9_2, hw_compat_9_2_len); } -DEFINE_VIRT_MACHINE_AS_LATEST(9, 2) +DEFINE_VIRT_MACHINE(9, 2) static void virt_machine_9_1_options(MachineClass *mc) { diff --git a/hw/core/machine.c b/hw/core/machine.c index f29fe95964..e6900b43ef 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -36,6 +36,9 @@ #include "hw/virtio/virtio-iommu.h" #include "audio/audio.h" +GlobalProperty hw_compat_9_2[] = {}; +const size_t hw_compat_9_2_len = G_N_ELEMENTS(hw_compat_9_2); + GlobalProperty hw_compat_9_1[] = { { TYPE_PCI_DEVICE, "x-pcie-ext-tag", "false" }, }; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 317aaca25a..99b9b105e2 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -79,6 +79,9 @@ { "qemu64-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },\ { "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, }, +GlobalProperty pc_compat_9_2[] = {}; +const size_t pc_compat_9_2_len = G_N_ELEMENTS(pc_compat_9_2); + GlobalProperty pc_compat_9_1[] = { { "ICH9-LPC", "x-smi-swsmi-timer", "off" }, { "ICH9-LPC", "x-smi-periodic-timer", "off" }, diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 2bf6865d40..e4365cbdb0 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -446,7 +446,10 @@ static void pc_i440fx_init(MachineState *machine) } #define DEFINE_I440FX_MACHINE(major, minor) \ - DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, major, minor); + DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, false, NULL, major, minor); + +#define DEFINE_I440FX_MACHINE_AS_LATEST(major, minor) \ + DEFINE_PC_VER_MACHINE(pc_i440fx, "pc-i440fx", pc_i440fx_init, true, "pc", major, minor); static void pc_i440fx_machine_options(MachineClass *m) { @@ -474,11 +477,18 @@ static void pc_i440fx_machine_options(MachineClass *m) "Use a different south bridge than PIIX3"); } -static void pc_i440fx_machine_9_2_options(MachineClass *m) +static void pc_i440fx_machine_10_0_options(MachineClass *m) { pc_i440fx_machine_options(m); - m->alias = "pc"; - m->is_default = true; +} + +DEFINE_I440FX_MACHINE_AS_LATEST(10, 0); + +static void pc_i440fx_machine_9_2_options(MachineClass *m) +{ + pc_i440fx_machine_10_0_options(m); + compat_props_add(m->compat_props, hw_compat_9_2, hw_compat_9_2_len); + compat_props_add(m->compat_props, pc_compat_9_2, pc_compat_9_2_len); } DEFINE_I440FX_MACHINE(9, 2); @@ -486,8 +496,6 @@ DEFINE_I440FX_MACHINE(9, 2); static void pc_i440fx_machine_9_1_options(MachineClass *m) { pc_i440fx_machine_9_2_options(m); - m->alias = NULL; - m->is_default = false; compat_props_add(m->compat_props, hw_compat_9_1, hw_compat_9_1_len); compat_props_add(m->compat_props, pc_compat_9_1, pc_compat_9_1_len); } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 8319b6d45e..bbbdacda8e 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -327,10 +327,13 @@ static void pc_q35_init(MachineState *machine) } #define DEFINE_Q35_MACHINE(major, minor) \ - DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, major, minor); + DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor); + +#define DEFINE_Q35_MACHINE_AS_LATEST(major, minor) \ + DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, "q35", major, minor); #define DEFINE_Q35_MACHINE_BUGFIX(major, minor, micro) \ - DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, major, minor, micro); + DEFINE_PC_VER_MACHINE(pc_q35, "pc-q35", pc_q35_init, false, NULL, major, minor, micro); static void pc_q35_machine_options(MachineClass *m) { @@ -356,10 +359,18 @@ static void pc_q35_machine_options(MachineClass *m) pc_q35_compat_defaults, pc_q35_compat_defaults_len); } -static void pc_q35_machine_9_2_options(MachineClass *m) +static void pc_q35_machine_10_0_options(MachineClass *m) { pc_q35_machine_options(m); - m->alias = "q35"; +} + +DEFINE_Q35_MACHINE_AS_LATEST(10, 0); + +static void pc_q35_machine_9_2_options(MachineClass *m) +{ + pc_q35_machine_10_0_options(m); + compat_props_add(m->compat_props, hw_compat_9_2, hw_compat_9_2_len); + compat_props_add(m->compat_props, pc_compat_9_2, pc_compat_9_2_len); } DEFINE_Q35_MACHINE(9, 2); @@ -367,7 +378,6 @@ DEFINE_Q35_MACHINE(9, 2); static void pc_q35_machine_9_1_options(MachineClass *m) { pc_q35_machine_9_2_options(m); - m->alias = NULL; compat_props_add(m->compat_props, hw_compat_9_1, hw_compat_9_1_len); compat_props_add(m->compat_props, pc_compat_9_1, pc_compat_9_1_len); } diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index ea5c4a5a57..d0a7a6bfe2 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -366,10 +366,17 @@ type_init(virt_machine_register_types) #define DEFINE_VIRT_MACHINE(major, minor) \ DEFINE_VIRT_MACHINE_IMPL(false, major, minor) +static void virt_machine_10_0_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(10, 0) + static void virt_machine_9_2_options(MachineClass *mc) { + virt_machine_10_0_options(mc); + compat_props_add(mc->compat_props, hw_compat_9_2, hw_compat_9_2_len); } -DEFINE_VIRT_MACHINE_AS_LATEST(9, 2) +DEFINE_VIRT_MACHINE(9, 2) static void virt_machine_9_1_options(MachineClass *mc) { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0d4efaa0c0..7251eea521 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4733,14 +4733,25 @@ static void spapr_machine_latest_class_options(MachineClass *mc) DEFINE_SPAPR_MACHINE_IMPL(false, major, minor) /* + * pseries-10.0 + */ +static void spapr_machine_10_0_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE_AS_LATEST(10, 0); + +/* * pseries-9.2 */ static void spapr_machine_9_2_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_10_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_9_2, hw_compat_9_2_len); } -DEFINE_SPAPR_MACHINE_AS_LATEST(9, 2); +DEFINE_SPAPR_MACHINE(9, 2); /* * pseries-9.1 diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index fe03f716f3..67ae34aead 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -849,14 +849,26 @@ static const TypeInfo ccw_machine_info = { DEFINE_CCW_MACHINE_IMPL(false, major, minor) +static void ccw_machine_10_0_instance_options(MachineState *machine) +{ +} + +static void ccw_machine_10_0_class_options(MachineClass *mc) +{ +} +DEFINE_CCW_MACHINE_AS_LATEST(10, 0); + static void ccw_machine_9_2_instance_options(MachineState *machine) { + ccw_machine_10_0_instance_options(machine); } static void ccw_machine_9_2_class_options(MachineClass *mc) { + ccw_machine_10_0_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_9_2, hw_compat_9_2_len); } -DEFINE_CCW_MACHINE_AS_LATEST(9, 2); +DEFINE_CCW_MACHINE(9, 2); static void ccw_machine_9_1_instance_options(MachineState *machine) { diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c index 98d5460905..f82b05397e 100644 --- a/hw/sd/aspeed_sdhci.c +++ b/hw/sd/aspeed_sdhci.c @@ -87,10 +87,12 @@ static void aspeed_sdhci_write(void *opaque, hwaddr addr, uint64_t val, sdhci->regs[TO_REG(addr)] = (uint32_t)val & ~ASPEED_SDHCI_INFO_RESET; break; case ASPEED_SDHCI_SDIO_140: - sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg, 0, 32, val); + sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg, + 0, 32, val); break; case ASPEED_SDHCI_SDIO_144: - sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg, 32, 32, val); + sdhci->slots[0].capareg = deposit64(sdhci->slots[0].capareg, + 32, 32, val); break; case ASPEED_SDHCI_SDIO_148: sdhci->slots[0].maxcurr = deposit64(sdhci->slots[0].maxcurr, @@ -146,6 +148,7 @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp) { SysBusDevice *sbd = SYS_BUS_DEVICE(dev); AspeedSDHCIState *sdhci = ASPEED_SDHCI(dev); + AspeedSDHCIClass *asc = ASPEED_SDHCI_GET_CLASS(sdhci); /* Create input irqs for the slots */ qdev_init_gpio_in_named_with_opaque(DEVICE(sbd), aspeed_sdhci_set_irq, @@ -165,7 +168,7 @@ static void aspeed_sdhci_realize(DeviceState *dev, Error **errp) } if (!object_property_set_uint(sdhci_slot, "capareg", - ASPEED_SDHCI_CAPABILITIES, errp)) { + asc->capareg, errp)) { return; } @@ -216,12 +219,70 @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data) device_class_set_props(dc, aspeed_sdhci_properties); } +static void aspeed_2400_sdhci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); + + dc->desc = "ASPEED 2400 SDHCI Controller"; + asc->capareg = 0x0000000001e80080; +} + +static void aspeed_2500_sdhci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); + + dc->desc = "ASPEED 2500 SDHCI Controller"; + asc->capareg = 0x0000000001e80080; +} + +static void aspeed_2600_sdhci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); + + dc->desc = "ASPEED 2600 SDHCI Controller"; + asc->capareg = 0x0000000701f80080; +} + +static void aspeed_2700_sdhci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); + + dc->desc = "ASPEED 2700 SDHCI Controller"; + asc->capareg = 0x0000000719f80080; +} + static const TypeInfo aspeed_sdhci_types[] = { { .name = TYPE_ASPEED_SDHCI, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(AspeedSDHCIState), .class_init = aspeed_sdhci_class_init, + .class_size = sizeof(AspeedSDHCIClass), + .abstract = true, + }, + { + .name = TYPE_ASPEED_2400_SDHCI, + .parent = TYPE_ASPEED_SDHCI, + .class_init = aspeed_2400_sdhci_class_init, + }, + { + .name = TYPE_ASPEED_2500_SDHCI, + .parent = TYPE_ASPEED_SDHCI, + .class_init = aspeed_2500_sdhci_class_init, + }, + { + .name = TYPE_ASPEED_2600_SDHCI, + .parent = TYPE_ASPEED_SDHCI, + .class_init = aspeed_2600_sdhci_class_init, + }, + { + .name = TYPE_ASPEED_2700_SDHCI, + .parent = TYPE_ASPEED_SDHCI, + .class_init = aspeed_2700_sdhci_class_init, }, }; diff --git a/include/hw/boards.h b/include/hw/boards.h index 36fbb9b59d..7456889c37 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -756,6 +756,9 @@ struct MachineState { } \ type_init(machine_initfn##_register_types) +extern GlobalProperty hw_compat_9_2[]; +extern const size_t hw_compat_9_2_len; + extern GlobalProperty hw_compat_9_1[]; extern const size_t hw_compat_9_1_len; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 14ee06287d..1b26a417bd 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -215,6 +215,9 @@ void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size); /* sgx.c */ void pc_machine_init_sgx_epc(PCMachineState *pcms); +extern GlobalProperty pc_compat_9_2[]; +extern const size_t pc_compat_9_2_len; + extern GlobalProperty pc_compat_9_1[]; extern const size_t pc_compat_9_1_len; @@ -320,7 +323,7 @@ extern const size_t pc_compat_2_3_len; } \ type_init(pc_machine_init_##suffix) -#define DEFINE_PC_VER_MACHINE(namesym, namestr, initfn, ...) \ +#define DEFINE_PC_VER_MACHINE(namesym, namestr, initfn, isdefault, malias, ...) \ static void MACHINE_VER_SYM(init, namesym, __VA_ARGS__)( \ MachineState *machine) \ { \ @@ -334,6 +337,8 @@ extern const size_t pc_compat_2_3_len; MACHINE_VER_SYM(options, namesym, __VA_ARGS__)(mc); \ mc->init = MACHINE_VER_SYM(init, namesym, __VA_ARGS__); \ MACHINE_VER_DEPRECATION(__VA_ARGS__); \ + mc->is_default = isdefault; \ + mc->alias = malias; \ } \ static const TypeInfo MACHINE_VER_SYM(info, namesym, __VA_ARGS__) = \ { \ diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h index 057bc5f3d1..4ef1770471 100644 --- a/include/hw/sd/aspeed_sdhci.h +++ b/include/hw/sd/aspeed_sdhci.h @@ -13,9 +13,12 @@ #include "qom/object.h" #define TYPE_ASPEED_SDHCI "aspeed.sdhci" -OBJECT_DECLARE_SIMPLE_TYPE(AspeedSDHCIState, ASPEED_SDHCI) +#define TYPE_ASPEED_2400_SDHCI TYPE_ASPEED_SDHCI "-ast2400" +#define TYPE_ASPEED_2500_SDHCI TYPE_ASPEED_SDHCI "-ast2500" +#define TYPE_ASPEED_2600_SDHCI TYPE_ASPEED_SDHCI "-ast2600" +#define TYPE_ASPEED_2700_SDHCI TYPE_ASPEED_SDHCI "-ast2700" +OBJECT_DECLARE_TYPE(AspeedSDHCIState, AspeedSDHCIClass, ASPEED_SDHCI) -#define ASPEED_SDHCI_CAPABILITIES 0x01E80080 #define ASPEED_SDHCI_NUM_SLOTS 2 #define ASPEED_SDHCI_NUM_REGS (ASPEED_SDHCI_REG_SIZE / sizeof(uint32_t)) #define ASPEED_SDHCI_REG_SIZE 0x100 @@ -32,4 +35,10 @@ struct AspeedSDHCIState { uint32_t regs[ASPEED_SDHCI_NUM_REGS]; }; +struct AspeedSDHCIClass { + SysBusDeviceClass parent_class; + + uint64_t capareg; +}; + #endif /* ASPEED_SDHCI_H */ diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h index d4a2231306..708647776f 100644 --- a/include/standard-headers/drm/drm_fourcc.h +++ b/include/standard-headers/drm/drm_fourcc.h @@ -1515,6 +1515,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier) * 64K_D_2D on GFX12 is identical to 64K_D on GFX11. */ #define AMD_FMT_MOD_TILE_GFX9_64K_D 10 +#define AMD_FMT_MOD_TILE_GFX9_4K_D_X 22 #define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 #define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26 #define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h index b05e84825b..67c47912e5 100644 --- a/include/standard-headers/linux/ethtool.h +++ b/include/standard-headers/linux/ethtool.h @@ -2526,6 +2526,11 @@ struct ethtool_link_settings { uint8_t master_slave_state; uint8_t rate_matching; uint32_t reserved[7]; + /* Linux builds with -Wflex-array-member-not-at-end but does + * not use the "link_mode_masks" member. Leave it defined for + * userspace for now, and when userspace wants to start using + * -Wfamnae, we'll need a new solution. + */ uint32_t link_mode_masks[]; /* layout of link_mode_masks fields: * uint32_t map_supported[link_mode_masks_nwords]; diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index 12323b3334..1601c7ed5f 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -340,7 +340,8 @@ #define PCI_MSIX_ENTRY_UPPER_ADDR 0x4 /* Message Upper Address */ #define PCI_MSIX_ENTRY_DATA 0x8 /* Message Data */ #define PCI_MSIX_ENTRY_VECTOR_CTRL 0xc /* Vector Control */ -#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 /* Mask Bit */ +#define PCI_MSIX_ENTRY_CTRL_ST 0xffff0000 /* Steering Tag */ /* CompactPCI Hotswap Register */ @@ -659,6 +660,7 @@ #define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* 64b AtomicOp completion */ #define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200 /* 128b AtomicOp completion */ #define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */ +#define PCI_EXP_DEVCAP2_TPH_COMP_MASK 0x00003000 /* TPH completer support */ #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */ #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */ @@ -678,6 +680,7 @@ #define PCI_EXP_DEVSTA2 0x2a /* Device Status 2 */ #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c /* end of v2 EPs w/o link */ #define PCI_EXP_LNKCAP2 0x2c /* Link Capabilities 2 */ +#define PCI_EXP_LNKCAP2_SLS 0x000000fe /* Supported Link Speeds Vector */ #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */ #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */ @@ -1023,15 +1026,34 @@ #define PCI_DPA_CAP_SUBSTATE_MASK 0x1F /* # substates - 1 */ #define PCI_DPA_BASE_SIZEOF 16 /* size with 0 substates */ +/* TPH Completer Support */ +#define PCI_EXP_DEVCAP2_TPH_COMP_NONE 0x0 /* None */ +#define PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY 0x1 /* TPH only */ +#define PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH 0x3 /* TPH and Extended TPH */ + /* TPH Requester */ #define PCI_TPH_CAP 4 /* capability register */ -#define PCI_TPH_CAP_LOC_MASK 0x600 /* location mask */ -#define PCI_TPH_LOC_NONE 0x000 /* no location */ -#define PCI_TPH_LOC_CAP 0x200 /* in capability */ -#define PCI_TPH_LOC_MSIX 0x400 /* in MSI-X */ -#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST table mask */ -#define PCI_TPH_CAP_ST_SHIFT 16 /* ST table shift */ -#define PCI_TPH_BASE_SIZEOF 0xc /* size with no ST table */ +#define PCI_TPH_CAP_ST_NS 0x00000001 /* No ST Mode Supported */ +#define PCI_TPH_CAP_ST_IV 0x00000002 /* Interrupt Vector Mode Supported */ +#define PCI_TPH_CAP_ST_DS 0x00000004 /* Device Specific Mode Supported */ +#define PCI_TPH_CAP_EXT_TPH 0x00000100 /* Ext TPH Requester Supported */ +#define PCI_TPH_CAP_LOC_MASK 0x00000600 /* ST Table Location */ +#define PCI_TPH_LOC_NONE 0x00000000 /* Not present */ +#define PCI_TPH_LOC_CAP 0x00000200 /* In capability */ +#define PCI_TPH_LOC_MSIX 0x00000400 /* In MSI-X */ +#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST Table Size */ +#define PCI_TPH_CAP_ST_SHIFT 16 /* ST Table Size shift */ +#define PCI_TPH_BASE_SIZEOF 0xc /* Size with no ST table */ + +#define PCI_TPH_CTRL 8 /* control register */ +#define PCI_TPH_CTRL_MODE_SEL_MASK 0x00000007 /* ST Mode Select */ +#define PCI_TPH_ST_NS_MODE 0x0 /* No ST Mode */ +#define PCI_TPH_ST_IV_MODE 0x1 /* Interrupt Vector Mode */ +#define PCI_TPH_ST_DS_MODE 0x2 /* Device Specific Mode */ +#define PCI_TPH_CTRL_REQ_EN_MASK 0x00000300 /* TPH Requester Enable */ +#define PCI_TPH_REQ_DISABLE 0x0 /* No TPH requests allowed */ +#define PCI_TPH_REQ_TPH_ONLY 0x1 /* TPH only requests allowed */ +#define PCI_TPH_REQ_EXT_TPH 0x3 /* Extended TPH requests allowed */ /* Downstream Port Containment */ #define PCI_EXP_DPC_CAP 0x04 /* DPC Capability */ diff --git a/include/standard-headers/linux/virtio_crypto.h b/include/standard-headers/linux/virtio_crypto.h index 68066dafb6..4d350ae595 100644 --- a/include/standard-headers/linux/virtio_crypto.h +++ b/include/standard-headers/linux/virtio_crypto.h @@ -329,6 +329,7 @@ struct virtio_crypto_op_header { VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x00) #define VIRTIO_CRYPTO_AKCIPHER_DECRYPT \ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x01) + /* akcipher sign/verify opcodes are deprecated */ #define VIRTIO_CRYPTO_AKCIPHER_SIGN \ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x02) #define VIRTIO_CRYPTO_AKCIPHER_VERIFY \ diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h index 4010216103..b177ed8972 100644 --- a/include/standard-headers/linux/virtio_pci.h +++ b/include/standard-headers/linux/virtio_pci.h @@ -40,6 +40,7 @@ #define _LINUX_VIRTIO_PCI_H #include "standard-headers/linux/types.h" +#include "standard-headers/linux/kernel.h" #ifndef VIRTIO_PCI_NO_LEGACY @@ -240,6 +241,17 @@ struct virtio_pci_cfg_cap { #define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5 #define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6 +/* Device parts access commands. */ +#define VIRTIO_ADMIN_CMD_CAP_ID_LIST_QUERY 0x7 +#define VIRTIO_ADMIN_CMD_DEVICE_CAP_GET 0x8 +#define VIRTIO_ADMIN_CMD_DRIVER_CAP_SET 0x9 +#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_CREATE 0xa +#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_DESTROY 0xd +#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_GET 0xe +#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET 0xf +#define VIRTIO_ADMIN_CMD_DEV_PARTS_SET 0x10 +#define VIRTIO_ADMIN_CMD_DEV_MODE_SET 0x11 + struct virtio_admin_cmd_hdr { uint16_t opcode; /* @@ -286,4 +298,123 @@ struct virtio_admin_cmd_notify_info_result { struct virtio_admin_cmd_notify_info_data entries[VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO]; }; +#define VIRTIO_DEV_PARTS_CAP 0x0000 + +struct virtio_dev_parts_cap { + uint8_t get_parts_resource_objects_limit; + uint8_t set_parts_resource_objects_limit; +}; + +#define MAX_CAP_ID __KERNEL_DIV_ROUND_UP(VIRTIO_DEV_PARTS_CAP + 1, 64) + +struct virtio_admin_cmd_query_cap_id_result { + uint64_t supported_caps[MAX_CAP_ID]; +}; + +struct virtio_admin_cmd_cap_get_data { + uint16_t id; + uint8_t reserved[6]; +}; + +struct virtio_admin_cmd_cap_set_data { + uint16_t id; + uint8_t reserved[6]; + uint8_t cap_specific_data[]; +}; + +struct virtio_admin_cmd_resource_obj_cmd_hdr { + uint16_t type; + uint8_t reserved[2]; + uint32_t id; /* Indicates unique resource object id per resource object type */ +}; + +struct virtio_admin_cmd_resource_obj_create_data { + struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; + uint64_t flags; + uint8_t resource_obj_specific_data[]; +}; + +#define VIRTIO_RESOURCE_OBJ_DEV_PARTS 0 + +#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_GET 0 +#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_SET 1 + +struct virtio_resource_obj_dev_parts { + uint8_t type; + uint8_t reserved[7]; +}; + +#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_SIZE 0 +#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_COUNT 1 +#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_LIST 2 + +struct virtio_admin_cmd_dev_parts_metadata_data { + struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; + uint8_t type; + uint8_t reserved[7]; +}; + +#define VIRTIO_DEV_PART_F_OPTIONAL 0 + +struct virtio_dev_part_hdr { + uint16_t part_type; + uint8_t flags; + uint8_t reserved; + union { + struct { + uint32_t offset; + uint32_t reserved; + } pci_common_cfg; + struct { + uint16_t index; + uint8_t reserved[6]; + } vq_index; + } selector; + uint32_t length; +}; + +struct virtio_dev_part { + struct virtio_dev_part_hdr hdr; + uint8_t value[]; +}; + +struct virtio_admin_cmd_dev_parts_metadata_result { + union { + struct { + uint32_t size; + uint32_t reserved; + } parts_size; + struct { + uint32_t count; + uint32_t reserved; + } hdr_list_count; + struct { + uint32_t count; + uint32_t reserved; + struct virtio_dev_part_hdr hdrs[]; + } hdr_list; + }; +}; + +#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_SELECTED 0 +#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_ALL 1 + +struct virtio_admin_cmd_dev_parts_get_data { + struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; + uint8_t type; + uint8_t reserved[7]; + struct virtio_dev_part_hdr hdr_list[]; +}; + +struct virtio_admin_cmd_dev_parts_set_data { + struct virtio_admin_cmd_resource_obj_cmd_hdr hdr; + struct virtio_dev_part parts[]; +}; + +#define VIRTIO_ADMIN_CMD_DEV_MODE_F_STOPPED 0 + +struct virtio_admin_cmd_dev_mode_set_data { + uint8_t flags; +}; + #endif diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h index 2af9931ae9..dccd5d965f 100644 --- a/linux-headers/asm-arm64/kvm.h +++ b/linux-headers/asm-arm64/kvm.h @@ -473,6 +473,12 @@ enum { */ #define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0) +/* + * Shutdown caused by a PSCI v1.3 SYSTEM_OFF2 call. + * Valid only when the system event has a type of KVM_SYSTEM_EVENT_SHUTDOWN. + */ +#define KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2 (1ULL << 0) + /* run->fail_entry.hardware_entry_failure_reason codes. */ #define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0) diff --git a/linux-headers/asm-arm64/unistd_64.h b/linux-headers/asm-arm64/unistd_64.h index 99a1d70459..d4e90fff76 100644 --- a/linux-headers/asm-arm64/unistd_64.h +++ b/linux-headers/asm-arm64/unistd_64.h @@ -319,6 +319,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_64_H */ diff --git a/linux-headers/asm-generic/mman-common.h b/linux-headers/asm-generic/mman-common.h index 6ce1f1ceb4..1ea2c4c33b 100644 --- a/linux-headers/asm-generic/mman-common.h +++ b/linux-headers/asm-generic/mman-common.h @@ -79,6 +79,9 @@ #define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */ +#define MADV_GUARD_INSTALL 102 /* fatal signal on access to range */ +#define MADV_GUARD_REMOVE 103 /* unguard range */ + /* compatibility flags */ #define MAP_FILE 0 diff --git a/linux-headers/asm-generic/mman.h b/linux-headers/asm-generic/mman.h index 57e8195d0b..5e3d61ddbd 100644 --- a/linux-headers/asm-generic/mman.h +++ b/linux-headers/asm-generic/mman.h @@ -19,4 +19,8 @@ #define MCL_FUTURE 2 /* lock all future mappings */ #define MCL_ONFAULT 4 /* lock all pages that are faulted in */ +#define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ +#define SHADOW_STACK_SET_MARKER (1ULL << 1) /* Set up a top of stack marker in the shadow stack */ + + #endif /* __ASM_GENERIC_MMAN_H */ diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h index 5bf6148cac..88dc393c2b 100644 --- a/linux-headers/asm-generic/unistd.h +++ b/linux-headers/asm-generic/unistd.h @@ -841,8 +841,17 @@ __SYSCALL(__NR_lsm_list_modules, sys_lsm_list_modules) #define __NR_mseal 462 __SYSCALL(__NR_mseal, sys_mseal) +#define __NR_setxattrat 463 +__SYSCALL(__NR_setxattrat, sys_setxattrat) +#define __NR_getxattrat 464 +__SYSCALL(__NR_getxattrat, sys_getxattrat) +#define __NR_listxattrat 465 +__SYSCALL(__NR_listxattrat, sys_listxattrat) +#define __NR_removexattrat 466 +__SYSCALL(__NR_removexattrat, sys_removexattrat) + #undef __NR_syscalls -#define __NR_syscalls 463 +#define __NR_syscalls 467 /* * 32 bit systems traditionally used different diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h index 70d89070bf..5f354f5c68 100644 --- a/linux-headers/asm-loongarch/kvm.h +++ b/linux-headers/asm-loongarch/kvm.h @@ -8,6 +8,8 @@ #include <linux/types.h> +#define __KVM_HAVE_IRQ_LINE + /* * KVM LoongArch specific structures and definitions. * @@ -132,4 +134,22 @@ struct kvm_iocsr_entry { #define KVM_IRQCHIP_NUM_PINS 64 #define KVM_MAX_CORES 256 +#define KVM_DEV_LOONGARCH_IPI_GRP_REGS 0x40000001 + +#define KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS 0x40000002 + +#define KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS 0x40000003 +#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU 0x0 +#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_FEATURE 0x1 +#define KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE 0x2 + +#define KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL 0x40000004 +#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU 0x0 +#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE 0x1 +#define KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED 0x3 + +#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS 0x40000005 +#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL 0x40000006 +#define KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT 0 + #endif /* __UAPI_ASM_LOONGARCH_KVM_H */ diff --git a/linux-headers/asm-loongarch/unistd_64.h b/linux-headers/asm-loongarch/unistd_64.h index 887ea50cca..23fb96a8a7 100644 --- a/linux-headers/asm-loongarch/unistd_64.h +++ b/linux-headers/asm-loongarch/unistd_64.h @@ -315,6 +315,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_64_H */ diff --git a/linux-headers/asm-mips/mman.h b/linux-headers/asm-mips/mman.h index 9c48d9a21a..b700dae28c 100644 --- a/linux-headers/asm-mips/mman.h +++ b/linux-headers/asm-mips/mman.h @@ -105,6 +105,9 @@ #define MADV_COLLAPSE 25 /* Synchronous hugepage collapse */ +#define MADV_GUARD_INSTALL 102 /* fatal signal on access to range */ +#define MADV_GUARD_REMOVE 103 /* unguard range */ + /* compatibility flags */ #define MAP_FILE 0 diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h index fc93b3be30..9a75719644 100644 --- a/linux-headers/asm-mips/unistd_n32.h +++ b/linux-headers/asm-mips/unistd_n32.h @@ -391,5 +391,9 @@ #define __NR_lsm_set_self_attr (__NR_Linux + 460) #define __NR_lsm_list_modules (__NR_Linux + 461) #define __NR_mseal (__NR_Linux + 462) +#define __NR_setxattrat (__NR_Linux + 463) +#define __NR_getxattrat (__NR_Linux + 464) +#define __NR_listxattrat (__NR_Linux + 465) +#define __NR_removexattrat (__NR_Linux + 466) #endif /* _ASM_UNISTD_N32_H */ diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h index e72a3eb2c9..7086783b0c 100644 --- a/linux-headers/asm-mips/unistd_n64.h +++ b/linux-headers/asm-mips/unistd_n64.h @@ -367,5 +367,9 @@ #define __NR_lsm_set_self_attr (__NR_Linux + 460) #define __NR_lsm_list_modules (__NR_Linux + 461) #define __NR_mseal (__NR_Linux + 462) +#define __NR_setxattrat (__NR_Linux + 463) +#define __NR_getxattrat (__NR_Linux + 464) +#define __NR_listxattrat (__NR_Linux + 465) +#define __NR_removexattrat (__NR_Linux + 466) #endif /* _ASM_UNISTD_N64_H */ diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h index b86eb0786c..b3825823e4 100644 --- a/linux-headers/asm-mips/unistd_o32.h +++ b/linux-headers/asm-mips/unistd_o32.h @@ -437,5 +437,9 @@ #define __NR_lsm_set_self_attr (__NR_Linux + 460) #define __NR_lsm_list_modules (__NR_Linux + 461) #define __NR_mseal (__NR_Linux + 462) +#define __NR_setxattrat (__NR_Linux + 463) +#define __NR_getxattrat (__NR_Linux + 464) +#define __NR_listxattrat (__NR_Linux + 465) +#define __NR_removexattrat (__NR_Linux + 466) #endif /* _ASM_UNISTD_O32_H */ diff --git a/linux-headers/asm-powerpc/unistd_32.h b/linux-headers/asm-powerpc/unistd_32.h index 28627b6546..38ee4dc35d 100644 --- a/linux-headers/asm-powerpc/unistd_32.h +++ b/linux-headers/asm-powerpc/unistd_32.h @@ -444,6 +444,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_32_H */ diff --git a/linux-headers/asm-powerpc/unistd_64.h b/linux-headers/asm-powerpc/unistd_64.h index 1fc42a8300..5e5f156834 100644 --- a/linux-headers/asm-powerpc/unistd_64.h +++ b/linux-headers/asm-powerpc/unistd_64.h @@ -416,6 +416,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_64_H */ diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h index e97db32964..3482c9a73d 100644 --- a/linux-headers/asm-riscv/kvm.h +++ b/linux-headers/asm-riscv/kvm.h @@ -175,6 +175,10 @@ enum KVM_RISCV_ISA_EXT_ID { KVM_RISCV_ISA_EXT_ZCF, KVM_RISCV_ISA_EXT_ZCMOP, KVM_RISCV_ISA_EXT_ZAWRS, + KVM_RISCV_ISA_EXT_SMNPM, + KVM_RISCV_ISA_EXT_SSNPM, + KVM_RISCV_ISA_EXT_SVADE, + KVM_RISCV_ISA_EXT_SVADU, KVM_RISCV_ISA_EXT_MAX, }; diff --git a/linux-headers/asm-riscv/unistd_32.h b/linux-headers/asm-riscv/unistd_32.h index 9625743dfd..74f6127aed 100644 --- a/linux-headers/asm-riscv/unistd_32.h +++ b/linux-headers/asm-riscv/unistd_32.h @@ -310,6 +310,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_32_H */ diff --git a/linux-headers/asm-riscv/unistd_64.h b/linux-headers/asm-riscv/unistd_64.h index 95bca8ae81..bb6a15a2ec 100644 --- a/linux-headers/asm-riscv/unistd_64.h +++ b/linux-headers/asm-riscv/unistd_64.h @@ -320,6 +320,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_64_H */ diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h index 684c4e1205..ab5a6bce59 100644 --- a/linux-headers/asm-s390/kvm.h +++ b/linux-headers/asm-s390/kvm.h @@ -469,7 +469,8 @@ struct kvm_s390_vm_cpu_subfunc { __u8 kdsa[16]; /* with MSA9 */ __u8 sortl[32]; /* with STFLE.150 */ __u8 dfltcc[32]; /* with STFLE.151 */ - __u8 reserved[1728]; + __u8 pfcr[16]; /* with STFLE.201 */ + __u8 reserved[1712]; }; #define KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST 6 diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h index 7706c21b87..620201cb36 100644 --- a/linux-headers/asm-s390/unistd_32.h +++ b/linux-headers/asm-s390/unistd_32.h @@ -435,5 +435,9 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_S390_UNISTD_32_H */ diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h index 62082d592d..e7e4a10aaf 100644 --- a/linux-headers/asm-s390/unistd_64.h +++ b/linux-headers/asm-s390/unistd_64.h @@ -383,5 +383,9 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_S390_UNISTD_64_H */ diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h index 4711ef2c3d..96589490c4 100644 --- a/linux-headers/asm-x86/kvm.h +++ b/linux-headers/asm-x86/kvm.h @@ -438,6 +438,7 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_FIX_HYPERCALL_INSN (1 << 5) #define KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS (1 << 6) #define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) +#define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) #define KVM_STATE_NESTED_FORMAT_VMX 0 #define KVM_STATE_NESTED_FORMAT_SVM 1 diff --git a/linux-headers/asm-x86/mman.h b/linux-headers/asm-x86/mman.h index 46cdc941f9..ac1e627721 100644 --- a/linux-headers/asm-x86/mman.h +++ b/linux-headers/asm-x86/mman.h @@ -5,9 +5,6 @@ #define MAP_32BIT 0x40 /* only give out 32bit addresses */ #define MAP_ABOVE4G 0x80 /* only map above 4GB */ -/* Flags for map_shadow_stack(2) */ -#define SHADOW_STACK_SET_TOKEN (1ULL << 0) /* Set up a restore token in the shadow stack */ - #include <asm-generic/mman.h> #endif /* _ASM_X86_MMAN_H */ diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h index fb7b8b169b..a2eb492a75 100644 --- a/linux-headers/asm-x86/unistd_32.h +++ b/linux-headers/asm-x86/unistd_32.h @@ -453,6 +453,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_32_H */ diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h index 24c979be54..2f5fc400f5 100644 --- a/linux-headers/asm-x86/unistd_64.h +++ b/linux-headers/asm-x86/unistd_64.h @@ -376,6 +376,10 @@ #define __NR_lsm_set_self_attr 460 #define __NR_lsm_list_modules 461 #define __NR_mseal 462 +#define __NR_setxattrat 463 +#define __NR_getxattrat 464 +#define __NR_listxattrat 465 +#define __NR_removexattrat 466 #endif /* _ASM_UNISTD_64_H */ diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h index c23dd21a2d..fecd832e7f 100644 --- a/linux-headers/asm-x86/unistd_x32.h +++ b/linux-headers/asm-x86/unistd_x32.h @@ -329,6 +329,10 @@ #define __NR_lsm_set_self_attr (__X32_SYSCALL_BIT + 460) #define __NR_lsm_list_modules (__X32_SYSCALL_BIT + 461) #define __NR_mseal (__X32_SYSCALL_BIT + 462) +#define __NR_setxattrat (__X32_SYSCALL_BIT + 463) +#define __NR_getxattrat (__X32_SYSCALL_BIT + 464) +#define __NR_listxattrat (__X32_SYSCALL_BIT + 465) +#define __NR_removexattrat (__X32_SYSCALL_BIT + 466) #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) #define __NR_ioctl (__X32_SYSCALL_BIT + 514) diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h index 782baf477f..37aae16502 100644 --- a/linux-headers/linux/iommufd.h +++ b/linux-headers/linux/iommufd.h @@ -51,6 +51,10 @@ enum { IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP = 0x8c, IOMMUFD_CMD_HWPT_INVALIDATE = 0x8d, IOMMUFD_CMD_FAULT_QUEUE_ALLOC = 0x8e, + IOMMUFD_CMD_IOAS_MAP_FILE = 0x8f, + IOMMUFD_CMD_VIOMMU_ALLOC = 0x90, + IOMMUFD_CMD_VDEVICE_ALLOC = 0x91, + IOMMUFD_CMD_IOAS_CHANGE_PROCESS = 0x92, }; /** @@ -214,6 +218,30 @@ struct iommu_ioas_map { #define IOMMU_IOAS_MAP _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_MAP) /** + * struct iommu_ioas_map_file - ioctl(IOMMU_IOAS_MAP_FILE) + * @size: sizeof(struct iommu_ioas_map_file) + * @flags: same as for iommu_ioas_map + * @ioas_id: same as for iommu_ioas_map + * @fd: the memfd to map + * @start: byte offset from start of file to map from + * @length: same as for iommu_ioas_map + * @iova: same as for iommu_ioas_map + * + * Set an IOVA mapping from a memfd file. All other arguments and semantics + * match those of IOMMU_IOAS_MAP. + */ +struct iommu_ioas_map_file { + __u32 size; + __u32 flags; + __u32 ioas_id; + __s32 fd; + __aligned_u64 start; + __aligned_u64 length; + __aligned_u64 iova; +}; +#define IOMMU_IOAS_MAP_FILE _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_MAP_FILE) + +/** * struct iommu_ioas_copy - ioctl(IOMMU_IOAS_COPY) * @size: sizeof(struct iommu_ioas_copy) * @flags: Combination of enum iommufd_ioas_map_flags @@ -359,11 +387,19 @@ struct iommu_vfio_ioas { * enforced on device attachment * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is * valid. + * @IOMMU_HWPT_ALLOC_PASID: Requests a domain that can be used with PASID. The + * domain can be attached to any PASID on the device. + * Any domain attached to the non-PASID part of the + * device must also be flaged, otherwise attaching a + * PASID will blocked. + * If IOMMU does not support PASID it will return + * error (-EOPNOTSUPP). */ enum iommufd_hwpt_alloc_flags { IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, + IOMMU_HWPT_ALLOC_PASID = 1 << 3, }; /** @@ -395,13 +431,35 @@ struct iommu_hwpt_vtd_s1 { }; /** + * struct iommu_hwpt_arm_smmuv3 - ARM SMMUv3 nested STE + * (IOMMU_HWPT_DATA_ARM_SMMUV3) + * + * @ste: The first two double words of the user space Stream Table Entry for + * the translation. Must be little-endian. + * Allowed fields: (Refer to "5.2 Stream Table Entry" in SMMUv3 HW Spec) + * - word-0: V, Cfg, S1Fmt, S1ContextPtr, S1CDMax + * - word-1: EATS, S1DSS, S1CIR, S1COR, S1CSH, S1STALLD + * + * -EIO will be returned if @ste is not legal or contains any non-allowed field. + * Cfg can be used to select a S1, Bypass or Abort configuration. A Bypass + * nested domain will translate the same as the nesting parent. The S1 will + * install a Context Descriptor Table pointing at userspace memory translated + * by the nesting parent. + */ +struct iommu_hwpt_arm_smmuv3 { + __aligned_le64 ste[2]; +}; + +/** * enum iommu_hwpt_data_type - IOMMU HWPT Data Type * @IOMMU_HWPT_DATA_NONE: no data * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table + * @IOMMU_HWPT_DATA_ARM_SMMUV3: ARM SMMUv3 Context Descriptor Table */ enum iommu_hwpt_data_type { IOMMU_HWPT_DATA_NONE = 0, IOMMU_HWPT_DATA_VTD_S1 = 1, + IOMMU_HWPT_DATA_ARM_SMMUV3 = 2, }; /** @@ -409,7 +467,7 @@ enum iommu_hwpt_data_type { * @size: sizeof(struct iommu_hwpt_alloc) * @flags: Combination of enum iommufd_hwpt_alloc_flags * @dev_id: The device to allocate this HWPT for - * @pt_id: The IOAS or HWPT to connect this HWPT to + * @pt_id: The IOAS or HWPT or vIOMMU to connect this HWPT to * @out_hwpt_id: The ID of the new HWPT * @__reserved: Must be 0 * @data_type: One of enum iommu_hwpt_data_type @@ -428,11 +486,13 @@ enum iommu_hwpt_data_type { * IOMMU_HWPT_DATA_NONE. The HWPT can be allocated as a parent HWPT for a * nesting configuration by passing IOMMU_HWPT_ALLOC_NEST_PARENT via @flags. * - * A user-managed nested HWPT will be created from a given parent HWPT via - * @pt_id, in which the parent HWPT must be allocated previously via the - * same ioctl from a given IOAS (@pt_id). In this case, the @data_type - * must be set to a pre-defined type corresponding to an I/O page table - * type supported by the underlying IOMMU hardware. + * A user-managed nested HWPT will be created from a given vIOMMU (wrapping a + * parent HWPT) or a parent HWPT via @pt_id, in which the parent HWPT must be + * allocated previously via the same ioctl from a given IOAS (@pt_id). In this + * case, the @data_type must be set to a pre-defined type corresponding to an + * I/O page table type supported by the underlying IOMMU hardware. The device + * via @dev_id and the vIOMMU via @pt_id must be associated to the same IOMMU + * instance. * * If the @data_type is set to IOMMU_HWPT_DATA_NONE, @data_len and * @data_uptr should be zero. Otherwise, both @data_len and @data_uptr @@ -485,14 +545,49 @@ struct iommu_hw_info_vtd { }; /** + * struct iommu_hw_info_arm_smmuv3 - ARM SMMUv3 hardware information + * (IOMMU_HW_INFO_TYPE_ARM_SMMUV3) + * + * @flags: Must be set to 0 + * @__reserved: Must be 0 + * @idr: Implemented features for ARM SMMU Non-secure programming interface + * @iidr: Information about the implementation and implementer of ARM SMMU, + * and architecture version supported + * @aidr: ARM SMMU architecture version + * + * For the details of @idr, @iidr and @aidr, please refer to the chapters + * from 6.3.1 to 6.3.6 in the SMMUv3 Spec. + * + * User space should read the underlying ARM SMMUv3 hardware information for + * the list of supported features. + * + * Note that these values reflect the raw HW capability, without any insight if + * any required kernel driver support is present. Bits may be set indicating the + * HW has functionality that is lacking kernel software support, such as BTM. If + * a VMM is using this information to construct emulated copies of these + * registers it should only forward bits that it knows it can support. + * + * In future, presence of required kernel support will be indicated in flags. + */ +struct iommu_hw_info_arm_smmuv3 { + __u32 flags; + __u32 __reserved; + __u32 idr[6]; + __u32 iidr; + __u32 aidr; +}; + +/** * enum iommu_hw_info_type - IOMMU Hardware Info Types * @IOMMU_HW_INFO_TYPE_NONE: Used by the drivers that do not report hardware * info * @IOMMU_HW_INFO_TYPE_INTEL_VTD: Intel VT-d iommu info type + * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type */ enum iommu_hw_info_type { IOMMU_HW_INFO_TYPE_NONE = 0, IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, + IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, }; /** @@ -627,9 +722,11 @@ struct iommu_hwpt_get_dirty_bitmap { * enum iommu_hwpt_invalidate_data_type - IOMMU HWPT Cache Invalidation * Data Type * @IOMMU_HWPT_INVALIDATE_DATA_VTD_S1: Invalidation data for VTD_S1 + * @IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3: Invalidation data for ARM SMMUv3 */ enum iommu_hwpt_invalidate_data_type { IOMMU_HWPT_INVALIDATE_DATA_VTD_S1 = 0, + IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3 = 1, }; /** @@ -669,9 +766,31 @@ struct iommu_hwpt_vtd_s1_invalidate { }; /** + * struct iommu_viommu_arm_smmuv3_invalidate - ARM SMMUv3 cahce invalidation + * (IOMMU_VIOMMU_INVALIDATE_DATA_ARM_SMMUV3) + * @cmd: 128-bit cache invalidation command that runs in SMMU CMDQ. + * Must be little-endian. + * + * Supported command list only when passing in a vIOMMU via @hwpt_id: + * CMDQ_OP_TLBI_NSNH_ALL + * CMDQ_OP_TLBI_NH_VA + * CMDQ_OP_TLBI_NH_VAA + * CMDQ_OP_TLBI_NH_ALL + * CMDQ_OP_TLBI_NH_ASID + * CMDQ_OP_ATC_INV + * CMDQ_OP_CFGI_CD + * CMDQ_OP_CFGI_CD_ALL + * + * -EIO will be returned if the command is not supported. + */ +struct iommu_viommu_arm_smmuv3_invalidate { + __aligned_le64 cmd[2]; +}; + +/** * struct iommu_hwpt_invalidate - ioctl(IOMMU_HWPT_INVALIDATE) * @size: sizeof(struct iommu_hwpt_invalidate) - * @hwpt_id: ID of a nested HWPT for cache invalidation + * @hwpt_id: ID of a nested HWPT or a vIOMMU, for cache invalidation * @data_uptr: User pointer to an array of driver-specific cache invalidation * data. * @data_type: One of enum iommu_hwpt_invalidate_data_type, defining the data @@ -682,8 +801,11 @@ struct iommu_hwpt_vtd_s1_invalidate { * Output the number of requests successfully handled by kernel. * @__reserved: Must be 0. * - * Invalidate the iommu cache for user-managed page table. Modifications on a - * user-managed page table should be followed by this operation to sync cache. + * Invalidate iommu cache for user-managed page table or vIOMMU. Modifications + * on a user-managed page table should be followed by this operation, if a HWPT + * is passed in via @hwpt_id. Other caches, such as device cache or descriptor + * cache can be flushed if a vIOMMU is passed in via the @hwpt_id field. + * * Each ioctl can support one or more cache invalidation requests in the array * that has a total size of @entry_len * @entry_num. * @@ -797,4 +919,88 @@ struct iommu_fault_alloc { __u32 out_fault_fd; }; #define IOMMU_FAULT_QUEUE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_FAULT_QUEUE_ALLOC) + +/** + * enum iommu_viommu_type - Virtual IOMMU Type + * @IOMMU_VIOMMU_TYPE_DEFAULT: Reserved for future use + * @IOMMU_VIOMMU_TYPE_ARM_SMMUV3: ARM SMMUv3 driver specific type + */ +enum iommu_viommu_type { + IOMMU_VIOMMU_TYPE_DEFAULT = 0, + IOMMU_VIOMMU_TYPE_ARM_SMMUV3 = 1, +}; + +/** + * struct iommu_viommu_alloc - ioctl(IOMMU_VIOMMU_ALLOC) + * @size: sizeof(struct iommu_viommu_alloc) + * @flags: Must be 0 + * @type: Type of the virtual IOMMU. Must be defined in enum iommu_viommu_type + * @dev_id: The device's physical IOMMU will be used to back the virtual IOMMU + * @hwpt_id: ID of a nesting parent HWPT to associate to + * @out_viommu_id: Output virtual IOMMU ID for the allocated object + * + * Allocate a virtual IOMMU object, representing the underlying physical IOMMU's + * virtualization support that is a security-isolated slice of the real IOMMU HW + * that is unique to a specific VM. Operations global to the IOMMU are connected + * to the vIOMMU, such as: + * - Security namespace for guest owned ID, e.g. guest-controlled cache tags + * - Non-device-affiliated event reporting, e.g. invalidation queue errors + * - Access to a sharable nesting parent pagetable across physical IOMMUs + * - Virtualization of various platforms IDs, e.g. RIDs and others + * - Delivery of paravirtualized invalidation + * - Direct assigned invalidation queues + * - Direct assigned interrupts + */ +struct iommu_viommu_alloc { + __u32 size; + __u32 flags; + __u32 type; + __u32 dev_id; + __u32 hwpt_id; + __u32 out_viommu_id; +}; +#define IOMMU_VIOMMU_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VIOMMU_ALLOC) + +/** + * struct iommu_vdevice_alloc - ioctl(IOMMU_VDEVICE_ALLOC) + * @size: sizeof(struct iommu_vdevice_alloc) + * @viommu_id: vIOMMU ID to associate with the virtual device + * @dev_id: The physical device to allocate a virtual instance on the vIOMMU + * @out_vdevice_id: Object handle for the vDevice. Pass to IOMMU_DESTORY + * @virt_id: Virtual device ID per vIOMMU, e.g. vSID of ARM SMMUv3, vDeviceID + * of AMD IOMMU, and vRID of a nested Intel VT-d to a Context Table + * + * Allocate a virtual device instance (for a physical device) against a vIOMMU. + * This instance holds the device's information (related to its vIOMMU) in a VM. + */ +struct iommu_vdevice_alloc { + __u32 size; + __u32 viommu_id; + __u32 dev_id; + __u32 out_vdevice_id; + __aligned_u64 virt_id; +}; +#define IOMMU_VDEVICE_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VDEVICE_ALLOC) + +/** + * struct iommu_ioas_change_process - ioctl(VFIO_IOAS_CHANGE_PROCESS) + * @size: sizeof(struct iommu_ioas_change_process) + * @__reserved: Must be 0 + * + * This transfers pinned memory counts for every memory map in every IOAS + * in the context to the current process. This only supports maps created + * with IOMMU_IOAS_MAP_FILE, and returns EINVAL if other maps are present. + * If the ioctl returns a failure status, then nothing is changed. + * + * This API is useful for transferring operation of a device from one process + * to another, such as during userland live update. + */ +struct iommu_ioas_change_process { + __u32 size; + __u32 __reserved; +}; + +#define IOMMU_IOAS_CHANGE_PROCESS \ + _IO(IOMMUFD_TYPE, IOMMUFD_CMD_IOAS_CHANGE_PROCESS) + #endif diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 49dd1b30ce..3bcd4eabe3 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -1150,7 +1150,15 @@ enum kvm_device_type { #define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_RISCV_AIA, #define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA + KVM_DEV_TYPE_LOONGARCH_IPI, +#define KVM_DEV_TYPE_LOONGARCH_IPI KVM_DEV_TYPE_LOONGARCH_IPI + KVM_DEV_TYPE_LOONGARCH_EIOINTC, +#define KVM_DEV_TYPE_LOONGARCH_EIOINTC KVM_DEV_TYPE_LOONGARCH_EIOINTC + KVM_DEV_TYPE_LOONGARCH_PCHPIC, +#define KVM_DEV_TYPE_LOONGARCH_PCHPIC KVM_DEV_TYPE_LOONGARCH_PCHPIC + KVM_DEV_TYPE_MAX, + }; struct kvm_vfio_spapr_tce { diff --git a/linux-headers/linux/psci.h b/linux-headers/linux/psci.h index 74f3cb5007..a982afd498 100644 --- a/linux-headers/linux/psci.h +++ b/linux-headers/linux/psci.h @@ -59,6 +59,7 @@ #define PSCI_1_1_FN_SYSTEM_RESET2 PSCI_0_2_FN(18) #define PSCI_1_1_FN_MEM_PROTECT PSCI_0_2_FN(19) #define PSCI_1_1_FN_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN(20) +#define PSCI_1_3_FN_SYSTEM_OFF2 PSCI_0_2_FN(21) #define PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND PSCI_0_2_FN64(12) #define PSCI_1_0_FN64_NODE_HW_STATE PSCI_0_2_FN64(13) @@ -68,6 +69,7 @@ #define PSCI_1_1_FN64_SYSTEM_RESET2 PSCI_0_2_FN64(18) #define PSCI_1_1_FN64_MEM_PROTECT_CHECK_RANGE PSCI_0_2_FN64(20) +#define PSCI_1_3_FN64_SYSTEM_OFF2 PSCI_0_2_FN64(21) /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff @@ -100,6 +102,9 @@ #define PSCI_1_1_RESET_TYPE_SYSTEM_WARM_RESET 0 #define PSCI_1_1_RESET_TYPE_VENDOR_START 0x80000000U +/* PSCI v1.3 hibernate type for SYSTEM_OFF2 */ +#define PSCI_1_3_OFF_TYPE_HIBERNATE_OFF BIT(0) + /* PSCI version decoding (independent of PSCI version) */ #define PSCI_VERSION_MAJOR_SHIFT 16 #define PSCI_VERSION_MINOR_MASK \ diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h index b4be37b225..1b5e254d6a 100644 --- a/linux-headers/linux/vfio.h +++ b/linux-headers/linux/vfio.h @@ -35,7 +35,7 @@ #define VFIO_EEH 5 /* Two-stage IOMMU */ -#define VFIO_TYPE1_NESTING_IOMMU 6 /* Implies v2 */ +#define __VFIO_RESERVED_TYPE1_NESTING_IOMMU 6 /* Implies v2 */ #define VFIO_SPAPR_TCE_v2_IOMMU 7 diff --git a/target/s390x/cpu_features.c b/target/s390x/cpu_features.c index cb4e2b8920..4b5be6798e 100644 --- a/target/s390x/cpu_features.c +++ b/target/s390x/cpu_features.c @@ -93,6 +93,7 @@ void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type, case S390_FEAT_TYPE_KDSA: case S390_FEAT_TYPE_SORTL: case S390_FEAT_TYPE_DFLTCC: + case S390_FEAT_TYPE_PFCR: set_be_bit(0, data); /* query is always available */ break; default: @@ -239,8 +240,10 @@ void s390_get_deprecated_features(S390FeatBitmap features) /* indexed by feature group number for easy lookup */ static S390FeatGroupDef s390_feature_groups[] = { FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"), + FEAT_GROUP_INIT("plo_ext", PLO_EXT, "PLO-extension facility"), FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"), FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"), + FEAT_GROUP_INIT("gen17ptff", GEN17_PTFF, "PTFF enhancements introduced with gen17"), FEAT_GROUP_INIT("msa", MSA, "Message-security-assist facility"), FEAT_GROUP_INIT("msa1", MSA_EXT_1, "Message-security-assist-extension 1 facility"), FEAT_GROUP_INIT("msa2", MSA_EXT_2, "Message-security-assist-extension 2 facility"), @@ -252,9 +255,17 @@ static S390FeatGroupDef s390_feature_groups[] = { FEAT_GROUP_INIT("msa8", MSA_EXT_8, "Message-security-assist-extension 8 facility"), FEAT_GROUP_INIT("msa9", MSA_EXT_9, "Message-security-assist-extension 9 facility"), FEAT_GROUP_INIT("msa9_pckmo", MSA_EXT_9_PCKMO, "Message-security-assist-extension 9 PCKMO subfunctions"), + FEAT_GROUP_INIT("msa10", MSA_EXT_10, "Message-security-assist-extension 10 facility"), + FEAT_GROUP_INIT("msa10_pckmo", MSA_EXT_10_PCKMO, "Message-security-assist-extension 10 PCKMO subfunctions"), + FEAT_GROUP_INIT("msa11", MSA_EXT_11, "Message-security-assist-extension 11 facility"), + FEAT_GROUP_INIT("msa11_pckmo", MSA_EXT_11_PCKMO, "Message-security-assist-extension 11 PCKMO subfunctions"), + FEAT_GROUP_INIT("msa12", MSA_EXT_12, "Message-security-assist-extension 12 facility"), + FEAT_GROUP_INIT("msa13", MSA_EXT_13, "Message-security-assist-extension 13 facility"), + FEAT_GROUP_INIT("msa13_pckmo", MSA_EXT_13_PCKMO, "Message-security-assist-extension 13 PCKMO subfunctions"), FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"), FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"), FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"), + FEAT_GROUP_INIT("ccf", CONCURRENT_FUNCTIONS, "Concurrent-functions facility"), }; const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group) diff --git a/target/s390x/cpu_features.h b/target/s390x/cpu_features.h index 661a8cd6db..5635839d03 100644 --- a/target/s390x/cpu_features.h +++ b/target/s390x/cpu_features.h @@ -44,6 +44,7 @@ typedef enum { S390_FEAT_TYPE_SORTL, S390_FEAT_TYPE_DFLTCC, S390_FEAT_TYPE_UV_FEAT_GUEST, + S390_FEAT_TYPE_PFCR, } S390FeatType; /* Definition of a CPU feature */ diff --git a/target/s390x/cpu_features_def.h.inc b/target/s390x/cpu_features_def.h.inc index c53ac13352..e23e603a79 100644 --- a/target/s390x/cpu_features_def.h.inc +++ b/target/s390x/cpu_features_def.h.inc @@ -90,6 +90,10 @@ DEF_FEAT(EDAT_2, "edat2", STFL, 78, "Enhanced-DAT facility 2") DEF_FEAT(DFP_PACKED_CONVERSION, "dfppc", STFL, 80, "Decimal-floating-point packed-conversion facility") DEF_FEAT(PPA15, "ppa15", STFL, 81, "PPA15 is installed") DEF_FEAT(BPB, "bpb", STFL, 82, "Branch prediction blocking") +DEF_FEAT(MISC_INSTRUCTION_EXT4, "minste4", STFL, 84, "Miscellaneous-Instruction-Extensions Facility 4") +DEF_FEAT(SIF, "sif", STFL, 85, "Sequential-instruction-fetching facility") +DEF_FEAT(MSA_EXT_12, "msa12-base", STFL, 86, "Message-security-assist-extension-12 facility (excluding subfunctions)") +DEF_FEAT(PLO_EXT, "plo-ext", STFL, 87, "PLO-extension facility") DEF_FEAT(VECTOR, "vx", STFL, 129, "Vector facility") DEF_FEAT(INSTRUCTION_EXEC_PROT, "iep", STFL, 130, "Instruction-execution-protection facility") DEF_FEAT(SIDE_EFFECT_ACCESS_ESOP2, "sea_esop2", STFL, 131, "Side-effect-access facility and Enhanced-suppression-on-protection facility 2") @@ -110,11 +114,15 @@ DEF_FEAT(MSA_EXT_9, "msa9-base", STFL, 155, "Message-security-assist-extension-9 DEF_FEAT(ETOKEN, "etoken", STFL, 156, "Etoken facility") DEF_FEAT(UNPACK, "unpack", STFL, 161, "Unpack facility") DEF_FEAT(NNPA, "nnpa", STFL, 165, "NNPA facility") +DEF_FEAT(INEFF_NC_TX, "ineff_nc_tx", STFL, 170, "Ineffective-nonconstrained-transaction facility") DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH2, "vxpdeh2", STFL, 192, "Vector-Packed-Decimal-Enhancement facility 2") DEF_FEAT(BEAR_ENH, "beareh", STFL, 193, "BEAR-enhancement facility") DEF_FEAT(RDP, "rdp", STFL, 194, "Reset-DAT-protection facility") DEF_FEAT(PAI, "pai", STFL, 196, "Processor-Activity-Instrumentation facility") DEF_FEAT(PAIE, "paie", STFL, 197, "Processor-Activity-Instrumentation extension-1") +DEF_FEAT(VECTOR_ENH3, "vxeh3", STFL, 198, "Vector Enhancements facility 3") +DEF_FEAT(VECTOR_PACKED_DECIMAL_ENH3, "vxpdeh3", STFL, 199, "Vector-Packed-Decimal-Enhancement facility 3") +DEF_FEAT(CCF_BASE, "ccf-base", STFL, 201, "Concurrent-Functions facility") /* Features exposed via SCLP SCCB Byte 80 - 98 (bit numbers relative to byte-80) */ DEF_FEAT(SIE_GSLS, "gsls", SCLP_CONF_CHAR, 40, "SIE: Guest-storage-limit-suppression facility") @@ -151,28 +159,66 @@ DEF_FEAT(AP, "ap", MISC, 0, "AP instructions installed") /* Features exposed via the PLO instruction. */ DEF_FEAT(PLO_CL, "plo-cl", PLO, 0, "PLO Compare and load (32 bit in general registers)") DEF_FEAT(PLO_CLG, "plo-clg", PLO, 1, "PLO Compare and load (64 bit in parameter list)") -DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (32 bit in general registers)") +DEF_FEAT(PLO_CLGR, "plo-clgr", PLO, 2, "PLO Compare and load (64 bit in general registers)") DEF_FEAT(PLO_CLX, "plo-clx", PLO, 3, "PLO Compare and load (128 bit in parameter list)") DEF_FEAT(PLO_CS, "plo-cs", PLO, 4, "PLO Compare and swap (32 bit in general registers)") DEF_FEAT(PLO_CSG, "plo-csg", PLO, 5, "PLO Compare and swap (64 bit in parameter list)") -DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (32 bit in general registers)") +DEF_FEAT(PLO_CSGR, "plo-csgr", PLO, 6, "PLO Compare and swap (64 bit in general registers)") DEF_FEAT(PLO_CSX, "plo-csx", PLO, 7, "PLO Compare and swap (128 bit in parameter list)") DEF_FEAT(PLO_DCS, "plo-dcs", PLO, 8, "PLO Double compare and swap (32 bit in general registers)") DEF_FEAT(PLO_DCSG, "plo-dcsg", PLO, 9, "PLO Double compare and swap (64 bit in parameter list)") -DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (32 bit in general registers)") +DEF_FEAT(PLO_DCSGR, "plo-dcsgr", PLO, 10, "PLO Double compare and swap (64 bit in general registers)") DEF_FEAT(PLO_DCSX, "plo-dcsx", PLO, 11, "PLO Double compare and swap (128 bit in parameter list)") DEF_FEAT(PLO_CSST, "plo-csst", PLO, 12, "PLO Compare and swap and store (32 bit in general registers)") DEF_FEAT(PLO_CSSTG, "plo-csstg", PLO, 13, "PLO Compare and swap and store (64 bit in parameter list)") -DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (32 bit in general registers)") +DEF_FEAT(PLO_CSSTGR, "plo-csstgr", PLO, 14, "PLO Compare and swap and store (64 bit in general registers)") DEF_FEAT(PLO_CSSTX, "plo-csstx", PLO, 15, "PLO Compare and swap and store (128 bit in parameter list)") DEF_FEAT(PLO_CSDST, "plo-csdst", PLO, 16, "PLO Compare and swap and double store (32 bit in general registers)") DEF_FEAT(PLO_CSDSTG, "plo-csdstg", PLO, 17, "PLO Compare and swap and double store (64 bit in parameter list)") -DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (32 bit in general registers)") +DEF_FEAT(PLO_CSDSTGR, "plo-csdstgr", PLO, 18, "PLO Compare and swap and double store (64 bit in general registers)") DEF_FEAT(PLO_CSDSTX, "plo-csdstx", PLO, 19, "PLO Compare and swap and double store (128 bit in parameter list)") DEF_FEAT(PLO_CSTST, "plo-cstst", PLO, 20, "PLO Compare and swap and triple store (32 bit in general registers)") DEF_FEAT(PLO_CSTSTG, "plo-cststg", PLO, 21, "PLO Compare and swap and triple store (64 bit in parameter list)") -DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (32 bit in general registers)") +DEF_FEAT(PLO_CSTSTGR, "plo-cststgr", PLO, 22, "PLO Compare and swap and triple store (64 bit in general registers)") DEF_FEAT(PLO_CSTSTX, "plo-cststx", PLO, 23, "PLO Compare and swap and triple store (128 bit in parameter list)") +DEF_FEAT(PLO_CLO, "plo-clo", PLO, 24, "PLO Compare and load (256 bit in parameter list)") +DEF_FEAT(PLO_CSO, "plo-cso", PLO, 25, "PLO Compare and swap (256 bit in parameter list)") +DEF_FEAT(PLO_DCSO, "plo-dcso", PLO, 26, "PLO Double compare and swap (256 bit in parameter list)") +DEF_FEAT(PLO_CSSTO, "plo-cssto", PLO, 27, "PLO Compare and swap and store (256 bit in parameter list)") +DEF_FEAT(PLO_CSDSTO, "plo-csdsto", PLO, 28, "PLO Compare and swap and double store (256 bit in parameter list)") +DEF_FEAT(PLO_CSTSTO, "plo-cststo", PLO, 29, "PLO Compare and swap and trible store (256 bit in parameter list)") +DEF_FEAT(PLO_TCS, "plo-tcs", PLO, 30, "Triple compare and swap (32 bit in parameter list)") +DEF_FEAT(PLO_TCSG, "plo-tcsg", PLO, 31, "Triple compare and swap (64 bit in parameter list)") +DEF_FEAT(PLO_TCSX, "plo-tcsx", PLO, 32, "Triple compare and swap (128 bit in parameter list)") +DEF_FEAT(PLO_TCSO, "plo-tcso", PLO, 33, "Triple compare and swap (256 bit in parameter list)") +DEF_FEAT(PLO_QCS, "plo-qcs", PLO, 34, "Quadruple compare and swap (32 bit in parameter list)") +DEF_FEAT(PLO_QCSG, "plo-qcsg", PLO, 35, "Quadruple compare and swap (64 bit in parameter list)") +DEF_FEAT(PLO_QCSX, "plo-qcsx", PLO, 36, "Quadruple compare and swap (128 bit in parameter list)") +DEF_FEAT(PLO_QCSO, "plo-qcso", PLO, 37, "Quadruple compare and swap (256 bit in parameter list)") +DEF_FEAT(PLO_LO, "plo-lo", PLO, 38, "Load (256 bit in parameter list)") +DEF_FEAT(PLO_DLX, "plo-dlx", PLO, 39, "Double load (128 bit in parameter list)") +DEF_FEAT(PLO_DLO, "plo-dlo", PLO, 40, "Double load (256 bit in parameter list)") +DEF_FEAT(PLO_TL, "plo-tl", PLO, 41, "Triple load (32 bit in parameter list)") +DEF_FEAT(PLO_TLG, "plo-tlg", PLO, 42, "Triple load (64 bit in parameter list)") +DEF_FEAT(PLO_TLX, "plo-tlx", PLO, 43, "Triple load (128 bit in parameter list)") +DEF_FEAT(PLO_TLO, "plo-tlo", PLO, 44, "Triple load (256 bit in parameter list)") +DEF_FEAT(PLO_QL, "plo-ql", PLO, 45, "Quadruple load (32 bit in parameter list)") +DEF_FEAT(PLO_QLG, "plo-qlg", PLO, 46, "Quadruple load (64 bit in parameter list)") +DEF_FEAT(PLO_QLX, "plo-qlx", PLO, 47, "Quadruple load (128 bit in parameter list)") +DEF_FEAT(PLO_QLO, "plo-qlo", PLO, 48, "Quadruple load (256 bit in parameter list)") +DEF_FEAT(PLO_STO, "plo-sto", PLO, 49, "Store (256 bit in parameter list)") +DEF_FEAT(PLO_DST, "plo-dst", PLO, 50, "Double store (32 bit in parameter list)") +DEF_FEAT(PLO_DSTG, "plo-dstg", PLO, 51, "Double store (64 bit in parameter list)") +DEF_FEAT(PLO_DSTX, "plo-dstx", PLO, 52, "Double store (128 bit in parameter list)") +DEF_FEAT(PLO_DSTO, "plo-dsto", PLO, 53, "Double store (256 bit in parameter list)") +DEF_FEAT(PLO_TST, "plo-tst", PLO, 54, "Triple store (32 bit in parameter list)") +DEF_FEAT(PLO_TSTG, "plo-tstg", PLO, 55, "Triple store (64 bit in parameter list)") +DEF_FEAT(PLO_TSTX, "plo-tstx", PLO, 56, "Triple store (128 bit in parameter list)") +DEF_FEAT(PLO_TSTO, "plo-tsto", PLO, 57, "Triple store (256 bit in parameter list)") +DEF_FEAT(PLO_QST, "plo-qst", PLO, 58, "Quadruple store (32 bit in parameter list)") +DEF_FEAT(PLO_QSTG, "plo-qstg", PLO, 59, "Quadruple store (64 bit in parameter list)") +DEF_FEAT(PLO_QSTX, "plo-qstx", PLO, 60, "Quadruple store (128 bit in parameter list)") +DEF_FEAT(PLO_QSTO, "plo-qsto", PLO, 61, "Quadruple store (256 bit in parameter list)") /* Features exposed via the PTFF instruction. */ DEF_FEAT(PTFF_QTO, "ptff-qto", PTFF, 1, "PTFF Query TOD Offset") @@ -180,6 +226,7 @@ DEF_FEAT(PTFF_QSI, "ptff-qsi", PTFF, 2, "PTFF Query Steering Information") DEF_FEAT(PTFF_QPT, "ptff-qpc", PTFF, 3, "PTFF Query Physical Clock") DEF_FEAT(PTFF_QUI, "ptff-qui", PTFF, 4, "PTFF Query UTC Information") DEF_FEAT(PTFF_QTOU, "ptff-qtou", PTFF, 5, "PTFF Query TOD Offset User") +DEF_FEAT(PTFF_QTSE, "ptff-qtse", PTFF, 6, "PTFF Query Time-Stamp Event") DEF_FEAT(PTFF_QSIE, "ptff-qsie", PTFF, 10, "PTFF Query Steering Information Extended") DEF_FEAT(PTFF_QTOUE, "ptff-qtoue", PTFF, 13, "PTFF Query TOD Offset User Extended") DEF_FEAT(PTFF_STO, "ptff-sto", PTFF, 65, "PTFF Set TOD Offset") @@ -200,6 +247,15 @@ DEF_FEAT(KMAC_AES_256, "kmac-aes-256", KMAC, 20, "KMAC AES-256") DEF_FEAT(KMAC_EAES_128, "kmac-eaes-128", KMAC, 26, "KMAC Encrypted-AES-128") DEF_FEAT(KMAC_EAES_192, "kmac-eaes-192", KMAC, 27, "KMAC Encrypted-AES-192") DEF_FEAT(KMAC_EAES_256, "kmac-eaes-256", KMAC, 28, "KMAC Encrypted-AES-256") +DEF_FEAT(KMAC_HMAC_SHA_224, "kmac-hmac-sha-224", KMAC, 112, "KMAC HMAC-SHA-224") +DEF_FEAT(KMAC_HMAC_SHA_256, "kmac-hmac-sha-246", KMAC, 113, "KMAC HMAC-SHA-256") +DEF_FEAT(KMAC_HMAC_SHA_384, "kmac-hmac-sha-384", KMAC, 114, "KMAC HMAC-SHA-384") +DEF_FEAT(KMAC_HMAC_SHA_512, "kmac-hmac-sha-512", KMAC, 115, "KMAC HMAC-SHA-512") +DEF_FEAT(KMAC_HMAC_ESHA_224, "kmac-hmac-esha-224", KMAC, 120, "KMAC HMAC-Encrypted-SHA-224") +DEF_FEAT(KMAC_HMAC_ESHA_256, "kmac-hmac-esha-246", KMAC, 121, "KMAC HMAC-Encrypted-SHA-256") +DEF_FEAT(KMAC_HMAC_ESHA_384, "kmac-hmac-esha-384", KMAC, 122, "KMAC HMAC-Encrypted-SHA-384") +DEF_FEAT(KMAC_HMAC_ESHA_512, "kmac-hmac-esha-512", KMAC, 123, "KMAC HMAC-Encrypted-SHA-512") +DEF_FEAT(KMAC_QAI, "kmac-qai", KMAC, 127, "KMAC Query-Authentication-Information") /* Features exposed via the KMC instruction. */ DEF_FEAT(KMC_DEA, "kmc-dea", KMC, 1, "KMC DEA") @@ -233,6 +289,11 @@ DEF_FEAT(KM_XTS_AES_128, "km-xts-aes-128", KM, 50, "KM XTS-AES-128") DEF_FEAT(KM_XTS_AES_256, "km-xts-aes-256", KM, 52, "KM XTS-AES-256") DEF_FEAT(KM_XTS_EAES_128, "km-xts-eaes-128", KM, 58, "KM XTS-Encrypted-AES-128") DEF_FEAT(KM_XTS_EAES_256, "km-xts-eaes-256", KM, 60, "KM XTS-Encrypted-AES-256") +DEF_FEAT(KM_FULL_XTS_AES_128, "km-full-xts-aes-128", KM, 82, "KM Full-XTS-AES-128") +DEF_FEAT(KM_FULL_XTS_AES_256, "km-full-xts-aes-256", KM, 84, "KM Full-XTS-AES-256") +DEF_FEAT(KM_FULL_XTS_EAES_128, "km-full-xts-eaes-128", KM, 90, "KM Full-XTS-Encrypted-AES-128") +DEF_FEAT(KM_FULL_XTS_EAES_256, "km-full-xts-eaes-256", KM, 92, "KM Full-XTS-Encrypted-AES-256") +DEF_FEAT(KM_QAI, "km-qai", KM, 127, "KM Query-Authentication-Information") /* Features exposed via the KIMD instruction. */ DEF_FEAT(KIMD_SHA_1, "kimd-sha-1", KIMD, 1, "KIMD SHA-1") @@ -245,6 +306,7 @@ DEF_FEAT(KIMD_SHA3_512, "kimd-sha3-512", KIMD, 35, "KIMD SHA3-512") DEF_FEAT(KIMD_SHAKE_128, "kimd-shake-128", KIMD, 36, "KIMD SHAKE-128") DEF_FEAT(KIMD_SHAKE_256, "kimd-shake-256", KIMD, 37, "KIMD SHAKE-256") DEF_FEAT(KIMD_GHASH, "kimd-ghash", KIMD, 65, "KIMD GHASH") +DEF_FEAT(KIMD_QAI, "kimd-qai", KIMD, 127, "KIMD Query-Authentication-Information") /* Features exposed via the KLMD instruction. */ DEF_FEAT(KLMD_SHA_1, "klmd-sha-1", KLMD, 1, "KLMD SHA-1") @@ -256,6 +318,7 @@ DEF_FEAT(KLMD_SHA3_384, "klmd-sha3-384", KLMD, 34, "KLMD SHA3-384") DEF_FEAT(KLMD_SHA3_512, "klmd-sha3-512", KLMD, 35, "KLMD SHA3-512") DEF_FEAT(KLMD_SHAKE_128, "klmd-shake-128", KLMD, 36, "KLMD SHAKE-128") DEF_FEAT(KLMD_SHAKE_256, "klmd-shake-256", KLMD, 37, "KLMD SHAKE-256") +DEF_FEAT(KLMD_QAI, "klmd-qai", KLMD, 127, "KLMD Query-Authentication-Information") /* Features exposed via the PCKMO instruction. */ DEF_FEAT(PCKMO_EDEA, "pckmo-edea", PCKMO, 1, "PCKMO Encrypted-DEA-Key") @@ -264,11 +327,16 @@ DEF_FEAT(PCKMO_ETDEA_256, "pckmo-etdea-192", PCKMO, 3, "PCKMO Encrypted-TDEA-192 DEF_FEAT(PCKMO_AES_128, "pckmo-aes-128", PCKMO, 18, "PCKMO Encrypted-AES-128-Key") DEF_FEAT(PCKMO_AES_192, "pckmo-aes-192", PCKMO, 19, "PCKMO Encrypted-AES-192-Key") DEF_FEAT(PCKMO_AES_256, "pckmo-aes-256", PCKMO, 20, "PCKMO Encrypted-AES-256-Key") +DEF_FEAT(PCKMO_AES_XTS_128_DK, "pckmo-aes-xts-128-dk", PCKMO, 21, "PCKMO Encrypt-AES-XTS-128-Double-Key") +DEF_FEAT(PCKMO_AES_XTS_256_DK, "pckmo-aes-xts-256-dk", PCKMO, 22, "PCKMO Encrypt-AES-XTS-256-Double-Key") DEF_FEAT(PCKMO_ECC_P256, "pckmo-ecc-p256", PCKMO, 32, "PCKMO Encrypt-ECC-P256-Key") DEF_FEAT(PCKMO_ECC_P384, "pckmo-ecc-p384", PCKMO, 33, "PCKMO Encrypt-ECC-P384-Key") DEF_FEAT(PCKMO_ECC_P521, "pckmo-ecc-p521", PCKMO, 34, "PCKMO Encrypt-ECC-P521-Key") DEF_FEAT(PCKMO_ECC_ED25519, "pckmo-ecc-ed25519", PCKMO, 40 , "PCKMO Encrypt-ECC-Ed25519-Key") DEF_FEAT(PCKMO_ECC_ED448, "pckmo-ecc-ed448", PCKMO, 41 , "PCKMO Encrypt-ECC-Ed448-Key") +DEF_FEAT(PCKMO_HMAC_512, "pckmo-hmac-512", PCKMO, 118, "PCKMO Encrypt-HMAC-512-Key") +DEF_FEAT(PCKMO_HMAC_1024, "pckmo-hmac-1024", PCKMO, 122, "PCKMO Encrypt-HMAC-1024-Key") +DEF_FEAT(PCKMO_QAI, "pckmo-qai", PCKMO, 127, "PCKMO Query-Authentication-Information") /* Features exposed via the KMCTR instruction. */ DEF_FEAT(KMCTR_DEA, "kmctr-dea", KMCTR, 1, "KMCTR DEA") @@ -283,6 +351,7 @@ DEF_FEAT(KMCTR_AES_256, "kmctr-aes-256", KMCTR, 20, "KMCTR AES-256") DEF_FEAT(KMCTR_EAES_128, "kmctr-eaes-128", KMCTR, 26, "KMCTR Encrypted-AES-128") DEF_FEAT(KMCTR_EAES_192, "kmctr-eaes-192", KMCTR, 27, "KMCTR Encrypted-AES-192") DEF_FEAT(KMCTR_EAES_256, "kmctr-eaes-256", KMCTR, 28, "KMCTR Encrypted-AES-256") +DEF_FEAT(KMCTR_QAI, "kmctr-qai", KMCTR, 127, "KMCTR Query-Authentication-Information") /* Features exposed via the KMF instruction. */ DEF_FEAT(KMF_DEA, "kmf-dea", KMF, 1, "KMF DEA") @@ -297,6 +366,7 @@ DEF_FEAT(KMF_AES_256, "kmf-aes-256", KMF, 20, "KMF AES-256") DEF_FEAT(KMF_EAES_128, "kmf-eaes-128", KMF, 26, "KMF Encrypted-AES-128") DEF_FEAT(KMF_EAES_192, "kmf-eaes-192", KMF, 27, "KMF Encrypted-AES-192") DEF_FEAT(KMF_EAES_256, "kmf-eaes-256", KMF, 28, "KMF Encrypted-AES-256") +DEF_FEAT(KMF_QAI, "kmf-qai", KMF, 127, "KMF Query-Authentication-Information") /* Features exposed via the KMO instruction. */ DEF_FEAT(KMO_DEA, "kmo-dea", KMO, 1, "KMO DEA") @@ -311,6 +381,7 @@ DEF_FEAT(KMO_AES_256, "kmo-aes-256", KMO, 20, "KMO AES-256") DEF_FEAT(KMO_EAES_128, "kmo-eaes-128", KMO, 26, "KMO Encrypted-AES-128") DEF_FEAT(KMO_EAES_192, "kmo-eaes-192", KMO, 27, "KMO Encrypted-AES-192") DEF_FEAT(KMO_EAES_256, "kmo-eaes-256", KMO, 28, "KMO Encrypted-AES-256") +DEF_FEAT(KMO_QAI, "kmo-qai", KMO, 127, "KMO Query-Authentication-Information") /* Features exposed via the PCC instruction. */ DEF_FEAT(PCC_CMAC_DEA, "pcc-cmac-dea", PCC, 1, "PCC Compute-Last-Block-CMAC-Using-DEA") @@ -336,11 +407,13 @@ DEF_FEAT(PCC_SCALAR_MULT_ED25519, "pcc-scalar-mult-ed25519", PCC, 72, "PCC Scala DEF_FEAT(PCC_SCALAR_MULT_ED448, "pcc-scalar-mult-ed448", PCC, 73, "PCC Scalar-Multiply-Ed448") DEF_FEAT(PCC_SCALAR_MULT_X25519, "pcc-scalar-mult-x25519", PCC, 80, "PCC Scalar-Multiply-X25519") DEF_FEAT(PCC_SCALAR_MULT_X448, "pcc-scalar-mult-x448", PCC, 81, "PCC Scalar-Multiply-X448") +DEF_FEAT(PCC_QAI, "pcc-qai", PCC, 127, "PCC Query-Authentication-Information") /* Features exposed via the PPNO/PRNO instruction. */ DEF_FEAT(PPNO_SHA_512_DRNG, "ppno-sha-512-drng", PPNO, 3, "PPNO SHA-512-DRNG") DEF_FEAT(PRNO_TRNG_QRTCR, "prno-trng-qrtcr", PPNO, 112, "PRNO TRNG-Query-Raw-to-Conditioned-Ratio") DEF_FEAT(PRNO_TRNG, "prno-trng", PPNO, 114, "PRNO TRNG") +DEF_FEAT(PRNO_QAI, "prno-qai", PPNO, 127, "PRNO Query-Authentication-Information") /* Features exposed via the KMA instruction. */ DEF_FEAT(KMA_GCM_AES_128, "kma-gcm-aes-128", KMA, 18, "KMA GCM-AES-128") @@ -349,6 +422,7 @@ DEF_FEAT(KMA_GCM_AES_256, "kma-gcm-aes-256", KMA, 20, "KMA GCM-AES-256") DEF_FEAT(KMA_GCM_EAES_128, "kma-gcm-eaes-128", KMA, 26, "KMA GCM-Encrypted-AES-128") DEF_FEAT(KMA_GCM_EAES_192, "kma-gcm-eaes-192", KMA, 27, "KMA GCM-Encrypted-AES-192") DEF_FEAT(KMA_GCM_EAES_256, "kma-gcm-eaes-256", KMA, 28, "KMA GCM-Encrypted-AES-256") +DEF_FEAT(KMA_QAI, "kma-qai", KMA, 127, "KMA Query-Authentication-Information") /* Features exposed via the KDSA instruction. */ DEF_FEAT(KDSA_ECDSA_VERIFY_P256, "kdsa-ecdsa-verify-p256", KDSA, 1, "KDSA ECDSA-Verify-P256") @@ -366,6 +440,7 @@ DEF_FEAT(KDSA_EDDSA_SIGN_ED25519, "kdsa-eddsa-sign-ed25519", KDSA, 40, "KDSA EdD DEF_FEAT(KDSA_EDDSA_SIGN_ED448, "kdsa-eddsa-sign-ed448", KDSA, 44, "KDSA EdDSA-Sign-Ed448") DEF_FEAT(KDSA_EEDDSA_SIGN_ED25519, "kdsa-eeddsa-sign-ed25519", KDSA, 48, "KDSA Encrypted-EdDSA-Sign-Ed25519") DEF_FEAT(KDSA_EEDDSA_SIGN_ED448, "kdsa-eeddsa-sign-ed448", KDSA, 52, "KDSA Encrypted-EdDSA-Sign-Ed448") +DEF_FEAT(KDSA_QAI, "kdsa-qai", KDSA, 127, "KDSA Query-Authentication-Information") /* Features exposed via the SORTL instruction. */ DEF_FEAT(SORTL_SFLR, "sortl-sflr", SORTL, 1, "SORTL SFLR") @@ -383,3 +458,10 @@ DEF_FEAT(DEFLATE_F0, "dfltcc-f0", DFLTCC, 192, "DFLTCC format 0 parameter-block" /* Features exposed via the UV-CALL instruction */ DEF_FEAT(UV_FEAT_AP, "appv", UV_FEAT_GUEST, 4, "AP instructions installed for secure guests") DEF_FEAT(UV_FEAT_AP_INTR, "appvi", UV_FEAT_GUEST, 5, "AP instructions interruption support for secure guests") + +/* Features exposed via the PFCR instruction (concurrent-functions facility). */ +DEF_FEAT(PFCR_QAF, "pfcr-qaf", PFCR, 0, "PFCR Query-Available-Functions") +DEF_FEAT(PFCR_CSDST, "pfcr-csdst", PFCR, 1, "PFCR Compare-and-Swap-and-Double-Store (32)") +DEF_FEAT(PFCR_CSDSTG, "pfcr-csdstg", PFCR, 2, "PFCR Compare-and-Swap-and-Double-Store (64)") +DEF_FEAT(PFCR_CSTST, "pfcr-cstst", PFCR, 3, "PFCR Compare-and-Swap-and-Triple-Store (32)") +DEF_FEAT(PFCR_CSTSTG, "pfcr-cststg", PFCR, 4, "PFCR Compare-and-Swap-and-Triple-Store (64)") diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c index a27f4b6f79..beb50b5300 100644 --- a/target/s390x/cpu_models.c +++ b/target/s390x/cpu_models.c @@ -94,6 +94,8 @@ static S390CPUDef s390_cpu_defs[] = { CPUDEF_INIT(0x8562, 15, 1, 47, 0x08000000U, "gen15b", "IBM z15 T02 GA1"), CPUDEF_INIT(0x3931, 16, 1, 47, 0x08000000U, "gen16a", "IBM 3931 GA1"), CPUDEF_INIT(0x3932, 16, 1, 47, 0x08000000U, "gen16b", "IBM 3932 GA1"), + CPUDEF_INIT(0x9175, 17, 1, 47, 0x08000000U, "gen17a", "IBM 9175 GA1"), + CPUDEF_INIT(0x9176, 17, 1, 47, 0x08000000U, "gen17b", "IBM 9176 GA1"), }; #define QEMU_MAX_CPU_TYPE 0x8561 @@ -457,7 +459,10 @@ static void check_consistency(const S390CPUModel *model) { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR }, { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH, S390_FEAT_VECTOR_PACKED_DECIMAL }, { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH }, + { S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, S390_FEAT_VECTOR_PACKED_DECIMAL_ENH2 }, { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, + { S390_FEAT_VECTOR_ENH2, S390_FEAT_VECTOR_ENH }, + { S390_FEAT_VECTOR_ENH3, S390_FEAT_VECTOR_ENH2 }, { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP }, { S390_FEAT_CMM_NT, S390_FEAT_CMM }, @@ -477,6 +482,18 @@ static void check_consistency(const S390CPUModel *model) { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, + { S390_FEAT_KMAC_HMAC_SHA_224, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KMAC_HMAC_SHA_256, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KMAC_HMAC_SHA_384, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KMAC_HMAC_SHA_512, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KMAC_HMAC_ESHA_224, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KMAC_HMAC_ESHA_256, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KMAC_HMAC_ESHA_384, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KMAC_HMAC_ESHA_512, S390_FEAT_MSA_EXT_3 }, + { S390_FEAT_KM_FULL_XTS_AES_128, S390_FEAT_MSA_EXT_4 }, + { S390_FEAT_KM_FULL_XTS_AES_256, S390_FEAT_MSA_EXT_4 }, + { S390_FEAT_KM_FULL_XTS_EAES_128, S390_FEAT_MSA_EXT_4 }, + { S390_FEAT_KM_FULL_XTS_EAES_256, S390_FEAT_MSA_EXT_4 }, { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 }, { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 }, { S390_FEAT_SIE_KSS, S390_FEAT_SIE_F2 }, @@ -492,6 +509,50 @@ static void check_consistency(const S390CPUModel *model) { S390_FEAT_RDP, S390_FEAT_LOCAL_TLB_CLEARING }, { S390_FEAT_UV_FEAT_AP, S390_FEAT_AP }, { S390_FEAT_UV_FEAT_AP_INTR, S390_FEAT_UV_FEAT_AP }, + { S390_FEAT_PFCR_QAF, S390_FEAT_CCF_BASE }, + { S390_FEAT_PFCR_CSDST, S390_FEAT_CCF_BASE }, + { S390_FEAT_PFCR_CSDSTG, S390_FEAT_CCF_BASE }, + { S390_FEAT_PFCR_CSTST, S390_FEAT_CCF_BASE }, + { S390_FEAT_PFCR_CSTSTG, S390_FEAT_CCF_BASE }, + { S390_FEAT_INEFF_NC_TX, S390_FEAT_TRANSACTIONAL_EXE }, + { S390_FEAT_PLO_CLO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_CSO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_DCSO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_CSSTO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_CSDSTO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_CSTSTO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TCS, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TCSG, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TCSX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TCSO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QCS, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QCSG, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QCSX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QCSO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_LO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_DLX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_DLO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TL, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TLG, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TLX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TLO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QL, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QLG, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QLX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QLO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_STO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_DST, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_DSTG, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_DSTX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_DSTO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TST, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TSTG, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TSTX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_TSTO, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QST, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QSTG, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QSTX, S390_FEAT_PLO_EXT }, + { S390_FEAT_PLO_QSTO, S390_FEAT_PLO_EXT }, }; int i; diff --git a/target/s390x/gen-features.c b/target/s390x/gen-features.c index 2b2bfc3736..41840677ce 100644 --- a/target/s390x/gen-features.c +++ b/target/s390x/gen-features.c @@ -46,6 +46,47 @@ S390_FEAT_PLO_CSTSTGR, \ S390_FEAT_PLO_CSTSTX +#define S390_FEAT_GROUP_PLO_EXT \ + S390_FEAT_PLO_EXT, \ + S390_FEAT_PLO_CLO, \ + S390_FEAT_PLO_CSO, \ + S390_FEAT_PLO_DCSO, \ + S390_FEAT_PLO_CSSTO, \ + S390_FEAT_PLO_CSDSTO, \ + S390_FEAT_PLO_CSTSTO, \ + S390_FEAT_PLO_TCS, \ + S390_FEAT_PLO_TCSG, \ + S390_FEAT_PLO_TCSX, \ + S390_FEAT_PLO_TCSO, \ + S390_FEAT_PLO_QCS, \ + S390_FEAT_PLO_QCSG, \ + S390_FEAT_PLO_QCSX, \ + S390_FEAT_PLO_QCSO, \ + S390_FEAT_PLO_LO, \ + S390_FEAT_PLO_DLX, \ + S390_FEAT_PLO_DLO, \ + S390_FEAT_PLO_TL, \ + S390_FEAT_PLO_TLG, \ + S390_FEAT_PLO_TLX, \ + S390_FEAT_PLO_TLO, \ + S390_FEAT_PLO_QL, \ + S390_FEAT_PLO_QLG, \ + S390_FEAT_PLO_QLX, \ + S390_FEAT_PLO_QLO, \ + S390_FEAT_PLO_STO, \ + S390_FEAT_PLO_DST, \ + S390_FEAT_PLO_DSTG, \ + S390_FEAT_PLO_DSTX, \ + S390_FEAT_PLO_DSTO, \ + S390_FEAT_PLO_TST, \ + S390_FEAT_PLO_TSTG, \ + S390_FEAT_PLO_TSTX, \ + S390_FEAT_PLO_TSTO, \ + S390_FEAT_PLO_QST, \ + S390_FEAT_PLO_QSTG, \ + S390_FEAT_PLO_QSTX, \ + S390_FEAT_PLO_QSTO + #define S390_FEAT_GROUP_TOD_CLOCK_STEERING \ S390_FEAT_TOD_CLOCK_STEERING, \ S390_FEAT_PTFF_QTO, \ @@ -64,6 +105,9 @@ S390_FEAT_PTFF_STOE, \ S390_FEAT_PTFF_STOUE +#define S390_FEAT_GROUP_GEN17_PTFF \ + S390_FEAT_PTFF_QTSE + #define S390_FEAT_GROUP_MSA \ S390_FEAT_MSA, \ S390_FEAT_KMAC_DEA, \ @@ -246,6 +290,49 @@ S390_FEAT_PCKMO_ECC_ED25519, \ S390_FEAT_PCKMO_ECC_ED448 +#define S390_FEAT_GROUP_MSA_EXT_10 \ + S390_FEAT_KM_FULL_XTS_AES_128, \ + S390_FEAT_KM_FULL_XTS_AES_256, \ + S390_FEAT_KM_FULL_XTS_EAES_128, \ + S390_FEAT_KM_FULL_XTS_EAES_256 + +#define S390_FEAT_GROUP_MSA_EXT_10_PCKMO \ + S390_FEAT_PCKMO_AES_XTS_128_DK, \ + S390_FEAT_PCKMO_AES_XTS_256_DK + +#define S390_FEAT_GROUP_MSA_EXT_11 \ + S390_FEAT_KMAC_HMAC_SHA_224, \ + S390_FEAT_KMAC_HMAC_SHA_256, \ + S390_FEAT_KMAC_HMAC_SHA_384, \ + S390_FEAT_KMAC_HMAC_SHA_512, \ + S390_FEAT_KMAC_HMAC_ESHA_224, \ + S390_FEAT_KMAC_HMAC_ESHA_256, \ + S390_FEAT_KMAC_HMAC_ESHA_384, \ + S390_FEAT_KMAC_HMAC_ESHA_512 + +#define S390_FEAT_GROUP_MSA_EXT_11_PCKMO \ + S390_FEAT_PCKMO_HMAC_512, \ + S390_FEAT_PCKMO_HMAC_1024 + +#define S390_FEAT_GROUP_MSA_EXT_12 \ + S390_FEAT_MSA_EXT_12 + +#define S390_FEAT_GROUP_MSA_EXT_13 \ + S390_FEAT_KDSA_QAI, \ + S390_FEAT_KIMD_QAI, \ + S390_FEAT_KLMD_QAI, \ + S390_FEAT_KMAC_QAI, \ + S390_FEAT_KMA_QAI, \ + S390_FEAT_KMCTR_QAI, \ + S390_FEAT_KMF_QAI, \ + S390_FEAT_KMO_QAI, \ + S390_FEAT_KM_QAI, \ + S390_FEAT_PCC_QAI, \ + S390_FEAT_PRNO_QAI + +#define S390_FEAT_GROUP_MSA_EXT_13_PCKMO \ + S390_FEAT_PCKMO_QAI + #define S390_FEAT_GROUP_ENH_SORT \ S390_FEAT_ESORT_BASE, \ S390_FEAT_SORTL_SFLR, \ @@ -262,10 +349,21 @@ S390_FEAT_DEFLATE_XPND, \ S390_FEAT_DEFLATE_F0 +#define S390_FEAT_GROUP_CONCURRENT_FUNCTIONS \ + S390_FEAT_CCF_BASE, \ + S390_FEAT_PFCR_QAF, \ + S390_FEAT_PFCR_CSDST, \ + S390_FEAT_PFCR_CSDSTG, \ + S390_FEAT_PFCR_CSTST, \ + S390_FEAT_PFCR_CSTSTG + /* cpu feature groups */ static uint16_t group_PLO[] = { S390_FEAT_GROUP_PLO, }; +static uint16_t group_PLO_EXT[] = { + S390_FEAT_GROUP_PLO_EXT, +}; static uint16_t group_TOD_CLOCK_STEERING[] = { S390_FEAT_GROUP_TOD_CLOCK_STEERING, }; @@ -275,6 +373,11 @@ static uint16_t group_GEN13_PTFF[] = { static uint16_t group_MULTIPLE_EPOCH_PTFF[] = { S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF, }; + +static uint16_t group_GEN17_PTFF[] = { + S390_FEAT_GROUP_GEN17_PTFF, +}; + static uint16_t group_MSA[] = { S390_FEAT_GROUP_MSA, }; @@ -307,10 +410,38 @@ static uint16_t group_MSA_EXT_9[] = { S390_FEAT_GROUP_MSA_EXT_9, }; +static uint16_t group_MSA_EXT_10[] = { + S390_FEAT_GROUP_MSA_EXT_10, +}; + +static uint16_t group_MSA_EXT_11[] = { + S390_FEAT_GROUP_MSA_EXT_11, +}; + +static uint16_t group_MSA_EXT_12[] = { + S390_FEAT_GROUP_MSA_EXT_12, +}; + +static uint16_t group_MSA_EXT_13[] = { + S390_FEAT_GROUP_MSA_EXT_13, +}; + static uint16_t group_MSA_EXT_9_PCKMO[] = { S390_FEAT_GROUP_MSA_EXT_9_PCKMO, }; +static uint16_t group_MSA_EXT_10_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_10_PCKMO, +}; + +static uint16_t group_MSA_EXT_11_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_11_PCKMO, +}; + +static uint16_t group_MSA_EXT_13_PCKMO[] = { + S390_FEAT_GROUP_MSA_EXT_13_PCKMO, +}; + static uint16_t group_ENH_SORT[] = { S390_FEAT_GROUP_ENH_SORT, }; @@ -319,6 +450,10 @@ static uint16_t group_DEFLATE_CONVERSION[] = { S390_FEAT_GROUP_DEFLATE_CONVERSION, }; +static uint16_t group_CONCURRENT_FUNCTIONS[] = { + S390_FEAT_GROUP_CONCURRENT_FUNCTIONS, +}; + /* Base features (in order of release) * Only non-hypervisor managed features belong here. * Base feature sets are static meaning they do not change in future QEMU @@ -426,6 +561,13 @@ static uint16_t base_GEN15_GA1[] = { #define base_GEN16_GA1 EmptyFeat +static uint16_t base_GEN17_GA1[] = { + S390_FEAT_MISC_INSTRUCTION_EXT4, + S390_FEAT_SIF, + S390_FEAT_GROUP_MSA_EXT_12, + S390_FEAT_GROUP_PLO_EXT, +}; + /* Full features (in order of release) * Automatically includes corresponding base features. * Full features are all features this hardware supports even if kvm/QEMU do not @@ -580,6 +722,20 @@ static uint16_t full_GEN16_GA1[] = { S390_FEAT_UV_FEAT_AP_INTR, }; +static uint16_t full_GEN17_GA1[] = { + S390_FEAT_VECTOR_ENH3, + S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, + S390_FEAT_INEFF_NC_TX, + S390_FEAT_GROUP_GEN17_PTFF, + S390_FEAT_GROUP_MSA_EXT_10, + S390_FEAT_GROUP_MSA_EXT_10_PCKMO, + S390_FEAT_GROUP_MSA_EXT_11, + S390_FEAT_GROUP_MSA_EXT_11_PCKMO, + S390_FEAT_GROUP_MSA_EXT_13, + S390_FEAT_GROUP_MSA_EXT_13_PCKMO, + S390_FEAT_GROUP_CONCURRENT_FUNCTIONS, +}; + /* Default features (in order of release) * Automatically includes corresponding base features. @@ -675,6 +831,17 @@ static uint16_t default_GEN16_GA1[] = { S390_FEAT_PAIE, }; +static uint16_t default_GEN17_GA1[] = { + S390_FEAT_VECTOR_ENH3, + S390_FEAT_VECTOR_PACKED_DECIMAL_ENH3, + S390_FEAT_GROUP_MSA_EXT_10, + S390_FEAT_GROUP_MSA_EXT_10_PCKMO, + S390_FEAT_GROUP_MSA_EXT_11, + S390_FEAT_GROUP_MSA_EXT_11_PCKMO, + S390_FEAT_GROUP_MSA_EXT_13, + S390_FEAT_GROUP_MSA_EXT_13_PCKMO, +}; + /* QEMU (CPU model) features */ static uint16_t qemu_V2_11[] = { @@ -823,6 +990,7 @@ static CpuFeatDefSpec CpuFeatDef[] = { CPU_FEAT_INITIALIZER(GEN14_GA2), CPU_FEAT_INITIALIZER(GEN15_GA1), CPU_FEAT_INITIALIZER(GEN16_GA1), + CPU_FEAT_INITIALIZER(GEN17_GA1), }; #define FEAT_GROUP_INITIALIZER(_name) \ @@ -845,8 +1013,10 @@ typedef struct { *******************************/ static FeatGroupDefSpec FeatGroupDef[] = { FEAT_GROUP_INITIALIZER(PLO), + FEAT_GROUP_INITIALIZER(PLO_EXT), FEAT_GROUP_INITIALIZER(TOD_CLOCK_STEERING), FEAT_GROUP_INITIALIZER(GEN13_PTFF), + FEAT_GROUP_INITIALIZER(GEN17_PTFF), FEAT_GROUP_INITIALIZER(MSA), FEAT_GROUP_INITIALIZER(MSA_EXT_1), FEAT_GROUP_INITIALIZER(MSA_EXT_2), @@ -858,9 +1028,17 @@ static FeatGroupDefSpec FeatGroupDef[] = { FEAT_GROUP_INITIALIZER(MSA_EXT_8), FEAT_GROUP_INITIALIZER(MSA_EXT_9), FEAT_GROUP_INITIALIZER(MSA_EXT_9_PCKMO), + FEAT_GROUP_INITIALIZER(MSA_EXT_10), + FEAT_GROUP_INITIALIZER(MSA_EXT_10_PCKMO), + FEAT_GROUP_INITIALIZER(MSA_EXT_11), + FEAT_GROUP_INITIALIZER(MSA_EXT_11_PCKMO), + FEAT_GROUP_INITIALIZER(MSA_EXT_12), + FEAT_GROUP_INITIALIZER(MSA_EXT_13), + FEAT_GROUP_INITIALIZER(MSA_EXT_13_PCKMO), FEAT_GROUP_INITIALIZER(MULTIPLE_EPOCH_PTFF), FEAT_GROUP_INITIALIZER(ENH_SORT), FEAT_GROUP_INITIALIZER(DEFLATE_CONVERSION), + FEAT_GROUP_INITIALIZER(CONCURRENT_FUNCTIONS), }; #define QEMU_FEAT_INITIALIZER(_name) \ diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index 8ffe0159d8..dd0322c43a 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -2195,6 +2195,9 @@ static int query_cpu_subfunc(S390FeatBitmap features) if (test_bit(S390_FEAT_DEFLATE_BASE, features)) { s390_add_from_feat_block(features, S390_FEAT_TYPE_DFLTCC, prop.dfltcc); } + if (test_bit(S390_FEAT_CCF_BASE, features)) { + s390_add_from_feat_block(features, S390_FEAT_TYPE_PFCR, prop.pfcr); + } return 0; } @@ -2248,6 +2251,9 @@ static int configure_cpu_subfunc(const S390FeatBitmap features) if (test_bit(S390_FEAT_DEFLATE_BASE, features)) { s390_fill_feat_block(features, S390_FEAT_TYPE_DFLTCC, prop.dfltcc); } + if (test_bit(S390_FEAT_CCF_BASE, features)) { + s390_fill_feat_block(features, S390_FEAT_TYPE_PFCR, prop.pfcr); + } return kvm_vm_ioctl(kvm_state, KVM_SET_DEVICE_ATTR, &attr); } diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py index 12e24bb05a..268b40ca31 100644 --- a/tests/avocado/boot_linux_console.py +++ b/tests/avocado/boot_linux_console.py @@ -24,27 +24,6 @@ from avocado_qemu import wait_for_console_pattern from avocado.utils import process from avocado.utils import archive -""" -Round up to next power of 2 -""" -def pow2ceil(x): - return 1 if x == 0 else 2**(x - 1).bit_length() - -def file_truncate(path, size): - if size != os.path.getsize(path): - with open(path, 'ab+') as fd: - fd.truncate(size) - -""" -Expand file size to next power of 2 -""" -def image_pow2ceil_expand(path): - size = os.path.getsize(path) - size_aligned = pow2ceil(size) - if size != size_aligned: - with open(path, 'ab+') as fd: - fd.truncate(size_aligned) - class LinuxKernelTest(QemuSystemTest): KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' @@ -116,33 +95,6 @@ class BootLinuxConsole(LinuxKernelTest): console_pattern = 'Kernel command line: %s' % kernel_command_line self.wait_for_console_pattern(console_pattern) - def test_aarch64_xlnx_versal_virt(self): - """ - :avocado: tags=arch:aarch64 - :avocado: tags=machine:xlnx-versal-virt - :avocado: tags=device:pl011 - :avocado: tags=device:arm_gicv3 - :avocado: tags=accel:tcg - """ - images_url = ('http://ports.ubuntu.com/ubuntu-ports/dists/' - 'bionic-updates/main/installer-arm64/' - '20101020ubuntu543.19/images/') - kernel_url = images_url + 'netboot/ubuntu-installer/arm64/linux' - kernel_hash = 'e167757620640eb26de0972f578741924abb3a82' - kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash) - - initrd_url = images_url + 'netboot/ubuntu-installer/arm64/initrd.gz' - initrd_hash = 'cab5cb3fcefca8408aa5aae57f24574bfce8bdb9' - initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - - self.vm.set_console() - self.vm.add_args('-m', '2G', - '-accel', 'tcg', - '-kernel', kernel_path, - '-initrd', initrd_path) - self.vm.launch() - self.wait_for_console_pattern('Checked W+X mappings: passed') - def test_arm_virt(self): """ :avocado: tags=arch:arm @@ -164,227 +116,6 @@ class BootLinuxConsole(LinuxKernelTest): console_pattern = 'Kernel command line: %s' % kernel_command_line self.wait_for_console_pattern(console_pattern) - def test_arm_emcraft_sf2(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:emcraft-sf2 - :avocado: tags=endian:little - :avocado: tags=u-boot - :avocado: tags=accel:tcg - """ - self.require_netdev('user') - - uboot_url = ('https://raw.githubusercontent.com/' - 'Subbaraya-Sundeep/qemu-test-binaries/' - 'fe371d32e50ca682391e1e70ab98c2942aeffb01/u-boot') - uboot_hash = 'cbb8cbab970f594bf6523b9855be209c08374ae2' - uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash) - spi_url = ('https://raw.githubusercontent.com/' - 'Subbaraya-Sundeep/qemu-test-binaries/' - 'fe371d32e50ca682391e1e70ab98c2942aeffb01/spi.bin') - spi_hash = '65523a1835949b6f4553be96dec1b6a38fb05501' - spi_path = self.fetch_asset(spi_url, asset_hash=spi_hash) - spi_path_rw = os.path.join(self.workdir, os.path.basename(spi_path)) - shutil.copy(spi_path, spi_path_rw) - - file_truncate(spi_path_rw, 16 << 20) # Spansion S25FL128SDPBHICO is 16 MiB - - self.vm.set_console() - kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE - self.vm.add_args('-kernel', uboot_path, - '-append', kernel_command_line, - '-drive', 'file=' + spi_path_rw + ',if=mtd,format=raw', - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Enter \'help\' for a list') - - exec_command_and_wait_for_pattern(self, 'ifconfig eth0 10.0.2.15', - 'eth0: link becomes ready') - exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2', - '3 packets transmitted, 3 packets received, 0% packet loss') - - def test_arm_exynos4210_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:smdkc210 - :avocado: tags=accel:tcg - """ - deb_url = ('https://snapshot.debian.org/archive/debian/' - '20190928T224601Z/pool/main/l/linux/' - 'linux-image-4.19.0-6-armmp_4.19.67-2+deb10u1_armhf.deb') - deb_hash = 'fa9df4a0d38936cb50084838f2cb933f570d7d82' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-4.19.0-6-armmp') - dtb_path = '/usr/lib/linux-image-4.19.0-6-armmp/exynos4210-smdkv310.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv5.cpio.gz') - initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'earlycon=exynos4210,0x13800000 earlyprintk ' + - 'console=ttySAC0,115200n8 ' + - 'random.trust_cpu=off cryptomgr.notests ' + - 'cpuidle.off=1 panic=-1 noreboot') - - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - - self.wait_for_console_pattern('Boot successful.') - # TODO user command, for now the uart is stuck - - def test_arm_cubieboard_initrd(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:cubieboard - :avocado: tags=accel:tcg - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - initrd_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv5.cpio.gz') - initrd_hash = '2b50f1873e113523967806f4da2afe385462ff9b' - initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash) - initrd_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(initrd_path_gz, initrd_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'usbcore.nousb ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-initrd', initrd_path, - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun4i/sun5i') - exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', - 'system-control@1c00000') - 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): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:cubieboard - :avocado: tags=accel:tcg - """ - deb_url = ('https://apt.armbian.com/pool/main/l/' - 'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb') - deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash) - kernel_path = self.extract_from_deb(deb_path, - '/boot/vmlinuz-6.6.16-current-sunxi') - dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' - dtb_path = self.extract_from_deb(deb_path, dtb_path) - rootfs_url = ('https://github.com/groeck/linux-build-test/raw/' - '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' - 'arm/rootfs-armv5.ext2.gz') - rootfs_hash = '093e89d2b4d982234bf528bc9fb2f2f17a9d1f93' - rootfs_path_gz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash) - rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') - archive.gzip_uncompress(rootfs_path_gz, rootfs_path) - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyS0,115200 ' - 'usbcore.nousb ' - 'root=/dev/sda ro ' - 'panic=-1 noreboot') - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-drive', 'if=none,format=raw,id=disk0,file=' - + rootfs_path, - '-device', 'ide-hd,bus=ide.0,drive=disk0', - '-append', kernel_command_line, - '-no-reboot') - self.vm.launch() - self.wait_for_console_pattern('Boot successful.') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun4i/sun5i') - exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', - 'sda') - 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): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:cubieboard - :avocado: tags=device:sd - """ - - # This test download a 7.5 MiB compressed image and expand it - # to 126 MiB. - image_url = ('https://downloads.openwrt.org/releases/22.03.2/targets/' - 'sunxi/cortexa8/openwrt-22.03.2-sunxi-cortexa8-' - 'cubietech_a10-cubieboard-ext4-sdcard.img.gz') - image_hash = ('94b5ecbfbc0b3b56276e5146b899eafa' - '2ac5dc2d08733d6705af9f144f39f554') - image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash, - algorithm='sha256') - image_path = archive.extract(image_path_gz, self.workdir) - image_pow2ceil_expand(image_path) - - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw', - '-nic', 'user', - '-no-reboot') - self.vm.launch() - - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'usbcore.nousb ' - 'noreboot') - - self.wait_for_console_pattern('U-Boot SPL') - - interrupt_interactive_console_until_pattern( - self, 'Hit any key to stop autoboot:', '=>') - exec_command_and_wait_for_pattern(self, "setenv extraargs '" + - kernel_command_line + "'", '=>') - exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...'); - - self.wait_for_console_pattern( - 'Please press Enter to activate this console.') - - exec_command_and_wait_for_pattern(self, ' ', 'root@') - - exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', - 'Allwinner sun4i/sun5i') - 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): """ @@ -470,29 +201,3 @@ class BootLinuxConsole(LinuxKernelTest): self.wait_for_console_pattern('CPU1: thread -1, cpu 1, socket 0') self.wait_for_console_pattern( 'Give root password for system maintenance') - - def test_arm_ast2600_debian(self): - """ - :avocado: tags=arch:arm - :avocado: tags=machine:rainier-bmc - """ - deb_url = ('http://snapshot.debian.org/archive/debian/' - '20220606T211338Z/' - 'pool/main/l/linux/' - 'linux-image-5.17.0-2-armmp_5.17.6-1%2Bb1_armhf.deb') - deb_hash = '8acb2b4439faedc2f3ed4bdb2847ad4f6e0491f73debaeb7f660c8abe4dcdc0e' - deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash, - algorithm='sha256') - kernel_path = self.extract_from_deb(deb_path, '/boot/vmlinuz-5.17.0-2-armmp') - dtb_path = self.extract_from_deb(deb_path, - '/usr/lib/linux-image-5.17.0-2-armmp/aspeed-bmc-ibm-rainier.dtb') - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_path, - '-dtb', dtb_path, - '-net', 'nic') - self.vm.launch() - self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00") - self.wait_for_console_pattern("SMP: Total of 2 processors activated") - self.wait_for_console_pattern("No filesystem could mount root") - diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py new file mode 100644 index 0000000000..62f50bab7a --- /dev/null +++ b/tests/functional/aspeed.py @@ -0,0 +1,56 @@ +# Test class to boot aspeed machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test import LinuxKernelTest + +class AspeedTest(LinuxKernelTest): + + def do_test_arm_aspeed(self, machine, image): + self.set_machine(machine) + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', + '-net', 'nic', '-snapshot') + self.vm.launch() + + self.wait_for_console_pattern("U-Boot 2016.07") + self.wait_for_console_pattern("## Loading kernel from FIT Image at 20080000") + self.wait_for_console_pattern("Starting kernel ...") + self.wait_for_console_pattern("Booting Linux on physical CPU 0x0") + self.wait_for_console_pattern( + "aspeed-smc 1e620000.spi: read control register: 203b0641") + self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ") + self.wait_for_console_pattern("systemd[1]: Set hostname to") + + def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'): + self.require_netdev('user') + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw,read-only=true', + '-net', 'nic', '-net', 'user') + self.vm.launch() + + self.wait_for_console_pattern('U-Boot 2019.04') + self.wait_for_console_pattern('## Loading kernel from FIT Image') + self.wait_for_console_pattern('Starting kernel ...') + self.wait_for_console_pattern('Booting Linux on physical CPU ' + cpu_id) + self.wait_for_console_pattern('lease of 10.0.2.15') + # the line before login: + self.wait_for_console_pattern(pattern) + exec_command_and_wait_for_pattern(self, 'root', 'Password:') + exec_command_and_wait_for_pattern(self, 'passw0rd', '#') + + def do_test_arm_aspeed_buildroot_poweroff(self): + exec_command_and_wait_for_pattern(self, 'poweroff', + 'reboot: System halted'); + + def do_test_arm_aspeed_sdk_start(self, image): + self.require_netdev('user') + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', + '-net', 'nic', '-net', 'user', '-snapshot') + self.vm.launch() + + self.wait_for_console_pattern('U-Boot 2019.04') + self.wait_for_console_pattern('## Loading kernel from FIT Image') + self.wait_for_console_pattern('Starting kernel ...') diff --git a/tests/functional/meson.build b/tests/functional/meson.build index d6d2c0196c..1bc5ba5229 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -18,9 +18,14 @@ test_timeouts = { 'aarch64_tuxrun' : 240, 'aarch64_virt' : 720, 'acpi_bits' : 420, - 'arm_aspeed' : 600, + 'arm_aspeed_palmetto' : 120, + 'arm_aspeed_romulus' : 120, + 'arm_aspeed_ast2500' : 480, + 'arm_aspeed_ast2600' : 720, + 'arm_aspeed_rainier' : 240, 'arm_bpim2u' : 500, 'arm_collie' : 180, + 'arm_cubieboard' : 360, 'arm_orangepi' : 540, 'arm_raspi2' : 120, 'arm_tuxrun' : 240, @@ -34,6 +39,7 @@ test_timeouts = { 'ppc64_tuxrun' : 420, 'riscv64_tuxrun' : 120, 's390x_ccw_virtio' : 420, + 'sh4_tuxrun' : 240, } tests_generic_system = [ @@ -57,6 +63,7 @@ tests_aarch64_system_thorough = [ 'aarch64_sbsaref_freebsd', 'aarch64_tuxrun', 'aarch64_virt', + 'aarch64_xlnx_versal', 'multiprocess', ] @@ -65,13 +72,21 @@ tests_alpha_system_thorough = [ ] tests_arm_system_thorough = [ - 'arm_aspeed', + 'arm_aspeed_ast1030', + 'arm_aspeed_palmetto', + 'arm_aspeed_romulus', + 'arm_aspeed_ast2500', + 'arm_aspeed_ast2600', + 'arm_aspeed_rainier', 'arm_bpim2u', 'arm_canona1100', 'arm_collie', + 'arm_cubieboard', + 'arm_emcraft_sf2', 'arm_integratorcp', 'arm_orangepi', 'arm_raspi2', + 'arm_smdkc210', 'arm_sx1', 'arm_vexpress', 'arm_tuxrun', diff --git a/tests/functional/test_aarch64_sbsaref.py b/tests/functional/test_aarch64_sbsaref.py index 9fda396b3a..6db08da522 100755 --- a/tests/functional/test_aarch64_sbsaref.py +++ b/tests/functional/test_aarch64_sbsaref.py @@ -14,7 +14,6 @@ from qemu_test import QemuSystemTest, Asset from qemu_test import wait_for_console_pattern from qemu_test import interrupt_interactive_console_until_pattern from qemu_test.utils import lzma_uncompress -from unittest import skipUnless def fetch_firmware(test): """ diff --git a/tests/functional/test_aarch64_xlnx_versal.py b/tests/functional/test_aarch64_xlnx_versal.py new file mode 100755 index 0000000000..4b9c49e5d6 --- /dev/null +++ b/tests/functional/test_aarch64_xlnx_versal.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel and checks the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import LinuxKernelTest, Asset + +class XlnxVersalVirtMachine(LinuxKernelTest): + + ASSET_KERNEL = Asset( + ('http://ports.ubuntu.com/ubuntu-ports/dists/bionic-updates/main/' + 'installer-arm64/20101020ubuntu543.19/images/netboot/' + 'ubuntu-installer/arm64/linux'), + 'ce54f74ab0b15cfd13d1a293f2d27ffd79d8a85b7bb9bf21093ae9513864ac79') + + ASSET_INITRD = Asset( + ('http://ports.ubuntu.com/ubuntu-ports/dists/bionic-updates/main/' + 'installer-arm64/20101020ubuntu543.19/images/netboot/' + '/ubuntu-installer/arm64/initrd.gz'), + 'e7a5e716b6f516d8be315c06e7331aaf16994fe4222e0e7cfb34bc015698929e') + + def test_aarch64_xlnx_versal_virt(self): + self.set_machine('xlnx-versal-virt') + kernel_path = self.ASSET_KERNEL.fetch() + initrd_path = self.ASSET_INITRD.fetch() + + self.vm.set_console() + self.vm.add_args('-m', '2G', + '-accel', 'tcg', + '-kernel', kernel_path, + '-initrd', initrd_path) + self.vm.launch() + self.wait_for_console_pattern('Checked W+X mappings: passed') + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_acpi_bits.py b/tests/functional/test_acpi_bits.py index e2f84414d7..63e2c5309d 100755 --- a/tests/functional/test_acpi_bits.py +++ b/tests/functional/test_acpi_bits.py @@ -39,7 +39,6 @@ import shutil import subprocess import tarfile import tempfile -import time import zipfile from pathlib import Path diff --git a/tests/functional/test_arm_aspeed.py b/tests/functional/test_arm_aspeed.py deleted file mode 100755 index d88170ac24..0000000000 --- a/tests/functional/test_arm_aspeed.py +++ /dev/null @@ -1,351 +0,0 @@ -#!/usr/bin/env python3 -# -# Functional test that boots the ASPEED SoCs with firmware -# -# Copyright (C) 2022 ASPEED Technology Inc -# -# SPDX-License-Identifier: GPL-2.0-or-later - -import os -import time -import subprocess -import tempfile - -from qemu_test import LinuxKernelTest, Asset -from qemu_test import exec_command_and_wait_for_pattern -from qemu_test import interrupt_interactive_console_until_pattern -from qemu_test import has_cmd -from qemu_test.utils import archive_extract -from zipfile import ZipFile -from unittest import skipUnless - -class AST1030Machine(LinuxKernelTest): - - ASSET_ZEPHYR_1_04 = Asset( - ('https://github.com/AspeedTech-BMC' - '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip'), - '4ac6210adcbc61294927918707c6762483fd844dde5e07f3ba834ad1f91434d3') - - def test_ast1030_zephyros_1_04(self): - self.set_machine('ast1030-evb') - - zip_file = self.ASSET_ZEPHYR_1_04.fetch() - - kernel_name = "ast1030-evb-demo/zephyr.elf" - with ZipFile(zip_file, 'r') as zf: - zf.extract(kernel_name, path=self.workdir) - kernel_file = os.path.join(self.workdir, kernel_name) - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_file, '-nographic') - self.vm.launch() - self.wait_for_console_pattern("Booting Zephyr OS") - exec_command_and_wait_for_pattern(self, "help", - "Available commands") - - ASSET_ZEPHYR_1_07 = Asset( - ('https://github.com/AspeedTech-BMC' - '/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip'), - 'ad52e27959746988afaed8429bf4e12ab988c05c4d07c9d90e13ec6f7be4574c') - - def test_ast1030_zephyros_1_07(self): - self.set_machine('ast1030-evb') - - zip_file = self.ASSET_ZEPHYR_1_07.fetch() - - kernel_name = "ast1030-evb-demo/zephyr.bin" - with ZipFile(zip_file, 'r') as zf: - zf.extract(kernel_name, path=self.workdir) - kernel_file = os.path.join(self.workdir, kernel_name) - - self.vm.set_console() - self.vm.add_args('-kernel', kernel_file, '-nographic') - self.vm.launch() - self.wait_for_console_pattern("Booting Zephyr OS") - for shell_cmd in [ - 'kernel stacks', - 'otp info conf', - 'otp info scu', - 'hwinfo devid', - 'crypto aes256_cbc_vault', - 'random get', - 'jtag JTAG1 sw_xfer high TMS', - 'adc ADC0 resolution 12', - 'adc ADC0 read 42', - 'adc ADC1 read 69', - 'i2c scan I2C_0', - 'i3c attach I3C_0', - 'hash test', - 'kernel uptime', - 'kernel reboot warm', - 'kernel uptime', - 'kernel reboot cold', - 'kernel uptime', - ]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$") - -class AST2x00Machine(LinuxKernelTest): - - def do_test_arm_aspeed(self, machine, image): - self.set_machine(machine) - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', - '-net', 'nic', '-snapshot') - self.vm.launch() - - self.wait_for_console_pattern("U-Boot 2016.07") - self.wait_for_console_pattern("## Loading kernel from FIT Image at 20080000") - self.wait_for_console_pattern("Starting kernel ...") - self.wait_for_console_pattern("Booting Linux on physical CPU 0x0") - self.wait_for_console_pattern( - "aspeed-smc 1e620000.spi: read control register: 203b0641") - self.wait_for_console_pattern("ftgmac100 1e660000.ethernet eth0: irq ") - self.wait_for_console_pattern("systemd[1]: Set hostname to") - - ASSET_PALMETTO_FLASH = Asset( - ('https://github.com/openbmc/openbmc/releases/download/2.9.0/' - 'obmc-phosphor-image-palmetto.static.mtd'), - '3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d'); - - def test_arm_ast2400_palmetto_openbmc_v2_9_0(self): - image_path = self.ASSET_PALMETTO_FLASH.fetch() - - self.do_test_arm_aspeed('palmetto-bmc', image_path) - - ASSET_ROMULUS_FLASH = Asset( - ('https://github.com/openbmc/openbmc/releases/download/2.9.0/' - 'obmc-phosphor-image-romulus.static.mtd'), - '820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25') - - def test_arm_ast2500_romulus_openbmc_v2_9_0(self): - image_path = self.ASSET_ROMULUS_FLASH.fetch() - - self.do_test_arm_aspeed('romulus-bmc', image_path) - - def do_test_arm_aspeed_buildroot_start(self, image, cpu_id, pattern='Aspeed EVB'): - self.require_netdev('user') - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw,read-only=true', - '-net', 'nic', '-net', 'user') - self.vm.launch() - - self.wait_for_console_pattern('U-Boot 2019.04') - self.wait_for_console_pattern('## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - self.wait_for_console_pattern('Booting Linux on physical CPU ' + cpu_id) - self.wait_for_console_pattern('lease of 10.0.2.15') - # the line before login: - self.wait_for_console_pattern(pattern) - exec_command_and_wait_for_pattern(self, 'root', 'Password:') - exec_command_and_wait_for_pattern(self, 'passw0rd', '#') - - def do_test_arm_aspeed_buildroot_poweroff(self): - exec_command_and_wait_for_pattern(self, 'poweroff', - 'reboot: System halted'); - - ASSET_BR2_202311_AST2500_FLASH = Asset( - ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2500-evb/buildroot-2023.11/flash.img'), - 'c23db6160cf77d0258397eb2051162c8473a56c441417c52a91ba217186e715f') - - def test_arm_ast2500_evb_buildroot(self): - self.set_machine('ast2500-evb') - - image_path = self.ASSET_BR2_202311_AST2500_FLASH.fetch() - - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); - self.do_test_arm_aspeed_buildroot_start(image_path, '0x0', - 'ast2500-evb login:') - - exec_command_and_wait_for_pattern(self, - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', - 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') - - self.do_test_arm_aspeed_buildroot_poweroff() - - ASSET_BR2_202311_AST2600_FLASH = Asset( - ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2600-evb/buildroot-2023.11/flash.img'), - 'b62808daef48b438d0728ee07662290490ecfa65987bb91294cafb1bb7ad1a68') - - def test_arm_ast2600_evb_buildroot(self): - self.set_machine('ast2600-evb') - - image_path = self.ASSET_BR2_202311_AST2600_FLASH.fetch() - - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); - self.vm.add_args('-device', - 'ds1338,bus=aspeed.i2c.bus.3,address=0x32'); - self.vm.add_args('-device', - 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42'); - self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', - 'ast2600-evb login:') - - exec_command_and_wait_for_pattern(self, - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', - 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') - - exec_command_and_wait_for_pattern(self, - 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device', - 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32'); - year = time.strftime("%Y") - exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year); - - exec_command_and_wait_for_pattern(self, - 'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device', - 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64'); - exec_command_and_wait_for_pattern(self, - 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#'); - exec_command_and_wait_for_pattern(self, - 'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom', - '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff'); - self.do_test_arm_aspeed_buildroot_poweroff() - - ASSET_BR2_202302_AST2600_TPM_FLASH = Asset( - ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2600-evb/buildroot-2023.02-tpm/flash.img'), - 'a46009ae8a5403a0826d607215e731a8c68d27c14c41e55331706b8f9c7bd997') - - @skipUnless(*has_cmd('swtpm')) - def test_arm_ast2600_evb_buildroot_tpm(self): - self.set_machine('ast2600-evb') - - image_path = self.ASSET_BR2_202302_AST2600_TPM_FLASH.fetch() - - tpmstate_dir = tempfile.TemporaryDirectory(prefix="qemu_") - socket = os.path.join(tpmstate_dir.name, 'swtpm-socket') - - # We must put the TPM state dir in /tmp/, not the build dir, - # because some distros use AppArmor to lock down swtpm and - # restrict the set of locations it can access files in. - subprocess.run(['swtpm', 'socket', '-d', '--tpm2', - '--tpmstate', f'dir={tpmstate_dir.name}', - '--ctrl', f'type=unixio,path={socket}']) - - self.vm.add_args('-chardev', f'socket,id=chrtpm,path={socket}') - self.vm.add_args('-tpmdev', 'emulator,id=tpm0,chardev=chrtpm') - self.vm.add_args('-device', - 'tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.12,address=0x2e') - self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', 'Aspeed AST2600 EVB') - - exec_command_and_wait_for_pattern(self, - 'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device', - 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)'); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/tpm/tpm0/pcr-sha256/0', - 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0'); - - self.do_test_arm_aspeed_buildroot_poweroff() - - def do_test_arm_aspeed_sdk_start(self, image): - self.require_netdev('user') - self.vm.set_console() - self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', - '-net', 'nic', '-net', 'user', '-snapshot') - self.vm.launch() - - self.wait_for_console_pattern('U-Boot 2019.04') - self.wait_for_console_pattern('## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - - ASSET_SDK_V806_AST2500 = Asset( - 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz', - 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca') - - def test_arm_ast2500_evb_sdk(self): - self.set_machine('ast2500-evb') - - image_path = self.ASSET_SDK_V806_AST2500.fetch() - - archive_extract(image_path, self.workdir) - - self.do_test_arm_aspeed_sdk_start( - self.workdir + '/ast2500-default/image-bmc') - - self.wait_for_console_pattern('ast2500-default login:') - - ASSET_SDK_V806_AST2600_A2 = Asset( - 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz', - '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4') - - def test_arm_ast2600_evb_sdk(self): - self.set_machine('ast2600-evb') - - image_path = self.ASSET_SDK_V806_AST2600_A2.fetch() - - archive_extract(image_path, self.workdir) - - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test'); - self.vm.add_args('-device', - 'ds1338,bus=aspeed.i2c.bus.5,address=0x32'); - self.do_test_arm_aspeed_sdk_start( - self.workdir + '/ast2600-a2/image-bmc') - - self.wait_for_console_pattern('ast2600-a2 login:') - - exec_command_and_wait_for_pattern(self, 'root', 'Password:') - exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#') - - exec_command_and_wait_for_pattern(self, - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device', - 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d'); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon19/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', - property='temperature', value=18000); - exec_command_and_wait_for_pattern(self, - 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000') - - exec_command_and_wait_for_pattern(self, - 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device', - 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32'); - year = time.strftime("%Y") - exec_command_and_wait_for_pattern(self, - '/sbin/hwclock -f /dev/rtc1', year); - - -class AST2x00MachineMMC(LinuxKernelTest): - - ASSET_RAINIER_EMMC = Asset( - ('https://fileserver.linaro.org/s/B6pJTwWEkzSDi36/download/' - 'mmc-p10bmc-20240617.qcow2'), - 'd523fb478d2b84d5adc5658d08502bc64b1486955683814f89c6137518acd90b') - - def test_arm_aspeed_emmc_boot(self): - self.set_machine('rainier-bmc') - self.require_netdev('user') - - image_path = self.ASSET_RAINIER_EMMC.fetch() - - self.vm.set_console() - self.vm.add_args('-drive', - 'file=' + image_path + ',if=sd,id=sd2,index=2', - '-net', 'nic', '-net', 'user', '-snapshot') - self.vm.launch() - - self.wait_for_console_pattern('U-Boot SPL 2019.04') - self.wait_for_console_pattern('Trying to boot from MMC1') - self.wait_for_console_pattern('U-Boot 2019.04') - self.wait_for_console_pattern('eMMC 2nd Boot') - self.wait_for_console_pattern('## Loading kernel from FIT Image') - self.wait_for_console_pattern('Starting kernel ...') - self.wait_for_console_pattern('Booting Linux on physical CPU 0xf00') - self.wait_for_console_pattern('mmcblk0: p1 p2 p3 p4 p5 p6 p7') - self.wait_for_console_pattern('IBM eBMC (OpenBMC for IBM Enterprise') - -if __name__ == '__main__': - LinuxKernelTest.main() diff --git a/tests/functional/test_arm_aspeed_ast1030.py b/tests/functional/test_arm_aspeed_ast1030.py new file mode 100644 index 0000000000..380a76ec01 --- /dev/null +++ b/tests/functional/test_arm_aspeed_ast1030.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED SoCs with firmware +# +# Copyright (C) 2022 ASPEED Technology Inc +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os + +from qemu_test import LinuxKernelTest, Asset +from qemu_test import exec_command_and_wait_for_pattern +from zipfile import ZipFile + +class AST1030Machine(LinuxKernelTest): + + ASSET_ZEPHYR_1_04 = Asset( + ('https://github.com/AspeedTech-BMC' + '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip'), + '4ac6210adcbc61294927918707c6762483fd844dde5e07f3ba834ad1f91434d3') + + def test_ast1030_zephyros_1_04(self): + self.set_machine('ast1030-evb') + + zip_file = self.ASSET_ZEPHYR_1_04.fetch() + + kernel_name = "ast1030-evb-demo/zephyr.elf" + with ZipFile(zip_file, 'r') as zf: + zf.extract(kernel_name, path=self.workdir) + kernel_file = os.path.join(self.workdir, kernel_name) + + self.vm.set_console() + self.vm.add_args('-kernel', kernel_file, '-nographic') + self.vm.launch() + self.wait_for_console_pattern("Booting Zephyr OS") + exec_command_and_wait_for_pattern(self, "help", + "Available commands") + + ASSET_ZEPHYR_1_07 = Asset( + ('https://github.com/AspeedTech-BMC' + '/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip'), + 'ad52e27959746988afaed8429bf4e12ab988c05c4d07c9d90e13ec6f7be4574c') + + def test_ast1030_zephyros_1_07(self): + self.set_machine('ast1030-evb') + + zip_file = self.ASSET_ZEPHYR_1_07.fetch() + + kernel_name = "ast1030-evb-demo/zephyr.bin" + with ZipFile(zip_file, 'r') as zf: + zf.extract(kernel_name, path=self.workdir) + kernel_file = os.path.join(self.workdir, kernel_name) + + self.vm.set_console() + self.vm.add_args('-kernel', kernel_file, '-nographic') + self.vm.launch() + self.wait_for_console_pattern("Booting Zephyr OS") + for shell_cmd in [ + 'kernel stacks', + 'otp info conf', + 'otp info scu', + 'hwinfo devid', + 'crypto aes256_cbc_vault', + 'random get', + 'jtag JTAG1 sw_xfer high TMS', + 'adc ADC0 resolution 12', + 'adc ADC0 read 42', + 'adc ADC1 read 69', + 'i2c scan I2C_0', + 'i3c attach I3C_0', + 'hash test', + 'kernel uptime', + 'kernel reboot warm', + 'kernel uptime', + 'kernel reboot cold', + 'kernel uptime', + ]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$") + + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_arm_aspeed_ast2500.py b/tests/functional/test_arm_aspeed_ast2500.py new file mode 100644 index 0000000000..79baf37537 --- /dev/null +++ b/tests/functional/test_arm_aspeed_ast2500.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import Asset +from aspeed import AspeedTest +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test.utils import archive_extract + +class AST2500Machine(AspeedTest): + + ASSET_BR2_202311_AST2500_FLASH = Asset( + ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' + 'images/ast2500-evb/buildroot-2023.11/flash.img'), + 'c23db6160cf77d0258397eb2051162c8473a56c441417c52a91ba217186e715f') + + def test_arm_ast2500_evb_buildroot(self): + self.set_machine('ast2500-evb') + + image_path = self.ASSET_BR2_202311_AST2500_FLASH.fetch() + + self.vm.add_args('-device', + 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); + self.do_test_arm_aspeed_buildroot_start(image_path, '0x0', + 'ast2500-evb login:') + + exec_command_and_wait_for_pattern(self, + 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', + 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon1/temp1_input', '0') + self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', + property='temperature', value=18000); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') + + self.do_test_arm_aspeed_buildroot_poweroff() + + ASSET_SDK_V806_AST2500 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz', + 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca') + + def test_arm_ast2500_evb_sdk(self): + self.set_machine('ast2500-evb') + + image_path = self.ASSET_SDK_V806_AST2500.fetch() + + archive_extract(image_path, self.workdir) + + self.do_test_arm_aspeed_sdk_start( + self.workdir + '/ast2500-default/image-bmc') + + self.wait_for_console_pattern('ast2500-default login:') + + +if __name__ == '__main__': + AspeedTest.main() diff --git a/tests/functional/test_arm_aspeed_ast2600.py b/tests/functional/test_arm_aspeed_ast2600.py new file mode 100644 index 0000000000..74d025e0fc --- /dev/null +++ b/tests/functional/test_arm_aspeed_ast2600.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import time +import tempfile +import subprocess + +from qemu_test import Asset +from aspeed import AspeedTest +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test import has_cmd +from qemu_test.utils import archive_extract +from unittest import skipUnless + +class AST2600Machine(AspeedTest): + + ASSET_BR2_202311_AST2600_FLASH = Asset( + ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' + 'images/ast2600-evb/buildroot-2023.11/flash.img'), + 'b62808daef48b438d0728ee07662290490ecfa65987bb91294cafb1bb7ad1a68') + + def test_arm_ast2600_evb_buildroot(self): + self.set_machine('ast2600-evb') + + image_path = self.ASSET_BR2_202311_AST2600_FLASH.fetch() + + self.vm.add_args('-device', + 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test'); + self.vm.add_args('-device', + 'ds1338,bus=aspeed.i2c.bus.3,address=0x32'); + self.vm.add_args('-device', + 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42'); + self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', + 'ast2600-evb login:') + + exec_command_and_wait_for_pattern(self, + 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device', + 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d'); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon1/temp1_input', '0') + self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', + property='temperature', value=18000); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon1/temp1_input', '18000') + + exec_command_and_wait_for_pattern(self, + 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device', + 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32'); + year = time.strftime("%Y") + exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year); + + exec_command_and_wait_for_pattern(self, + 'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device', + 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64'); + exec_command_and_wait_for_pattern(self, + 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#'); + exec_command_and_wait_for_pattern(self, + 'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom', + '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff'); + self.do_test_arm_aspeed_buildroot_poweroff() + + ASSET_BR2_202302_AST2600_TPM_FLASH = Asset( + ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' + 'images/ast2600-evb/buildroot-2023.02-tpm/flash.img'), + 'a46009ae8a5403a0826d607215e731a8c68d27c14c41e55331706b8f9c7bd997') + + @skipUnless(*has_cmd('swtpm')) + def test_arm_ast2600_evb_buildroot_tpm(self): + self.set_machine('ast2600-evb') + + image_path = self.ASSET_BR2_202302_AST2600_TPM_FLASH.fetch() + + tpmstate_dir = tempfile.TemporaryDirectory(prefix="qemu_") + socket = os.path.join(tpmstate_dir.name, 'swtpm-socket') + + # We must put the TPM state dir in /tmp/, not the build dir, + # because some distros use AppArmor to lock down swtpm and + # restrict the set of locations it can access files in. + subprocess.run(['swtpm', 'socket', '-d', '--tpm2', + '--tpmstate', f'dir={tpmstate_dir.name}', + '--ctrl', f'type=unixio,path={socket}']) + + self.vm.add_args('-chardev', f'socket,id=chrtpm,path={socket}') + self.vm.add_args('-tpmdev', 'emulator,id=tpm0,chardev=chrtpm') + self.vm.add_args('-device', + 'tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.12,address=0x2e') + self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00', 'Aspeed AST2600 EVB') + + exec_command_and_wait_for_pattern(self, + 'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device', + 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)'); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/tpm/tpm0/pcr-sha256/0', + 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0'); + + self.do_test_arm_aspeed_buildroot_poweroff() + + ASSET_SDK_V806_AST2600_A2 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz', + '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4') + + def test_arm_ast2600_evb_sdk(self): + self.set_machine('ast2600-evb') + + image_path = self.ASSET_SDK_V806_AST2600_A2.fetch() + + archive_extract(image_path, self.workdir) + + self.vm.add_args('-device', + 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test'); + self.vm.add_args('-device', + 'ds1338,bus=aspeed.i2c.bus.5,address=0x32'); + self.do_test_arm_aspeed_sdk_start( + self.workdir + '/ast2600-a2/image-bmc') + + self.wait_for_console_pattern('ast2600-a2 login:') + + exec_command_and_wait_for_pattern(self, 'root', 'Password:') + exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#') + + exec_command_and_wait_for_pattern(self, + 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device', + 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d'); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon19/temp1_input', '0') + self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', + property='temperature', value=18000); + exec_command_and_wait_for_pattern(self, + 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000') + + exec_command_and_wait_for_pattern(self, + 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device', + 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32'); + year = time.strftime("%Y") + exec_command_and_wait_for_pattern(self, + '/sbin/hwclock -f /dev/rtc1', year); + +if __name__ == '__main__': + AspeedTest.main() diff --git a/tests/functional/test_arm_aspeed_palmetto.py b/tests/functional/test_arm_aspeed_palmetto.py new file mode 100644 index 0000000000..6588c02aad --- /dev/null +++ b/tests/functional/test_arm_aspeed_palmetto.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import Asset +from aspeed import AspeedTest + +class PalmettoMachine(AspeedTest): + + ASSET_PALMETTO_FLASH = Asset( + ('https://github.com/openbmc/openbmc/releases/download/2.9.0/' + 'obmc-phosphor-image-palmetto.static.mtd'), + '3e13bbbc28e424865dc42f35ad672b10f2e82cdb11846bb28fa625b48beafd0d'); + + def test_arm_ast2400_palmetto_openbmc_v2_9_0(self): + image_path = self.ASSET_PALMETTO_FLASH.fetch() + + self.do_test_arm_aspeed('palmetto-bmc', image_path) + + +if __name__ == '__main__': + AspeedTest.main() diff --git a/tests/functional/test_arm_aspeed_rainier.py b/tests/functional/test_arm_aspeed_rainier.py new file mode 100644 index 0000000000..b856aea6db --- /dev/null +++ b/tests/functional/test_arm_aspeed_rainier.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import Asset +from aspeed import AspeedTest + +class RainierMachine(AspeedTest): + + ASSET_RAINIER_EMMC = Asset( + ('https://fileserver.linaro.org/s/B6pJTwWEkzSDi36/download/' + 'mmc-p10bmc-20240617.qcow2'), + 'd523fb478d2b84d5adc5658d08502bc64b1486955683814f89c6137518acd90b') + + def test_arm_aspeed_emmc_boot(self): + self.set_machine('rainier-bmc') + self.require_netdev('user') + + image_path = self.ASSET_RAINIER_EMMC.fetch() + + self.vm.set_console() + self.vm.add_args('-drive', + 'file=' + image_path + ',if=sd,id=sd2,index=2', + '-net', 'nic', '-net', 'user', '-snapshot') + self.vm.launch() + + self.wait_for_console_pattern('U-Boot SPL 2019.04') + self.wait_for_console_pattern('Trying to boot from MMC1') + self.wait_for_console_pattern('U-Boot 2019.04') + self.wait_for_console_pattern('eMMC 2nd Boot') + self.wait_for_console_pattern('## Loading kernel from FIT Image') + self.wait_for_console_pattern('Starting kernel ...') + self.wait_for_console_pattern('Booting Linux on physical CPU 0xf00') + self.wait_for_console_pattern('mmcblk0: p1 p2 p3 p4 p5 p6 p7') + self.wait_for_console_pattern('IBM eBMC (OpenBMC for IBM Enterprise') + + ASSET_DEBIAN_LINUX_ARMHF_DEB = Asset( + ('http://snapshot.debian.org/archive/debian/20220606T211338Z/pool/main/l/linux/linux-image-5.17.0-2-armmp_5.17.6-1%2Bb1_armhf.deb'), + '8acb2b4439faedc2f3ed4bdb2847ad4f6e0491f73debaeb7f660c8abe4dcdc0e') + + def test_arm_debian_kernel_boot(self): + self.set_machine('rainier-bmc') + + deb_path = self.ASSET_DEBIAN_LINUX_ARMHF_DEB.fetch() + + kernel_path = self.extract_from_deb(deb_path, '/boot/vmlinuz-5.17.0-2-armmp') + dtb_path = self.extract_from_deb(deb_path, + '/usr/lib/linux-image-5.17.0-2-armmp/aspeed-bmc-ibm-rainier.dtb') + + self.vm.set_console() + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-net', 'nic') + self.vm.launch() + + self.wait_for_console_pattern("Booting Linux on physical CPU 0xf00") + self.wait_for_console_pattern("SMP: Total of 2 processors activated") + self.wait_for_console_pattern("No filesystem could mount root") + + +if __name__ == '__main__': + AspeedTest.main() diff --git a/tests/functional/test_arm_aspeed_romulus.py b/tests/functional/test_arm_aspeed_romulus.py new file mode 100644 index 0000000000..747b616201 --- /dev/null +++ b/tests/functional/test_arm_aspeed_romulus.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# +# Functional test that boots the ASPEED machines +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import Asset +from aspeed import AspeedTest + +class RomulusMachine(AspeedTest): + + ASSET_ROMULUS_FLASH = Asset( + ('https://github.com/openbmc/openbmc/releases/download/2.9.0/' + 'obmc-phosphor-image-romulus.static.mtd'), + '820341076803f1955bc31e647a512c79f9add4f5233d0697678bab4604c7bb25') + + def test_arm_ast2500_romulus_openbmc_v2_9_0(self): + image_path = self.ASSET_ROMULUS_FLASH.fetch() + + self.do_test_arm_aspeed('romulus-bmc', image_path) + + +if __name__ == '__main__': + AspeedTest.main() diff --git a/tests/functional/test_arm_cubieboard.py b/tests/functional/test_arm_cubieboard.py new file mode 100755 index 0000000000..2b33a1b50b --- /dev/null +++ b/tests/functional/test_arm_cubieboard.py @@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel and checks the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import shutil + +from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern +from qemu_test import interrupt_interactive_console_until_pattern +from qemu_test.utils import gzip_uncompress, image_pow2ceil_expand +from unittest import skipUnless + +class CubieboardMachine(LinuxKernelTest): + + ASSET_DEB = Asset( + ('https://apt.armbian.com/pool/main/l/linux-6.6.16/' + 'linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb'), + '3d968c15b121ede871dce49d13ee7644d6f74b6b121b84c9a40f51b0c80d6d22') + + ASSET_INITRD = Asset( + ('https://github.com/groeck/linux-build-test/raw/' + '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' + 'arm/rootfs-armv5.cpio.gz'), + '334b8d256db67a3f2b3ad070aa08b5ade39624e0e7e35b02f4359a577bc8f39b') + + ASSET_SATA_ROOTFS = Asset( + ('https://github.com/groeck/linux-build-test/raw/' + '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/' + 'arm/rootfs-armv5.ext2.gz'), + '17fc750da568580b39372133051ef2f0a963c0c0b369b845614442d025701745') + + ASSET_OPENWRT = Asset( + ('https://downloads.openwrt.org/releases/22.03.2/targets/sunxi/cortexa8/' + 'openwrt-22.03.2-sunxi-cortexa8-cubietech_a10-cubieboard-ext4-sdcard.img.gz'), + '94b5ecbfbc0b3b56276e5146b899eafa2ac5dc2d08733d6705af9f144f39f554') + + def test_arm_cubieboard_initrd(self): + self.set_machine('cubieboard') + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' + dtb_path = self.extract_from_deb(deb_path, dtb_path) + initrd_path_gz = self.ASSET_INITRD.fetch() + initrd_path = os.path.join(self.workdir, 'rootfs.cpio') + gzip_uncompress(initrd_path_gz, initrd_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200 ' + 'usbcore.nousb ' + 'panic=-1 noreboot') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-initrd', initrd_path, + '-append', kernel_command_line, + '-no-reboot') + self.vm.launch() + self.wait_for_console_pattern('Boot successful.') + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun4i/sun5i') + exec_command_and_wait_for_pattern(self, 'cat /proc/iomem', + 'system-control@1c00000') + 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): + self.set_machine('cubieboard') + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-6.6.16-current-sunxi') + dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb' + dtb_path = self.extract_from_deb(deb_path, dtb_path) + + rootfs_path_gz = self.ASSET_SATA_ROOTFS.fetch() + rootfs_path = os.path.join(self.workdir, 'rootfs.cpio') + gzip_uncompress(rootfs_path_gz, rootfs_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyS0,115200 ' + 'usbcore.nousb ' + 'root=/dev/sda ro ' + 'panic=-1 noreboot') + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-drive', 'if=none,format=raw,id=disk0,file=' + + rootfs_path, + '-device', 'ide-hd,bus=ide.0,drive=disk0', + '-append', kernel_command_line, + '-no-reboot') + self.vm.launch() + self.wait_for_console_pattern('Boot successful.') + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun4i/sun5i') + exec_command_and_wait_for_pattern(self, 'cat /proc/partitions', + 'sda') + 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): + # This test download a 7.5 MiB compressed image and expand it + # to 126 MiB. + self.set_machine('cubieboard') + image_path_gz = self.ASSET_OPENWRT.fetch() + image_path = os.path.join(self.workdir, 'sdcard.img') + gzip_uncompress(image_path_gz, image_path) + image_pow2ceil_expand(image_path) + + self.vm.set_console() + self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw', + '-nic', 'user', + '-no-reboot') + self.vm.launch() + + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'usbcore.nousb ' + 'noreboot') + + self.wait_for_console_pattern('U-Boot SPL') + + interrupt_interactive_console_until_pattern( + self, 'Hit any key to stop autoboot:', '=>') + exec_command_and_wait_for_pattern(self, "setenv extraargs '" + + kernel_command_line + "'", '=>') + exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...'); + + self.wait_for_console_pattern( + 'Please press Enter to activate this console.') + + exec_command_and_wait_for_pattern(self, ' ', 'root@') + + exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', + 'Allwinner sun4i/sun5i') + exec_command_and_wait_for_pattern(self, 'reboot', + 'reboot: Restarting system') + # Wait for VM to shut down gracefully + self.vm.wait() + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_arm_emcraft_sf2.py b/tests/functional/test_arm_emcraft_sf2.py new file mode 100755 index 0000000000..ada4dfd82e --- /dev/null +++ b/tests/functional/test_arm_emcraft_sf2.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel and checks the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import shutil + +from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern +from qemu_test.utils import file_truncate + +class EmcraftSf2Machine(LinuxKernelTest): + + ASSET_UBOOT = Asset( + ('https://raw.githubusercontent.com/Subbaraya-Sundeep/qemu-test-binaries/' + 'fe371d32e50ca682391e1e70ab98c2942aeffb01/u-boot'), + '5c6a15103375db11b21f2236473679a9dbbed6d89652bfcdd501c263d68ab725') + + ASSET_SPI = Asset( + ('https://raw.githubusercontent.com/Subbaraya-Sundeep/qemu-test-binaries/' + 'fe371d32e50ca682391e1e70ab98c2942aeffb01/spi.bin'), + 'cd9bdd2c4cb55a59c3adb6bcf74881667c4500dde0570a43aa3be2b17eecfdb6') + + def test_arm_emcraft_sf2(self): + self.set_machine('emcraft-sf2') + self.require_netdev('user') + + uboot_path = self.ASSET_UBOOT.fetch() + spi_path = self.ASSET_SPI.fetch() + spi_path_rw = os.path.join(self.workdir, 'spi.bin') + shutil.copy(spi_path, spi_path_rw) + os.chmod(spi_path_rw, 0o600) + + file_truncate(spi_path_rw, 16 << 20) # Spansion S25FL128SDPBHICO is 16 MiB + + self.vm.set_console() + kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + self.vm.add_args('-kernel', uboot_path, + '-append', kernel_command_line, + '-drive', 'file=' + spi_path_rw + ',if=mtd,format=raw', + '-no-reboot') + self.vm.launch() + self.wait_for_console_pattern('Enter \'help\' for a list') + + exec_command_and_wait_for_pattern(self, 'ifconfig eth0 10.0.2.15', + 'eth0: link becomes ready') + exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2', + '3 packets transmitted, 3 packets received, 0% packet loss') + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_arm_smdkc210.py b/tests/functional/test_arm_smdkc210.py new file mode 100755 index 0000000000..967752feeb --- /dev/null +++ b/tests/functional/test_arm_smdkc210.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# +# Functional test that boots a Linux kernel and checks the console +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +import shutil + +from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern +from qemu_test.utils import gzip_uncompress + +class Smdkc210Machine(LinuxKernelTest): + + ASSET_DEB = Asset( + ('https://snapshot.debian.org/archive/debian/20190928T224601Z/pool/' + 'main/l/linux/linux-image-4.19.0-6-armmp_4.19.67-2+deb10u1_armhf.deb'), + '421804e7579ef40d554c962850dbdf1bfc79f7fa7faec9d391397170dc806c3e') + + ASSET_ROOTFS = Asset( + ('https://github.com/groeck/linux-build-test/raw/' + '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/arm/' + 'rootfs-armv5.cpio.gz'), + '334b8d256db67a3f2b3ad070aa08b5ade39624e0e7e35b02f4359a577bc8f39b') + + def test_arm_exynos4210_initrd(self): + self.set_machine('smdkc210') + + deb_path = self.ASSET_DEB.fetch() + kernel_path = self.extract_from_deb(deb_path, + '/boot/vmlinuz-4.19.0-6-armmp') + dtb_path = '/usr/lib/linux-image-4.19.0-6-armmp/exynos4210-smdkv310.dtb' + dtb_path = self.extract_from_deb(deb_path, dtb_path) + + initrd_path_gz = self.ASSET_ROOTFS.fetch() + initrd_path = os.path.join(self.workdir, 'rootfs.cpio') + gzip_uncompress(initrd_path_gz, initrd_path) + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'earlycon=exynos4210,0x13800000 earlyprintk ' + + 'console=ttySAC0,115200n8 ' + + 'random.trust_cpu=off cryptomgr.notests ' + + 'cpuidle.off=1 panic=-1 noreboot') + + self.vm.add_args('-kernel', kernel_path, + '-dtb', dtb_path, + '-initrd', initrd_path, + '-append', kernel_command_line, + '-no-reboot') + self.vm.launch() + + self.wait_for_console_pattern('Boot successful.') + # TODO user command, for now the uart is stuck + +if __name__ == '__main__': + LinuxKernelTest.main() diff --git a/tests/functional/test_m68k_mcf5208evb.py b/tests/functional/test_m68k_mcf5208evb.py index 00c59590c3..fb178fde1c 100755 --- a/tests/functional/test_m68k_mcf5208evb.py +++ b/tests/functional/test_m68k_mcf5208evb.py @@ -5,8 +5,6 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -import os - from qemu_test import LinuxKernelTest, Asset from qemu_test.utils import archive_extract diff --git a/tests/functional/test_microblaze_s3adsp1800.py b/tests/functional/test_microblaze_s3adsp1800.py index 4f692ffdb1..d2be3105a2 100755 --- a/tests/functional/test_microblaze_s3adsp1800.py +++ b/tests/functional/test_microblaze_s3adsp1800.py @@ -7,7 +7,6 @@ # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. -import time from qemu_test import exec_command, exec_command_and_wait_for_pattern from qemu_test import QemuSystemTest, Asset from qemu_test import wait_for_console_pattern diff --git a/tests/functional/test_mips64el_loongson3v.py b/tests/functional/test_mips64el_loongson3v.py index 55d62928c7..e57ec5499e 100755 --- a/tests/functional/test_mips64el_loongson3v.py +++ b/tests/functional/test_mips64el_loongson3v.py @@ -10,7 +10,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later import os -import time from unittest import skipUnless from qemu_test import QemuSystemTest, Asset diff --git a/tests/functional/test_or1k_sim.py b/tests/functional/test_or1k_sim.py index 10e0437c50..5b68b6b628 100755 --- a/tests/functional/test_or1k_sim.py +++ b/tests/functional/test_or1k_sim.py @@ -5,8 +5,6 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -import os - from qemu_test import LinuxKernelTest, Asset from qemu_test.utils import archive_extract diff --git a/tests/functional/test_ppc64_hv.py b/tests/functional/test_ppc64_hv.py index 312248bbfe..d97b62e364 100755 --- a/tests/functional/test_ppc64_hv.py +++ b/tests/functional/test_ppc64_hv.py @@ -72,10 +72,9 @@ class HypervisorTest(QemuSystemTest): cwd = os.getcwd() os.chdir(self.workdir) - with open(filename, "w") as outfile: - cmd = "xorriso -osirrox on -indev %s -cpx %s %s" % (iso, path, filename) - subprocess.run(cmd.split(), - stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + cmd = "xorriso -osirrox on -indev %s -cpx %s %s" % (iso, path, filename) + subprocess.run(cmd.split(), + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) os.chmod(filename, 0o600) os.chdir(cwd) diff --git a/tests/functional/test_s390x_topology.py b/tests/functional/test_s390x_topology.py index 20727f6bdf..c54c7a8177 100755 --- a/tests/functional/test_s390x_topology.py +++ b/tests/functional/test_s390x_topology.py @@ -11,7 +11,6 @@ # later. See the COPYING file in the top-level directory. import os -import time from qemu_test import QemuSystemTest, Asset from qemu_test import exec_command diff --git a/tests/functional/test_sh4_tuxrun.py b/tests/functional/test_sh4_tuxrun.py index b33533fc7e..1748f8c7ef 100755 --- a/tests/functional/test_sh4_tuxrun.py +++ b/tests/functional/test_sh4_tuxrun.py @@ -11,10 +11,6 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -import os -import time - -from unittest import skipUnless from qemu_test import Asset, exec_command_and_wait_for_pattern from qemu_test.tuxruntest import TuxRunBaselineTest diff --git a/tests/functional/test_sh4eb_r2d.py b/tests/functional/test_sh4eb_r2d.py index d9c022c8b8..cd46007942 100755 --- a/tests/functional/test_sh4eb_r2d.py +++ b/tests/functional/test_sh4eb_r2d.py @@ -10,7 +10,6 @@ import shutil from qemu_test import LinuxKernelTest, Asset from qemu_test import exec_command_and_wait_for_pattern from qemu_test.utils import archive_extract -from unittest import skipUnless class R2dEBTest(LinuxKernelTest): diff --git a/tests/functional/test_virtio_version.py b/tests/functional/test_virtio_version.py index 92e3f5caf0..a5ea73237f 100755 --- a/tests/functional/test_virtio_version.py +++ b/tests/functional/test_virtio_version.py @@ -9,8 +9,6 @@ Check compatibility of virtio device types # # This work is licensed under the terms of the GNU GPL, version 2 or # later. See the COPYING file in the top-level directory. -import sys -import os from qemu.machine import QEMUMachine from qemu_test import QemuSystemTest diff --git a/tests/qtest/aspeed-smc-utils.c b/tests/qtest/aspeed-smc-utils.c new file mode 100644 index 0000000000..c27d09e767 --- /dev/null +++ b/tests/qtest/aspeed-smc-utils.c @@ -0,0 +1,686 @@ +/* + * QTest testcase for the M25P80 Flash (Using the Aspeed SPI + * Controller) + * + * Copyright (C) 2016 IBM Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "libqtest-single.h" +#include "qemu/bitops.h" +#include "aspeed-smc-utils.h" + +/* + * Use an explicit bswap for the values read/wrote to the flash region + * as they are BE and the Aspeed CPU is LE. + */ +static inline uint32_t make_be32(uint32_t data) +{ + return bswap32(data); +} + +static inline void spi_writel(const AspeedSMCTestData *data, uint64_t offset, + uint32_t value) +{ + qtest_writel(data->s, data->spi_base + offset, value); +} + +static inline uint32_t spi_readl(const AspeedSMCTestData *data, uint64_t offset) +{ + return qtest_readl(data->s, data->spi_base + offset); +} + +static inline void flash_writeb(const AspeedSMCTestData *data, uint64_t offset, + uint8_t value) +{ + qtest_writeb(data->s, data->flash_base + offset, value); +} + +static inline void flash_writel(const AspeedSMCTestData *data, uint64_t offset, + uint32_t value) +{ + qtest_writel(data->s, data->flash_base + offset, value); +} + +static inline uint8_t flash_readb(const AspeedSMCTestData *data, + uint64_t offset) +{ + return qtest_readb(data->s, data->flash_base + offset); +} + +static inline uint32_t flash_readl(const AspeedSMCTestData *data, + uint64_t offset) +{ + return qtest_readl(data->s, data->flash_base + offset); +} + +static void spi_conf(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t conf = spi_readl(data, R_CONF); + + conf |= value; + spi_writel(data, R_CONF, conf); +} + +static void spi_conf_remove(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t conf = spi_readl(data, R_CONF); + + conf &= ~value; + spi_writel(data, R_CONF, conf); +} + +static void spi_ce_ctrl(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t conf = spi_readl(data, R_CE_CTRL); + + conf |= value; + spi_writel(data, R_CE_CTRL, conf); +} + +static void spi_ctrl_setmode(const AspeedSMCTestData *data, uint8_t mode, + uint8_t cmd) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + ctrl &= ~(CTRL_USERMODE | 0xff << 16); + ctrl |= mode | (cmd << 16); + spi_writel(data, ctrl_reg, ctrl); +} + +static void spi_ctrl_start_user(const AspeedSMCTestData *data) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + + ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; + spi_writel(data, ctrl_reg, ctrl); + + ctrl &= ~CTRL_CE_STOP_ACTIVE; + spi_writel(data, ctrl_reg, ctrl); +} + +static void spi_ctrl_stop_user(const AspeedSMCTestData *data) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + + ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; + spi_writel(data, ctrl_reg, ctrl); +} + +static void spi_ctrl_set_io_mode(const AspeedSMCTestData *data, uint32_t value) +{ + uint32_t ctrl_reg = R_CTRL0 + data->cs * 4; + uint32_t ctrl = spi_readl(data, ctrl_reg); + uint32_t mode; + + mode = value & CTRL_IO_MODE_MASK; + ctrl &= ~CTRL_IO_MODE_MASK; + ctrl |= mode; + spi_writel(data, ctrl_reg, ctrl); +} + +static void flash_reset(const AspeedSMCTestData *data) +{ + spi_conf(data, 1 << (CONF_ENABLE_W0 + data->cs)); + + spi_ctrl_start_user(data); + flash_writeb(data, 0, RESET_ENABLE); + flash_writeb(data, 0, RESET_MEMORY); + flash_writeb(data, 0, WREN); + flash_writeb(data, 0, BULK_ERASE); + flash_writeb(data, 0, WRDI); + spi_ctrl_stop_user(data); + + spi_conf_remove(data, 1 << (CONF_ENABLE_W0 + data->cs)); +} + +static void read_page(const AspeedSMCTestData *data, uint32_t addr, + uint32_t *page) +{ + int i; + + spi_ctrl_start_user(data); + + flash_writeb(data, 0, EN_4BYTE_ADDR); + flash_writeb(data, 0, READ); + flash_writel(data, 0, make_be32(addr)); + + /* Continuous read are supported */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + page[i] = make_be32(flash_readl(data, 0)); + } + spi_ctrl_stop_user(data); +} + +static void read_page_mem(const AspeedSMCTestData *data, uint32_t addr, + uint32_t *page) +{ + int i; + + /* move out USER mode to use direct reads from the AHB bus */ + spi_ctrl_setmode(data, CTRL_READMODE, READ); + + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + page[i] = make_be32(flash_readl(data, addr + i * 4)); + } +} + +static void write_page_mem(const AspeedSMCTestData *data, uint32_t addr, + uint32_t write_value) +{ + spi_ctrl_setmode(data, CTRL_WRITEMODE, PP); + + for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(data, addr + i * 4, write_value); + } +} + +static void assert_page_mem(const AspeedSMCTestData *data, uint32_t addr, + uint32_t expected_value) +{ + uint32_t page[FLASH_PAGE_SIZE / 4]; + read_page_mem(data, addr, page); + for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, expected_value); + } +} + +void aspeed_smc_test_read_jedec(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t jedec = 0x0; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, JEDEC_READ); + jedec |= flash_readb(test_data, 0) << 16; + jedec |= flash_readb(test_data, 0) << 8; + jedec |= flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + flash_reset(test_data); + + g_assert_cmphex(jedec, ==, test_data->jedec_id); +} + +void aspeed_smc_test_erase_sector(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t some_page_addr = test_data->page_addr; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* + * Previous page should be full of 0xffs after backend is + * initialized + */ + read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(some_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + + /* Check the page is correctly written */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, some_page_addr + i * 4); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, ERASE_SECTOR); + flash_writel(test_data, 0, make_be32(some_page_addr)); + spi_ctrl_stop_user(test_data); + + /* Check the page is erased */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_erase_all(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t some_page_addr = test_data->page_addr; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* + * Previous page should be full of 0xffs after backend is + * initialized + */ + read_page(test_data, some_page_addr - FLASH_PAGE_SIZE, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(some_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(some_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + + /* Check the page is correctly written */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, some_page_addr + i * 4); + } + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + spi_ctrl_stop_user(test_data); + + /* Check the page is erased */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_page(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + + /* Check what was written */ + read_page(test_data, my_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, my_page_addr + i * 4); + } + + /* Check some other page. It should be full of 0xff */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_read_page_mem(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + /* + * Enable 4BYTE mode for controller. + */ + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + + /* Enable 4BYTE mode for flash. */ + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); + + /* Fill the page with its own addresses */ + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); + } + spi_ctrl_stop_user(test_data); + spi_conf_remove(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* Check what was written */ + read_page_mem(test_data, my_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, my_page_addr + i * 4); + } + + /* Check some other page. It should be full of 0xff */ + read_page_mem(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_page_mem(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t page[FLASH_PAGE_SIZE / 4]; + int i; + + /* + * Enable 4BYTE mode for controller. + */ + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + + /* Enable 4BYTE mode for flash. */ + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); + + /* move out USER mode to use direct writes to the AHB bus */ + spi_ctrl_setmode(test_data, CTRL_WRITEMODE, PP); + + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, my_page_addr + i * 4, + make_be32(my_page_addr + i * 4)); + } + + /* Check what was written */ + read_page_mem(test_data, my_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, my_page_addr + i * 4); + } + + flash_reset(test_data); +} + +void aspeed_smc_test_read_status_reg(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint8_t r; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + g_assert_cmphex(r & SR_WEL, ==, 0); + g_assert(!qtest_qom_get_bool + (test_data->s, test_data->node, "write-enable")); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + g_assert_cmphex(r & SR_WEL, ==, SR_WEL); + g_assert(qtest_qom_get_bool + (test_data->s, test_data->node, "write-enable")); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WRDI); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + + g_assert_cmphex(r & SR_WEL, ==, 0); + g_assert(!qtest_qom_get_bool + (test_data->s, test_data->node, "write-enable")); + + flash_reset(test_data); +} + +void aspeed_smc_test_status_reg_write_protection(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint8_t r; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* default case: WP# is high and SRWD is low -> status register writable */ + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, SRWD); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + g_assert_cmphex(r & SRWD, ==, SRWD); + + /* WP# high and SRWD high -> status register writable */ + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, 0); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + g_assert_cmphex(r & SRWD, ==, 0); + + /* WP# low and SRWD low -> status register writable */ + qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 0); + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, SRWD); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + g_assert_cmphex(r & SRWD, ==, SRWD); + + /* WP# low and SRWD high -> status register NOT writable */ + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0 , WREN); + /* test ability to write SRWD */ + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, 0); + flash_writeb(test_data, 0, RDSR); + r = flash_readb(test_data, 0); + spi_ctrl_stop_user(test_data); + /* write is not successful */ + g_assert_cmphex(r & SRWD, ==, SRWD); + + qtest_set_irq_in(test_data->s, test_data->node, "WP#", 0, 1); + flash_reset(test_data); +} + +void aspeed_smc_test_write_block_protect(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t sector_size = 65536; + uint32_t n_sectors = 512; + + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + uint32_t bp_bits = 0b0; + + for (int i = 0; i < 16; i++) { + bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, bp_bits); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); + + uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; + uint32_t protection_start = n_sectors - num_protected_sectors; + uint32_t protection_end = n_sectors; + + for (int sector = 0; sector < n_sectors; sector++) { + uint32_t addr = sector * sector_size; + + assert_page_mem(test_data, addr, 0xffffffff); + write_page_mem(test_data, addr, make_be32(0xabcdef12)); + + uint32_t expected_value = protection_start <= sector + && sector < protection_end + ? 0xffffffff : 0xabcdef12; + + assert_page_mem(test_data, addr, expected_value); + } + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_block_protect_bottom_bit(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t sector_size = 65536; + uint32_t n_sectors = 512; + + spi_ce_ctrl(test_data, 1 << (CRTL_EXTENDED0 + test_data->cs)); + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + /* top bottom bit is enabled */ + uint32_t bp_bits = 0b00100 << 3; + + for (int i = 0; i < 16; i++) { + bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, BULK_ERASE); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, WRSR); + flash_writeb(test_data, 0, bp_bits); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + spi_ctrl_stop_user(test_data); + + uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; + uint32_t protection_start = 0; + uint32_t protection_end = num_protected_sectors; + + for (int sector = 0; sector < n_sectors; sector++) { + uint32_t addr = sector * sector_size; + + assert_page_mem(test_data, addr, 0xffffffff); + write_page_mem(test_data, addr, make_be32(0xabcdef12)); + + uint32_t expected_value = protection_start <= sector + && sector < protection_end + ? 0xffffffff : 0xabcdef12; + + assert_page_mem(test_data, addr, expected_value); + } + } + + flash_reset(test_data); +} + +void aspeed_smc_test_write_page_qpi(const void *data) +{ + const AspeedSMCTestData *test_data = (const AspeedSMCTestData *)data; + uint32_t my_page_addr = test_data->page_addr; + uint32_t some_page_addr = my_page_addr + FLASH_PAGE_SIZE; + uint32_t page[FLASH_PAGE_SIZE / 4]; + uint32_t page_pattern[] = { + 0xebd8c134, 0x5da196bc, 0xae15e729, 0x5085ccdf + }; + int i; + + spi_conf(test_data, 1 << (CONF_ENABLE_W0 + test_data->cs)); + + spi_ctrl_start_user(test_data); + flash_writeb(test_data, 0, EN_4BYTE_ADDR); + flash_writeb(test_data, 0, WREN); + flash_writeb(test_data, 0, PP); + flash_writel(test_data, 0, make_be32(my_page_addr)); + + /* Set QPI mode */ + spi_ctrl_set_io_mode(test_data, CTRL_IO_QUAD_IO); + + /* Fill the page pattern */ + for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { + flash_writel(test_data, 0, make_be32(page_pattern[i])); + } + + /* Fill the page with its own addresses */ + for (; i < FLASH_PAGE_SIZE / 4; i++) { + flash_writel(test_data, 0, make_be32(my_page_addr + i * 4)); + } + + /* Restore io mode */ + spi_ctrl_set_io_mode(test_data, 0); + spi_ctrl_stop_user(test_data); + + /* Check what was written */ + read_page(test_data, my_page_addr, page); + for (i = 0; i < ARRAY_SIZE(page_pattern); i++) { + g_assert_cmphex(page[i], ==, page_pattern[i]); + } + for (; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, my_page_addr + i * 4); + } + + /* Check some other page. It should be full of 0xff */ + read_page(test_data, some_page_addr, page); + for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { + g_assert_cmphex(page[i], ==, 0xffffffff); + } + + flash_reset(test_data); +} + diff --git a/tests/qtest/aspeed-smc-utils.h b/tests/qtest/aspeed-smc-utils.h new file mode 100644 index 0000000000..b07870f3b8 --- /dev/null +++ b/tests/qtest/aspeed-smc-utils.h @@ -0,0 +1,95 @@ +/* + * QTest testcase for the M25P80 Flash (Using the Aspeed SPI + * Controller) + * + * Copyright (C) 2016 IBM Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef TESTS_ASPEED_SMC_UTILS_H +#define TESTS_ASPEED_SMC_UTILS_H + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "libqtest-single.h" +#include "qemu/bitops.h" + +/* + * ASPEED SPI Controller registers + */ +#define R_CONF 0x00 +#define CONF_ENABLE_W0 16 +#define R_CE_CTRL 0x04 +#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */ +#define R_CTRL0 0x10 +#define CTRL_IO_QUAD_IO BIT(31) +#define CTRL_CE_STOP_ACTIVE BIT(2) +#define CTRL_READMODE 0x0 +#define CTRL_FREADMODE 0x1 +#define CTRL_WRITEMODE 0x2 +#define CTRL_USERMODE 0x3 +#define SR_WEL BIT(1) + +/* + * Flash commands + */ +enum { + JEDEC_READ = 0x9f, + RDSR = 0x5, + WRDI = 0x4, + BULK_ERASE = 0xc7, + READ = 0x03, + PP = 0x02, + WRSR = 0x1, + WREN = 0x6, + SRWD = 0x80, + RESET_ENABLE = 0x66, + RESET_MEMORY = 0x99, + EN_4BYTE_ADDR = 0xB7, + ERASE_SECTOR = 0xd8, +}; + +#define CTRL_IO_MODE_MASK (BIT(31) | BIT(30) | BIT(29) | BIT(28)) +#define FLASH_PAGE_SIZE 256 + +typedef struct AspeedSMCTestData { + QTestState *s; + uint64_t spi_base; + uint64_t flash_base; + uint32_t jedec_id; + char *tmp_path; + uint8_t cs; + const char *node; + uint32_t page_addr; +} AspeedSMCTestData; + +void aspeed_smc_test_read_jedec(const void *data); +void aspeed_smc_test_erase_sector(const void *data); +void aspeed_smc_test_erase_all(const void *data); +void aspeed_smc_test_write_page(const void *data); +void aspeed_smc_test_read_page_mem(const void *data); +void aspeed_smc_test_write_page_mem(const void *data); +void aspeed_smc_test_read_status_reg(const void *data); +void aspeed_smc_test_status_reg_write_protection(const void *data); +void aspeed_smc_test_write_block_protect(const void *data); +void aspeed_smc_test_write_block_protect_bottom_bit(const void *data); +void aspeed_smc_test_write_page_qpi(const void *data); + +#endif /* TESTS_ASPEED_SMC_UTILS_H */ diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c index 4673371d95..4e1389385d 100644 --- a/tests/qtest/aspeed_smc-test.c +++ b/tests/qtest/aspeed_smc-test.c @@ -27,625 +27,206 @@ #include "qemu/bswap.h" #include "libqtest-single.h" #include "qemu/bitops.h" +#include "aspeed-smc-utils.h" -/* - * ASPEED SPI Controller registers - */ -#define R_CONF 0x00 -#define CONF_ENABLE_W0 (1 << 16) -#define R_CE_CTRL 0x04 -#define CRTL_EXTENDED0 0 /* 32 bit addressing for SPI */ -#define R_CTRL0 0x10 -#define CTRL_CE_STOP_ACTIVE (1 << 2) -#define CTRL_READMODE 0x0 -#define CTRL_FREADMODE 0x1 -#define CTRL_WRITEMODE 0x2 -#define CTRL_USERMODE 0x3 -#define SR_WEL BIT(1) - -#define ASPEED_FMC_BASE 0x1E620000 -#define ASPEED_FLASH_BASE 0x20000000 - -/* - * Flash commands - */ -enum { - JEDEC_READ = 0x9f, - RDSR = 0x5, - WRDI = 0x4, - BULK_ERASE = 0xc7, - READ = 0x03, - PP = 0x02, - WRSR = 0x1, - WREN = 0x6, - SRWD = 0x80, - RESET_ENABLE = 0x66, - RESET_MEMORY = 0x99, - EN_4BYTE_ADDR = 0xB7, - ERASE_SECTOR = 0xd8, -}; - -#define FLASH_JEDEC 0x20ba19 /* n25q256a */ -#define FLASH_SIZE (32 * 1024 * 1024) - -#define FLASH_PAGE_SIZE 256 - -/* - * Use an explicit bswap for the values read/wrote to the flash region - * as they are BE and the Aspeed CPU is LE. - */ -static inline uint32_t make_be32(uint32_t data) -{ - return bswap32(data); -} - -static void spi_conf(uint32_t value) -{ - uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF); - - conf |= value; - writel(ASPEED_FMC_BASE + R_CONF, conf); -} - -static void spi_conf_remove(uint32_t value) -{ - uint32_t conf = readl(ASPEED_FMC_BASE + R_CONF); - - conf &= ~value; - writel(ASPEED_FMC_BASE + R_CONF, conf); -} - -static void spi_ce_ctrl(uint32_t value) -{ - uint32_t conf = readl(ASPEED_FMC_BASE + R_CE_CTRL); - - conf |= value; - writel(ASPEED_FMC_BASE + R_CE_CTRL, conf); -} - -static void spi_ctrl_setmode(uint8_t mode, uint8_t cmd) -{ - uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0); - ctrl &= ~(CTRL_USERMODE | 0xff << 16); - ctrl |= mode | (cmd << 16); - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); -} - -static void spi_ctrl_start_user(void) -{ - uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0); - - ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); - - ctrl &= ~CTRL_CE_STOP_ACTIVE; - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); -} - -static void spi_ctrl_stop_user(void) -{ - uint32_t ctrl = readl(ASPEED_FMC_BASE + R_CTRL0); - - ctrl |= CTRL_USERMODE | CTRL_CE_STOP_ACTIVE; - writel(ASPEED_FMC_BASE + R_CTRL0, ctrl); -} - -static void flash_reset(void) -{ - spi_conf(CONF_ENABLE_W0); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, RESET_ENABLE); - writeb(ASPEED_FLASH_BASE, RESET_MEMORY); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - writeb(ASPEED_FLASH_BASE, WRDI); - spi_ctrl_stop_user(); - - spi_conf_remove(CONF_ENABLE_W0); -} - -static void test_read_jedec(void) -{ - uint32_t jedec = 0x0; - - spi_conf(CONF_ENABLE_W0); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, JEDEC_READ); - jedec |= readb(ASPEED_FLASH_BASE) << 16; - jedec |= readb(ASPEED_FLASH_BASE) << 8; - jedec |= readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - - flash_reset(); - - g_assert_cmphex(jedec, ==, FLASH_JEDEC); -} - -static void read_page(uint32_t addr, uint32_t *page) -{ - int i; - - spi_ctrl_start_user(); - - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, READ); - writel(ASPEED_FLASH_BASE, make_be32(addr)); - - /* Continuous read are supported */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - page[i] = make_be32(readl(ASPEED_FLASH_BASE)); - } - spi_ctrl_stop_user(); -} - -static void read_page_mem(uint32_t addr, uint32_t *page) -{ - int i; - - /* move out USER mode to use direct reads from the AHB bus */ - spi_ctrl_setmode(CTRL_READMODE, READ); - - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - page[i] = make_be32(readl(ASPEED_FLASH_BASE + addr + i * 4)); - } -} - -static void write_page_mem(uint32_t addr, uint32_t write_value) -{ - spi_ctrl_setmode(CTRL_WRITEMODE, PP); - - for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE + addr + i * 4, write_value); - } -} - -static void assert_page_mem(uint32_t addr, uint32_t expected_value) -{ - uint32_t page[FLASH_PAGE_SIZE / 4]; - read_page_mem(addr, page); - for (int i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, expected_value); - } -} - -static void test_erase_sector(void) -{ - uint32_t some_page_addr = 0x600 * FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - spi_conf(CONF_ENABLE_W0); - - /* - * Previous page should be full of 0xffs after backend is - * initialized - */ - read_page(some_page_addr - FLASH_PAGE_SIZE, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr + i * 4)); - } - spi_ctrl_stop_user(); - - /* Check the page is correctly written */ - read_page(some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, some_page_addr + i * 4); - } - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, ERASE_SECTOR); - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr)); - spi_ctrl_stop_user(); - - /* Check the page is erased */ - read_page(some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(); -} - -static void test_erase_all(void) -{ - uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - spi_conf(CONF_ENABLE_W0); - - /* - * Previous page should be full of 0xffs after backend is - * initialized - */ - read_page(some_page_addr - FLASH_PAGE_SIZE, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(some_page_addr + i * 4)); - } - spi_ctrl_stop_user(); - - /* Check the page is correctly written */ - read_page(some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, some_page_addr + i * 4); - } - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - spi_ctrl_stop_user(); - - /* Check the page is erased */ - read_page(some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(); -} - -static void test_write_page(void) -{ - uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */ - uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - spi_conf(CONF_ENABLE_W0); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr + i * 4)); - } - spi_ctrl_stop_user(); - - /* Check what was written */ - read_page(my_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, my_page_addr + i * 4); - } - - /* Check some other page. It should be full of 0xff */ - read_page(some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(); -} - -static void test_read_page_mem(void) -{ - uint32_t my_page_addr = 0x14000 * FLASH_PAGE_SIZE; /* beyond 16MB */ - uint32_t some_page_addr = 0x15000 * FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - /* - * Enable 4BYTE mode for controller. This is should be strapped by - * HW for CE0 anyhow. - */ - spi_ce_ctrl(1 << CRTL_EXTENDED0); - - /* Enable 4BYTE mode for flash. */ - spi_conf(CONF_ENABLE_W0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, PP); - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr)); - - /* Fill the page with its own addresses */ - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE, make_be32(my_page_addr + i * 4)); - } - spi_ctrl_stop_user(); - spi_conf_remove(CONF_ENABLE_W0); - - /* Check what was written */ - read_page_mem(my_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, my_page_addr + i * 4); - } - - /* Check some other page. It should be full of 0xff */ - read_page_mem(some_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, 0xffffffff); - } - - flash_reset(); -} - -static void test_write_page_mem(void) -{ - uint32_t my_page_addr = 0x15000 * FLASH_PAGE_SIZE; - uint32_t page[FLASH_PAGE_SIZE / 4]; - int i; - - /* - * Enable 4BYTE mode for controller. This is should be strapped by - * HW for CE0 anyhow. - */ - spi_ce_ctrl(1 << CRTL_EXTENDED0); - - /* Enable 4BYTE mode for flash. */ - spi_conf(CONF_ENABLE_W0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - spi_ctrl_stop_user(); - - /* move out USER mode to use direct writes to the AHB bus */ - spi_ctrl_setmode(CTRL_WRITEMODE, PP); - - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - writel(ASPEED_FLASH_BASE + my_page_addr + i * 4, - make_be32(my_page_addr + i * 4)); - } - - /* Check what was written */ - read_page_mem(my_page_addr, page); - for (i = 0; i < FLASH_PAGE_SIZE / 4; i++) { - g_assert_cmphex(page[i], ==, my_page_addr + i * 4); - } - - flash_reset(); -} - -static void test_read_status_reg(void) +static void test_palmetto_bmc(AspeedSMCTestData *data) { - uint8_t r; - - spi_conf(CONF_ENABLE_W0); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - - g_assert_cmphex(r & SR_WEL, ==, 0); - g_assert(!qtest_qom_get_bool - (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - - g_assert_cmphex(r & SR_WEL, ==, SR_WEL); - g_assert(qtest_qom_get_bool - (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WRDI); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - - g_assert_cmphex(r & SR_WEL, ==, 0); - g_assert(!qtest_qom_get_bool - (global_qtest, "/machine/soc/fmc/ssi.0/child[0]", "write-enable")); + int ret; + int fd; - flash_reset(); -} + fd = g_file_open_tmp("qtest.m25p80.n25q256a.XXXXXX", &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 32 * 1024 * 1024); + g_assert(ret == 0); + close(fd); -static void test_status_reg_write_protection(void) + data->s = qtest_initf("-m 256 -machine palmetto-bmc " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with n25q256a flash */ + data->flash_base = 0x20000000; + data->spi_base = 0x1E620000; + data->jedec_id = 0x20ba19; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 16MB */ + data->page_addr = 0x14000 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast2400/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2400/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2400/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2400/smc/write_page", + data, aspeed_smc_test_write_page); + qtest_add_data_func("/ast2400/smc/read_page_mem", + data, aspeed_smc_test_read_page_mem); + qtest_add_data_func("/ast2400/smc/write_page_mem", + data, aspeed_smc_test_write_page_mem); + qtest_add_data_func("/ast2400/smc/read_status_reg", + data, aspeed_smc_test_read_status_reg); + qtest_add_data_func("/ast2400/smc/status_reg_write_protection", + data, aspeed_smc_test_status_reg_write_protection); + qtest_add_data_func("/ast2400/smc/write_block_protect", + data, aspeed_smc_test_write_block_protect); + qtest_add_data_func("/ast2400/smc/write_block_protect_bottom_bit", + data, aspeed_smc_test_write_block_protect_bottom_bit); +} + +static void test_ast2500_evb(AspeedSMCTestData *data) { - uint8_t r; - - spi_conf(CONF_ENABLE_W0); - - /* default case: WP# is high and SRWD is low -> status register writable */ - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, SRWD); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - g_assert_cmphex(r & SRWD, ==, SRWD); - - /* WP# high and SRWD high -> status register writable */ - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, 0); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - g_assert_cmphex(r & SRWD, ==, 0); - - /* WP# low and SRWD low -> status register writable */ - qtest_set_irq_in(global_qtest, - "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 0); - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, SRWD); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - g_assert_cmphex(r & SRWD, ==, SRWD); - - /* WP# low and SRWD high -> status register NOT writable */ - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - /* test ability to write SRWD */ - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, 0); - writeb(ASPEED_FLASH_BASE, RDSR); - r = readb(ASPEED_FLASH_BASE); - spi_ctrl_stop_user(); - /* write is not successful */ - g_assert_cmphex(r & SRWD, ==, SRWD); + int ret; + int fd; - qtest_set_irq_in(global_qtest, - "/machine/soc/fmc/ssi.0/child[0]", "WP#", 0, 1); - flash_reset(); -} + fd = g_file_open_tmp("qtest.m25p80.mx25l25635e.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 32 * 1024 * 1024); + g_assert(ret == 0); + close(fd); -static void test_write_block_protect(void) + data->s = qtest_initf("-machine ast2500-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with mx25l25635e flash */ + data->flash_base = 0x20000000; + data->spi_base = 0x1E620000; + data->jedec_id = 0xc22019; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 16MB */ + data->page_addr = 0x14000 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast2500/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2500/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2500/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2500/smc/write_page", + data, aspeed_smc_test_write_page); + qtest_add_data_func("/ast2500/smc/read_page_mem", + data, aspeed_smc_test_read_page_mem); + qtest_add_data_func("/ast2500/smc/write_page_mem", + data, aspeed_smc_test_write_page_mem); + qtest_add_data_func("/ast2500/smc/read_status_reg", + data, aspeed_smc_test_read_status_reg); + qtest_add_data_func("/ast2500/smc/write_page_qpi", + data, aspeed_smc_test_write_page_qpi); +} + +static void test_ast2600_evb(AspeedSMCTestData *data) { - uint32_t sector_size = 65536; - uint32_t n_sectors = 512; - - spi_ce_ctrl(1 << CRTL_EXTENDED0); - spi_conf(CONF_ENABLE_W0); - - uint32_t bp_bits = 0b0; - - for (int i = 0; i < 16; i++) { - bp_bits = ((i & 0b1000) << 3) | ((i & 0b0111) << 2); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, bp_bits); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - spi_ctrl_stop_user(); - - uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; - uint32_t protection_start = n_sectors - num_protected_sectors; - uint32_t protection_end = n_sectors; - - for (int sector = 0; sector < n_sectors; sector++) { - uint32_t addr = sector * sector_size; - - assert_page_mem(addr, 0xffffffff); - write_page_mem(addr, make_be32(0xabcdef12)); - - uint32_t expected_value = protection_start <= sector - && sector < protection_end - ? 0xffffffff : 0xabcdef12; - - assert_page_mem(addr, expected_value); - } - } + int ret; + int fd; - flash_reset(); -} + fd = g_file_open_tmp("qtest.m25p80.mx66u51235f.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 64 * 1024 * 1024); + g_assert(ret == 0); + close(fd); -static void test_write_block_protect_bottom_bit(void) + data->s = qtest_initf("-machine ast2600-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with mx66u51235f flash */ + data->flash_base = 0x20000000; + data->spi_base = 0x1E620000; + data->jedec_id = 0xc2253a; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 16MB */ + data->page_addr = 0x14000 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast2600/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2600/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2600/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2600/smc/write_page", + data, aspeed_smc_test_write_page); + qtest_add_data_func("/ast2600/smc/read_page_mem", + data, aspeed_smc_test_read_page_mem); + qtest_add_data_func("/ast2600/smc/write_page_mem", + data, aspeed_smc_test_write_page_mem); + qtest_add_data_func("/ast2600/smc/read_status_reg", + data, aspeed_smc_test_read_status_reg); + qtest_add_data_func("/ast2600/smc/write_page_qpi", + data, aspeed_smc_test_write_page_qpi); +} + +static void test_ast1030_evb(AspeedSMCTestData *data) { - uint32_t sector_size = 65536; - uint32_t n_sectors = 512; - - spi_ce_ctrl(1 << CRTL_EXTENDED0); - spi_conf(CONF_ENABLE_W0); - - /* top bottom bit is enabled */ - uint32_t bp_bits = 0b00100 << 3; - - for (int i = 0; i < 16; i++) { - bp_bits = (((i & 0b1000) | 0b0100) << 3) | ((i & 0b0111) << 2); - - spi_ctrl_start_user(); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, BULK_ERASE); - writeb(ASPEED_FLASH_BASE, WREN); - writeb(ASPEED_FLASH_BASE, WRSR); - writeb(ASPEED_FLASH_BASE, bp_bits); - writeb(ASPEED_FLASH_BASE, EN_4BYTE_ADDR); - writeb(ASPEED_FLASH_BASE, WREN); - spi_ctrl_stop_user(); - - uint32_t num_protected_sectors = i ? MIN(1 << (i - 1), n_sectors) : 0; - uint32_t protection_start = 0; - uint32_t protection_end = num_protected_sectors; - - for (int sector = 0; sector < n_sectors; sector++) { - uint32_t addr = sector * sector_size; - - assert_page_mem(addr, 0xffffffff); - write_page_mem(addr, make_be32(0xabcdef12)); - - uint32_t expected_value = protection_start <= sector - && sector < protection_end - ? 0xffffffff : 0xabcdef12; + int ret; + int fd; - assert_page_mem(addr, expected_value); - } - } + fd = g_file_open_tmp("qtest.m25p80.w25q80bl.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 1 * 1024 * 1024); + g_assert(ret == 0); + close(fd); - flash_reset(); + data->s = qtest_initf("-machine ast1030-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with w25q80bl flash */ + data->flash_base = 0x80000000; + data->spi_base = 0x7E620000; + data->jedec_id = 0xef4014; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 512KB */ + data->page_addr = 0x800 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast1030/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast1030/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast1030/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast1030/smc/write_page", + data, aspeed_smc_test_write_page); + qtest_add_data_func("/ast1030/smc/read_page_mem", + data, aspeed_smc_test_read_page_mem); + qtest_add_data_func("/ast1030/smc/write_page_mem", + data, aspeed_smc_test_write_page_mem); + qtest_add_data_func("/ast1030/smc/read_status_reg", + data, aspeed_smc_test_read_status_reg); + qtest_add_data_func("/ast1030/smc/write_page_qpi", + data, aspeed_smc_test_write_page_qpi); } int main(int argc, char **argv) { - g_autofree char *tmp_path = NULL; + AspeedSMCTestData palmetto_data; + AspeedSMCTestData ast2500_evb_data; + AspeedSMCTestData ast2600_evb_data; + AspeedSMCTestData ast1030_evb_data; int ret; - int fd; g_test_init(&argc, &argv, NULL); - fd = g_file_open_tmp("qtest.m25p80.XXXXXX", &tmp_path, NULL); - g_assert(fd >= 0); - ret = ftruncate(fd, FLASH_SIZE); - g_assert(ret == 0); - close(fd); - - global_qtest = qtest_initf("-m 256 -machine palmetto-bmc " - "-drive file=%s,format=raw,if=mtd", - tmp_path); - - qtest_add_func("/ast2400/smc/read_jedec", test_read_jedec); - qtest_add_func("/ast2400/smc/erase_sector", test_erase_sector); - qtest_add_func("/ast2400/smc/erase_all", test_erase_all); - qtest_add_func("/ast2400/smc/write_page", test_write_page); - qtest_add_func("/ast2400/smc/read_page_mem", test_read_page_mem); - qtest_add_func("/ast2400/smc/write_page_mem", test_write_page_mem); - qtest_add_func("/ast2400/smc/read_status_reg", test_read_status_reg); - qtest_add_func("/ast2400/smc/status_reg_write_protection", - test_status_reg_write_protection); - qtest_add_func("/ast2400/smc/write_block_protect", - test_write_block_protect); - qtest_add_func("/ast2400/smc/write_block_protect_bottom_bit", - test_write_block_protect_bottom_bit); - - flash_reset(); + test_palmetto_bmc(&palmetto_data); + test_ast2500_evb(&ast2500_evb_data); + test_ast2600_evb(&ast2600_evb_data); + test_ast1030_evb(&ast1030_evb_data); ret = g_test_run(); - qtest_quit(global_qtest); - unlink(tmp_path); + qtest_quit(palmetto_data.s); + qtest_quit(ast2500_evb_data.s); + qtest_quit(ast2600_evb_data.s); + qtest_quit(ast1030_evb_data.s); + unlink(palmetto_data.tmp_path); + unlink(ast2500_evb_data.tmp_path); + unlink(ast2600_evb_data.tmp_path); + unlink(ast1030_evb_data.tmp_path); return ret; } diff --git a/tests/qtest/ast2700-smc-test.c b/tests/qtest/ast2700-smc-test.c new file mode 100644 index 0000000000..d1c4856307 --- /dev/null +++ b/tests/qtest/ast2700-smc-test.c @@ -0,0 +1,71 @@ +/* + * QTest testcase for the M25P80 Flash using the ASPEED SPI Controller since + * AST2700. + * + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (C) 2024 ASPEED Technology Inc. + */ + +#include "qemu/osdep.h" +#include "qemu/bswap.h" +#include "libqtest-single.h" +#include "qemu/bitops.h" +#include "aspeed-smc-utils.h" + +static void test_ast2700_evb(AspeedSMCTestData *data) +{ + int ret; + int fd; + + fd = g_file_open_tmp("qtest.m25p80.w25q01jvq.XXXXXX", + &data->tmp_path, NULL); + g_assert(fd >= 0); + ret = ftruncate(fd, 128 * 1024 * 1024); + g_assert(ret == 0); + close(fd); + + data->s = qtest_initf("-machine ast2700-evb " + "-drive file=%s,format=raw,if=mtd", + data->tmp_path); + + /* fmc cs0 with w25q01jvq flash */ + data->flash_base = 0x100000000; + data->spi_base = 0x14000000; + data->jedec_id = 0xef4021; + data->cs = 0; + data->node = "/machine/soc/fmc/ssi.0/child[0]"; + /* beyond 64MB */ + data->page_addr = 0x40000 * FLASH_PAGE_SIZE; + + qtest_add_data_func("/ast2700/smc/read_jedec", + data, aspeed_smc_test_read_jedec); + qtest_add_data_func("/ast2700/smc/erase_sector", + data, aspeed_smc_test_erase_sector); + qtest_add_data_func("/ast2700/smc/erase_all", + data, aspeed_smc_test_erase_all); + qtest_add_data_func("/ast2700/smc/write_page", + data, aspeed_smc_test_write_page); + qtest_add_data_func("/ast2700/smc/read_page_mem", + data, aspeed_smc_test_read_page_mem); + qtest_add_data_func("/ast2700/smc/write_page_mem", + data, aspeed_smc_test_write_page_mem); + qtest_add_data_func("/ast2700/smc/read_status_reg", + data, aspeed_smc_test_read_status_reg); + qtest_add_data_func("/ast2700/smc/write_page_qpi", + data, aspeed_smc_test_write_page_qpi); +} + +int main(int argc, char **argv) +{ + AspeedSMCTestData ast2700_evb_data; + int ret; + + g_test_init(&argc, &argv, NULL); + + test_ast2700_evb(&ast2700_evb_data); + ret = g_test_run(); + + qtest_quit(ast2700_evb_data.s); + unlink(ast2700_evb_data.tmp_path); + return ret; +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index bd41c9da5f..89db3ecf2f 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -214,7 +214,8 @@ qtests_aspeed = \ 'aspeed_smc-test', 'aspeed_gpio-test'] qtests_aspeed64 = \ - ['ast2700-gpio-test'] + ['ast2700-gpio-test', + 'ast2700-smc-test'] qtests_stm32l4x5 = \ ['stm32l4x5_exti-test', @@ -360,6 +361,8 @@ qtests = { 'virtio-net-failover': files('migration-helpers.c'), 'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'), 'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'), + 'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'), + 'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'), } if vnc.found() |