diff options
Diffstat (limited to 'include/hw')
306 files changed, 5173 insertions, 3005 deletions
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index 0e6e82b..2e6e341 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -112,7 +112,6 @@ typedef struct AcpiSpcrData { uint8_t flow_control; uint8_t terminal_type; uint8_t language; - uint8_t reserved1; uint16_t pci_device_id; /* Must be 0xffff if not PCI device */ uint16_t pci_vendor_id; /* Must be 0xffff if not PCI device */ uint8_t pci_bus; @@ -120,7 +119,11 @@ typedef struct AcpiSpcrData { uint8_t pci_function; uint32_t pci_flags; uint8_t pci_segment; - uint32_t reserved2; + uint32_t uart_clk_freq; + uint32_t precise_baudrate; + uint32_t namespace_string_length; + uint32_t namespace_string_offset; + char namespace_string[]; } AcpiSpcrData; #define ACPI_FADT_ARM_PSCI_COMPLIANT (1 << 0) diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index e0e51e8..4b8ee09 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -21,7 +21,7 @@ */ #include "qemu/notify.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/acpi/acpi_dev_interface.h" /* @@ -150,6 +150,9 @@ struct ACPIREGS { Notifier wakeup; }; +/* Return whether ACPI subsystem is built in */ +bool acpi_builtin(void); + /* PM_TMR */ void acpi_pm_tmr_update(ACPIREGS *ar, bool enable); void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar); diff --git a/include/hw/acpi/acpi_generic_initiator.h b/include/hw/acpi/acpi_generic_initiator.h deleted file mode 100644 index a304bad..0000000 --- a/include/hw/acpi/acpi_generic_initiator.h +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved - */ - -#ifndef ACPI_GENERIC_INITIATOR_H -#define ACPI_GENERIC_INITIATOR_H - -#include "qom/object_interfaces.h" - -#define TYPE_ACPI_GENERIC_INITIATOR "acpi-generic-initiator" - -typedef struct AcpiGenericInitiator { - /* private */ - Object parent; - - /* public */ - char *pci_dev; - uint16_t node; -} AcpiGenericInitiator; - -/* - * ACPI 6.3: - * Table 5-81 Flags – Generic Initiator Affinity Structure - */ -typedef enum { - /* - * If clear, the OSPM ignores the contents of the Generic - * Initiator/Port Affinity Structure. This allows system firmware - * to populate the SRAT with a static number of structures, but only - * enable them as necessary. - */ - GEN_AFFINITY_ENABLED = (1 << 0), -} GenericAffinityFlags; - -/* - * ACPI 6.3: - * Table 5-80 Device Handle - PCI - */ -typedef struct PCIDeviceHandle { - uint16_t segment; - uint16_t bdf; -} PCIDeviceHandle; - -void build_srat_generic_pci_initiator(GArray *table_data); - -#endif diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index a378415..c18f681 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -486,6 +486,13 @@ Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set, uint32_t io_offset, void build_srat_memory(GArray *table_data, uint64_t base, uint64_t len, int node, MemoryAffinityFlags flags); +void build_srat_pci_generic_initiator(GArray *table_data, uint32_t node, + uint16_t segment, uint8_t bus, + uint8_t devfn); + +void build_srat_acpi_generic_port(GArray *table_data, uint32_t node, + const char *hid, uint32_t uid); + void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms, const char *oem_id, const char *oem_table_id); @@ -500,5 +507,5 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog, void build_spcr(GArray *table_data, BIOSLinker *linker, const AcpiSpcrData *f, const uint8_t rev, - const char *oem_id, const char *oem_table_id); + const char *oem_id, const char *oem_table_id, const char *name); #endif diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h index 40af355..d2dac87 100644 --- a/include/hw/acpi/generic_event_device.h +++ b/include/hw/acpi/generic_event_device.h @@ -81,8 +81,11 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) /* ACPI_GED_REG_RESET value for reset*/ #define ACPI_GED_RESET_VALUE 0x42 -/* ACPI_GED_REG_SLEEP_CTL.SLP_TYP value for S5 (aka poweroff) */ -#define ACPI_GED_SLP_TYP_S5 0x05 +/* [ACPI 5.0 Chapter 4.8.3.7] Sleep Control and Status Register */ +#define ACPI_GED_SLP_TYP_POS 0x2 /* SLP_TYPx Bit Offset */ +#define ACPI_GED_SLP_TYP_MASK 0x07 /* SLP_TYPx 3-bit mask */ +#define ACPI_GED_SLP_TYP_S5 0x05 /* System _S5 State (Soft Off) */ +#define ACPI_GED_SLP_EN 0x20 /* SLP_EN write-only bit */ #define GED_DEVICE "GED" #define AML_GED_EVT_REG "EREG" diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h index 674f695..578a582 100644 --- a/include/hw/acpi/ghes.h +++ b/include/hw/acpi/ghes.h @@ -23,6 +23,7 @@ #define ACPI_GHES_H #include "hw/acpi/bios-linker-loader.h" +#include "qapi/error.h" /* * Values for Hardware Error Notification Type field @@ -59,26 +60,27 @@ enum AcpiGhesNotifyType { enum { ACPI_HEST_SRC_ID_SEA = 0, /* future ids go here */ - ACPI_HEST_SRC_ID_RESERVED, + + ACPI_GHES_ERROR_SOURCE_COUNT }; typedef struct AcpiGhesState { - uint64_t ghes_addr_le; + uint64_t hw_error_le; bool present; /* True if GHES is present at all on this board */ } AcpiGhesState; -void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker); -void acpi_build_hest(GArray *table_data, BIOSLinker *linker, +void acpi_build_hest(GArray *table_data, GArray *hardware_errors, + BIOSLinker *linker, const char *oem_id, const char *oem_table_id); void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s, GArray *hardware_errors); -int acpi_ghes_record_errors(uint8_t notify, uint64_t error_physical_addr); +int acpi_ghes_memory_errors(uint16_t source_id, uint64_t error_physical_addr); /** * acpi_ghes_present: Report whether ACPI GHES table is present * * Returns: true if the system has an ACPI GHES table and it is - * safe to call acpi_ghes_record_errors() to record a memory error. + * safe to call acpi_ghes_memory_errors() to record a memory error. */ bool acpi_ghes_present(void); #endif diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 2faf7f0..245fe08 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -46,6 +46,7 @@ typedef struct ICH9LPCPMRegs { uint32_t smi_en; uint32_t smi_en_wmask; uint32_t smi_sts; + uint32_t smi_sts_wmask; qemu_irq irq; /* SCI */ @@ -68,6 +69,11 @@ typedef struct ICH9LPCPMRegs { bool smm_compat; bool enable_tco; TCOIORegs tco_regs; + + bool swsmi_timer_enabled; + bool periodic_timer_enabled; + QEMUTimer *swsmi_timer; + QEMUTimer *periodic_timer; } ICH9LPCPMRegs; #define ACPI_PM_PROP_TCO_ENABLED "enable_tco" diff --git a/include/hw/acpi/ich9_tco.h b/include/hw/acpi/ich9_tco.h index 2562a7c..b3c3f69 100644 --- a/include/hw/acpi/ich9_tco.h +++ b/include/hw/acpi/ich9_tco.h @@ -10,7 +10,7 @@ #ifndef HW_ACPI_TCO_H #define HW_ACPI_TCO_H -#include "exec/memory.h" +#include "system/memory.h" #include "migration/vmstate.h" /* As per ICH9 spec, the internal timer has an error of ~0.6s on every tick */ diff --git a/include/hw/acpi/ich9_timer.h b/include/hw/acpi/ich9_timer.h new file mode 100644 index 0000000..5112df4 --- /dev/null +++ b/include/hw/acpi/ich9_timer.h @@ -0,0 +1,23 @@ +/* + * QEMU ICH9 Timer emulation + * + * Copyright (c) 2024 Dominic Prinz <git@dprinz.de> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_ACPI_ICH9_TIMER_H +#define HW_ACPI_ICH9_TIMER_H + +#include "hw/acpi/ich9.h" + +void ich9_pm_update_swsmi_timer(ICH9LPCPMRegs *pm, bool enable); + +void ich9_pm_swsmi_timer_init(ICH9LPCPMRegs *pm); + +void ich9_pm_update_periodic_timer(ICH9LPCPMRegs *pm, bool enable); + +void ich9_pm_periodic_timer_init(ICH9LPCPMRegs *pm); + +#endif diff --git a/include/hw/acpi/pci.h b/include/hw/acpi/pci.h index 467a994..6359d57 100644 --- a/include/hw/acpi/pci.h +++ b/include/hw/acpi/pci.h @@ -40,4 +40,7 @@ Aml *aml_pci_device_dsm(void); void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus); void build_pci_bridge_aml(AcpiDevAmlIf *adev, Aml *scope); + +void build_srat_generic_affinity_structures(GArray *table_data); + #endif diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h index ac21a95..cdc0cb8 100644 --- a/include/hw/acpi/pcihp.h +++ b/include/hw/acpi/pcihp.h @@ -3,7 +3,7 @@ * * QEMU supports PCI hotplug via ACPI. This module * implements the interface between QEMU and the ACPI BIOS. - * Interface specification - see docs/specs/acpi_pci_hotplug.txt + * Interface specification - see docs/specs/acpi_pci_hotplug.rst * * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com) * Copyright (c) 2006 Fabrice Bellard @@ -58,7 +58,7 @@ typedef struct AcpiPciHpState { void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root, MemoryRegion *io, uint16_t io_base); -bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus); +bool acpi_pcihp_is_hotpluggable_bus(AcpiPciHpState *s, BusState *bus); void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, diff --git a/include/hw/acpi/tpm.h b/include/hw/acpi/tpm.h index 579c45f..9d0fe6f 100644 --- a/include/hw/acpi/tpm.h +++ b/include/hw/acpi/tpm.h @@ -19,7 +19,7 @@ #include "qemu/units.h" #include "hw/registerfields.h" #include "hw/acpi/aml-build.h" -#include "sysemu/tpm.h" +#include "system/tpm.h" #ifdef CONFIG_TPM diff --git a/include/hw/acpi/vmclock.h b/include/hw/acpi/vmclock.h new file mode 100644 index 0000000..5605605 --- /dev/null +++ b/include/hw/acpi/vmclock.h @@ -0,0 +1,34 @@ +#ifndef ACPI_VMCLOCK_H +#define ACPI_VMCLOCK_H + +#include "hw/acpi/bios-linker-loader.h" +#include "hw/qdev-core.h" +#include "qemu/uuid.h" +#include "qom/object.h" + +#define TYPE_VMCLOCK "vmclock" + +#define VMCLOCK_ADDR 0xfeffb000 +#define VMCLOCK_SIZE 0x1000 + +OBJECT_DECLARE_SIMPLE_TYPE(VmclockState, VMCLOCK) + +struct vmclock_abi; + +struct VmclockState { + DeviceState parent_obj; + MemoryRegion clk_page; + uint64_t physaddr; + struct vmclock_abi *clk; +}; + +/* returns NULL unless there is exactly one device */ +static inline Object *find_vmclock_dev(void) +{ + return object_resolve_path_type("", TYPE_VMCLOCK, NULL); +} + +void vmclock_build_acpi(VmclockState *vms, GArray *table_data, + BIOSLinker *linker, const char *oem_id); + +#endif diff --git a/include/hw/adc/max111x.h b/include/hw/adc/max111x.h deleted file mode 100644 index beff59c..0000000 --- a/include/hw/adc/max111x.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Maxim MAX1110/1111 ADC chip emulation. - * - * Copyright (c) 2006 Openedhand Ltd. - * Written by Andrzej Zaborowski <balrog@zabor.org> - * - * This code is licensed under the GNU GPLv2. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#ifndef HW_MISC_MAX111X_H -#define HW_MISC_MAX111X_H - -#include "hw/ssi/ssi.h" -#include "qom/object.h" - -/* - * This is a model of the Maxim MAX1110/1111 ADC chip, which for QEMU - * is an SSI slave device. It has either 4 (max1110) or 8 (max1111) - * 8-bit ADC channels. - * - * QEMU interface: - * + GPIO inputs 0..3 (for max1110) or 0..7 (for max1111): set the value - * of each ADC input, as an unsigned 8-bit value - * + GPIO output 0: interrupt line - * + Properties "input0" to "input3" (max1110) or "input0" to "input7" - * (max1111): initial reset values for ADC inputs. - * - * Known bugs: - * + the interrupt line is not correctly implemented, and will never - * be lowered once it has been asserted. - */ -struct MAX111xState { - SSIPeripheral parent_obj; - - qemu_irq interrupt; - /* Values of inputs at system reset (settable by QOM property) */ - uint8_t reset_input[8]; - - uint8_t tb1, rb2, rb3; - int cycle; - - uint8_t input[8]; - int inputs, com; -}; - -#define TYPE_MAX_111X "max111x" - -OBJECT_DECLARE_SIMPLE_TYPE(MAX111xState, MAX_111X) - -#define TYPE_MAX_1110 "max1110" -#define TYPE_MAX_1111 "max1111" - -#endif diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index 67a9a17..445ba1b 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -12,8 +12,9 @@ #include "hw/misc/allwinner-a10-ccm.h" #include "hw/misc/allwinner-a10-dramc.h" #include "hw/i2c/allwinner-i2c.h" +#include "hw/ssi/allwinner-a10-spi.h" #include "hw/watchdog/allwinner-wdt.h" -#include "sysemu/block-backend.h" +#include "system/block-backend.h" #include "target/arm/cpu.h" #include "qom/object.h" @@ -40,6 +41,7 @@ struct AwA10State { AllwinnerAHCIState sata; AwSdHostState mmc0; AWI2CState i2c0; + AWA10SPIState spi0; AwRtcState rtc; AwWdtState wdt; MemoryRegion sram_a; diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h index 24ba4e1..db897c8 100644 --- a/include/hw/arm/allwinner-h3.h +++ b/include/hw/arm/allwinner-h3.h @@ -49,7 +49,7 @@ #include "hw/i2c/allwinner-i2c.h" #include "hw/watchdog/allwinner-wdt.h" #include "target/arm/cpu.h" -#include "sysemu/block-backend.h" +#include "system/block-backend.h" /** * Allwinner H3 device list diff --git a/include/hw/arm/allwinner-r40.h b/include/hw/arm/allwinner-r40.h index 614e74b..f8a0e94 100644 --- a/include/hw/arm/allwinner-r40.h +++ b/include/hw/arm/allwinner-r40.h @@ -35,7 +35,7 @@ #include "hw/usb/hcd-ehci.h" #include "hw/watchdog/allwinner-wdt.h" #include "target/arm/cpu.h" -#include "sysemu/block-backend.h" +#include "system/block-backend.h" enum { AW_R40_DEV_SRAM_A1, diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h index cbeacb2..973277b 100644 --- a/include/hw/arm/aspeed.h +++ b/include/hw/arm/aspeed.h @@ -39,6 +39,8 @@ struct AspeedMachineClass { uint32_t macs_mask; void (*i2c_init)(AspeedMachineState *bmc); uint32_t uart_default; + bool sdhci_wp_inverted; + bool vbootrom; }; diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 624d489..217ef0e 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -39,11 +39,11 @@ #include "hw/misc/unimp.h" #include "hw/misc/aspeed_peci.h" #include "hw/fsi/aspeed_apb2opb.h" -#include "hw/char/serial.h" +#include "hw/char/serial-mm.h" #include "hw/intc/arm_gicv3.h" -#define ASPEED_SPIS_NUM 2 -#define ASPEED_EHCIS_NUM 2 +#define ASPEED_SPIS_NUM 3 +#define ASPEED_EHCIS_NUM 4 #define ASPEED_WDTS_NUM 8 #define ASPEED_CPUS_NUM 4 #define ASPEED_MACS_NUM 4 @@ -59,6 +59,7 @@ struct AspeedSoCState { MemoryRegion sram; MemoryRegion spi_boot_container; MemoryRegion spi_boot; + MemoryRegion vbootrom; AddressSpace dram_as; AspeedRtcState rtc; AspeedTimerCtrlState timerctrl; @@ -90,6 +91,8 @@ struct AspeedSoCState { SerialMM uart[ASPEED_UARTS_NUM]; Clock *sysclk; UnimplementedDeviceState iomem; + UnimplementedDeviceState iomem0; + UnimplementedDeviceState iomem1; UnimplementedDeviceState video; UnimplementedDeviceState emmc_boot_controller; UnimplementedDeviceState dpmcu; @@ -97,6 +100,7 @@ struct AspeedSoCState { UnimplementedDeviceState espi; UnimplementedDeviceState udc; UnimplementedDeviceState sgpiom; + UnimplementedDeviceState ltpi; UnimplementedDeviceState jtag[ASPEED_JTAG_NUM]; AspeedAPB2OPBState fsi[2]; }; @@ -128,7 +132,7 @@ struct Aspeed27x0SoCState { AspeedSoCState parent; ARMCPU cpu[ASPEED_CPUS_NUM]; - AspeedINTCState intc; + AspeedINTCState intc[2]; GICv3State gic; MemoryRegion dram_empty; }; @@ -142,13 +146,36 @@ struct Aspeed10x0SoCState { ARMv7MState armv7m; }; +struct Aspeed27x0SSPSoCState { + AspeedSoCState parent; + AspeedINTCState intc[2]; + UnimplementedDeviceState ipc[2]; + UnimplementedDeviceState scuio; + + ARMv7MState armv7m; +}; + +#define TYPE_ASPEED27X0SSP_SOC "aspeed27x0ssp-soc" +OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0SSPSoCState, ASPEED27X0SSP_SOC) + +struct Aspeed27x0TSPSoCState { + AspeedSoCState parent; + AspeedINTCState intc[2]; + UnimplementedDeviceState ipc[2]; + UnimplementedDeviceState scuio; + + ARMv7MState armv7m; +}; + +#define TYPE_ASPEED27X0TSP_SOC "aspeed27x0tsp-soc" +OBJECT_DECLARE_SIMPLE_TYPE(Aspeed27x0TSPSoCState, ASPEED27X0TSP_SOC) + #define TYPE_ASPEED10X0_SOC "aspeed10x0-soc" OBJECT_DECLARE_SIMPLE_TYPE(Aspeed10x0SoCState, ASPEED10X0_SOC) struct AspeedSoCClass { DeviceClass parent_class; - const char *name; /** valid_cpu_types: NULL terminated array of a single CPU type. */ const char * const *valid_cpu_types; uint32_t silicon_rev; @@ -170,8 +197,12 @@ struct AspeedSoCClass { const char *aspeed_soc_cpu_type(AspeedSoCClass *sc); enum { + ASPEED_DEV_VBOOTROM, ASPEED_DEV_SPI_BOOT, ASPEED_DEV_IOMEM, + ASPEED_DEV_IOMEM0, + ASPEED_DEV_IOMEM1, + ASPEED_DEV_LTPI, ASPEED_DEV_UART0, ASPEED_DEV_UART1, ASPEED_DEV_UART2, @@ -193,8 +224,11 @@ enum { ASPEED_DEV_SPI2, ASPEED_DEV_EHCI1, ASPEED_DEV_EHCI2, + ASPEED_DEV_EHCI3, + ASPEED_DEV_EHCI4, ASPEED_DEV_VIC, ASPEED_DEV_INTC, + ASPEED_DEV_INTCIO, ASPEED_DEV_SDMC, ASPEED_DEV_SCU, ASPEED_DEV_ADC, @@ -249,6 +283,8 @@ enum { ASPEED_DEV_SLIIO, ASPEED_GIC_DIST, ASPEED_GIC_REDIST, + ASPEED_DEV_IPC0, + ASPEED_DEV_IPC1, }; qemu_irq aspeed_soc_get_irq(AspeedSoCState *s, int dev); diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index 80c492d..a2e22bd 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -132,6 +132,9 @@ struct arm_boot_info { bool secure_board_setup; arm_endianness endianness; + + /* CPU having load the kernel and that should be the first to boot. */ + ARMCPU *primary_cpu; }; /** @@ -160,6 +163,7 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu, * @binfo: struct describing the boot environment * @addr_limit: upper limit of the available memory area at @addr * @as: address space to load image to + * @cpu: ARM CPU object * * Load a device tree supplied by the machine or by the user with the * '-dtb' command line option, and put it at offset @addr in target @@ -176,7 +180,8 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu, * Note: Must not be called unless have_dtb(binfo) is true. */ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, - hwaddr addr_limit, AddressSpace *as, MachineState *ms); + hwaddr addr_limit, AddressSpace *as, MachineState *ms, + ARMCPU *cpu); /* Write a secure board setup routine with a dummy handler for SMCs */ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu, diff --git a/include/hw/arm/bsa.h b/include/hw/arm/bsa.h index 8eaab60..13ed2d2 100644 --- a/include/hw/arm/bsa.h +++ b/include/hw/arm/bsa.h @@ -22,6 +22,8 @@ #define QEMU_ARM_BSA_H /* These are architectural INTID values */ +#define ARCH_TIMER_S_EL2_VIRT_IRQ 19 +#define ARCH_TIMER_S_EL2_IRQ 20 #define VIRTUAL_PMU_IRQ 23 #define ARCH_GIC_MAINT_IRQ 25 #define ARCH_TIMER_NS_EL2_IRQ 26 diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h index df2f839..b68d433 100644 --- a/include/hw/arm/fsl-imx25.h +++ b/include/hw/arm/fsl-imx25.h @@ -29,7 +29,7 @@ #include "hw/sd/sdhci.h" #include "hw/usb/chipidea.h" #include "hw/watchdog/wdt_imx2.h" -#include "exec/memory.h" +#include "system/memory.h" #include "target/arm/cpu.h" #include "qom/object.h" diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h index 40c593a..41232a2 100644 --- a/include/hw/arm/fsl-imx31.h +++ b/include/hw/arm/fsl-imx31.h @@ -25,7 +25,7 @@ #include "hw/i2c/imx_i2c.h" #include "hw/gpio/imx_gpio.h" #include "hw/watchdog/wdt_imx2.h" -#include "exec/memory.h" +#include "system/memory.h" #include "target/arm/cpu.h" #include "qom/object.h" diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h index 61c593f..124bbd4 100644 --- a/include/hw/arm/fsl-imx6.h +++ b/include/hw/arm/fsl-imx6.h @@ -33,7 +33,8 @@ #include "hw/usb/chipidea.h" #include "hw/usb/imx-usb-phy.h" #include "hw/pci-host/designware.h" -#include "exec/memory.h" +#include "hw/or-irq.h" +#include "system/memory.h" #include "cpu.h" #include "qom/object.h" @@ -73,6 +74,7 @@ struct FslIMX6State { ChipideaState usb[FSL_IMX6_NUM_USBS]; IMXFECState eth; DesignwarePCIEHost pcie; + OrIRQState pcie4_msi_irq; MemoryRegion rom; MemoryRegion caam; MemoryRegion ocram; @@ -457,7 +459,7 @@ struct FslIMX6State { #define FSL_IMX6_PCIE1_IRQ 120 #define FSL_IMX6_PCIE2_IRQ 121 #define FSL_IMX6_PCIE3_IRQ 122 -#define FSL_IMX6_PCIE4_IRQ 123 +#define FSL_IMX6_PCIE4_MSI_IRQ 123 #define FSL_IMX6_DCIC1_IRQ 124 #define FSL_IMX6_DCIC2_IRQ 125 #define FSL_IMX6_MLB150_HIGH_IRQ 126 diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h index 8277b0e..4e3209b 100644 --- a/include/hw/arm/fsl-imx6ul.h +++ b/include/hw/arm/fsl-imx6ul.h @@ -33,7 +33,7 @@ #include "hw/net/imx_fec.h" #include "hw/usb/chipidea.h" #include "hw/usb/imx-usb-phy.h" -#include "exec/memory.h" +#include "system/memory.h" #include "cpu.h" #include "qom/object.h" #include "qemu/units.h" diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h index 411fa1c..aa7818c 100644 --- a/include/hw/arm/fsl-imx7.h +++ b/include/hw/arm/fsl-imx7.h @@ -36,6 +36,7 @@ #include "hw/net/imx_fec.h" #include "hw/pci-host/designware.h" #include "hw/usb/chipidea.h" +#include "hw/or-irq.h" #include "cpu.h" #include "qom/object.h" #include "qemu/units.h" @@ -85,6 +86,7 @@ struct FslIMX7State { IMX7GPRState gpr; ChipideaState usb[FSL_IMX7_NUM_USBS]; DesignwarePCIEHost pcie; + OrIRQState pcie4_msi_irq; MemoryRegion rom; MemoryRegion caam; MemoryRegion ocram; @@ -428,7 +430,7 @@ enum FslIMX7IRQs { FSL_IMX7_PCI_INTA_IRQ = 125, FSL_IMX7_PCI_INTB_IRQ = 124, FSL_IMX7_PCI_INTC_IRQ = 123, - FSL_IMX7_PCI_INTD_IRQ = 122, + FSL_IMX7_PCI_INTD_MSI_IRQ = 122, FSL_IMX7_UART7_IRQ = 126, diff --git a/include/hw/arm/fsl-imx8mp.h b/include/hw/arm/fsl-imx8mp.h new file mode 100644 index 0000000..d016f7d --- /dev/null +++ b/include/hw/arm/fsl-imx8mp.h @@ -0,0 +1,284 @@ +/* + * i.MX 8M Plus SoC Definitions + * + * Copyright (c) 2024, Bernhard Beschow <shentey@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef FSL_IMX8MP_H +#define FSL_IMX8MP_H + +#include "cpu.h" +#include "hw/char/imx_serial.h" +#include "hw/gpio/imx_gpio.h" +#include "hw/i2c/imx_i2c.h" +#include "hw/intc/arm_gicv3_common.h" +#include "hw/misc/imx7_snvs.h" +#include "hw/misc/imx8mp_analog.h" +#include "hw/misc/imx8mp_ccm.h" +#include "hw/net/imx_fec.h" +#include "hw/or-irq.h" +#include "hw/pci-host/designware.h" +#include "hw/pci-host/fsl_imx8m_phy.h" +#include "hw/sd/sdhci.h" +#include "hw/ssi/imx_spi.h" +#include "hw/timer/imx_gpt.h" +#include "hw/usb/hcd-dwc3.h" +#include "hw/watchdog/wdt_imx2.h" +#include "hw/sysbus.h" +#include "qom/object.h" +#include "qemu/units.h" + +#define TYPE_FSL_IMX8MP "fsl-imx8mp" +OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mpState, FSL_IMX8MP) + +#define FSL_IMX8MP_RAM_START 0x40000000 +#define FSL_IMX8MP_RAM_SIZE_MAX (8 * GiB) + +enum FslImx8mpConfiguration { + FSL_IMX8MP_NUM_CPUS = 4, + FSL_IMX8MP_NUM_ECSPIS = 3, + FSL_IMX8MP_NUM_GPIOS = 5, + FSL_IMX8MP_NUM_GPTS = 6, + FSL_IMX8MP_NUM_I2CS = 6, + FSL_IMX8MP_NUM_IRQS = 160, + FSL_IMX8MP_NUM_UARTS = 4, + FSL_IMX8MP_NUM_USBS = 2, + FSL_IMX8MP_NUM_USDHCS = 3, + FSL_IMX8MP_NUM_WDTS = 3, +}; + +struct FslImx8mpState { + SysBusDevice parent_obj; + + ARMCPU cpu[FSL_IMX8MP_NUM_CPUS]; + GICv3State gic; + IMXGPTState gpt[FSL_IMX8MP_NUM_GPTS]; + IMXGPIOState gpio[FSL_IMX8MP_NUM_GPIOS]; + IMX8MPCCMState ccm; + IMX8MPAnalogState analog; + IMX7SNVSState snvs; + IMXSPIState spi[FSL_IMX8MP_NUM_ECSPIS]; + IMXI2CState i2c[FSL_IMX8MP_NUM_I2CS]; + IMXSerialState uart[FSL_IMX8MP_NUM_UARTS]; + IMXFECState enet; + SDHCIState usdhc[FSL_IMX8MP_NUM_USDHCS]; + IMX2WdtState wdt[FSL_IMX8MP_NUM_WDTS]; + USBDWC3 usb[FSL_IMX8MP_NUM_USBS]; + DesignwarePCIEHost pcie; + FslImx8mPciePhyState pcie_phy; + OrIRQState gpt5_gpt6_irq; + MemoryRegion ocram; + + uint32_t phy_num; + bool phy_connected; +}; + +enum FslImx8mpMemoryRegions { + FSL_IMX8MP_A53_DAP, + FSL_IMX8MP_AIPS1_CONFIGURATION, + FSL_IMX8MP_AIPS2_CONFIGURATION, + FSL_IMX8MP_AIPS3_CONFIGURATION, + FSL_IMX8MP_AIPS4_CONFIGURATION, + FSL_IMX8MP_AIPS5_CONFIGURATION, + FSL_IMX8MP_ANA_OSC, + FSL_IMX8MP_ANA_PLL, + FSL_IMX8MP_ANA_TSENSOR, + FSL_IMX8MP_APBH_DMA, + FSL_IMX8MP_ASRC, + FSL_IMX8MP_AUDIO_BLK_CTRL, + FSL_IMX8MP_AUDIO_DSP, + FSL_IMX8MP_AUDIO_XCVR_RX, + FSL_IMX8MP_AUD_IRQ_STEER, + FSL_IMX8MP_BOOT_ROM, + FSL_IMX8MP_BOOT_ROM_PROTECTED, + FSL_IMX8MP_CAAM, + FSL_IMX8MP_CAAM_MEM, + FSL_IMX8MP_CCM, + FSL_IMX8MP_CSU, + FSL_IMX8MP_DDR_BLK_CTRL, + FSL_IMX8MP_DDR_CTL, + FSL_IMX8MP_DDR_PERF_MON, + FSL_IMX8MP_DDR_PHY, + FSL_IMX8MP_DDR_PHY_BROADCAST, + FSL_IMX8MP_ECSPI1, + FSL_IMX8MP_ECSPI2, + FSL_IMX8MP_ECSPI3, + FSL_IMX8MP_EDMA_CHANNELS, + FSL_IMX8MP_EDMA_MANAGEMENT_PAGE, + FSL_IMX8MP_ENET1, + FSL_IMX8MP_ENET2_TSN, + FSL_IMX8MP_FLEXCAN1, + FSL_IMX8MP_FLEXCAN2, + FSL_IMX8MP_GIC_DIST, + FSL_IMX8MP_GIC_REDIST, + FSL_IMX8MP_GPC, + FSL_IMX8MP_GPIO1, + FSL_IMX8MP_GPIO2, + FSL_IMX8MP_GPIO3, + FSL_IMX8MP_GPIO4, + FSL_IMX8MP_GPIO5, + FSL_IMX8MP_GPT1, + FSL_IMX8MP_GPT2, + FSL_IMX8MP_GPT3, + FSL_IMX8MP_GPT4, + FSL_IMX8MP_GPT5, + FSL_IMX8MP_GPT6, + FSL_IMX8MP_GPU2D, + FSL_IMX8MP_GPU3D, + FSL_IMX8MP_HDMI_TX, + FSL_IMX8MP_HDMI_TX_AUDLNK_MSTR, + FSL_IMX8MP_HSIO_BLK_CTL, + FSL_IMX8MP_I2C1, + FSL_IMX8MP_I2C2, + FSL_IMX8MP_I2C3, + FSL_IMX8MP_I2C4, + FSL_IMX8MP_I2C5, + FSL_IMX8MP_I2C6, + FSL_IMX8MP_INTERCONNECT, + FSL_IMX8MP_IOMUXC, + FSL_IMX8MP_IOMUXC_GPR, + FSL_IMX8MP_IPS_DEWARP, + FSL_IMX8MP_ISI, + FSL_IMX8MP_ISP1, + FSL_IMX8MP_ISP2, + FSL_IMX8MP_LCDIF1, + FSL_IMX8MP_LCDIF2, + FSL_IMX8MP_MEDIA_BLK_CTL, + FSL_IMX8MP_MIPI_CSI1, + FSL_IMX8MP_MIPI_CSI2, + FSL_IMX8MP_MIPI_DSI1, + FSL_IMX8MP_MU_1_A, + FSL_IMX8MP_MU_1_B, + FSL_IMX8MP_MU_2_A, + FSL_IMX8MP_MU_2_B, + FSL_IMX8MP_MU_3_A, + FSL_IMX8MP_MU_3_B, + FSL_IMX8MP_NPU, + FSL_IMX8MP_OCOTP_CTRL, + FSL_IMX8MP_OCRAM, + FSL_IMX8MP_OCRAM_S, + FSL_IMX8MP_PCIE1, + FSL_IMX8MP_PCIE1_MEM, + FSL_IMX8MP_PCIE_PHY1, + FSL_IMX8MP_PDM, + FSL_IMX8MP_PERFMON1, + FSL_IMX8MP_PERFMON2, + FSL_IMX8MP_PWM1, + FSL_IMX8MP_PWM2, + FSL_IMX8MP_PWM3, + FSL_IMX8MP_PWM4, + FSL_IMX8MP_QOSC, + FSL_IMX8MP_QSPI, + FSL_IMX8MP_QSPI1_RX_BUFFER, + FSL_IMX8MP_QSPI1_TX_BUFFER, + FSL_IMX8MP_QSPI_MEM, + FSL_IMX8MP_RAM, + FSL_IMX8MP_RDC, + FSL_IMX8MP_SAI1, + FSL_IMX8MP_SAI2, + FSL_IMX8MP_SAI3, + FSL_IMX8MP_SAI5, + FSL_IMX8MP_SAI6, + FSL_IMX8MP_SAI7, + FSL_IMX8MP_SDMA1, + FSL_IMX8MP_SDMA2, + FSL_IMX8MP_SDMA3, + FSL_IMX8MP_SEMAPHORE1, + FSL_IMX8MP_SEMAPHORE2, + FSL_IMX8MP_SEMAPHORE_HS, + FSL_IMX8MP_SNVS_HP, + FSL_IMX8MP_SPBA1, + FSL_IMX8MP_SPBA2, + FSL_IMX8MP_SRC, + FSL_IMX8MP_SYSCNT_CMP, + FSL_IMX8MP_SYSCNT_CTRL, + FSL_IMX8MP_SYSCNT_RD, + FSL_IMX8MP_TCM_DTCM, + FSL_IMX8MP_TCM_ITCM, + FSL_IMX8MP_TZASC, + FSL_IMX8MP_UART1, + FSL_IMX8MP_UART2, + FSL_IMX8MP_UART3, + FSL_IMX8MP_UART4, + FSL_IMX8MP_USB1, + FSL_IMX8MP_USB2, + FSL_IMX8MP_USB1_DEV, + FSL_IMX8MP_USB2_DEV, + FSL_IMX8MP_USB1_OTG, + FSL_IMX8MP_USB2_OTG, + FSL_IMX8MP_USB1_GLUE, + FSL_IMX8MP_USB2_GLUE, + FSL_IMX8MP_USDHC1, + FSL_IMX8MP_USDHC2, + FSL_IMX8MP_USDHC3, + FSL_IMX8MP_VPU, + FSL_IMX8MP_VPU_BLK_CTRL, + FSL_IMX8MP_VPU_G1_DECODER, + FSL_IMX8MP_VPU_G2_DECODER, + FSL_IMX8MP_VPU_VC8000E_ENCODER, + FSL_IMX8MP_WDOG1, + FSL_IMX8MP_WDOG2, + FSL_IMX8MP_WDOG3, +}; + +enum FslImx8mpIrqs { + FSL_IMX8MP_USDHC1_IRQ = 22, + FSL_IMX8MP_USDHC2_IRQ = 23, + FSL_IMX8MP_USDHC3_IRQ = 24, + + FSL_IMX8MP_UART1_IRQ = 26, + FSL_IMX8MP_UART2_IRQ = 27, + FSL_IMX8MP_UART3_IRQ = 28, + FSL_IMX8MP_UART4_IRQ = 29, + FSL_IMX8MP_UART5_IRQ = 30, + FSL_IMX8MP_UART6_IRQ = 16, + + FSL_IMX8MP_ECSPI1_IRQ = 31, + FSL_IMX8MP_ECSPI2_IRQ = 32, + FSL_IMX8MP_ECSPI3_IRQ = 33, + + FSL_IMX8MP_I2C1_IRQ = 35, + FSL_IMX8MP_I2C2_IRQ = 36, + FSL_IMX8MP_I2C3_IRQ = 37, + FSL_IMX8MP_I2C4_IRQ = 38, + + FSL_IMX8MP_USB1_IRQ = 40, + FSL_IMX8MP_USB2_IRQ = 41, + + FSL_IMX8MP_GPT1_IRQ = 55, + FSL_IMX8MP_GPT2_IRQ = 54, + FSL_IMX8MP_GPT3_IRQ = 53, + FSL_IMX8MP_GPT4_IRQ = 52, + FSL_IMX8MP_GPT5_GPT6_IRQ = 51, + + FSL_IMX8MP_GPIO1_LOW_IRQ = 64, + FSL_IMX8MP_GPIO1_HIGH_IRQ = 65, + FSL_IMX8MP_GPIO2_LOW_IRQ = 66, + FSL_IMX8MP_GPIO2_HIGH_IRQ = 67, + FSL_IMX8MP_GPIO3_LOW_IRQ = 68, + FSL_IMX8MP_GPIO3_HIGH_IRQ = 69, + FSL_IMX8MP_GPIO4_LOW_IRQ = 70, + FSL_IMX8MP_GPIO4_HIGH_IRQ = 71, + FSL_IMX8MP_GPIO5_LOW_IRQ = 72, + FSL_IMX8MP_GPIO5_HIGH_IRQ = 73, + + FSL_IMX8MP_I2C5_IRQ = 76, + FSL_IMX8MP_I2C6_IRQ = 77, + + FSL_IMX8MP_WDOG1_IRQ = 78, + FSL_IMX8MP_WDOG2_IRQ = 79, + FSL_IMX8MP_WDOG3_IRQ = 10, + + FSL_IMX8MP_ENET1_MAC_IRQ = 118, + FSL_IMX6_ENET1_MAC_1588_IRQ = 121, + + FSL_IMX8MP_PCI_INTA_IRQ = 126, + FSL_IMX8MP_PCI_INTB_IRQ = 125, + FSL_IMX8MP_PCI_INTC_IRQ = 124, + FSL_IMX8MP_PCI_INTD_IRQ = 123, + FSL_IMX8MP_PCI_MSI_IRQ = 140, +}; + +#endif /* FSL_IMX8MP_H */ diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h index 4e0d210..5653656 100644 --- a/include/hw/arm/npcm7xx.h +++ b/include/hw/arm/npcm7xx.h @@ -23,8 +23,8 @@ #include "hw/gpio/npcm7xx_gpio.h" #include "hw/i2c/npcm7xx_smbus.h" #include "hw/mem/npcm7xx_mc.h" -#include "hw/misc/npcm7xx_clk.h" -#include "hw/misc/npcm7xx_gcr.h" +#include "hw/misc/npcm_clk.h" +#include "hw/misc/npcm_gcr.h" #include "hw/misc/npcm7xx_mft.h" #include "hw/misc/npcm7xx_pwm.h" #include "hw/misc/npcm7xx_rng.h" @@ -89,8 +89,8 @@ struct NPCM7xxState { MemoryRegion ram3; MemoryRegion *dram; - NPCM7xxGCRState gcr; - NPCM7xxCLKState clk; + NPCMGCRState gcr; + NPCMCLKState clk; NPCM7xxTimerCtrlState tim[3]; NPCM7xxADCState adc; NPCM7xxPWMState pwm[NPCM7XX_NR_PWM_MODULES]; diff --git a/include/hw/arm/npcm8xx.h b/include/hw/arm/npcm8xx.h new file mode 100644 index 0000000..a8377db --- /dev/null +++ b/include/hw/arm/npcm8xx.h @@ -0,0 +1,132 @@ +/* + * Nuvoton NPCM8xx SoC family. + * + * Copyright 2022 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#ifndef NPCM8XX_H +#define NPCM8XX_H + +#include "hw/adc/npcm7xx_adc.h" +#include "hw/core/split-irq.h" +#include "hw/cpu/cluster.h" +#include "hw/gpio/npcm7xx_gpio.h" +#include "hw/i2c/npcm7xx_smbus.h" +#include "hw/intc/arm_gic_common.h" +#include "hw/mem/npcm7xx_mc.h" +#include "hw/misc/npcm_clk.h" +#include "hw/misc/npcm_gcr.h" +#include "hw/misc/npcm7xx_mft.h" +#include "hw/misc/npcm7xx_pwm.h" +#include "hw/misc/npcm7xx_rng.h" +#include "hw/net/npcm_gmac.h" +#include "hw/net/npcm_pcs.h" +#include "hw/nvram/npcm7xx_otp.h" +#include "hw/sd/npcm7xx_sdhci.h" +#include "hw/timer/npcm7xx_timer.h" +#include "hw/ssi/npcm7xx_fiu.h" +#include "hw/usb/hcd-ehci.h" +#include "hw/usb/hcd-ohci.h" +#include "target/arm/cpu.h" +#include "hw/ssi/npcm_pspi.h" + +#define NPCM8XX_MAX_NUM_CPUS (4) + +/* The first half of the address space is reserved for DDR4 DRAM. */ +#define NPCM8XX_DRAM_BA (0x00000000) +#define NPCM8XX_DRAM_SZ (2 * GiB) + +/* Magic addresses for setting up direct kernel booting and SMP boot stubs. */ +#define NPCM8XX_LOADER_START (0x00000000) /* Start of SDRAM */ +#define NPCM8XX_SMP_LOADER_START (0xffff0000) /* Boot ROM */ +#define NPCM8XX_SMP_BOOTREG_ADDR (0xf080013c) /* GCR.SCRPAD */ +#define NPCM8XX_BOARD_SETUP_ADDR (0xffff1000) /* Boot ROM */ + +#define NPCM8XX_NR_PWM_MODULES 3 + +struct NPCM8xxMachine { + MachineState parent_obj; + + /* + * PWM fan splitter. each splitter connects to one PWM output and + * multiple MFT inputs. + */ + SplitIRQ fan_splitter[NPCM8XX_NR_PWM_MODULES * + NPCM7XX_PWM_PER_MODULE]; +}; + + +struct NPCM8xxMachineClass { + MachineClass parent_class; + + const char *soc_type; +}; + +#define TYPE_NPCM8XX_MACHINE MACHINE_TYPE_NAME("npcm8xx") +OBJECT_DECLARE_TYPE(NPCM8xxMachine, NPCM8xxMachineClass, NPCM8XX_MACHINE) + +struct NPCM8xxState { + DeviceState parent_obj; + + ARMCPU cpu[NPCM8XX_MAX_NUM_CPUS]; + CPUClusterState cpu_cluster; + GICState gic; + + MemoryRegion sram; + MemoryRegion irom; + MemoryRegion ram3; + MemoryRegion *dram; + + NPCMGCRState gcr; + NPCMCLKState clk; + NPCM7xxTimerCtrlState tim[3]; + NPCM7xxADCState adc; + NPCM7xxPWMState pwm[NPCM8XX_NR_PWM_MODULES]; + NPCM7xxMFTState mft[8]; + NPCM7xxOTPState fuse_array; + NPCM7xxMCState mc; + NPCM7xxRNGState rng; + NPCM7xxGPIOState gpio[8]; + NPCM7xxSMBusState smbus[27]; + EHCISysBusState ehci[2]; + OHCISysBusState ohci[2]; + NPCM7xxFIUState fiu[3]; + NPCMGMACState gmac[4]; + NPCMPCSState pcs; + NPCM7xxSDHCIState mmc; + NPCMPSPIState pspi; +}; + +struct NPCM8xxClass { + DeviceClass parent_class; + + /* Bitmask of modules that are permanently disabled on this chip. */ + uint32_t disabled_modules; + /* Number of CPU cores enabled in this SoC class. */ + uint32_t num_cpus; +}; + +#define TYPE_NPCM8XX "npcm8xx" +OBJECT_DECLARE_TYPE(NPCM8xxState, NPCM8xxClass, NPCM8XX) + +/** + * npcm8xx_load_kernel - Loads memory with everything needed to boot + * @machine - The machine containing the SoC to be booted. + * @soc - The SoC containing the CPU to be booted. + * + * This will set up the ARM boot info structure for the specific NPCM8xx + * derivative and call arm_load_kernel() to set up loading of the kernel, etc. + * into memory, if requested by the user. + */ +void npcm8xx_load_kernel(MachineState *machine, NPCM8xxState *soc); + +#endif /* NPCM8XX_H */ diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h index e52a56e..f88ab1b 100644 --- a/include/hw/arm/nrf51_soc.h +++ b/include/hw/arm/nrf51_soc.h @@ -30,7 +30,7 @@ struct NRF51State { SysBusDevice parent_obj; /*< public >*/ - ARMv7MState cpu; + ARMv7MState armv7m; NRF51UARTState uart; NRF51RNGState rng; diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h index 40ee8ea..bdb2e88 100644 --- a/include/hw/arm/omap.h +++ b/include/hw/arm/omap.h @@ -20,39 +20,29 @@ #ifndef HW_ARM_OMAP_H #define HW_ARM_OMAP_H -#include "exec/memory.h" -#include "hw/input/tsc2xxx.h" +#include "system/memory.h" #include "target/arm/cpu-qom.h" #include "qemu/log.h" #include "qom/object.h" -# define OMAP_EMIFS_BASE 0x00000000 -# define OMAP2_Q0_BASE 0x00000000 -# define OMAP_CS0_BASE 0x00000000 -# define OMAP_CS1_BASE 0x04000000 -# define OMAP_CS2_BASE 0x08000000 -# define OMAP_CS3_BASE 0x0c000000 -# define OMAP_EMIFF_BASE 0x10000000 -# define OMAP_IMIF_BASE 0x20000000 -# define OMAP_LOCALBUS_BASE 0x30000000 -# define OMAP2_Q1_BASE 0x40000000 -# define OMAP2_L4_BASE 0x48000000 -# define OMAP2_SRAM_BASE 0x40200000 -# define OMAP2_L3_BASE 0x68000000 -# define OMAP2_Q2_BASE 0x80000000 -# define OMAP2_Q3_BASE 0xc0000000 -# define OMAP_MPUI_BASE 0xe1000000 - -# define OMAP730_SRAM_SIZE 0x00032000 -# define OMAP15XX_SRAM_SIZE 0x00030000 -# define OMAP16XX_SRAM_SIZE 0x00004000 -# define OMAP1611_SRAM_SIZE 0x0003e800 -# define OMAP242X_SRAM_SIZE 0x000a0000 -# define OMAP243X_SRAM_SIZE 0x00010000 -# define OMAP_CS0_SIZE 0x04000000 -# define OMAP_CS1_SIZE 0x04000000 -# define OMAP_CS2_SIZE 0x04000000 -# define OMAP_CS3_SIZE 0x04000000 +#define OMAP_EMIFS_BASE 0x00000000 +#define OMAP_CS0_BASE 0x00000000 +#define OMAP_CS1_BASE 0x04000000 +#define OMAP_CS2_BASE 0x08000000 +#define OMAP_CS3_BASE 0x0c000000 +#define OMAP_EMIFF_BASE 0x10000000 +#define OMAP_IMIF_BASE 0x20000000 +#define OMAP_LOCALBUS_BASE 0x30000000 +#define OMAP_MPUI_BASE 0xe1000000 + +#define OMAP730_SRAM_SIZE 0x00032000 +#define OMAP15XX_SRAM_SIZE 0x00030000 +#define OMAP16XX_SRAM_SIZE 0x00004000 +#define OMAP1611_SRAM_SIZE 0x0003e800 +#define OMAP_CS0_SIZE 0x04000000 +#define OMAP_CS1_SIZE 0x04000000 +#define OMAP_CS2_SIZE 0x04000000 +#define OMAP_CS3_SIZE 0x04000000 /* omap_clk.c */ struct omap_mpu_state_s; @@ -69,7 +59,7 @@ int64_t omap_clk_getrate(omap_clk clk); void omap_clk_reparent(omap_clk clk, omap_clk parent); /* omap_intc.c */ -#define TYPE_OMAP_INTC "common-omap-intc" +#define TYPE_OMAP_INTC "omap-intc" typedef struct OMAPIntcState OMAPIntcState; DECLARE_INSTANCE_CHECKER(OMAPIntcState, OMAP_INTC, TYPE_OMAP_INTC) @@ -106,385 +96,241 @@ typedef struct Omap1GpioState Omap1GpioState; DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO, TYPE_OMAP1_GPIO) -#define TYPE_OMAP2_GPIO "omap2-gpio" -typedef struct Omap2GpioState Omap2GpioState; -DECLARE_INSTANCE_CHECKER(Omap2GpioState, OMAP2_GPIO, - TYPE_OMAP2_GPIO) - /* TODO: clock framework (see above) */ void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk); -void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk); -void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk); - -/* OMAP2 l4 Interconnect */ -struct omap_l4_s; -struct omap_l4_region_s { - hwaddr offset; - size_t size; - int access; -}; -struct omap_l4_agent_info_s { - int ta; - int region; - int regions; - int ta_region; -}; -struct omap_target_agent_s { - MemoryRegion iomem; - struct omap_l4_s *bus; - int regions; - const struct omap_l4_region_s *start; - hwaddr base; - uint32_t component; - uint32_t control; - uint32_t status; -}; -struct omap_l4_s *omap_l4_init(MemoryRegion *address_space, - hwaddr base, int ta_num); - -struct omap_target_agent_s; -struct omap_target_agent_s *omap_l4ta_get( - struct omap_l4_s *bus, - const struct omap_l4_region_s *regions, - const struct omap_l4_agent_info_s *agents, - int cs); -hwaddr omap_l4_attach(struct omap_target_agent_s *ta, - int region, MemoryRegion *mr); -hwaddr omap_l4_region_base(struct omap_target_agent_s *ta, - int region); -hwaddr omap_l4_region_size(struct omap_target_agent_s *ta, - int region); - -/* OMAP2 SDRAM controller */ -struct omap_sdrc_s; -struct omap_sdrc_s *omap_sdrc_init(MemoryRegion *sysmem, - hwaddr base); -void omap_sdrc_reset(struct omap_sdrc_s *s); - -/* OMAP2 general purpose memory controller */ -struct omap_gpmc_s; -struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu, - hwaddr base, - qemu_irq irq, qemu_irq drq); -void omap_gpmc_reset(struct omap_gpmc_s *s); -void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem); -void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand); - /* * Common IRQ numbers for level 1 interrupt handler * See /usr/include/asm-arm/arch-omap/irqs.h in Linux. */ -# define OMAP_INT_CAMERA 1 -# define OMAP_INT_FIQ 3 -# define OMAP_INT_RTDX 6 -# define OMAP_INT_DSP_MMU_ABORT 7 -# define OMAP_INT_HOST 8 -# define OMAP_INT_ABORT 9 -# define OMAP_INT_BRIDGE_PRIV 13 -# define OMAP_INT_GPIO_BANK1 14 -# define OMAP_INT_UART3 15 -# define OMAP_INT_TIMER3 16 -# define OMAP_INT_DMA_CH0_6 19 -# define OMAP_INT_DMA_CH1_7 20 -# define OMAP_INT_DMA_CH2_8 21 -# define OMAP_INT_DMA_CH3 22 -# define OMAP_INT_DMA_CH4 23 -# define OMAP_INT_DMA_CH5 24 -# define OMAP_INT_DMA_LCD 25 -# define OMAP_INT_TIMER1 26 -# define OMAP_INT_WD_TIMER 27 -# define OMAP_INT_BRIDGE_PUB 28 -# define OMAP_INT_TIMER2 30 -# define OMAP_INT_LCD_CTRL 31 +#define OMAP_INT_CAMERA 1 +#define OMAP_INT_FIQ 3 +#define OMAP_INT_RTDX 6 +#define OMAP_INT_DSP_MMU_ABORT 7 +#define OMAP_INT_HOST 8 +#define OMAP_INT_ABORT 9 +#define OMAP_INT_BRIDGE_PRIV 13 +#define OMAP_INT_GPIO_BANK1 14 +#define OMAP_INT_UART3 15 +#define OMAP_INT_TIMER3 16 +#define OMAP_INT_DMA_CH0_6 19 +#define OMAP_INT_DMA_CH1_7 20 +#define OMAP_INT_DMA_CH2_8 21 +#define OMAP_INT_DMA_CH3 22 +#define OMAP_INT_DMA_CH4 23 +#define OMAP_INT_DMA_CH5 24 +#define OMAP_INT_DMA_LCD 25 +#define OMAP_INT_TIMER1 26 +#define OMAP_INT_WD_TIMER 27 +#define OMAP_INT_BRIDGE_PUB 28 +#define OMAP_INT_TIMER2 30 +#define OMAP_INT_LCD_CTRL 31 /* * Common OMAP-15xx IRQ numbers for level 1 interrupt handler */ -# define OMAP_INT_15XX_IH2_IRQ 0 -# define OMAP_INT_15XX_LB_MMU 17 -# define OMAP_INT_15XX_LOCAL_BUS 29 +#define OMAP_INT_15XX_IH2_IRQ 0 +#define OMAP_INT_15XX_LB_MMU 17 +#define OMAP_INT_15XX_LOCAL_BUS 29 /* * OMAP-1510 specific IRQ numbers for level 1 interrupt handler */ -# define OMAP_INT_1510_SPI_TX 4 -# define OMAP_INT_1510_SPI_RX 5 -# define OMAP_INT_1510_DSP_MAILBOX1 10 -# define OMAP_INT_1510_DSP_MAILBOX2 11 +#define OMAP_INT_1510_SPI_TX 4 +#define OMAP_INT_1510_SPI_RX 5 +#define OMAP_INT_1510_DSP_MAILBOX1 10 +#define OMAP_INT_1510_DSP_MAILBOX2 11 /* * OMAP-310 specific IRQ numbers for level 1 interrupt handler */ -# define OMAP_INT_310_McBSP2_TX 4 -# define OMAP_INT_310_McBSP2_RX 5 -# define OMAP_INT_310_HSB_MAILBOX1 12 -# define OMAP_INT_310_HSAB_MMU 18 +#define OMAP_INT_310_McBSP2_TX 4 +#define OMAP_INT_310_McBSP2_RX 5 +#define OMAP_INT_310_HSB_MAILBOX1 12 +#define OMAP_INT_310_HSAB_MMU 18 /* * OMAP-1610 specific IRQ numbers for level 1 interrupt handler */ -# define OMAP_INT_1610_IH2_IRQ 0 -# define OMAP_INT_1610_IH2_FIQ 2 -# define OMAP_INT_1610_McBSP2_TX 4 -# define OMAP_INT_1610_McBSP2_RX 5 -# define OMAP_INT_1610_DSP_MAILBOX1 10 -# define OMAP_INT_1610_DSP_MAILBOX2 11 -# define OMAP_INT_1610_LCD_LINE 12 -# define OMAP_INT_1610_GPTIMER1 17 -# define OMAP_INT_1610_GPTIMER2 18 -# define OMAP_INT_1610_SSR_FIFO_0 29 +#define OMAP_INT_1610_IH2_IRQ 0 +#define OMAP_INT_1610_IH2_FIQ 2 +#define OMAP_INT_1610_McBSP2_TX 4 +#define OMAP_INT_1610_McBSP2_RX 5 +#define OMAP_INT_1610_DSP_MAILBOX1 10 +#define OMAP_INT_1610_DSP_MAILBOX2 11 +#define OMAP_INT_1610_LCD_LINE 12 +#define OMAP_INT_1610_GPTIMER1 17 +#define OMAP_INT_1610_GPTIMER2 18 +#define OMAP_INT_1610_SSR_FIFO_0 29 /* * OMAP-730 specific IRQ numbers for level 1 interrupt handler */ -# define OMAP_INT_730_IH2_FIQ 0 -# define OMAP_INT_730_IH2_IRQ 1 -# define OMAP_INT_730_USB_NON_ISO 2 -# define OMAP_INT_730_USB_ISO 3 -# define OMAP_INT_730_ICR 4 -# define OMAP_INT_730_EAC 5 -# define OMAP_INT_730_GPIO_BANK1 6 -# define OMAP_INT_730_GPIO_BANK2 7 -# define OMAP_INT_730_GPIO_BANK3 8 -# define OMAP_INT_730_McBSP2TX 10 -# define OMAP_INT_730_McBSP2RX 11 -# define OMAP_INT_730_McBSP2RX_OVF 12 -# define OMAP_INT_730_LCD_LINE 14 -# define OMAP_INT_730_GSM_PROTECT 15 -# define OMAP_INT_730_TIMER3 16 -# define OMAP_INT_730_GPIO_BANK5 17 -# define OMAP_INT_730_GPIO_BANK6 18 -# define OMAP_INT_730_SPGIO_WR 29 +#define OMAP_INT_730_IH2_FIQ 0 +#define OMAP_INT_730_IH2_IRQ 1 +#define OMAP_INT_730_USB_NON_ISO 2 +#define OMAP_INT_730_USB_ISO 3 +#define OMAP_INT_730_ICR 4 +#define OMAP_INT_730_EAC 5 +#define OMAP_INT_730_GPIO_BANK1 6 +#define OMAP_INT_730_GPIO_BANK2 7 +#define OMAP_INT_730_GPIO_BANK3 8 +#define OMAP_INT_730_McBSP2TX 10 +#define OMAP_INT_730_McBSP2RX 11 +#define OMAP_INT_730_McBSP2RX_OVF 12 +#define OMAP_INT_730_LCD_LINE 14 +#define OMAP_INT_730_GSM_PROTECT 15 +#define OMAP_INT_730_TIMER3 16 +#define OMAP_INT_730_GPIO_BANK5 17 +#define OMAP_INT_730_GPIO_BANK6 18 +#define OMAP_INT_730_SPGIO_WR 29 /* * Common IRQ numbers for level 2 interrupt handler */ -# define OMAP_INT_KEYBOARD 1 -# define OMAP_INT_uWireTX 2 -# define OMAP_INT_uWireRX 3 -# define OMAP_INT_I2C 4 -# define OMAP_INT_MPUIO 5 -# define OMAP_INT_USB_HHC_1 6 -# define OMAP_INT_McBSP3TX 10 -# define OMAP_INT_McBSP3RX 11 -# define OMAP_INT_McBSP1TX 12 -# define OMAP_INT_McBSP1RX 13 -# define OMAP_INT_UART1 14 -# define OMAP_INT_UART2 15 -# define OMAP_INT_USB_W2FC 20 -# define OMAP_INT_1WIRE 21 -# define OMAP_INT_OS_TIMER 22 -# define OMAP_INT_OQN 23 -# define OMAP_INT_GAUGE_32K 24 -# define OMAP_INT_RTC_TIMER 25 -# define OMAP_INT_RTC_ALARM 26 -# define OMAP_INT_DSP_MMU 28 +#define OMAP_INT_KEYBOARD 1 +#define OMAP_INT_uWireTX 2 +#define OMAP_INT_uWireRX 3 +#define OMAP_INT_I2C 4 +#define OMAP_INT_MPUIO 5 +#define OMAP_INT_USB_HHC_1 6 +#define OMAP_INT_McBSP3TX 10 +#define OMAP_INT_McBSP3RX 11 +#define OMAP_INT_McBSP1TX 12 +#define OMAP_INT_McBSP1RX 13 +#define OMAP_INT_UART1 14 +#define OMAP_INT_UART2 15 +#define OMAP_INT_USB_W2FC 20 +#define OMAP_INT_1WIRE 21 +#define OMAP_INT_OS_TIMER 22 +#define OMAP_INT_OQN 23 +#define OMAP_INT_GAUGE_32K 24 +#define OMAP_INT_RTC_TIMER 25 +#define OMAP_INT_RTC_ALARM 26 +#define OMAP_INT_DSP_MMU 28 /* * OMAP-1510 specific IRQ numbers for level 2 interrupt handler */ -# define OMAP_INT_1510_BT_MCSI1TX 16 -# define OMAP_INT_1510_BT_MCSI1RX 17 -# define OMAP_INT_1510_SoSSI_MATCH 19 -# define OMAP_INT_1510_MEM_STICK 27 -# define OMAP_INT_1510_COM_SPI_RO 31 +#define OMAP_INT_1510_BT_MCSI1TX 16 +#define OMAP_INT_1510_BT_MCSI1RX 17 +#define OMAP_INT_1510_SoSSI_MATCH 19 +#define OMAP_INT_1510_MEM_STICK 27 +#define OMAP_INT_1510_COM_SPI_RO 31 /* * OMAP-310 specific IRQ numbers for level 2 interrupt handler */ -# define OMAP_INT_310_FAC 0 -# define OMAP_INT_310_USB_HHC_2 7 -# define OMAP_INT_310_MCSI1_FE 16 -# define OMAP_INT_310_MCSI2_FE 17 -# define OMAP_INT_310_USB_W2FC_ISO 29 -# define OMAP_INT_310_USB_W2FC_NON_ISO 30 -# define OMAP_INT_310_McBSP2RX_OF 31 +#define OMAP_INT_310_FAC 0 +#define OMAP_INT_310_USB_HHC_2 7 +#define OMAP_INT_310_MCSI1_FE 16 +#define OMAP_INT_310_MCSI2_FE 17 +#define OMAP_INT_310_USB_W2FC_ISO 29 +#define OMAP_INT_310_USB_W2FC_NON_ISO 30 +#define OMAP_INT_310_McBSP2RX_OF 31 /* * OMAP-1610 specific IRQ numbers for level 2 interrupt handler */ -# define OMAP_INT_1610_FAC 0 -# define OMAP_INT_1610_USB_HHC_2 7 -# define OMAP_INT_1610_USB_OTG 8 -# define OMAP_INT_1610_SoSSI 9 -# define OMAP_INT_1610_BT_MCSI1TX 16 -# define OMAP_INT_1610_BT_MCSI1RX 17 -# define OMAP_INT_1610_SoSSI_MATCH 19 -# define OMAP_INT_1610_MEM_STICK 27 -# define OMAP_INT_1610_McBSP2RX_OF 31 -# define OMAP_INT_1610_STI 32 -# define OMAP_INT_1610_STI_WAKEUP 33 -# define OMAP_INT_1610_GPTIMER3 34 -# define OMAP_INT_1610_GPTIMER4 35 -# define OMAP_INT_1610_GPTIMER5 36 -# define OMAP_INT_1610_GPTIMER6 37 -# define OMAP_INT_1610_GPTIMER7 38 -# define OMAP_INT_1610_GPTIMER8 39 -# define OMAP_INT_1610_GPIO_BANK2 40 -# define OMAP_INT_1610_GPIO_BANK3 41 -# define OMAP_INT_1610_MMC2 42 -# define OMAP_INT_1610_CF 43 -# define OMAP_INT_1610_WAKE_UP_REQ 46 -# define OMAP_INT_1610_GPIO_BANK4 48 -# define OMAP_INT_1610_SPI 49 -# define OMAP_INT_1610_DMA_CH6 53 -# define OMAP_INT_1610_DMA_CH7 54 -# define OMAP_INT_1610_DMA_CH8 55 -# define OMAP_INT_1610_DMA_CH9 56 -# define OMAP_INT_1610_DMA_CH10 57 -# define OMAP_INT_1610_DMA_CH11 58 -# define OMAP_INT_1610_DMA_CH12 59 -# define OMAP_INT_1610_DMA_CH13 60 -# define OMAP_INT_1610_DMA_CH14 61 -# define OMAP_INT_1610_DMA_CH15 62 -# define OMAP_INT_1610_NAND 63 +#define OMAP_INT_1610_FAC 0 +#define OMAP_INT_1610_USB_HHC_2 7 +#define OMAP_INT_1610_USB_OTG 8 +#define OMAP_INT_1610_SoSSI 9 +#define OMAP_INT_1610_BT_MCSI1TX 16 +#define OMAP_INT_1610_BT_MCSI1RX 17 +#define OMAP_INT_1610_SoSSI_MATCH 19 +#define OMAP_INT_1610_MEM_STICK 27 +#define OMAP_INT_1610_McBSP2RX_OF 31 +#define OMAP_INT_1610_STI 32 +#define OMAP_INT_1610_STI_WAKEUP 33 +#define OMAP_INT_1610_GPTIMER3 34 +#define OMAP_INT_1610_GPTIMER4 35 +#define OMAP_INT_1610_GPTIMER5 36 +#define OMAP_INT_1610_GPTIMER6 37 +#define OMAP_INT_1610_GPTIMER7 38 +#define OMAP_INT_1610_GPTIMER8 39 +#define OMAP_INT_1610_GPIO_BANK2 40 +#define OMAP_INT_1610_GPIO_BANK3 41 +#define OMAP_INT_1610_MMC2 42 +#define OMAP_INT_1610_CF 43 +#define OMAP_INT_1610_WAKE_UP_REQ 46 +#define OMAP_INT_1610_GPIO_BANK4 48 +#define OMAP_INT_1610_SPI 49 +#define OMAP_INT_1610_DMA_CH6 53 +#define OMAP_INT_1610_DMA_CH7 54 +#define OMAP_INT_1610_DMA_CH8 55 +#define OMAP_INT_1610_DMA_CH9 56 +#define OMAP_INT_1610_DMA_CH10 57 +#define OMAP_INT_1610_DMA_CH11 58 +#define OMAP_INT_1610_DMA_CH12 59 +#define OMAP_INT_1610_DMA_CH13 60 +#define OMAP_INT_1610_DMA_CH14 61 +#define OMAP_INT_1610_DMA_CH15 62 +#define OMAP_INT_1610_NAND 63 /* * OMAP-730 specific IRQ numbers for level 2 interrupt handler */ -# define OMAP_INT_730_HW_ERRORS 0 -# define OMAP_INT_730_NFIQ_PWR_FAIL 1 -# define OMAP_INT_730_CFCD 2 -# define OMAP_INT_730_CFIREQ 3 -# define OMAP_INT_730_I2C 4 -# define OMAP_INT_730_PCC 5 -# define OMAP_INT_730_MPU_EXT_NIRQ 6 -# define OMAP_INT_730_SPI_100K_1 7 -# define OMAP_INT_730_SYREN_SPI 8 -# define OMAP_INT_730_VLYNQ 9 -# define OMAP_INT_730_GPIO_BANK4 10 -# define OMAP_INT_730_McBSP1TX 11 -# define OMAP_INT_730_McBSP1RX 12 -# define OMAP_INT_730_McBSP1RX_OF 13 -# define OMAP_INT_730_UART_MODEM_IRDA_2 14 -# define OMAP_INT_730_UART_MODEM_1 15 -# define OMAP_INT_730_MCSI 16 -# define OMAP_INT_730_uWireTX 17 -# define OMAP_INT_730_uWireRX 18 -# define OMAP_INT_730_SMC_CD 19 -# define OMAP_INT_730_SMC_IREQ 20 -# define OMAP_INT_730_HDQ_1WIRE 21 -# define OMAP_INT_730_TIMER32K 22 -# define OMAP_INT_730_MMC_SDIO 23 -# define OMAP_INT_730_UPLD 24 -# define OMAP_INT_730_USB_HHC_1 27 -# define OMAP_INT_730_USB_HHC_2 28 -# define OMAP_INT_730_USB_GENI 29 -# define OMAP_INT_730_USB_OTG 30 -# define OMAP_INT_730_CAMERA_IF 31 -# define OMAP_INT_730_RNG 32 -# define OMAP_INT_730_DUAL_MODE_TIMER 33 -# define OMAP_INT_730_DBB_RF_EN 34 -# define OMAP_INT_730_MPUIO_KEYPAD 35 -# define OMAP_INT_730_SHA1_MD5 36 -# define OMAP_INT_730_SPI_100K_2 37 -# define OMAP_INT_730_RNG_IDLE 38 -# define OMAP_INT_730_MPUIO 39 -# define OMAP_INT_730_LLPC_LCD_CTRL_OFF 40 -# define OMAP_INT_730_LLPC_OE_FALLING 41 -# define OMAP_INT_730_LLPC_OE_RISING 42 -# define OMAP_INT_730_LLPC_VSYNC 43 -# define OMAP_INT_730_WAKE_UP_REQ 46 -# define OMAP_INT_730_DMA_CH6 53 -# define OMAP_INT_730_DMA_CH7 54 -# define OMAP_INT_730_DMA_CH8 55 -# define OMAP_INT_730_DMA_CH9 56 -# define OMAP_INT_730_DMA_CH10 57 -# define OMAP_INT_730_DMA_CH11 58 -# define OMAP_INT_730_DMA_CH12 59 -# define OMAP_INT_730_DMA_CH13 60 -# define OMAP_INT_730_DMA_CH14 61 -# define OMAP_INT_730_DMA_CH15 62 -# define OMAP_INT_730_NAND 63 - -/* - * OMAP-24xx common IRQ numbers - */ -# define OMAP_INT_24XX_STI 4 -# define OMAP_INT_24XX_SYS_NIRQ 7 -# define OMAP_INT_24XX_L3_IRQ 10 -# define OMAP_INT_24XX_PRCM_MPU_IRQ 11 -# define OMAP_INT_24XX_SDMA_IRQ0 12 -# define OMAP_INT_24XX_SDMA_IRQ1 13 -# define OMAP_INT_24XX_SDMA_IRQ2 14 -# define OMAP_INT_24XX_SDMA_IRQ3 15 -# define OMAP_INT_243X_MCBSP2_IRQ 16 -# define OMAP_INT_243X_MCBSP3_IRQ 17 -# define OMAP_INT_243X_MCBSP4_IRQ 18 -# define OMAP_INT_243X_MCBSP5_IRQ 19 -# define OMAP_INT_24XX_GPMC_IRQ 20 -# define OMAP_INT_24XX_GUFFAW_IRQ 21 -# define OMAP_INT_24XX_IVA_IRQ 22 -# define OMAP_INT_24XX_EAC_IRQ 23 -# define OMAP_INT_24XX_CAM_IRQ 24 -# define OMAP_INT_24XX_DSS_IRQ 25 -# define OMAP_INT_24XX_MAIL_U0_MPU 26 -# define OMAP_INT_24XX_DSP_UMA 27 -# define OMAP_INT_24XX_DSP_MMU 28 -# define OMAP_INT_24XX_GPIO_BANK1 29 -# define OMAP_INT_24XX_GPIO_BANK2 30 -# define OMAP_INT_24XX_GPIO_BANK3 31 -# define OMAP_INT_24XX_GPIO_BANK4 32 -# define OMAP_INT_243X_GPIO_BANK5 33 -# define OMAP_INT_24XX_MAIL_U3_MPU 34 -# define OMAP_INT_24XX_WDT3 35 -# define OMAP_INT_24XX_WDT4 36 -# define OMAP_INT_24XX_GPTIMER1 37 -# define OMAP_INT_24XX_GPTIMER2 38 -# define OMAP_INT_24XX_GPTIMER3 39 -# define OMAP_INT_24XX_GPTIMER4 40 -# define OMAP_INT_24XX_GPTIMER5 41 -# define OMAP_INT_24XX_GPTIMER6 42 -# define OMAP_INT_24XX_GPTIMER7 43 -# define OMAP_INT_24XX_GPTIMER8 44 -# define OMAP_INT_24XX_GPTIMER9 45 -# define OMAP_INT_24XX_GPTIMER10 46 -# define OMAP_INT_24XX_GPTIMER11 47 -# define OMAP_INT_24XX_GPTIMER12 48 -# define OMAP_INT_24XX_PKA_IRQ 50 -# define OMAP_INT_24XX_SHA1MD5_IRQ 51 -# define OMAP_INT_24XX_RNG_IRQ 52 -# define OMAP_INT_24XX_MG_IRQ 53 -# define OMAP_INT_24XX_I2C1_IRQ 56 -# define OMAP_INT_24XX_I2C2_IRQ 57 -# define OMAP_INT_24XX_MCBSP1_IRQ_TX 59 -# define OMAP_INT_24XX_MCBSP1_IRQ_RX 60 -# define OMAP_INT_24XX_MCBSP2_IRQ_TX 62 -# define OMAP_INT_24XX_MCBSP2_IRQ_RX 63 -# define OMAP_INT_243X_MCBSP1_IRQ 64 -# define OMAP_INT_24XX_MCSPI1_IRQ 65 -# define OMAP_INT_24XX_MCSPI2_IRQ 66 -# define OMAP_INT_24XX_SSI1_IRQ0 67 -# define OMAP_INT_24XX_SSI1_IRQ1 68 -# define OMAP_INT_24XX_SSI2_IRQ0 69 -# define OMAP_INT_24XX_SSI2_IRQ1 70 -# define OMAP_INT_24XX_SSI_GDD_IRQ 71 -# define OMAP_INT_24XX_UART1_IRQ 72 -# define OMAP_INT_24XX_UART2_IRQ 73 -# define OMAP_INT_24XX_UART3_IRQ 74 -# define OMAP_INT_24XX_USB_IRQ_GEN 75 -# define OMAP_INT_24XX_USB_IRQ_NISO 76 -# define OMAP_INT_24XX_USB_IRQ_ISO 77 -# define OMAP_INT_24XX_USB_IRQ_HGEN 78 -# define OMAP_INT_24XX_USB_IRQ_HSOF 79 -# define OMAP_INT_24XX_USB_IRQ_OTG 80 -# define OMAP_INT_24XX_VLYNQ_IRQ 81 -# define OMAP_INT_24XX_MMC_IRQ 83 -# define OMAP_INT_24XX_MS_IRQ 84 -# define OMAP_INT_24XX_FAC_IRQ 85 -# define OMAP_INT_24XX_MCSPI3_IRQ 91 -# define OMAP_INT_243X_HS_USB_MC 92 -# define OMAP_INT_243X_HS_USB_DMA 93 -# define OMAP_INT_243X_CARKIT 94 -# define OMAP_INT_34XX_GPTIMER12 95 +#define OMAP_INT_730_HW_ERRORS 0 +#define OMAP_INT_730_NFIQ_PWR_FAIL 1 +#define OMAP_INT_730_CFCD 2 +#define OMAP_INT_730_CFIREQ 3 +#define OMAP_INT_730_I2C 4 +#define OMAP_INT_730_PCC 5 +#define OMAP_INT_730_MPU_EXT_NIRQ 6 +#define OMAP_INT_730_SPI_100K_1 7 +#define OMAP_INT_730_SYREN_SPI 8 +#define OMAP_INT_730_VLYNQ 9 +#define OMAP_INT_730_GPIO_BANK4 10 +#define OMAP_INT_730_McBSP1TX 11 +#define OMAP_INT_730_McBSP1RX 12 +#define OMAP_INT_730_McBSP1RX_OF 13 +#define OMAP_INT_730_UART_MODEM_IRDA_2 14 +#define OMAP_INT_730_UART_MODEM_1 15 +#define OMAP_INT_730_MCSI 16 +#define OMAP_INT_730_uWireTX 17 +#define OMAP_INT_730_uWireRX 18 +#define OMAP_INT_730_SMC_CD 19 +#define OMAP_INT_730_SMC_IREQ 20 +#define OMAP_INT_730_HDQ_1WIRE 21 +#define OMAP_INT_730_TIMER32K 22 +#define OMAP_INT_730_MMC_SDIO 23 +#define OMAP_INT_730_UPLD 24 +#define OMAP_INT_730_USB_HHC_1 27 +#define OMAP_INT_730_USB_HHC_2 28 +#define OMAP_INT_730_USB_GENI 29 +#define OMAP_INT_730_USB_OTG 30 +#define OMAP_INT_730_CAMERA_IF 31 +#define OMAP_INT_730_RNG 32 +#define OMAP_INT_730_DUAL_MODE_TIMER 33 +#define OMAP_INT_730_DBB_RF_EN 34 +#define OMAP_INT_730_MPUIO_KEYPAD 35 +#define OMAP_INT_730_SHA1_MD5 36 +#define OMAP_INT_730_SPI_100K_2 37 +#define OMAP_INT_730_RNG_IDLE 38 +#define OMAP_INT_730_MPUIO 39 +#define OMAP_INT_730_LLPC_LCD_CTRL_OFF 40 +#define OMAP_INT_730_LLPC_OE_FALLING 41 +#define OMAP_INT_730_LLPC_OE_RISING 42 +#define OMAP_INT_730_LLPC_VSYNC 43 +#define OMAP_INT_730_WAKE_UP_REQ 46 +#define OMAP_INT_730_DMA_CH6 53 +#define OMAP_INT_730_DMA_CH7 54 +#define OMAP_INT_730_DMA_CH8 55 +#define OMAP_INT_730_DMA_CH9 56 +#define OMAP_INT_730_DMA_CH10 57 +#define OMAP_INT_730_DMA_CH11 58 +#define OMAP_INT_730_DMA_CH12 59 +#define OMAP_INT_730_DMA_CH13 60 +#define OMAP_INT_730_DMA_CH14 61 +#define OMAP_INT_730_DMA_CH15 62 +#define OMAP_INT_730_NAND 63 /* omap_dma.c */ enum omap_dma_model { omap_dma_3_0, omap_dma_3_1, omap_dma_3_2, - omap_dma_4, }; struct soc_dma_s; @@ -507,9 +353,9 @@ struct dma_irq_map { enum omap_dma_port { emiff = 0, emifs, - imif, /* omap16xx: ocp_t1 */ + imif, /* omap16xx: ocp_t1 */ tipb, - local, /* omap16xx: ocp_t2 */ + local, /* omap16xx: ocp_t2 */ tipb_mpui, __omap_dma_port_last, }; @@ -572,157 +418,71 @@ struct omap_dma_lcd_channel_s { * DMA request numbers for OMAP1 * See /usr/include/asm-arm/arch-omap/dma.h in Linux. */ -# define OMAP_DMA_NO_DEVICE 0 -# define OMAP_DMA_MCSI1_TX 1 -# define OMAP_DMA_MCSI1_RX 2 -# define OMAP_DMA_I2C_RX 3 -# define OMAP_DMA_I2C_TX 4 -# define OMAP_DMA_EXT_NDMA_REQ0 5 -# define OMAP_DMA_EXT_NDMA_REQ1 6 -# define OMAP_DMA_UWIRE_TX 7 -# define OMAP_DMA_MCBSP1_TX 8 -# define OMAP_DMA_MCBSP1_RX 9 -# define OMAP_DMA_MCBSP3_TX 10 -# define OMAP_DMA_MCBSP3_RX 11 -# define OMAP_DMA_UART1_TX 12 -# define OMAP_DMA_UART1_RX 13 -# define OMAP_DMA_UART2_TX 14 -# define OMAP_DMA_UART2_RX 15 -# define OMAP_DMA_MCBSP2_TX 16 -# define OMAP_DMA_MCBSP2_RX 17 -# define OMAP_DMA_UART3_TX 18 -# define OMAP_DMA_UART3_RX 19 -# define OMAP_DMA_CAMERA_IF_RX 20 -# define OMAP_DMA_MMC_TX 21 -# define OMAP_DMA_MMC_RX 22 -# define OMAP_DMA_NAND 23 /* Not in OMAP310 */ -# define OMAP_DMA_IRQ_LCD_LINE 24 /* Not in OMAP310 */ -# define OMAP_DMA_MEMORY_STICK 25 /* Not in OMAP310 */ -# define OMAP_DMA_USB_W2FC_RX0 26 -# define OMAP_DMA_USB_W2FC_RX1 27 -# define OMAP_DMA_USB_W2FC_RX2 28 -# define OMAP_DMA_USB_W2FC_TX0 29 -# define OMAP_DMA_USB_W2FC_TX1 30 -# define OMAP_DMA_USB_W2FC_TX2 31 +#define OMAP_DMA_NO_DEVICE 0 +#define OMAP_DMA_MCSI1_TX 1 +#define OMAP_DMA_MCSI1_RX 2 +#define OMAP_DMA_I2C_RX 3 +#define OMAP_DMA_I2C_TX 4 +#define OMAP_DMA_EXT_NDMA_REQ0 5 +#define OMAP_DMA_EXT_NDMA_REQ1 6 +#define OMAP_DMA_UWIRE_TX 7 +#define OMAP_DMA_MCBSP1_TX 8 +#define OMAP_DMA_MCBSP1_RX 9 +#define OMAP_DMA_MCBSP3_TX 10 +#define OMAP_DMA_MCBSP3_RX 11 +#define OMAP_DMA_UART1_TX 12 +#define OMAP_DMA_UART1_RX 13 +#define OMAP_DMA_UART2_TX 14 +#define OMAP_DMA_UART2_RX 15 +#define OMAP_DMA_MCBSP2_TX 16 +#define OMAP_DMA_MCBSP2_RX 17 +#define OMAP_DMA_UART3_TX 18 +#define OMAP_DMA_UART3_RX 19 +#define OMAP_DMA_CAMERA_IF_RX 20 +#define OMAP_DMA_MMC_TX 21 +#define OMAP_DMA_MMC_RX 22 +#define OMAP_DMA_NAND 23 /* Not in OMAP310 */ +#define OMAP_DMA_IRQ_LCD_LINE 24 /* Not in OMAP310 */ +#define OMAP_DMA_MEMORY_STICK 25 /* Not in OMAP310 */ +#define OMAP_DMA_USB_W2FC_RX0 26 +#define OMAP_DMA_USB_W2FC_RX1 27 +#define OMAP_DMA_USB_W2FC_RX2 28 +#define OMAP_DMA_USB_W2FC_TX0 29 +#define OMAP_DMA_USB_W2FC_TX1 30 +#define OMAP_DMA_USB_W2FC_TX2 31 /* These are only for 1610 */ -# define OMAP_DMA_CRYPTO_DES_IN 32 -# define OMAP_DMA_SPI_TX 33 -# define OMAP_DMA_SPI_RX 34 -# define OMAP_DMA_CRYPTO_HASH 35 -# define OMAP_DMA_CCP_ATTN 36 -# define OMAP_DMA_CCP_FIFO_NOT_EMPTY 37 -# define OMAP_DMA_CMT_APE_TX_CHAN_0 38 -# define OMAP_DMA_CMT_APE_RV_CHAN_0 39 -# define OMAP_DMA_CMT_APE_TX_CHAN_1 40 -# define OMAP_DMA_CMT_APE_RV_CHAN_1 41 -# define OMAP_DMA_CMT_APE_TX_CHAN_2 42 -# define OMAP_DMA_CMT_APE_RV_CHAN_2 43 -# define OMAP_DMA_CMT_APE_TX_CHAN_3 44 -# define OMAP_DMA_CMT_APE_RV_CHAN_3 45 -# define OMAP_DMA_CMT_APE_TX_CHAN_4 46 -# define OMAP_DMA_CMT_APE_RV_CHAN_4 47 -# define OMAP_DMA_CMT_APE_TX_CHAN_5 48 -# define OMAP_DMA_CMT_APE_RV_CHAN_5 49 -# define OMAP_DMA_CMT_APE_TX_CHAN_6 50 -# define OMAP_DMA_CMT_APE_RV_CHAN_6 51 -# define OMAP_DMA_CMT_APE_TX_CHAN_7 52 -# define OMAP_DMA_CMT_APE_RV_CHAN_7 53 -# define OMAP_DMA_MMC2_TX 54 -# define OMAP_DMA_MMC2_RX 55 -# define OMAP_DMA_CRYPTO_DES_OUT 56 - -/* - * DMA request numbers for the OMAP2 - */ -# define OMAP24XX_DMA_NO_DEVICE 0 -# define OMAP24XX_DMA_XTI_DMA 1 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_EXT_DMAREQ0 2 -# define OMAP24XX_DMA_EXT_DMAREQ1 3 -# define OMAP24XX_DMA_GPMC 4 -# define OMAP24XX_DMA_GFX 5 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_DSS 6 -# define OMAP24XX_DMA_VLYNQ_TX 7 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_CWT 8 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_AES_TX 9 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_AES_RX 10 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_DES_TX 11 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_DES_RX 12 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_SHA1MD5_RX 13 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_EXT_DMAREQ2 14 -# define OMAP24XX_DMA_EXT_DMAREQ3 15 -# define OMAP24XX_DMA_EXT_DMAREQ4 16 -# define OMAP24XX_DMA_EAC_AC_RD 17 -# define OMAP24XX_DMA_EAC_AC_WR 18 -# define OMAP24XX_DMA_EAC_MD_UL_RD 19 -# define OMAP24XX_DMA_EAC_MD_UL_WR 20 -# define OMAP24XX_DMA_EAC_MD_DL_RD 21 -# define OMAP24XX_DMA_EAC_MD_DL_WR 22 -# define OMAP24XX_DMA_EAC_BT_UL_RD 23 -# define OMAP24XX_DMA_EAC_BT_UL_WR 24 -# define OMAP24XX_DMA_EAC_BT_DL_RD 25 -# define OMAP24XX_DMA_EAC_BT_DL_WR 26 -# define OMAP24XX_DMA_I2C1_TX 27 -# define OMAP24XX_DMA_I2C1_RX 28 -# define OMAP24XX_DMA_I2C2_TX 29 -# define OMAP24XX_DMA_I2C2_RX 30 -# define OMAP24XX_DMA_MCBSP1_TX 31 -# define OMAP24XX_DMA_MCBSP1_RX 32 -# define OMAP24XX_DMA_MCBSP2_TX 33 -# define OMAP24XX_DMA_MCBSP2_RX 34 -# define OMAP24XX_DMA_SPI1_TX0 35 -# define OMAP24XX_DMA_SPI1_RX0 36 -# define OMAP24XX_DMA_SPI1_TX1 37 -# define OMAP24XX_DMA_SPI1_RX1 38 -# define OMAP24XX_DMA_SPI1_TX2 39 -# define OMAP24XX_DMA_SPI1_RX2 40 -# define OMAP24XX_DMA_SPI1_TX3 41 -# define OMAP24XX_DMA_SPI1_RX3 42 -# define OMAP24XX_DMA_SPI2_TX0 43 -# define OMAP24XX_DMA_SPI2_RX0 44 -# define OMAP24XX_DMA_SPI2_TX1 45 -# define OMAP24XX_DMA_SPI2_RX1 46 - -# define OMAP24XX_DMA_UART1_TX 49 -# define OMAP24XX_DMA_UART1_RX 50 -# define OMAP24XX_DMA_UART2_TX 51 -# define OMAP24XX_DMA_UART2_RX 52 -# define OMAP24XX_DMA_UART3_TX 53 -# define OMAP24XX_DMA_UART3_RX 54 -# define OMAP24XX_DMA_USB_W2FC_TX0 55 -# define OMAP24XX_DMA_USB_W2FC_RX0 56 -# define OMAP24XX_DMA_USB_W2FC_TX1 57 -# define OMAP24XX_DMA_USB_W2FC_RX1 58 -# define OMAP24XX_DMA_USB_W2FC_TX2 59 -# define OMAP24XX_DMA_USB_W2FC_RX2 60 -# define OMAP24XX_DMA_MMC1_TX 61 -# define OMAP24XX_DMA_MMC1_RX 62 -# define OMAP24XX_DMA_MS 63 /* Not in OMAP2420 */ -# define OMAP24XX_DMA_EXT_DMAREQ5 64 - -/* omap[123].c */ -/* OMAP2 gp timer */ -struct omap_gp_timer_s; -struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta, - qemu_irq irq, omap_clk fclk, omap_clk iclk); -void omap_gp_timer_reset(struct omap_gp_timer_s *s); - -/* OMAP2 sysctimer */ -struct omap_synctimer_s; -struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta, - struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk); -void omap_synctimer_reset(struct omap_synctimer_s *s); +#define OMAP_DMA_CRYPTO_DES_IN 32 +#define OMAP_DMA_SPI_TX 33 +#define OMAP_DMA_SPI_RX 34 +#define OMAP_DMA_CRYPTO_HASH 35 +#define OMAP_DMA_CCP_ATTN 36 +#define OMAP_DMA_CCP_FIFO_NOT_EMPTY 37 +#define OMAP_DMA_CMT_APE_TX_CHAN_0 38 +#define OMAP_DMA_CMT_APE_RV_CHAN_0 39 +#define OMAP_DMA_CMT_APE_TX_CHAN_1 40 +#define OMAP_DMA_CMT_APE_RV_CHAN_1 41 +#define OMAP_DMA_CMT_APE_TX_CHAN_2 42 +#define OMAP_DMA_CMT_APE_RV_CHAN_2 43 +#define OMAP_DMA_CMT_APE_TX_CHAN_3 44 +#define OMAP_DMA_CMT_APE_RV_CHAN_3 45 +#define OMAP_DMA_CMT_APE_TX_CHAN_4 46 +#define OMAP_DMA_CMT_APE_RV_CHAN_4 47 +#define OMAP_DMA_CMT_APE_TX_CHAN_5 48 +#define OMAP_DMA_CMT_APE_RV_CHAN_5 49 +#define OMAP_DMA_CMT_APE_TX_CHAN_6 50 +#define OMAP_DMA_CMT_APE_RV_CHAN_6 51 +#define OMAP_DMA_CMT_APE_TX_CHAN_7 52 +#define OMAP_DMA_CMT_APE_RV_CHAN_7 53 +#define OMAP_DMA_MMC2_TX 54 +#define OMAP_DMA_MMC2_RX 55 +#define OMAP_DMA_CRYPTO_DES_OUT 56 struct omap_uart_s; struct omap_uart_s *omap_uart_init(hwaddr base, qemu_irq irq, omap_clk fclk, omap_clk iclk, qemu_irq txdma, qemu_irq rxdma, const char *label, Chardev *chr); -struct omap_uart_s *omap2_uart_init(MemoryRegion *sysmem, - struct omap_target_agent_s *ta, - qemu_irq irq, omap_clk fclk, omap_clk iclk, - qemu_irq txdma, qemu_irq rxdma, - const char *label, Chardev *chr); void omap_uart_reset(struct omap_uart_s *s); struct omap_mpuio_s; @@ -731,17 +491,6 @@ void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler); void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down); struct omap_uwire_s; -void omap_uwire_attach(struct omap_uwire_s *s, - uWireSlave *slave, int chipselect); - -/* OMAP2 spi */ -struct omap_mcspi_s; -struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum, - qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk); -void omap_mcspi_attach(struct omap_mcspi_s *s, - uint32_t (*txrx)(void *opaque, uint32_t, int), void *opaque, - int chipselect); -void omap_mcspi_reset(struct omap_mcspi_s *s); struct I2SCodec { void *opaque; @@ -770,9 +519,6 @@ struct I2SCodec { struct omap_mcbsp_s; void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave); -void omap_tap_init(struct omap_target_agent_s *ta, - struct omap_mpu_state_s *mpu); - /* omap_lcdc.c */ struct omap_lcd_panel_s; void omap_lcdc_reset(struct omap_lcd_panel_s *s); @@ -782,61 +528,29 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem, struct omap_dma_lcd_channel_s *dma, omap_clk clk); -/* omap_dss.c */ -struct rfbi_chip_s { - void *opaque; - void (*write)(void *opaque, int dc, uint16_t value); - void (*block)(void *opaque, int dc, void *buf, size_t len, int pitch); - uint16_t (*read)(void *opaque, int dc); -}; -struct omap_dss_s; -void omap_dss_reset(struct omap_dss_s *s); -struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta, - MemoryRegion *sysmem, - hwaddr l3_base, - qemu_irq irq, qemu_irq drq, - omap_clk fck1, omap_clk fck2, omap_clk ck54m, - omap_clk ick1, omap_clk ick2); -void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip); - /* omap_mmc.c */ -struct omap_mmc_s; -struct omap_mmc_s *omap_mmc_init(hwaddr base, - MemoryRegion *sysmem, - BlockBackend *blk, - qemu_irq irq, qemu_irq dma[], omap_clk clk); -struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta, - BlockBackend *blk, qemu_irq irq, qemu_irq dma[], - omap_clk fclk, omap_clk iclk); -void omap_mmc_reset(struct omap_mmc_s *s); -void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover); -void omap_mmc_enable(struct omap_mmc_s *s, int enable); +#define TYPE_OMAP_MMC "omap-mmc" +OBJECT_DECLARE_SIMPLE_TYPE(OMAPMMCState, OMAP_MMC) + +DeviceState *omap_mmc_init(hwaddr base, + MemoryRegion *sysmem, + qemu_irq irq, qemu_irq dma[], omap_clk clk); +/* TODO: clock framework (see above) */ +void omap_mmc_set_clk(DeviceState *dev, omap_clk clk); + /* omap_i2c.c */ I2CBus *omap_i2c_bus(DeviceState *omap_i2c); -# define cpu_is_omap310(cpu) (cpu->mpu_model == omap310) -# define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510) -# define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610) -# define cpu_is_omap1710(cpu) (cpu->mpu_model == omap1710) -# define cpu_is_omap2410(cpu) (cpu->mpu_model == omap2410) -# define cpu_is_omap2420(cpu) (cpu->mpu_model == omap2420) -# define cpu_is_omap2430(cpu) (cpu->mpu_model == omap2430) -# define cpu_is_omap3430(cpu) (cpu->mpu_model == omap3430) -# define cpu_is_omap3630(cpu) (cpu->mpu_model == omap3630) - -# define cpu_is_omap15xx(cpu) \ +#define cpu_is_omap310(cpu) (cpu->mpu_model == omap310) +#define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510) +#define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610) +#define cpu_is_omap1710(cpu) (cpu->mpu_model == omap1710) + +#define cpu_is_omap15xx(cpu) \ (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu)) -# define cpu_is_omap16xx(cpu) \ +#define cpu_is_omap16xx(cpu) \ (cpu_is_omap1610(cpu) || cpu_is_omap1710(cpu)) -# define cpu_is_omap24xx(cpu) \ - (cpu_is_omap2410(cpu) || cpu_is_omap2420(cpu) || cpu_is_omap2430(cpu)) - -# define cpu_class_omap1(cpu) \ - (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu)) -# define cpu_class_omap2(cpu) cpu_is_omap24xx(cpu) -# define cpu_class_omap3(cpu) \ - (cpu_is_omap3430(cpu) || cpu_is_omap3630(cpu)) struct omap_mpu_state_s { enum omap_mpu_model { @@ -844,13 +558,6 @@ struct omap_mpu_state_s { omap1510, omap1610, omap1710, - omap2410, - omap2420, - omap2422, - omap2423, - omap2430, - omap3430, - omap3630, } mpu_model; ARMCPU *cpu; @@ -897,7 +604,7 @@ struct omap_mpu_state_s { /* MPU public TIPB peripherals */ struct omap_32khz_timer_s *os_timer; - struct omap_mmc_s *mmc; + DeviceState *mmc; struct omap_mpuio_s *mpuio; @@ -960,33 +667,12 @@ struct omap_mpu_state_s { uint16_t dsp_idlect2; uint16_t dsp_rstct2; } clkm; - - /* OMAP2-only peripherals */ - struct omap_l4_s *l4; - - struct omap_gp_timer_s *gptimer[12]; - struct omap_synctimer_s *synctimer; - - struct omap_prcm_s *prcm; - struct omap_sdrc_s *sdrc; - struct omap_gpmc_s *gpmc; - struct omap_sysctl_s *sysc; - - struct omap_mcspi_s *mcspi[2]; - - struct omap_dss_s *dss; - - struct omap_eac_s *eac; }; /* omap1.c */ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *sdram, const char *core); -/* omap2.c */ -struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sdram, - const char *core); - uint32_t omap_badwidth_read8(void *opaque, hwaddr addr); void omap_badwidth_write8(void *opaque, hwaddr addr, uint32_t value); @@ -999,43 +685,14 @@ void omap_badwidth_write32(void *opaque, hwaddr addr, void omap_mpu_wakeup(void *opaque, int irq, int req); -# define OMAP_BAD_REG(paddr) \ +#define OMAP_BAD_REG(paddr) \ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad register %#08"HWADDR_PRIx"\n", \ __func__, paddr) -# define OMAP_RO_REG(paddr) \ +#define OMAP_RO_REG(paddr) \ qemu_log_mask(LOG_GUEST_ERROR, "%s: Read-only register %#08" \ HWADDR_PRIx "\n", \ __func__, paddr) -/* OMAP-specific Linux bootloader tags for the ATAG_BOARD area - * (Board-specific tags are not here) - */ -#define OMAP_TAG_CLOCK 0x4f01 -#define OMAP_TAG_MMC 0x4f02 -#define OMAP_TAG_SERIAL_CONSOLE 0x4f03 -#define OMAP_TAG_USB 0x4f04 -#define OMAP_TAG_LCD 0x4f05 -#define OMAP_TAG_GPIO_SWITCH 0x4f06 -#define OMAP_TAG_UART 0x4f07 -#define OMAP_TAG_FBMEM 0x4f08 -#define OMAP_TAG_STI_CONSOLE 0x4f09 -#define OMAP_TAG_CAMERA_SENSOR 0x4f0a -#define OMAP_TAG_PARTITION 0x4f0b -#define OMAP_TAG_TEA5761 0x4f10 -#define OMAP_TAG_TMP105 0x4f11 -#define OMAP_TAG_BOOT_REASON 0x4f80 -#define OMAP_TAG_FLASH_PART_STR 0x4f81 -#define OMAP_TAG_VERSION_STR 0x4f82 - -enum { - OMAP_GPIOSW_TYPE_COVER = 0 << 4, - OMAP_GPIOSW_TYPE_CONNECTION = 1 << 4, - OMAP_GPIOSW_TYPE_ACTIVITY = 2 << 4, -}; - -#define OMAP_GPIOSW_INVERTED 0x0001 -#define OMAP_GPIOSW_OUTPUT 0x0002 - -# define OMAP_MPUI_REG_MASK 0x000007ff +#define OMAP_MPUI_REG_MASK 0x000007ff #endif diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h deleted file mode 100644 index 4c6caee..0000000 --- a/include/hw/arm/pxa.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Intel XScale PXA255/270 processor support. - * - * Copyright (c) 2006 Openedhand Ltd. - * Written by Andrzej Zaborowski <balrog@zabor.org> - * - * This code is licensed under the GNU GPL v2. - */ - -#ifndef PXA_H -#define PXA_H - -#include "exec/memory.h" -#include "target/arm/cpu-qom.h" -#include "hw/pcmcia.h" -#include "qom/object.h" - -/* Interrupt numbers */ -# define PXA2XX_PIC_SSP3 0 -# define PXA2XX_PIC_USBH2 2 -# define PXA2XX_PIC_USBH1 3 -# define PXA2XX_PIC_KEYPAD 4 -# define PXA2XX_PIC_PWRI2C 6 -# define PXA25X_PIC_HWUART 7 -# define PXA27X_PIC_OST_4_11 7 -# define PXA2XX_PIC_GPIO_0 8 -# define PXA2XX_PIC_GPIO_1 9 -# define PXA2XX_PIC_GPIO_X 10 -# define PXA2XX_PIC_I2S 13 -# define PXA26X_PIC_ASSP 15 -# define PXA25X_PIC_NSSP 16 -# define PXA27X_PIC_SSP2 16 -# define PXA2XX_PIC_LCD 17 -# define PXA2XX_PIC_I2C 18 -# define PXA2XX_PIC_ICP 19 -# define PXA2XX_PIC_STUART 20 -# define PXA2XX_PIC_BTUART 21 -# define PXA2XX_PIC_FFUART 22 -# define PXA2XX_PIC_MMC 23 -# define PXA2XX_PIC_SSP 24 -# define PXA2XX_PIC_DMA 25 -# define PXA2XX_PIC_OST_0 26 -# define PXA2XX_PIC_RTC1HZ 30 -# define PXA2XX_PIC_RTCALARM 31 - -/* DMA requests */ -# define PXA2XX_RX_RQ_I2S 2 -# define PXA2XX_TX_RQ_I2S 3 -# define PXA2XX_RX_RQ_BTUART 4 -# define PXA2XX_TX_RQ_BTUART 5 -# define PXA2XX_RX_RQ_FFUART 6 -# define PXA2XX_TX_RQ_FFUART 7 -# define PXA2XX_RX_RQ_SSP1 13 -# define PXA2XX_TX_RQ_SSP1 14 -# define PXA2XX_RX_RQ_SSP2 15 -# define PXA2XX_TX_RQ_SSP2 16 -# define PXA2XX_RX_RQ_ICP 17 -# define PXA2XX_TX_RQ_ICP 18 -# define PXA2XX_RX_RQ_STUART 19 -# define PXA2XX_TX_RQ_STUART 20 -# define PXA2XX_RX_RQ_MMCI 21 -# define PXA2XX_TX_RQ_MMCI 22 -# define PXA2XX_USB_RQ(x) ((x) + 24) -# define PXA2XX_RX_RQ_SSP3 66 -# define PXA2XX_TX_RQ_SSP3 67 - -# define PXA2XX_SDRAM_BASE 0xa0000000 -# define PXA2XX_INTERNAL_BASE 0x5c000000 -# define PXA2XX_INTERNAL_SIZE 0x40000 - -/* pxa2xx_pic.c */ -DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu); - -/* pxa2xx_gpio.c */ -DeviceState *pxa2xx_gpio_init(hwaddr base, - ARMCPU *cpu, DeviceState *pic, int lines); -void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler); - -/* pxa2xx_dma.c */ -DeviceState *pxa255_dma_init(hwaddr base, qemu_irq irq); -DeviceState *pxa27x_dma_init(hwaddr base, qemu_irq irq); - -/* pxa2xx_lcd.c */ -typedef struct PXA2xxLCDState PXA2xxLCDState; -PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem, - hwaddr base, qemu_irq irq); -void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler); - -/* pxa2xx_mmci.c */ -#define TYPE_PXA2XX_MMCI "pxa2xx-mmci" -OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxMMCIState, PXA2XX_MMCI) - -PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem, - hwaddr base, - qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma); -void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly, - qemu_irq coverswitch); - -/* pxa2xx_pcmcia.c */ -#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia" -OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA) - -int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card); -int pxa2xx_pcmcia_detach(void *opaque); -void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq); - -/* pxa2xx_keypad.c */ -struct keymap { - int8_t column; - int8_t row; -}; -typedef struct PXA2xxKeyPadState PXA2xxKeyPadState; -PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem, - hwaddr base, - qemu_irq irq); -void pxa27x_register_keypad(PXA2xxKeyPadState *kp, - const struct keymap *map, int size); - -/* pxa2xx.c */ -#define TYPE_PXA2XX_I2C "pxa2xx_i2c" -OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CState, PXA2XX_I2C) - -PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base, - qemu_irq irq, uint32_t page_size); -I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s); - -typedef struct PXA2xxI2SState PXA2xxI2SState; - -#define TYPE_PXA2XX_FIR "pxa2xx-fir" -OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxFIrState, PXA2XX_FIR) - -typedef struct { - ARMCPU *cpu; - DeviceState *pic; - qemu_irq reset; - MemoryRegion sdram; - MemoryRegion internal; - MemoryRegion cm_iomem; - MemoryRegion mm_iomem; - MemoryRegion pm_iomem; - DeviceState *dma; - DeviceState *gpio; - PXA2xxLCDState *lcd; - SSIBus **ssp; - PXA2xxI2CState *i2c[2]; - PXA2xxMMCIState *mmc; - PXA2xxPCMCIAState *pcmcia[2]; - PXA2xxI2SState *i2s; - PXA2xxFIrState *fir; - PXA2xxKeyPadState *kp; - - /* Power management */ - hwaddr pm_base; - uint32_t pm_regs[0x40]; - - /* Clock management */ - hwaddr cm_base; - uint32_t cm_regs[4]; - uint32_t clkcfg; - - /* Memory management */ - hwaddr mm_base; - uint32_t mm_regs[0x1a]; - - /* Performance monitoring */ - uint32_t pmnc; -} PXA2xxState; - -struct PXA2xxI2SState { - MemoryRegion iomem; - qemu_irq irq; - qemu_irq rx_dma; - qemu_irq tx_dma; - void (*data_req)(void *, int, int); - - uint32_t control[2]; - uint32_t status; - uint32_t mask; - uint32_t clk; - - int enable; - int rx_len; - int tx_len; - void (*codec_out)(void *, uint32_t); - uint32_t (*codec_in)(void *); - void *opaque; - - int fifo_len; - uint32_t fifo[16]; -}; - -# define PA_FMT "0x%08lx" - -PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision); -PXA2xxState *pxa255_init(unsigned int sdram_size); - -#endif /* PXA_H */ diff --git a/include/hw/arm/sharpsl.h b/include/hw/arm/sharpsl.h index e986b28..1e3992f 100644 --- a/include/hw/arm/sharpsl.h +++ b/include/hw/arm/sharpsl.h @@ -11,7 +11,7 @@ /* zaurus.c */ -#define SL_PXA_PARAM_BASE 0xa0000a00 +#define SL_PXA_PARAM_BASE 0xa0000a00 void sl_bootparam_write(hwaddr ptr); #endif diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h index d1a4a64..e5e2d09 100644 --- a/include/hw/arm/smmu-common.h +++ b/include/hw/arm/smmu-common.h @@ -110,7 +110,6 @@ typedef struct SMMUTransCfg { /* Used by stage-1 only. */ bool aa64; /* arch64 or aarch32 translation table */ bool record_faults; /* record fault events */ - uint64_t ttb; /* TT base address */ uint8_t oas; /* output address width */ uint8_t tbi; /* Top Byte Ignore */ int asid; @@ -143,6 +142,11 @@ typedef struct SMMUIOTLBKey { uint8_t level; } SMMUIOTLBKey; +typedef struct SMMUSIDRange { + uint32_t start; + uint32_t end; +} SMMUSIDRange; + struct SMMUState { /* <private> */ SysBusDevice dev; @@ -220,6 +224,7 @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, int vmid, dma_addr_t iova, uint8_t tg, uint64_t num_pages, uint8_t ttl); void smmu_iotlb_inv_ipa(SMMUState *s, int vmid, dma_addr_t ipa, uint8_t tg, uint64_t num_pages, uint8_t ttl); +void smmu_configs_inv_sid_range(SMMUState *s, SMMUSIDRange sid_range); /* Unmap the range of all the notifiers registered to any IOMMU mr */ void smmu_inv_notifiers_all(SMMUState *s); diff --git a/include/hw/arm/soc_dma.h b/include/hw/arm/soc_dma.h index e93a749..bcdb914 100644 --- a/include/hw/arm/soc_dma.h +++ b/include/hw/arm/soc_dma.h @@ -54,7 +54,7 @@ struct soc_dma_ch_s { int bytes; /* Initialised by the DMA module, call soc_dma_ch_update after writing. */ enum soc_dma_access_type type[2]; - hwaddr vaddr[2]; /* Updated by .transfer_fn(). */ + hwaddr vaddr[2]; /* Updated by .transfer_fn(). */ /* Private */ void *paddr[2]; soc_dma_io_t io_fn[2]; @@ -70,7 +70,7 @@ struct soc_dma_ch_s { struct soc_dma_s { /* Following fields are set by the SoC DMA module and can be used * by anybody. */ - uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */ + uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */ qemu_irq *drq; void *opaque; int64_t freq; diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h index d15c03c..2eeada6 100644 --- a/include/hw/arm/stm32f405_soc.h +++ b/include/hw/arm/stm32f405_soc.h @@ -25,6 +25,7 @@ #ifndef HW_ARM_STM32F405_SOC_H #define HW_ARM_STM32F405_SOC_H +#include "hw/misc/stm32_rcc.h" #include "hw/misc/stm32f4xx_syscfg.h" #include "hw/timer/stm32f2xx_timer.h" #include "hw/char/stm32f2xx_usart.h" @@ -55,6 +56,7 @@ struct STM32F405State { ARMv7MState armv7m; + STM32RccState rcc; STM32F4xxSyscfgState syscfg; STM32F4xxExtiState exti; STM32F2XXUsartState usart[STM_NUM_USARTS]; diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h index c243fb0..c2fae6e 100644 --- a/include/hw/arm/stm32l4x5_soc.h +++ b/include/hw/arm/stm32l4x5_soc.h @@ -24,7 +24,7 @@ #ifndef HW_ARM_STM32L4x5_SOC_H #define HW_ARM_STM32L4x5_SOC_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/arm/armv7m.h" #include "hw/or-irq.h" #include "hw/misc/stm32l4x5_syscfg.h" diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index ab961bb..9a1b0f5 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -36,7 +36,7 @@ #include "hw/arm/boot.h" #include "hw/arm/bsa.h" #include "hw/block/flash.h" -#include "sysemu/kvm.h" +#include "system/kvm.h" #include "hw/intc/arm_gicv3_common.h" #include "qom/object.h" @@ -47,6 +47,9 @@ /* See Linux kernel arch/arm64/include/asm/pvclock-abi.h */ #define PVTIME_SIZE_PER_CPU 64 +/* GPIO pins */ +#define GPIO_PIN_POWER_BUTTON 3 + enum { VIRT_FLASH, VIRT_MEM, @@ -114,14 +117,8 @@ typedef enum VirtGICType { struct VirtMachineClass { MachineClass parent; - bool disallow_affinity_adjustment; - bool no_its; bool no_tcg_its; - bool no_pmu; - bool claim_edge_triggered_timers; - bool smbios_old_sys_ver; bool no_highmem_compact; - bool no_highmem_ecam; bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */ bool kvm_no_adjvtime; bool no_kvm_steal_time; @@ -131,6 +128,7 @@ struct VirtMachineClass { bool no_cpu_topology; bool no_tcg_lpa2; bool no_ns_el2_virt_timer_irq; + bool no_nested_smmu; }; struct VirtMachineState { diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 025beb5..05ed641 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -78,6 +78,7 @@ struct Versal { struct { PL011State uart[XLNX_VERSAL_NR_UARTS]; CadenceGEMState gem[XLNX_VERSAL_NR_GEMS]; + OrIRQState gem_irq_orgate[XLNX_VERSAL_NR_GEMS]; XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS]; VersalUsb2 usb; CanBusState *canbus[XLNX_VERSAL_NR_CANFD]; diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h index 48f7948..c137ac5 100644 --- a/include/hw/arm/xlnx-zynqmp.h +++ b/include/hw/arm/xlnx-zynqmp.h @@ -116,6 +116,7 @@ struct XlnxZynqMPState { MemoryRegion mr_unimp[XLNX_ZYNQMP_NUM_UNIMP_AREAS]; CadenceGEMState gem[XLNX_ZYNQMP_NUM_GEMS]; + OrIRQState gem_irq_orgate[XLNX_ZYNQMP_NUM_GEMS]; CadenceUARTState uart[XLNX_ZYNQMP_NUM_UARTS]; XlnxZynqMPCANState can[XLNX_ZYNQMP_NUM_CAN]; SysbusAHCIState sata; diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h index 2b5ccd9..3671f01 100644 --- a/include/hw/block/flash.h +++ b/include/hw/block/flash.h @@ -44,38 +44,6 @@ PFlashCFI02 *pflash_cfi02_register(hwaddr base, uint16_t unlock_addr1, int be); -/* nand.c */ -DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id); -void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale, - uint8_t ce, uint8_t wp, uint8_t gnd); -void nand_getpins(DeviceState *dev, int *rb); -void nand_setio(DeviceState *dev, uint32_t value); -uint32_t nand_getio(DeviceState *dev); -uint32_t nand_getbuswidth(DeviceState *dev); - -#define NAND_MFR_TOSHIBA 0x98 -#define NAND_MFR_SAMSUNG 0xec -#define NAND_MFR_FUJITSU 0x04 -#define NAND_MFR_NATIONAL 0x8f -#define NAND_MFR_RENESAS 0x07 -#define NAND_MFR_STMICRO 0x20 -#define NAND_MFR_HYNIX 0xad -#define NAND_MFR_MICRON 0x2c - -/* onenand.c */ -void *onenand_raw_otp(DeviceState *onenand_device); - -/* ecc.c */ -typedef struct { - uint8_t cp; /* Column parity */ - uint16_t lp[2]; /* Line parity */ - uint16_t count; -} ECCState; - -uint8_t ecc_digest(ECCState *s, uint8_t sample); -void ecc_reset(ECCState *s); -extern const VMStateDescription vmstate_ecc_state; - /* m25p80.c */ #define TYPE_M25P80 "m25p80-generic" diff --git a/include/hw/boards.h b/include/hw/boards.h index 48ff6d8..f424b2b 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -3,13 +3,14 @@ #ifndef HW_BOARDS_H #define HW_BOARDS_H -#include "exec/memory.h" -#include "sysemu/hostmem.h" -#include "sysemu/blockdev.h" +#include "system/memory.h" +#include "system/hostmem.h" +#include "system/blockdev.h" #include "qapi/qapi-types-machine.h" #include "qemu/module.h" #include "qom/object.h" #include "hw/core/cpu.h" +#include "hw/resettable.h" #define TYPE_MACHINE_SUFFIX "-machine" @@ -43,8 +44,16 @@ void machine_set_cpu_numa_node(MachineState *machine, Error **errp); void machine_parse_smp_config(MachineState *ms, const SMPConfiguration *config, Error **errp); +bool machine_parse_smp_cache(MachineState *ms, + const SmpCachePropertiesList *caches, + Error **errp); unsigned int machine_topo_get_cores_per_socket(const MachineState *ms); unsigned int machine_topo_get_threads_per_socket(const MachineState *ms); +CpuTopologyLevel machine_get_cache_topo_level(const MachineState *ms, + CacheLevelAndType cache); +void machine_set_cache_topo_level(MachineState *ms, CacheLevelAndType cache, + CpuTopologyLevel level); +bool machine_check_smp_cache(const MachineState *ms, Error **errp); void machine_memory_devices_init(MachineState *ms, hwaddr base, uint64_t size); /** @@ -145,6 +154,10 @@ typedef struct { * @books_supported - whether books are supported by the machine * @drawers_supported - whether drawers are supported by the machine * @modules_supported - whether modules are supported by the machine + * @cache_supported - whether cache (l1d, l1i, l2 and l3) configuration are + * supported by the machine + * @has_caches - whether cache properties are explicitly specified in the + * user provided smp-cache configuration */ typedef struct { bool prefer_sockets; @@ -154,6 +167,8 @@ typedef struct { bool books_supported; bool drawers_supported; bool modules_supported; + bool cache_supported[CACHE_LEVEL_AND_TYPE__MAX]; + bool has_caches; } SMPCompatProps; /** @@ -215,6 +230,10 @@ typedef struct { * Return the type of KVM corresponding to the kvm-type string option or * computed based on other criteria such as the host kernel capabilities. * kvm-type may be NULL if it is not needed. + * @hvf_get_physical_address_range: + * Returns the physical address range in bits to use for the HVF virtual + * machine based on the current boards memory map. This may be NULL if it + * is not needed. * @numa_mem_supported: * true if '--numa node.mem' option is supported and false otherwise * @hotplug_allowed: @@ -253,9 +272,10 @@ struct MachineClass { const char *deprecation_reason; void (*init)(MachineState *state); - void (*reset)(MachineState *state, ShutdownCause reason); + void (*reset)(MachineState *state, ResetType type); void (*wakeup)(MachineState *state); int (*kvm_type)(MachineState *machine, const char *arg); + int (*hvf_get_physical_address_range)(MachineState *machine); BlockInterfaceType block_default_type; int units_per_default_bus; @@ -266,9 +286,8 @@ struct MachineClass { no_parallel:1, no_floppy:1, no_cdrom:1, - no_sdcard:1, - pci_allow_0_address:1, - legacy_fw_cfg_order:1; + pci_allow_0_address:1; + bool auto_create_sdcard; bool is_default; const char *default_machine_opts; const char *default_boot_order; @@ -308,6 +327,8 @@ struct MachineClass { int64_t (*get_default_cpu_node_id)(const MachineState *ms, int idx); ram_addr_t (*fixup_ram_size)(ram_addr_t size); uint64_t smbios_memory_device_size; + bool (*create_default_memdev)(MachineState *ms, const char *path, + Error **errp); }; /** @@ -363,6 +384,10 @@ typedef struct CpuTopology { unsigned int max_cpus; } CpuTopology; +typedef struct SmpCache { + SmpCacheProperties props[CACHE_LEVEL_AND_TYPE__MAX]; +} SmpCache; + /** * MachineState: */ @@ -387,6 +412,7 @@ struct MachineState { bool enable_graphics; ConfidentialGuestSupport *cgs; HostMemoryBackend *memdev; + bool aux_ram_share; /* * convenience alias to ram_memdev_id backend memory region * or to numa container memory region @@ -408,11 +434,13 @@ struct MachineState { BootConfiguration boot_config; char *kernel_filename; char *kernel_cmdline; + char *shim_filename; char *initrd_filename; const char *cpu_type; AccelState *accelerator; CPUArchIdList *possible_cpus; CpuTopology smp; + SmpCache smp_cache; struct NVDIMMState *nvdimms_state; struct NumaState *numa_state; }; @@ -607,7 +635,11 @@ struct MachineState { /* * How many years/major releases for each phase * of the life cycle. Assumes use of versioning - * scheme where major is bumped each year + * scheme where major is bumped each year. + * + * These values must match the ver_machine_deprecation_version + * and ver_machine_deletion_version logic in docs/conf.py and + * the text in docs/about/deprecated.rst */ #define MACHINE_VER_DELETION_MAJOR 6 #define MACHINE_VER_DEPRECATION_MAJOR 3 @@ -621,11 +653,42 @@ struct MachineState { " years old are subject to deletion after " \ stringify(MACHINE_VER_DELETION_MAJOR) " years" -#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \ +#define _MACHINE_VER_IS_CURRENT_EXPIRED(cutoff, major, minor) \ (((QEMU_VERSION_MAJOR - major) > cutoff) || \ (((QEMU_VERSION_MAJOR - major) == cutoff) && \ (QEMU_VERSION_MINOR - minor) >= 0)) +#define _MACHINE_VER_IS_NEXT_MINOR_EXPIRED(cutoff, major, minor) \ + (((QEMU_VERSION_MAJOR - major) > cutoff) || \ + (((QEMU_VERSION_MAJOR - major) == cutoff) && \ + ((QEMU_VERSION_MINOR + 1) - minor) >= 0)) + +#define _MACHINE_VER_IS_NEXT_MAJOR_EXPIRED(cutoff, major, minor) \ + ((((QEMU_VERSION_MAJOR + 1) - major) > cutoff) || \ + ((((QEMU_VERSION_MAJOR + 1) - major) == cutoff) && \ + (0 - minor) >= 0)) + +/* + * - The first check applies to formal releases + * - The second check applies to dev snapshots / release candidates + * where the next major version is the same. + * e.g. 9.0.50, 9.1.50, 9.0.90, 9.1.90 + * - The third check applies to dev snapshots / release candidates + * where the next major version will change. + * e.g. 9.2.50, 9.2.90 + * + * NB: this assumes we do 3 minor releases per year, before bumping major, + * and dev snapshots / release candidates are numbered with micro >= 50 + * If this ever changes the logic below will need modifying.... + */ +#define _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) \ + ((QEMU_VERSION_MICRO < 50 && \ + _MACHINE_VER_IS_CURRENT_EXPIRED(cutoff, major, minor)) || \ + (QEMU_VERSION_MICRO >= 50 && QEMU_VERSION_MINOR < 2 && \ + _MACHINE_VER_IS_NEXT_MINOR_EXPIRED(cutoff, major, minor)) || \ + (QEMU_VERSION_MICRO >= 50 && QEMU_VERSION_MINOR == 2 && \ + _MACHINE_VER_IS_NEXT_MAJOR_EXPIRED(cutoff, major, minor))) + #define _MACHINE_VER_IS_EXPIRED2(cutoff, major, minor) \ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor) #define _MACHINE_VER_IS_EXPIRED3(cutoff, major, minor, micro) \ @@ -690,33 +753,16 @@ struct MachineState { * suitable period of time has passed, it will cause * execution of the method to return, avoiding registration * of the machine - * - * The new deprecation and deletion policy for versioned - * machine types was introduced in QEMU 9.1.0. - * - * Under the new policy a number of old machine types (any - * prior to 2.12) would be liable for immediate deletion - * which would be a violation of our historical deprecation - * and removal policy - * - * Thus deletions are temporarily gated on existance of - * the env variable "QEMU_DELETE_MACHINES" / QEMU version - * number >= 10.1.0. This gate can be deleted in the 10.1.0 - * dev cycle */ #define MACHINE_VER_DELETION(...) \ do { \ if (MACHINE_VER_SHOULD_DELETE(__VA_ARGS__)) { \ - if (getenv("QEMU_DELETE_MACHINES") || \ - QEMU_VERSION_MAJOR > 10 || (QEMU_VERSION_MAJOR == 10 && \ - QEMU_VERSION_MINOR >= 1)) { \ - return; \ - } \ + return; \ } \ } while (0) #define DEFINE_MACHINE(namestr, machine_initfn) \ - static void machine_initfn##_class_init(ObjectClass *oc, void *data) \ + static void machine_initfn##_class_init(ObjectClass *oc, const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ machine_initfn(mc); \ @@ -732,6 +778,15 @@ struct MachineState { } \ type_init(machine_initfn##_register_types) +extern GlobalProperty hw_compat_10_0[]; +extern const size_t hw_compat_10_0_len; + +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; + extern GlobalProperty hw_compat_9_0[]; extern const size_t hw_compat_9_0_len; @@ -807,19 +862,4 @@ extern const size_t hw_compat_2_7_len; extern GlobalProperty hw_compat_2_6[]; extern const size_t hw_compat_2_6_len; -extern GlobalProperty hw_compat_2_5[]; -extern const size_t hw_compat_2_5_len; - -extern GlobalProperty hw_compat_2_4[]; -extern const size_t hw_compat_2_4_len; - -extern GlobalProperty hw_compat_2_3[]; -extern const size_t hw_compat_2_3_len; - -extern GlobalProperty hw_compat_2_2[]; -extern const size_t hw_compat_2_2_len; - -extern GlobalProperty hw_compat_2_1[]; -extern const size_t hw_compat_2_1_len; - #endif diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h index 5669a5b..8c4c6a7 100644 --- a/include/hw/char/escc.h +++ b/include/hw/char/escc.h @@ -46,6 +46,9 @@ typedef struct ESCCChannelState { uint8_t rx, tx; QemuInputHandlerState *hs; char *sunkbd_layout; + int sunmouse_dx; + int sunmouse_dy; + int sunmouse_buttons; } ESCCChannelState; struct ESCCState { diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h index 65f0e97..90ba3ff 100644 --- a/include/hw/char/imx_serial.h +++ b/include/hw/char/imx_serial.h @@ -109,13 +109,13 @@ struct IMXSerialState { uint32_t ucr1; uint32_t ucr2; uint32_t uts1; + uint32_t ufcr; /* * The registers below are implemented just so that the * guest OS sees what it has written */ uint32_t onems; - uint32_t ufcr; uint32_t ubmr; uint32_t ubrc; uint32_t ucr3; diff --git a/include/hw/char/mchp_pfsoc_mmuart.h b/include/hw/char/mchp_pfsoc_mmuart.h index b0e14ca..a7b8b1b 100644 --- a/include/hw/char/mchp_pfsoc_mmuart.h +++ b/include/hw/char/mchp_pfsoc_mmuart.h @@ -29,7 +29,7 @@ #define HW_MCHP_PFSOC_MMUART_H #include "hw/sysbus.h" -#include "hw/char/serial.h" +#include "hw/char/serial-mm.h" #define MCHP_PFSOC_MMUART_REG_COUNT 13 diff --git a/include/hw/char/parallel-isa.h b/include/hw/char/parallel-isa.h index 5284b2f..3edaf9d 100644 --- a/include/hw/char/parallel-isa.h +++ b/include/hw/char/parallel-isa.h @@ -12,7 +12,7 @@ #include "parallel.h" -#include "exec/ioport.h" +#include "system/ioport.h" #include "hw/isa/isa.h" #include "qom/object.h" diff --git a/include/hw/char/parallel.h b/include/hw/char/parallel.h index cfb97cc..7b04478 100644 --- a/include/hw/char/parallel.h +++ b/include/hw/char/parallel.h @@ -1,7 +1,7 @@ #ifndef HW_PARALLEL_H #define HW_PARALLEL_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/isa/isa.h" #include "hw/irq.h" #include "chardev/char-fe.h" diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h index d853802..299ca9b 100644 --- a/include/hw/char/pl011.h +++ b/include/hw/char/pl011.h @@ -32,7 +32,6 @@ struct PL011State { SysBusDevice parent_obj; MemoryRegion iomem; - uint32_t readbuff; uint32_t flags; uint32_t lcr; uint32_t rsr; @@ -53,6 +52,11 @@ struct PL011State { Clock *clk; bool migrate_clk; const unsigned char *id; + /* + * Since some users embed this struct directly, we must + * ensure that the C struct is at least as big as the Rust one. + */ + uint8_t padding_for_rust[16]; }; DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr); diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h index df493fd..ee0ca29 100644 --- a/include/hw/char/riscv_htif.h +++ b/include/hw/char/riscv_htif.h @@ -22,7 +22,7 @@ #include "chardev/char.h" #include "chardev/char-fe.h" -#include "exec/memory.h" +#include "system/memory.h" #define TYPE_HTIF_UART "riscv.htif.uart" diff --git a/include/hw/char/serial-isa.h b/include/hw/char/serial-isa.h new file mode 100644 index 0000000..8517afa --- /dev/null +++ b/include/hw/char/serial-isa.h @@ -0,0 +1,38 @@ +/* + * QEMU ISA 16550A UART emulation + * + * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2008 Citrix Systems, Inc. + * + * 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 HW_SERIAL_ISA_H +#define HW_SERIAL_ISA_H + +#include "hw/isa/isa.h" + +#define MAX_ISA_SERIAL_PORTS 4 + +#define TYPE_ISA_SERIAL "isa-serial" +void serial_hds_isa_init(ISABus *bus, int from, int to); +void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase); +void isa_serial_set_enabled(ISADevice *serial, bool enabled); + +#endif diff --git a/include/hw/cris/etraxfs.h b/include/hw/char/serial-mm.h index 012c4e9..77abd09 100644 --- a/include/hw/cris/etraxfs.h +++ b/include/hw/char/serial-mm.h @@ -1,7 +1,8 @@ /* - * QEMU ETRAX System Emulator + * QEMU 16550A UART emulation * - * Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB. + * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2008 Citrix Systems, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,33 +23,30 @@ * THE SOFTWARE. */ -#ifndef HW_ETRAXFS_H -#define HW_ETRAXFS_H +#ifndef HW_SERIAL_MM_H +#define HW_SERIAL_MM_H -#include "net/net.h" -#include "hw/cris/etraxfs_dma.h" -#include "hw/qdev-properties.h" +#include "hw/char/serial.h" +#include "system/memory.h" +#include "chardev/char.h" #include "hw/sysbus.h" -#include "qapi/error.h" - -DeviceState *etraxfs_eth_init(hwaddr base, int phyaddr, - struct etraxfs_dma_client *dma_out, - struct etraxfs_dma_client *dma_in); - -static inline DeviceState *etraxfs_ser_create(hwaddr addr, - qemu_irq irq, - Chardev *chr) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new("etraxfs-serial"); - s = SYS_BUS_DEVICE(dev); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, addr); - sysbus_connect_irq(s, 0, irq); - return dev; -} +#include "qom/object.h" + +#define TYPE_SERIAL_MM "serial-mm" +OBJECT_DECLARE_SIMPLE_TYPE(SerialMM, SERIAL_MM) + +struct SerialMM { + SysBusDevice parent; + + SerialState serial; + + uint8_t regshift; + uint8_t endianness; +}; + +SerialMM *serial_mm_init(MemoryRegion *address_space, + hwaddr base, int regshift, + qemu_irq irq, int baudbase, + Chardev *chr, enum device_endian end); #endif diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 6e14099..4bf90a4 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -27,10 +27,8 @@ #define HW_SERIAL_H #include "chardev/char-fe.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/fifo8.h" -#include "chardev/char.h" -#include "hw/sysbus.h" #include "qom/object.h" #define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */ @@ -81,38 +79,10 @@ struct SerialState { }; typedef struct SerialState SerialState; -struct SerialMM { - SysBusDevice parent; - - SerialState serial; - - uint8_t regshift; - uint8_t endianness; -}; - extern const VMStateDescription vmstate_serial; extern const MemoryRegionOps serial_io_ops; -void serial_set_frequency(SerialState *s, uint32_t frequency); - #define TYPE_SERIAL "serial" OBJECT_DECLARE_SIMPLE_TYPE(SerialState, SERIAL) -#define TYPE_SERIAL_MM "serial-mm" -OBJECT_DECLARE_SIMPLE_TYPE(SerialMM, SERIAL_MM) - -SerialMM *serial_mm_init(MemoryRegion *address_space, - hwaddr base, int regshift, - qemu_irq irq, int baudbase, - Chardev *chr, enum device_endian end); - -/* serial-isa.c */ - -#define MAX_ISA_SERIAL_PORTS 4 - -#define TYPE_ISA_SERIAL "isa-serial" -void serial_hds_isa_init(ISABus *bus, int from, int to); -void isa_serial_set_iobase(ISADevice *serial, hwaddr iobase); -void isa_serial_set_enabled(ISADevice *serial, bool enabled); - #endif diff --git a/include/hw/char/sifive_uart.h b/include/hw/char/sifive_uart.h index 7f6c79f..0846cf6 100644 --- a/include/hw/char/sifive_uart.h +++ b/include/hw/char/sifive_uart.h @@ -24,6 +24,7 @@ #include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "qom/object.h" +#include "qemu/fifo8.h" enum { SIFIVE_UART_TXFIFO = 0, @@ -48,9 +49,13 @@ enum { SIFIVE_UART_IP_RXWM = 2 /* Receive watermark interrupt pending */ }; +#define SIFIVE_UART_TXFIFO_FULL 0x80000000 + #define SIFIVE_UART_GET_TXCNT(txctrl) ((txctrl >> 16) & 0x7) #define SIFIVE_UART_GET_RXCNT(rxctrl) ((rxctrl >> 16) & 0x7) + #define SIFIVE_UART_RX_FIFO_SIZE 8 +#define SIFIVE_UART_TX_FIFO_SIZE 8 #define TYPE_SIFIVE_UART "riscv.sifive.uart" OBJECT_DECLARE_SIMPLE_TYPE(SiFiveUARTState, SIFIVE_UART) @@ -63,13 +68,20 @@ struct SiFiveUARTState { qemu_irq irq; MemoryRegion mmio; CharBackend chr; - uint8_t rx_fifo[SIFIVE_UART_RX_FIFO_SIZE]; - uint8_t rx_fifo_len; + + uint32_t txfifo; uint32_t ie; uint32_t ip; uint32_t txctrl; uint32_t rxctrl; uint32_t div; + + uint8_t rx_fifo[SIFIVE_UART_RX_FIFO_SIZE]; + uint8_t rx_fifo_len; + + Fifo8 tx_fifo; + + QEMUTimer *fifo_trigger_handle; }; SiFiveUARTState *sifive_uart_create(MemoryRegion *address_space, hwaddr base, diff --git a/include/hw/clock.h b/include/hw/clock.h index eb58599..a279bd4 100644 --- a/include/hw/clock.h +++ b/include/hw/clock.h @@ -142,14 +142,6 @@ void clock_set_callback(Clock *clk, ClockCallback *cb, void *opaque, unsigned int events); /** - * clock_clear_callback: - * @clk: the clock to delete the callback from - * - * Unregister the callback registered with clock_set_callback. - */ -void clock_clear_callback(Clock *clk); - -/** * clock_set_source: * @clk: the clock. * @src: the source clock diff --git a/include/hw/core/accel-cpu.h b/include/hw/core/accel-cpu.h deleted file mode 100644 index 24dad45..0000000 --- a/include/hw/core/accel-cpu.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Accelerator interface, specializes CPUClass - * This header is used only by target-specific code. - * - * Copyright 2021 SUSE LLC - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef ACCEL_CPU_H -#define ACCEL_CPU_H - -/* - * This header is used to define new accelerator-specific target-specific - * accelerator cpu subclasses. - * It uses CPU_RESOLVING_TYPE, so this is clearly target-specific. - * - * Do not try to use for any other purpose than the implementation of new - * subclasses in target/, or the accel implementation itself in accel/ - */ - -#define TYPE_ACCEL_CPU "accel-" CPU_RESOLVING_TYPE -#define ACCEL_CPU_NAME(name) (name "-" TYPE_ACCEL_CPU) -typedef struct AccelCPUClass AccelCPUClass; -DECLARE_CLASS_CHECKERS(AccelCPUClass, ACCEL_CPU, TYPE_ACCEL_CPU) - -typedef struct AccelCPUClass { - /*< private >*/ - ObjectClass parent_class; - /*< public >*/ - - void (*cpu_class_init)(CPUClass *cc); - void (*cpu_instance_init)(CPUState *cpu); - bool (*cpu_target_realize)(CPUState *cpu, Error **errp); -} AccelCPUClass; - -#endif /* ACCEL_CPU_H */ diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 1c9c775..162a56a 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -33,6 +33,7 @@ #include "qemu/bitmap.h" #include "qemu/rcu_queue.h" #include "qemu/queue.h" +#include "qemu/lockcnt.h" #include "qemu/thread.h" #include "qom/object.h" @@ -101,11 +102,9 @@ struct SysemuCPUOps; * CPUClass: * @class_by_name: Callback to map -cpu command line model name to an * instantiatable CPU type. + * @list_cpus: list available CPU models and flags. * @parse_features: Callback to parse command line arguments. * @reset_dump_flags: #CPUDumpFlags to use for reset logging. - * @has_work: Callback for checking if there is work to do. - * @mmu_index: Callback for choosing softmmu mmu index; - * may be used internally by memory_rw_debug without TCG. * @memory_rw_debug: Callback for GDB memory access. * @dump_state: Callback for dumping state. * @query_cpu_fast: @@ -123,17 +122,24 @@ struct SysemuCPUOps; * @get_pc: Callback for getting the Program Counter register. * As above, with the semantics of the target architecture. * @gdb_read_register: Callback for letting GDB read a register. + * No more than @gdb_num_core_regs registers can be read. * @gdb_write_register: Callback for letting GDB write a register. + * No more than @gdb_num_core_regs registers can be written. * @gdb_adjust_breakpoint: Callback for adjusting the address of a * breakpoint. Used by AVR to handle a gdb mis-feature with * its Harvard architecture split code and data. * @gdb_num_core_regs: Number of core registers accessible to GDB or 0 to infer * from @gdb_core_xml_file. * @gdb_core_xml_file: File name for core registers GDB XML description. + * @gdb_get_core_xml_file: Optional callback that returns the file name for + * the core registers GDB XML description. The returned value is expected to + * be a simple constant string: the caller will not g_free() it. If this + * is NULL then @gdb_core_xml_file will be used instead. * @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop * before the insn which triggers a watchpoint rather than after it. * @gdb_arch_name: Optional callback that returns the architecture name known - * to GDB. The caller must free the returned string with g_free. + * to GDB. The returned value is expected to be a simple constant string: + * the caller will not g_free() it. * @disas_set_info: Setup architecture specific components of disassembly info * @adjust_watchpoint_address: Perform a target-specific adjustment to an * address before attempting to match it against watchpoints. @@ -148,12 +154,11 @@ struct CPUClass { /*< public >*/ ObjectClass *(*class_by_name)(const char *cpu_model); + void (*list_cpus)(void); void (*parse_features)(const char *typename, char *str, Error **errp); - bool (*has_work)(CPUState *cpu); - int (*mmu_index)(CPUState *cpu, bool ifetch); int (*memory_rw_debug)(CPUState *cpu, vaddr addr, - uint8_t *buf, int len, bool is_write); + uint8_t *buf, size_t len, bool is_write); void (*dump_state)(CPUState *cpu, FILE *, int flags); void (*query_cpu_fast)(CPUState *cpu, CpuInfoFast *value); int64_t (*get_arch_id)(CPUState *cpu); @@ -165,6 +170,7 @@ struct CPUClass { const char *gdb_core_xml_file; const gchar * (*gdb_arch_name)(CPUState *cpu); + const char * (*gdb_get_core_xml_file)(CPUState *cpu); void (*disas_set_info)(CPUState *cpu, disassemble_info *info); @@ -205,7 +211,7 @@ struct CPUClass { * so the layout is not as critical as that of CPUTLBEntry. This is * also why we don't want to combine the two structs. */ -typedef struct CPUTLBEntryFull { +struct CPUTLBEntryFull { /* * @xlat_section contains: * - in the lower TARGET_PAGE_BITS, a physical section number @@ -261,7 +267,7 @@ typedef struct CPUTLBEntryFull { bool guarded; } arm; } extra; -} CPUTLBEntryFull; +}; /* * Data elements that are per MMU mode, minus the bits accessed by @@ -350,6 +356,8 @@ typedef union IcountDecr { * from CPUArchState, via small negative offsets. * @can_do_io: True if memory-mapped IO is allowed. * @plugin_mem_cbs: active plugin memory callbacks + * @plugin_mem_value_low: 64 lower bits of latest accessed mem value. + * @plugin_mem_value_high: 64 higher bits of latest accessed mem value. */ typedef struct CPUNegativeOffsetState { CPUTLB tlb; @@ -358,6 +366,9 @@ typedef struct CPUNegativeOffsetState { * The callback pointer are accessed via TCG (see gen_empty_mem_helper). */ GArray *plugin_mem_cbs; + uint64_t plugin_mem_value_low; + uint64_t plugin_mem_value_high; + int32_t plugin_cb_flags; #endif IcountDecr icount_decr; bool can_do_io; @@ -402,7 +413,6 @@ struct qemu_work_item; * Under TCG this value is propagated to @tcg_cflags. * See TranslationBlock::TCG CF_CLUSTER_MASK. * @tcg_cflags: Pre-computed cflags for this cpu. - * @nr_cores: Number of cores within this CPU package. * @nr_threads: Number of threads within this CPU core. * @thread: Host thread details, only live once @created is #true * @sem: WIN32 only semaphore used only for qtest @@ -461,7 +471,6 @@ struct CPUState { CPUClass *cc; /*< public >*/ - int nr_cores; int nr_threads; struct QemuThread *thread; @@ -579,7 +588,7 @@ QEMU_BUILD_BUG_ON(offsetof(CPUState, neg) != static inline CPUArchState *cpu_env(CPUState *cpu) { - /* We validate that CPUArchState follows CPUState in cpu-all.h. */ + /* We validate that CPUArchState follows CPUState in cpu-target.c */ return (CPUArchState *)(cpu + 1); } @@ -595,15 +604,6 @@ extern CPUTailQ cpus_queue; extern __thread CPUState *current_cpu; /** - * qemu_tcg_mttcg_enabled: - * Check whether we are running MultiThread TCG or not. - * - * Returns: %true if we are in MTTCG mode %false otherwise. - */ -extern bool mttcg_enabled; -#define qemu_tcg_mttcg_enabled() (mttcg_enabled) - -/** * cpu_paging_enabled: * @cpu: The CPU whose state is to be inspected. * @@ -622,8 +622,6 @@ bool cpu_paging_enabled(const CPUState *cpu); bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, Error **errp); -#if !defined(CONFIG_USER_ONLY) - /** * cpu_write_elf64_note: * @f: pointer to a function that writes memory to a file @@ -673,8 +671,6 @@ int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, */ GuestPanicInformation *cpu_get_crash_info(CPUState *cpu); -#endif /* !CONFIG_USER_ONLY */ - /** * CPUDumpFlags: * @CPU_DUMP_CODE: @@ -698,7 +694,6 @@ enum CPUDumpFlags { */ void cpu_dump_state(CPUState *cpu, FILE *f, int flags); -#ifndef CONFIG_USER_ONLY /** * cpu_get_phys_page_attrs_debug: * @cpu: The CPU to obtain the physical page address for. @@ -745,7 +740,15 @@ int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs); */ bool cpu_virtio_is_big_endian(CPUState *cpu); -#endif /* CONFIG_USER_ONLY */ +/** + * cpu_has_work: + * @cpu: The vCPU to check. + * + * Checks whether the CPU has work to do. + * + * Returns: %true if the CPU has work, %false otherwise. + */ +bool cpu_has_work(CPUState *cpu); /** * cpu_list_add: @@ -812,22 +815,6 @@ CPUState *cpu_create(const char *typename); const char *parse_cpu_option(const char *cpu_option); /** - * cpu_has_work: - * @cpu: The vCPU to check. - * - * Checks whether the CPU has work to do. - * - * Returns: %true if the CPU has work, %false otherwise. - */ -static inline bool cpu_has_work(CPUState *cpu) -{ - CPUClass *cc = CPU_GET_CLASS(cpu); - - g_assert(cc->has_work); - return cc->has_work(cpu); -} - -/** * qemu_cpu_is_self: * @cpu: The vCPU to check against. * @@ -963,9 +950,7 @@ void cpu_interrupt(CPUState *cpu, int mask); */ static inline void cpu_set_pc(CPUState *cpu, vaddr addr) { - CPUClass *cc = CPU_GET_CLASS(cpu); - - cc->set_pc(cpu, addr); + cpu->cc->set_pc(cpu, addr); } /** @@ -1114,36 +1099,6 @@ static inline bool cpu_breakpoint_test(CPUState *cpu, vaddr pc, int mask) return false; } -#if defined(CONFIG_USER_ONLY) -static inline int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len, - int flags, CPUWatchpoint **watchpoint) -{ - return -ENOSYS; -} - -static inline int cpu_watchpoint_remove(CPUState *cpu, vaddr addr, - vaddr len, int flags) -{ - return -ENOSYS; -} - -static inline void cpu_watchpoint_remove_by_ref(CPUState *cpu, - CPUWatchpoint *wp) -{ -} - -static inline void cpu_watchpoint_remove_all(CPUState *cpu, int mask) -{ -} -#else -int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len, - int flags, CPUWatchpoint **watchpoint); -int cpu_watchpoint_remove(CPUState *cpu, vaddr addr, - vaddr len, int flags); -void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint); -void cpu_watchpoint_remove_all(CPUState *cpu, int mask); -#endif - /** * cpu_get_address_space: * @cpu: CPU to get address space from @@ -1159,31 +1114,23 @@ G_NORETURN void cpu_abort(CPUState *cpu, const char *fmt, ...) /* $(top_srcdir)/cpu.c */ void cpu_class_init_props(DeviceClass *dc); +void cpu_exec_class_post_init(CPUClass *cc); void cpu_exec_initfn(CPUState *cpu); +void cpu_vmstate_register(CPUState *cpu); +void cpu_vmstate_unregister(CPUState *cpu); bool cpu_exec_realizefn(CPUState *cpu, Error **errp); void cpu_exec_unrealizefn(CPUState *cpu); void cpu_exec_reset_hold(CPUState *cpu); -const char *target_name(void); - -#ifdef COMPILING_PER_TARGET - -#ifndef CONFIG_USER_ONLY - extern const VMStateDescription vmstate_cpu_common; -#define VMSTATE_CPU() { \ - .name = "parent_obj", \ - .size = sizeof(CPUState), \ - .vmsd = &vmstate_cpu_common, \ - .flags = VMS_STRUCT, \ - .offset = 0, \ -} -#endif /* !CONFIG_USER_ONLY */ - -#endif /* COMPILING_PER_TARGET */ - #define UNASSIGNED_CPU_INDEX -1 #define UNASSIGNED_CLUSTER_INDEX -1 +enum CacheType { + DATA_CACHE, + INSTRUCTION_CACHE, + UNIFIED_CACHE +}; + #endif diff --git a/include/hw/core/resetcontainer.h b/include/hw/core/resetcontainer.h index 23db0c7..daeb18c 100644 --- a/include/hw/core/resetcontainer.h +++ b/include/hw/core/resetcontainer.h @@ -20,7 +20,7 @@ #include "qom/object.h" #define TYPE_RESETTABLE_CONTAINER "resettable-container" -OBJECT_DECLARE_TYPE(ResettableContainer, ResettableContainerClass, RESETTABLE_CONTAINER) +OBJECT_DECLARE_SIMPLE_TYPE(ResettableContainer, RESETTABLE_CONTAINER) /** * resettable_container_add: Add a resettable object to the container diff --git a/include/hw/core/sysemu-cpu-ops.h b/include/hw/core/sysemu-cpu-ops.h index 24d003f..8778923 100644 --- a/include/hw/core/sysemu-cpu-ops.h +++ b/include/hw/core/sysemu-cpu-ops.h @@ -7,8 +7,8 @@ * See the COPYING file in the top-level directory. */ -#ifndef SYSEMU_CPU_OPS_H -#define SYSEMU_CPU_OPS_H +#ifndef SYSTEM_CPU_OPS_H +#define SYSTEM_CPU_OPS_H #include "hw/core/cpu.h" @@ -17,6 +17,10 @@ */ typedef struct SysemuCPUOps { /** + * @has_work: Callback for checking if there is work to do. + */ + bool (*has_work)(CPUState *cpu); /* MANDATORY NON-NULL */ + /** * @get_memory_mapping: Callback for obtaining the memory mappings. */ bool (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, @@ -89,4 +93,4 @@ typedef struct SysemuCPUOps { } SysemuCPUOps; -#endif /* SYSEMU_CPU_OPS_H */ +#endif /* SYSTEM_CPU_OPS_H */ diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h deleted file mode 100644 index 34318cf..0000000 --- a/include/hw/core/tcg-cpu-ops.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * TCG CPU-specific operations - * - * Copyright 2021 SUSE LLC - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef TCG_CPU_OPS_H -#define TCG_CPU_OPS_H - -#include "exec/breakpoint.h" -#include "exec/hwaddr.h" -#include "exec/memattrs.h" -#include "exec/mmu-access-type.h" -#include "exec/vaddr.h" - -struct TCGCPUOps { - /** - * @initialize: Initialize TCG state - * - * Called when the first CPU is realized. - */ - void (*initialize)(void); - /** - * @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock - * - * This is called when we abandon execution of a TB before starting it, - * and must set all parts of the CPU state which the previous TB in the - * chain may not have updated. - * By default, when this is NULL, a call is made to @set_pc(tb->pc). - * - * If more state needs to be restored, the target must implement a - * function to restore all the state, and register it here. - */ - void (*synchronize_from_tb)(CPUState *cpu, const TranslationBlock *tb); - /** - * @restore_state_to_opc: Synchronize state from INDEX_op_start_insn - * - * This is called when we unwind state in the middle of a TB, - * usually before raising an exception. Set all part of the CPU - * state which are tracked insn-by-insn in the target-specific - * arguments to start_insn, passed as @data. - */ - void (*restore_state_to_opc)(CPUState *cpu, const TranslationBlock *tb, - const uint64_t *data); - - /** @cpu_exec_enter: Callback for cpu_exec preparation */ - void (*cpu_exec_enter)(CPUState *cpu); - /** @cpu_exec_exit: Callback for cpu_exec cleanup */ - void (*cpu_exec_exit)(CPUState *cpu); - /** @debug_excp_handler: Callback for handling debug exceptions */ - void (*debug_excp_handler)(CPUState *cpu); - -#ifdef CONFIG_USER_ONLY - /** - * @fake_user_interrupt: Callback for 'fake exception' handling. - * - * Simulate 'fake exception' which will be handled outside the - * cpu execution loop (hack for x86 user mode). - */ - void (*fake_user_interrupt)(CPUState *cpu); - - /** - * record_sigsegv: - * @cpu: cpu context - * @addr: faulting guest address - * @access_type: access was read/write/execute - * @maperr: true for invalid page, false for permission fault - * @ra: host pc for unwinding - * - * We are about to raise SIGSEGV with si_code set for @maperr, - * and si_addr set for @addr. Record anything further needed - * for the signal ucontext_t. - * - * If the emulated kernel does not provide anything to the signal - * handler with anything besides the user context registers, and - * the siginfo_t, then this hook need do nothing and may be omitted. - * Otherwise, record the data and return; the caller will raise - * the signal, unwind the cpu state, and return to the main loop. - * - * If it is simpler to re-use the sysemu tlb_fill code, @ra is provided - * so that a "normal" cpu exception can be raised. In this case, - * the signal must be raised by the architecture cpu_loop. - */ - void (*record_sigsegv)(CPUState *cpu, vaddr addr, - MMUAccessType access_type, - bool maperr, uintptr_t ra); - /** - * record_sigbus: - * @cpu: cpu context - * @addr: misaligned guest address - * @access_type: access was read/write/execute - * @ra: host pc for unwinding - * - * We are about to raise SIGBUS with si_code BUS_ADRALN, - * and si_addr set for @addr. Record anything further needed - * for the signal ucontext_t. - * - * If the emulated kernel does not provide the signal handler with - * anything besides the user context registers, and the siginfo_t, - * then this hook need do nothing and may be omitted. - * Otherwise, record the data and return; the caller will raise - * the signal, unwind the cpu state, and return to the main loop. - * - * If it is simpler to re-use the sysemu do_unaligned_access code, - * @ra is provided so that a "normal" cpu exception can be raised. - * In this case, the signal must be raised by the architecture cpu_loop. - */ - void (*record_sigbus)(CPUState *cpu, vaddr addr, - MMUAccessType access_type, uintptr_t ra); -#else - /** @do_interrupt: Callback for interrupt handling. */ - void (*do_interrupt)(CPUState *cpu); - /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */ - bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request); - /** - * @cpu_exec_halt: Callback for handling halt in cpu_exec. - * - * The target CPU should do any special processing here that it needs - * to do when the CPU is in the halted state. - * - * Return true to indicate that the CPU should now leave halt, false - * if it should remain in the halted state. (This should generally - * be the same value that cpu_has_work() would return.) - * - * This method must be provided. If the target does not need to - * do anything special for halt, the same function used for its - * CPUClass::has_work method can be used here, as they have the - * same function signature. - */ - bool (*cpu_exec_halt)(CPUState *cpu); - /** - * @tlb_fill: Handle a softmmu tlb miss - * - * If the access is valid, call tlb_set_page and return true; - * if the access is invalid and probe is true, return false; - * otherwise raise an exception and do not return. - */ - bool (*tlb_fill)(CPUState *cpu, vaddr address, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr); - /** - * @do_transaction_failed: Callback for handling failed memory transactions - * (ie bus faults or external aborts; not MMU faults) - */ - void (*do_transaction_failed)(CPUState *cpu, hwaddr physaddr, vaddr addr, - unsigned size, MMUAccessType access_type, - int mmu_idx, MemTxAttrs attrs, - MemTxResult response, uintptr_t retaddr); - /** - * @do_unaligned_access: Callback for unaligned access handling - * The callback must exit via raising an exception. - */ - G_NORETURN void (*do_unaligned_access)(CPUState *cpu, vaddr addr, - MMUAccessType access_type, - int mmu_idx, uintptr_t retaddr); - - /** - * @adjust_watchpoint_address: hack for cpu_check_watchpoint used by ARM - */ - vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len); - - /** - * @debug_check_watchpoint: return true if the architectural - * watchpoint whose address has matched should really fire, used by ARM - * and RISC-V - */ - bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp); - - /** - * @debug_check_breakpoint: return true if the architectural - * breakpoint whose PC has matched should really fire. - */ - bool (*debug_check_breakpoint)(CPUState *cpu); - - /** - * @io_recompile_replay_branch: Callback for cpu_io_recompile. - * - * The cpu has been stopped, and cpu_restore_state_from_tb has been - * called. If the faulting instruction is in a delay slot, and the - * target architecture requires re-execution of the branch, then - * adjust the cpu state as required and return true. - */ - bool (*io_recompile_replay_branch)(CPUState *cpu, - const TranslationBlock *tb); - /** - * @need_replay_interrupt: Return %true if @interrupt_request - * needs to be recorded for replay purposes. - */ - bool (*need_replay_interrupt)(int interrupt_request); -#endif /* !CONFIG_USER_ONLY */ -}; - -#if defined(CONFIG_USER_ONLY) - -static inline void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, - MemTxAttrs atr, int fl, uintptr_t ra) -{ -} - -static inline int cpu_watchpoint_address_matches(CPUState *cpu, - vaddr addr, vaddr len) -{ - return 0; -} - -#else - -/** - * cpu_check_watchpoint: - * @cpu: cpu context - * @addr: guest virtual address - * @len: access length - * @attrs: memory access attributes - * @flags: watchpoint access type - * @ra: unwind return address - * - * Check for a watchpoint hit in [addr, addr+len) of the type - * specified by @flags. Exit via exception with a hit. - */ -void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len, - MemTxAttrs attrs, int flags, uintptr_t ra); - -/** - * cpu_watchpoint_address_matches: - * @cpu: cpu context - * @addr: guest virtual address - * @len: access length - * - * Return the watchpoint flags that apply to [addr, addr+len). - * If no watchpoint is registered for the range, the result is 0. - */ -int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len); - -#endif - -#endif /* TCG_CPU_OPS_H */ diff --git a/include/hw/cris/etraxfs_dma.h b/include/hw/cris/etraxfs_dma.h deleted file mode 100644 index 095d76b..0000000 --- a/include/hw/cris/etraxfs_dma.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HW_ETRAXFS_DMA_H -#define HW_ETRAXFS_DMA_H - -#include "exec/hwaddr.h" - -struct dma_context_metadata { - /* data descriptor md */ - uint16_t metadata; -}; - -struct etraxfs_dma_client -{ - /* DMA controller. */ - int channel; - void *ctrl; - - /* client. */ - struct { - int (*push)(void *opaque, unsigned char *buf, - int len, bool eop); - void (*pull)(void *opaque); - void (*metadata_push)(void *opaque, - const struct dma_context_metadata *md); - void *opaque; - } client; -}; - -void *etraxfs_dmac_init(hwaddr base, int nr_channels); -void etraxfs_dmac_connect(void *opaque, int channel, qemu_irq *line, - int input); -void etraxfs_dmac_connect_client(void *opaque, int c, - struct etraxfs_dma_client *cl); -int etraxfs_dmac_input(struct etraxfs_dma_client *client, - void *buf, int len, int eop); - -#endif diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index fdd0f4e..ed6cd50 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -176,10 +176,12 @@ typedef struct CXLCCI { uint16_t opcode; uint16_t complete_pct; uint16_t ret_code; /* Current value of retcode */ + bool aborted; uint64_t starttime; /* set by each bg cmd, cleared by the bg_timer when complete */ uint64_t runtime; QEMUTimer *timer; + QemuMutex lock; /* serializes mbox abort vs timer cb */ } bg; /* firmware update */ @@ -201,6 +203,7 @@ typedef struct CXLCCI { DeviceState *d; /* Pointer to the device hosting the protocol conversion */ DeviceState *intf; + bool initialized; } CXLCCI; typedef struct cxl_device_state { @@ -264,8 +267,8 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev, typedef struct CXLType3Dev CXLType3Dev; typedef struct CSWMBCCIDev CSWMBCCIDev; /* Set up default values for the register block */ -void cxl_device_register_init_t3(CXLType3Dev *ct3d); -void cxl_device_register_init_swcci(CSWMBCCIDev *sw); +void cxl_device_register_init_t3(CXLType3Dev *ct3d, int msi_n); +void cxl_device_register_init_swcci(CSWMBCCIDev *sw, int msi_n); /* * CXL r3.1 Section 8.2.8.1: CXL Device Capabilities Array Register @@ -316,6 +319,7 @@ void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max); void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf, DeviceState *d, size_t payload_max); void cxl_init_cci(CXLCCI *cci, size_t payload_max); +void cxl_destroy_cci(CXLCCI *cci); void cxl_add_cci_commands(CXLCCI *cci, const struct cxl_cmd (*cxl_cmd_set)[256], size_t payload_max); int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd, @@ -463,18 +467,6 @@ typedef struct CXLMemPatrolScrubWriteAttrs { #define CXL_MEMDEV_PS_ENABLE_DEFAULT 0 /* CXL memory device DDR5 ECS control attributes */ -typedef struct CXLMemECSReadAttrs { - uint8_t ecs_log_cap; - uint8_t ecs_cap; - uint16_t ecs_config; - uint8_t ecs_flags; -} QEMU_PACKED CXLMemECSReadAttrs; - -typedef struct CXLMemECSWriteAttrs { - uint8_t ecs_log_cap; - uint16_t ecs_config; -} QEMU_PACKED CXLMemECSWriteAttrs; - #define CXL_ECS_GET_FEATURE_VERSION 0x01 #define CXL_ECS_SET_FEATURE_VERSION 0x01 #define CXL_ECS_LOG_ENTRY_TYPE_DEFAULT 0x01 @@ -483,6 +475,26 @@ typedef struct CXLMemECSWriteAttrs { #define CXL_ECS_MODE_DEFAULT 0 #define CXL_ECS_NUM_MEDIA_FRUS 3 /* Default */ +typedef struct CXLMemECSFRUReadAttrs { + uint8_t ecs_cap; + uint16_t ecs_config; + uint8_t ecs_flags; +} QEMU_PACKED CXLMemECSFRUReadAttrs; + +typedef struct CXLMemECSReadAttrs { + uint8_t ecs_log_cap; + CXLMemECSFRUReadAttrs fru_attrs[CXL_ECS_NUM_MEDIA_FRUS]; +} QEMU_PACKED CXLMemECSReadAttrs; + +typedef struct CXLMemECSFRUWriteAttrs { + uint16_t ecs_config; +} QEMU_PACKED CXLMemECSFRUWriteAttrs; + +typedef struct CXLMemECSWriteAttrs { + uint8_t ecs_log_cap; + CXLMemECSFRUWriteAttrs fru_attrs[CXL_ECS_NUM_MEDIA_FRUS]; +} QEMU_PACKED CXLMemECSWriteAttrs; + #define DCD_MAX_NUM_REGION 8 typedef struct CXLDCExtentRaw { @@ -528,6 +540,21 @@ typedef struct CXLSetFeatureInfo { size_t data_size; } CXLSetFeatureInfo; +struct CXLSanitizeInfo; + +typedef struct CXLAlertConfig { + uint8_t valid_alerts; + uint8_t enable_alerts; + uint8_t life_used_crit_alert_thresh; + uint8_t life_used_warn_thresh; + uint16_t over_temp_crit_alert_thresh; + uint16_t under_temp_crit_alert_thresh; + uint16_t over_temp_warn_thresh; + uint16_t under_temp_warn_thresh; + uint16_t cor_vmem_err_warn_thresh; + uint16_t cor_pmem_err_warn_thresh; +} QEMU_PACKED CXLAlertConfig; + struct CXLType3Dev { /* Private */ PCIDevice parent_obj; @@ -549,6 +576,12 @@ struct CXLType3Dev { CXLCCI vdm_fm_owned_ld_mctp_cci; CXLCCI ld0_cci; + CXLAlertConfig alert_config; + + /* PCIe link characteristics */ + PCIExpLinkSpeed speed; + PCIExpLinkWidth width; + /* DOE */ DOECap doe_cdat; @@ -571,8 +604,8 @@ struct CXLType3Dev { CXLMemPatrolScrubReadAttrs patrol_scrub_attrs; CXLMemPatrolScrubWriteAttrs patrol_scrub_wr_attrs; /* ECS control attributes */ - CXLMemECSReadAttrs ecs_attrs[CXL_ECS_NUM_MEDIA_FRUS]; - CXLMemECSWriteAttrs ecs_wr_attrs[CXL_ECS_NUM_MEDIA_FRUS]; + CXLMemECSReadAttrs ecs_attrs; + CXLMemECSWriteAttrs ecs_wr_attrs; struct dynamic_capacity { HostMemoryBackend *host_dc; @@ -590,6 +623,8 @@ struct CXLType3Dev { uint8_t num_regions; /* 0-8 regions */ CXLDCRegion regions[DCD_MAX_NUM_REGION]; } dc; + + struct CXLSanitizeInfo *media_op_sanitize; }; #define TYPE_CXL_TYPE3 "cxl-type3" diff --git a/include/hw/cxl/cxl_mailbox.h b/include/hw/cxl/cxl_mailbox.h index beb0480..9008402 100644 --- a/include/hw/cxl/cxl_mailbox.h +++ b/include/hw/cxl/cxl_mailbox.h @@ -14,5 +14,6 @@ #define CXL_MBOX_IMMEDIATE_LOG_CHANGE (1 << 4) #define CXL_MBOX_SECURITY_STATE_CHANGE (1 << 5) #define CXL_MBOX_BACKGROUND_OPERATION (1 << 6) +#define CXL_MBOX_BACKGROUND_OPERATION_ABORT (1 << 7) #endif diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h deleted file mode 100644 index 5b33018..0000000 --- a/include/hw/display/blizzard.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller. - * - * Copyright (C) 2008 Nokia Corporation - * Written by Andrzej Zaborowski - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef HW_DISPLAY_BLIZZARD_H -#define HW_DISPLAY_BLIZZARD_H - - -void *s1d13745_init(qemu_irq gpio_int); -void s1d13745_write(void *opaque, int dc, uint16_t value); -void s1d13745_write_block(void *opaque, int dc, - void *buf, size_t len, int pitch); -uint16_t s1d13745_read(void *opaque, int dc); - -#endif diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h index 27cebef..0fae1f3 100644 --- a/include/hw/display/macfb.h +++ b/include/hw/display/macfb.h @@ -13,7 +13,7 @@ #ifndef MACFB_H #define MACFB_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/irq.h" #include "hw/nubus/nubus.h" #include "hw/sysbus.h" diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h deleted file mode 100644 index f9263bf..0000000 --- a/include/hw/display/tc6393xb.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Toshiba TC6393XB I/O Controller. - * Found in Sharp Zaurus SL-6000 (tosa) or some - * Toshiba e-Series PDAs. - * - * Copyright (c) 2007 Hervé Poussineau - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef HW_DISPLAY_TC6393XB_H -#define HW_DISPLAY_TC6393XB_H - -typedef struct TC6393xbState TC6393xbState; - -TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem, - uint32_t base, qemu_irq irq); -qemu_irq tc6393xb_l3v_get(TC6393xbState *s); - -#endif diff --git a/include/hw/dma/i8257.h b/include/hw/dma/i8257.h index 4342e4a..33b6286 100644 --- a/include/hw/dma/i8257.h +++ b/include/hw/dma/i8257.h @@ -2,7 +2,7 @@ #define HW_I8257_H #include "hw/isa/isa.h" -#include "exec/ioport.h" +#include "system/ioport.h" #include "qom/object.h" #define TYPE_I8257 "i8257" diff --git a/include/hw/dma/xlnx-zdma.h b/include/hw/dma/xlnx-zdma.h index efc7521..9c57c49 100644 --- a/include/hw/dma/xlnx-zdma.h +++ b/include/hw/dma/xlnx-zdma.h @@ -31,7 +31,7 @@ #include "hw/sysbus.h" #include "hw/register.h" -#include "sysemu/dma.h" +#include "system/dma.h" #include "qom/object.h" #define ZDMA_R_MAX (0x204 / 4) diff --git a/include/hw/dma/xlnx_dpdma.h b/include/hw/dma/xlnx_dpdma.h index 40537a8..484b2e3 100644 --- a/include/hw/dma/xlnx_dpdma.h +++ b/include/hw/dma/xlnx_dpdma.h @@ -26,8 +26,7 @@ #define XLNX_DPDMA_H #include "hw/sysbus.h" -#include "ui/console.h" -#include "sysemu/dma.h" +#include "system/dma.h" #include "qom/object.h" #define XLNX_DPDMA_REG_ARRAY_SIZE (0x1000 >> 2) diff --git a/include/hw/fsi/aspeed_apb2opb.h b/include/hw/fsi/aspeed_apb2opb.h index f6a2387..878619e 100644 --- a/include/hw/fsi/aspeed_apb2opb.h +++ b/include/hw/fsi/aspeed_apb2opb.h @@ -8,7 +8,7 @@ #ifndef FSI_ASPEED_APB2OPB_H #define FSI_ASPEED_APB2OPB_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/fsi/fsi-master.h" #include "hw/sysbus.h" diff --git a/include/hw/fsi/cfam.h b/include/hw/fsi/cfam.h index 7abc3b2..cceb4bd 100644 --- a/include/hw/fsi/cfam.h +++ b/include/hw/fsi/cfam.h @@ -7,7 +7,7 @@ #ifndef FSI_CFAM_H #define FSI_CFAM_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/fsi/fsi.h" #include "hw/fsi/lbus.h" diff --git a/include/hw/fsi/fsi-master.h b/include/hw/fsi/fsi-master.h index 68e5f56..b634ecd 100644 --- a/include/hw/fsi/fsi-master.h +++ b/include/hw/fsi/fsi-master.h @@ -7,7 +7,7 @@ #ifndef FSI_FSI_MASTER_H #define FSI_FSI_MASTER_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "hw/fsi/fsi.h" #include "hw/fsi/cfam.h" diff --git a/include/hw/fsi/fsi.h b/include/hw/fsi/fsi.h index e00f6ef..f34765e 100644 --- a/include/hw/fsi/fsi.h +++ b/include/hw/fsi/fsi.h @@ -7,7 +7,7 @@ #ifndef FSI_FSI_H #define FSI_FSI_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "hw/fsi/lbus.h" #include "qemu/bitops.h" diff --git a/include/hw/fsi/lbus.h b/include/hw/fsi/lbus.h index 558268c..1251907 100644 --- a/include/hw/fsi/lbus.h +++ b/include/hw/fsi/lbus.h @@ -9,7 +9,7 @@ #include "hw/qdev-core.h" #include "qemu/units.h" -#include "exec/memory.h" +#include "system/memory.h" #define TYPE_FSI_LBUS_DEVICE "fsi.lbus.device" OBJECT_DECLARE_SIMPLE_TYPE(FSILBusDevice, FSI_LBUS_DEVICE) diff --git a/include/hw/gpio/aspeed_gpio.h b/include/hw/gpio/aspeed_gpio.h index 90a12ae..e6b2fe7 100644 --- a/include/hw/gpio/aspeed_gpio.h +++ b/include/hw/gpio/aspeed_gpio.h @@ -70,12 +70,14 @@ typedef struct AspeedGPIOReg { } AspeedGPIOReg; struct AspeedGPIOClass { - SysBusDevice parent_obj; + SysBusDeviceClass parent_class; const GPIOSetProperties *props; uint32_t nr_gpio_pins; uint32_t nr_gpio_sets; const AspeedGPIOReg *reg_table; unsigned reg_table_count; + uint64_t mem_size; + const MemoryRegionOps *reg_ops; }; struct AspeedGPIOState { @@ -88,7 +90,7 @@ struct AspeedGPIOState { qemu_irq irq; qemu_irq gpios[ASPEED_GPIO_MAX_NR_SETS][ASPEED_GPIOS_PER_SET]; -/* Parallel GPIO Registers */ + /* Parallel GPIO Registers */ uint32_t debounce_regs[ASPEED_GPIO_NR_DEBOUNCE_REGS]; struct GPIOSets { uint32_t data_value; /* Reflects pin values */ diff --git a/include/hw/gpio/npcm7xx_gpio.h b/include/hw/gpio/npcm7xx_gpio.h index b1d771b..7c0bf61 100644 --- a/include/hw/gpio/npcm7xx_gpio.h +++ b/include/hw/gpio/npcm7xx_gpio.h @@ -15,7 +15,7 @@ #ifndef NPCM7XX_GPIO_H #define NPCM7XX_GPIO_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" /* Number of pins managed by each controller. */ diff --git a/include/hw/hw.h b/include/hw/hw.h index 045c1c8..1b33d12 100644 --- a/include/hw/hw.h +++ b/include/hw/hw.h @@ -1,10 +1,6 @@ #ifndef QEMU_HW_H #define QEMU_HW_H -#ifdef CONFIG_USER_ONLY -#error Cannot include hw/hw.h from user emulation -#endif - G_NORETURN void hw_error(const char *fmt, ...) G_GNUC_PRINTF(1, 2); #endif diff --git a/include/hw/hyperv/hyperv-proto.h b/include/hw/hyperv/hyperv-proto.h index 4a22973..fffc5ce 100644 --- a/include/hw/hyperv/hyperv-proto.h +++ b/include/hw/hyperv/hyperv-proto.h @@ -62,6 +62,18 @@ #define HV_MESSAGE_X64_LEGACY_FP_ERROR 0x80010005 /* + * Hyper-V Synthetic debug options MSR + */ +#define HV_X64_MSR_SYNDBG_CONTROL 0x400000F1 +#define HV_X64_MSR_SYNDBG_STATUS 0x400000F2 +#define HV_X64_MSR_SYNDBG_SEND_BUFFER 0x400000F3 +#define HV_X64_MSR_SYNDBG_RECV_BUFFER 0x400000F4 +#define HV_X64_MSR_SYNDBG_PENDING_BUFFER 0x400000F5 +#define HV_X64_MSR_SYNDBG_OPTIONS 0x400000FF + +#define HV_X64_SYNDBG_OPTION_USE_HCALLS BIT(2) + +/* * Message flags */ #define HV_MESSAGE_FLAG_PENDING 0x1 diff --git a/include/hw/hyperv/hyperv.h b/include/hw/hyperv/hyperv.h index d717b4e..63a8b65 100644 --- a/include/hw/hyperv/hyperv.h +++ b/include/hw/hyperv/hyperv.h @@ -10,7 +10,8 @@ #ifndef HW_HYPERV_HYPERV_H #define HW_HYPERV_HYPERV_H -#include "cpu-qom.h" +#include "exec/hwaddr.h" +#include "hw/core/cpu.h" #include "hw/hyperv/hyperv-proto.h" typedef struct HvSintRoute HvSintRoute; diff --git a/include/hw/hyperv/vmbus.h b/include/hw/hyperv/vmbus.h index 5c50585..06b948b 100644 --- a/include/hw/hyperv/vmbus.h +++ b/include/hw/hyperv/vmbus.h @@ -10,8 +10,8 @@ #ifndef HW_HYPERV_VMBUS_H #define HW_HYPERV_VMBUS_H -#include "sysemu/sysemu.h" -#include "sysemu/dma.h" +#include "system/system.h" +#include "system/dma.h" #include "hw/qdev-core.h" #include "migration/vmstate.h" #include "hw/hyperv/vmbus-proto.h" diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h index fad5e92..2daacc1 100644 --- a/include/hw/i2c/aspeed_i2c.h +++ b/include/hw/i2c/aspeed_i2c.h @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * with this program; if not, see <https://www.gnu.org/licenses/>. */ #ifndef ASPEED_I2C_H @@ -31,12 +30,14 @@ #define TYPE_ASPEED_2500_I2C TYPE_ASPEED_I2C "-ast2500" #define TYPE_ASPEED_2600_I2C TYPE_ASPEED_I2C "-ast2600" #define TYPE_ASPEED_1030_I2C TYPE_ASPEED_I2C "-ast1030" +#define TYPE_ASPEED_2700_I2C TYPE_ASPEED_I2C "-ast2700" OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C) #define ASPEED_I2C_NR_BUSSES 16 #define ASPEED_I2C_SHARE_POOL_SIZE 0x800 +#define ASPEED_I2C_BUS_POOL_SIZE 0x20 #define ASPEED_I2C_OLD_NUM_REG 11 -#define ASPEED_I2C_NEW_NUM_REG 22 +#define ASPEED_I2C_NEW_NUM_REG 28 #define A_I2CD_M_STOP_CMD BIT(5) #define A_I2CD_M_RX_CMD BIT(3) @@ -225,6 +226,15 @@ REG32(I2CS_DMA_LEN_STS, 0x4c) FIELD(I2CS_DMA_LEN_STS, TX_LEN, 0, 13) REG32(I2CC_DMA_ADDR, 0x50) REG32(I2CC_DMA_LEN, 0x54) +/* DMA 64bits */ +REG32(I2CM_DMA_TX_ADDR_HI, 0x60) + FIELD(I2CM_DMA_TX_ADDR_HI, ADDR_HI, 0, 7) +REG32(I2CM_DMA_RX_ADDR_HI, 0x64) + FIELD(I2CM_DMA_RX_ADDR_HI, ADDR_HI, 0, 7) +REG32(I2CS_DMA_TX_ADDR_HI, 0x68) + FIELD(I2CS_DMA_TX_ADDR_HI, ADDR_HI, 0, 7) +REG32(I2CS_DMA_RX_ADDR_HI, 0x6c) + FIELD(I2CS_DMA_RX_ADDR_HI, ADDR_HI, 0, 7) struct AspeedI2CState; @@ -239,12 +249,15 @@ struct AspeedI2CBus { I2CSlave *slave; MemoryRegion mr; + MemoryRegion mr_pool; I2CBus *bus; uint8_t id; qemu_irq irq; uint32_t regs[ASPEED_I2C_NEW_NUM_REG]; + uint8_t pool[ASPEED_I2C_BUS_POOL_SIZE]; + uint64_t dma_dram_offset; }; struct AspeedI2CState { @@ -275,15 +288,19 @@ struct AspeedI2CClass { uint8_t num_busses; uint8_t reg_size; + uint32_t reg_gap_size; uint8_t gap; qemu_irq (*bus_get_irq)(AspeedI2CBus *); uint64_t pool_size; hwaddr pool_base; + uint32_t pool_gap_size; uint8_t *(*bus_pool_base)(AspeedI2CBus *); bool check_sram; bool has_dma; + bool has_share_pool; uint64_t mem_size; + bool has_dma64; }; static inline bool aspeed_i2c_is_new_mode(AspeedI2CState *s) @@ -363,14 +380,6 @@ static inline uint32_t aspeed_i2c_bus_dma_len_offset(AspeedI2CBus *bus) return R_I2CD_DMA_LEN; } -static inline uint32_t aspeed_i2c_bus_dma_addr_offset(AspeedI2CBus *bus) -{ - if (aspeed_i2c_is_new_mode(bus->controller)) { - return R_I2CC_DMA_ADDR; - } - return R_I2CD_DMA_ADDR; -} - static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus) { return SHARED_ARRAY_FIELD_EX32(bus->regs, aspeed_i2c_bus_ctrl_offset(bus), diff --git a/include/hw/i2c/npcm7xx_smbus.h b/include/hw/i2c/npcm7xx_smbus.h index dc45963..9c544c5 100644 --- a/include/hw/i2c/npcm7xx_smbus.h +++ b/include/hw/i2c/npcm7xx_smbus.h @@ -16,7 +16,7 @@ #ifndef NPCM7XX_SMBUS_H #define NPCM7XX_SMBUS_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/i2c/i2c.h" #include "hw/irq.h" #include "hw/sysbus.h" diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h index 0d74207..dafe0df 100644 --- a/include/hw/i2c/pm_smbus.h +++ b/include/hw/i2c/pm_smbus.h @@ -1,7 +1,7 @@ #ifndef PM_SMBUS_H #define PM_SMBUS_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/i2c/smbus_master.h" #define PM_SMBUS_MAX_MSG_SIZE 32 diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h index d6e8583..429278d 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -22,7 +22,7 @@ #define QEMU_APIC_INTERNAL_H #include "cpu.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/timer.h" #include "target/i386/cpu-qom.h" #include "qom/object.h" diff --git a/include/hw/i386/hostmem-epc.h b/include/hw/i386/hostmem-epc.h index 846c726..3988dec 100644 --- a/include/hw/i386/hostmem-epc.h +++ b/include/hw/i386/hostmem-epc.h @@ -12,7 +12,7 @@ #ifndef QEMU_HOSTMEM_EPC_H #define QEMU_HOSTMEM_EPC_H -#include "sysemu/hostmem.h" +#include "system/hostmem.h" #define TYPE_MEMORY_BACKEND_EPC "memory-backend-epc" diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index 1eb05c2..e95477e 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -45,8 +45,9 @@ OBJECT_DECLARE_SIMPLE_TYPE(IntelIOMMUState, INTEL_IOMMU_DEVICE) #define DMAR_REG_SIZE 0x230 #define VTD_HOST_AW_39BIT 39 #define VTD_HOST_AW_48BIT 48 -#define VTD_HOST_ADDRESS_WIDTH VTD_HOST_AW_39BIT +#define VTD_HOST_ADDRESS_WIDTH VTD_HOST_AW_48BIT #define VTD_HAW_MASK(aw) ((1ULL << (aw)) - 1) +#define VTD_MGAW_FROM_CAP(cap) ((cap >> 16) & 0x3fULL) #define DMAR_REPORT_F_INTR (1) @@ -152,9 +153,10 @@ struct VTDIOTLBEntry { uint64_t gfn; uint16_t domain_id; uint32_t pasid; - uint64_t slpte; + uint64_t pte; uint64_t mask; uint8_t access_flags; + uint8_t pgtt; }; /* VT-d Source-ID Qualifier types */ @@ -262,6 +264,7 @@ struct IntelIOMMUState { bool caching_mode; /* RO - is cap CM enabled? */ bool scalable_mode; /* RO - is Scalable Mode supported? */ + bool flts; /* RO - is stage-1 translation supported? */ bool snoop_control; /* RO - is SNP filed supported? */ dma_addr_t root; /* Current root table pointer */ @@ -305,6 +308,10 @@ struct IntelIOMMUState { bool dma_drain; /* Whether DMA r/w draining enabled */ bool dma_translation; /* Whether DMA translation supported */ bool pasid; /* Whether to support PASID */ + bool fs1gp; /* First Stage 1-GByte Page Support */ + + /* Transient Mapping, Reserved(0) since VTD spec revision 3.2 */ + bool stale_tm; /* * Protects IOMMU states in general. Currently it protects the diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h index fad97a8..b9ac34a 100644 --- a/include/hw/i386/microvm.h +++ b/include/hw/i386/microvm.h @@ -78,6 +78,8 @@ struct MicrovmMachineClass { X86MachineClass parent; HotplugHandler *(*orig_hotplug_handler)(MachineState *machine, DeviceState *dev); + void (*x86_load_linux)(X86MachineState *x86ms, FWCfgState *fw_cfg, + int acpi_data_size, bool pvh_enabled); }; struct MicrovmMachineState { diff --git a/include/hw/i386/nitro_enclave.h b/include/hw/i386/nitro_enclave.h new file mode 100644 index 0000000..885163f --- /dev/null +++ b/include/hw/i386/nitro_enclave.h @@ -0,0 +1,62 @@ +/* + * AWS nitro-enclave machine + * + * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + */ + +#ifndef HW_I386_NITRO_ENCLAVE_H +#define HW_I386_NITRO_ENCLAVE_H + +#include "crypto/hash.h" +#include "hw/i386/microvm.h" +#include "qom/object.h" +#include "hw/virtio/virtio-nsm.h" + +/* Machine type options */ +#define NITRO_ENCLAVE_VSOCK_CHARDEV_ID "vsock" +#define NITRO_ENCLAVE_ID "id" +#define NITRO_ENCLAVE_PARENT_ROLE "parent-role" +#define NITRO_ENCLAVE_PARENT_ID "parent-id" + +struct NitroEnclaveMachineClass { + MicrovmMachineClass parent; + + void (*parent_init)(MachineState *state); + void (*parent_reset)(MachineState *machine, ResetType type); +}; + +struct NitroEnclaveMachineState { + MicrovmMachineState parent; + + /* Machine type options */ + char *vsock; + /* Enclave identifier */ + char *id; + /* Parent instance IAM role ARN */ + char *parent_role; + /* Parent instance identifier */ + char *parent_id; + + /* Machine state */ + VirtIONSM *vnsm; + + /* kernel + ramdisks + cmdline SHA384 hash */ + uint8_t image_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + /* kernel + boot ramdisk + cmdline SHA384 hash */ + uint8_t bootstrap_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + /* application ramdisk(s) SHA384 hash */ + uint8_t app_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + /* certificate fingerprint SHA384 hash */ + uint8_t fingerprint_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384]; + bool signature_found; +}; + +#define TYPE_NITRO_ENCLAVE_MACHINE MACHINE_TYPE_NAME("nitro-enclave") +OBJECT_DECLARE_TYPE(NitroEnclaveMachineState, NitroEnclaveMachineClass, + NITRO_ENCLAVE_MACHINE) + +#endif diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 4e55d7e..79b72c5 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -107,7 +107,6 @@ struct PCMachineClass { /* RAM / address space compat: */ bool gigabyte_align; bool has_reserved_memory; - bool broken_reserved_end; bool enforce_amd_1tb_hole; bool isa_bios_alias; @@ -215,6 +214,15 @@ 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_10_0[]; +extern const size_t pc_compat_10_0_len; + +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; + extern GlobalProperty pc_compat_9_0[]; extern const size_t pc_compat_9_0_len; @@ -290,17 +298,9 @@ extern const size_t pc_compat_2_7_len; extern GlobalProperty pc_compat_2_6[]; extern const size_t pc_compat_2_6_len; -extern GlobalProperty pc_compat_2_5[]; -extern const size_t pc_compat_2_5_len; - -extern GlobalProperty pc_compat_2_4[]; -extern const size_t pc_compat_2_4_len; - -extern GlobalProperty pc_compat_2_3[]; -extern const size_t pc_compat_2_3_len; - #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \ - static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \ + static void pc_machine_##suffix##_class_init(ObjectClass *oc, \ + const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ optsfn(mc); \ @@ -313,11 +313,11 @@ extern const size_t pc_compat_2_3_len; }; \ static void pc_machine_init_##suffix(void) \ { \ - type_register(&pc_machine_type_##suffix); \ + type_register_static(&pc_machine_type_##suffix); \ } \ 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) \ { \ @@ -325,12 +325,14 @@ extern const size_t pc_compat_2_3_len; } \ static void MACHINE_VER_SYM(class_init, namesym, __VA_ARGS__)( \ ObjectClass *oc, \ - void *data) \ + const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ 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__) = \ { \ @@ -341,7 +343,7 @@ extern const size_t pc_compat_2_3_len; static void MACHINE_VER_SYM(register, namesym, __VA_ARGS__)(void) \ { \ MACHINE_VER_DELETION(__VA_ARGS__); \ - type_register(&MACHINE_VER_SYM(info, namesym, __VA_ARGS__)); \ + type_register_static(&MACHINE_VER_SYM(info, namesym, __VA_ARGS__)); \ } \ type_init(MACHINE_VER_SYM(register, namesym, __VA_ARGS__)); diff --git a/include/hw/i386/tdvf.h b/include/hw/i386/tdvf.h new file mode 100644 index 0000000..e75c8d1 --- /dev/null +++ b/include/hw/i386/tdvf.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Intel Corporation + * Author: Isaku Yamahata <isaku.yamahata at gmail.com> + * <isaku.yamahata at intel.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_I386_TDVF_H +#define HW_I386_TDVF_H + +#include "qemu/osdep.h" + +#define TDVF_SECTION_TYPE_BFV 0 +#define TDVF_SECTION_TYPE_CFV 1 +#define TDVF_SECTION_TYPE_TD_HOB 2 +#define TDVF_SECTION_TYPE_TEMP_MEM 3 + +#define TDVF_SECTION_ATTRIBUTES_MR_EXTEND (1U << 0) +#define TDVF_SECTION_ATTRIBUTES_PAGE_AUG (1U << 1) + +typedef struct TdxFirmwareEntry { + uint32_t data_offset; + uint32_t data_len; + uint64_t address; + uint64_t size; + uint32_t type; + uint32_t attributes; + + void *mem_ptr; +} TdxFirmwareEntry; + +typedef struct TdxFirmware { + void *mem_ptr; + + uint32_t nr_entries; + TdxFirmwareEntry *entries; +} TdxFirmware; + +#define for_each_tdx_fw_entry(fw, e) \ + for (e = (fw)->entries; e != (fw)->entries + (fw)->nr_entries; e++) + +int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size); + +#endif /* HW_I386_TDVF_H */ diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h index dff49fc..f6380f1 100644 --- a/include/hw/i386/topology.h +++ b/include/hw/i386/topology.h @@ -39,7 +39,7 @@ * CPUID Fn8000_0008_ECX[ApicIdCoreIdSize[3:0]] is set to apicid_core_width(). */ - +#include "qapi/qapi-types-machine-common.h" #include "qemu/bitops.h" /* @@ -62,21 +62,7 @@ typedef struct X86CPUTopoInfo { unsigned threads_per_core; } X86CPUTopoInfo; -/* - * CPUTopoLevel is the general i386 topology hierarchical representation, - * ordered by increasing hierarchical relationship. - * Its enumeration value is not bound to the type value of Intel (CPUID[0x1F]) - * or AMD (CPUID[0x80000026]). - */ -enum CPUTopoLevel { - CPU_TOPO_LEVEL_INVALID, - CPU_TOPO_LEVEL_SMT, - CPU_TOPO_LEVEL_CORE, - CPU_TOPO_LEVEL_MODULE, - CPU_TOPO_LEVEL_DIE, - CPU_TOPO_LEVEL_PACKAGE, - CPU_TOPO_LEVEL_MAX, -}; +#define CPU_TOPOLOGY_LEVEL_INVALID CPU_TOPOLOGY_LEVEL__MAX /* Return the bit width needed for 'count' IDs */ static unsigned apicid_bitwidth_for_count(unsigned count) @@ -135,9 +121,10 @@ static inline unsigned apicid_pkg_offset(X86CPUTopoInfo *topo_info) } /* - * Make APIC ID for the CPU based on Pkg_ID, Core_ID, SMT_ID + * Make APIC ID for the CPU based on topology and IDs of each topology level. * - * The caller must make sure core_id < nr_cores and smt_id < nr_threads. + * The caller must make sure the ID of each level doesn't exceed the width of + * the level. */ static inline apic_id_t x86_apicid_from_topo_ids(X86CPUTopoInfo *topo_info, const X86CPUTopoIDs *topo_ids) @@ -212,8 +199,33 @@ static inline apic_id_t x86_apicid_from_cpu_idx(X86CPUTopoInfo *topo_info, */ static inline bool x86_has_extended_topo(unsigned long *topo_bitmap) { - return test_bit(CPU_TOPO_LEVEL_MODULE, topo_bitmap) || - test_bit(CPU_TOPO_LEVEL_DIE, topo_bitmap); + return test_bit(CPU_TOPOLOGY_LEVEL_MODULE, topo_bitmap) || + test_bit(CPU_TOPOLOGY_LEVEL_DIE, topo_bitmap); +} + +static inline unsigned x86_module_per_pkg(X86CPUTopoInfo *topo_info) +{ + return topo_info->modules_per_die * topo_info->dies_per_pkg; +} + +static inline unsigned x86_cores_per_pkg(X86CPUTopoInfo *topo_info) +{ + return topo_info->cores_per_module * x86_module_per_pkg(topo_info); +} + +static inline unsigned x86_threads_per_pkg(X86CPUTopoInfo *topo_info) +{ + return topo_info->threads_per_core * x86_cores_per_pkg(topo_info); +} + +static inline unsigned x86_threads_per_module(X86CPUTopoInfo *topo_info) +{ + return topo_info->threads_per_core * topo_info->cores_per_module; +} + +static inline unsigned x86_threads_per_die(X86CPUTopoInfo *topo_info) +{ + return x86_threads_per_module(topo_info) * topo_info->modules_per_die; } #endif /* HW_I386_TOPOLOGY_H */ diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index d43cb39..fc460b8 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -18,7 +18,7 @@ #define HW_I386_X86_H #include "exec/hwaddr.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/boards.h" #include "hw/i386/topology.h" @@ -27,13 +27,8 @@ #include "qom/object.h" struct X86MachineClass { - /*< private >*/ MachineClass parent; - /*< public >*/ - - /* TSC rate migration: */ - bool save_tsc_khz; /* use DMA capable linuxboot option rom */ bool fwcfg_dma_enabled; /* CPU and apic information: */ diff --git a/include/hw/ide/ahci-pci.h b/include/hw/ide/ahci-pci.h index c2ee616..face1a9 100644 --- a/include/hw/ide/ahci-pci.h +++ b/include/hw/ide/ahci-pci.h @@ -9,6 +9,7 @@ #include "qom/object.h" #include "hw/ide/ahci.h" #include "hw/pci/pci_device.h" +#include "hw/irq.h" #define TYPE_ICH9_AHCI "ich9-ahci" OBJECT_DECLARE_SIMPLE_TYPE(AHCIPCIState, ICH9_AHCI) @@ -17,6 +18,7 @@ struct AHCIPCIState { PCIDevice parent_obj; AHCIState ahci; + IRQState irq; }; #endif diff --git a/include/hw/ide/ahci.h b/include/hw/ide/ahci.h index ba31e75..cd07b87 100644 --- a/include/hw/ide/ahci.h +++ b/include/hw/ide/ahci.h @@ -24,7 +24,7 @@ #ifndef HW_IDE_AHCI_H #define HW_IDE_AHCI_H -#include "exec/memory.h" +#include "system/memory.h" typedef struct AHCIDevice AHCIDevice; @@ -37,8 +37,6 @@ typedef struct AHCIControlRegs { } AHCIControlRegs; typedef struct AHCIState { - DeviceState *container; - AHCIDevice *dev; AHCIControlRegs control_regs; MemoryRegion mem; diff --git a/include/hw/ide/ide-bus.h b/include/hw/ide/ide-bus.h index 4841a7d..121b455 100644 --- a/include/hw/ide/ide-bus.h +++ b/include/hw/ide/ide-bus.h @@ -1,7 +1,7 @@ #ifndef HW_IDE_BUS_H #define HW_IDE_BUS_H -#include "exec/ioport.h" +#include "system/ioport.h" #include "hw/ide/ide-dev.h" #include "hw/ide/ide-dma.h" diff --git a/include/hw/ide/ide-dev.h b/include/hw/ide/ide-dev.h index 9a0d71d..92e8868 100644 --- a/include/hw/ide/ide-dev.h +++ b/include/hw/ide/ide-dev.h @@ -20,7 +20,7 @@ #ifndef IDE_DEV_H #define IDE_DEV_H -#include "sysemu/dma.h" +#include "system/dma.h" #include "hw/qdev-properties.h" #include "hw/block/block.h" diff --git a/include/hw/input/lm832x.h b/include/hw/input/lm832x.h deleted file mode 100644 index e0e5d5e..0000000 --- a/include/hw/input/lm832x.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * National Semiconductor LM8322/8323 GPIO keyboard & PWM chips. - * - * Copyright (C) 2008 Nokia Corporation - * Written by Andrzej Zaborowski <andrew@openedhand.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 or - * (at your option) version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef HW_INPUT_LM832X_H -#define HW_INPUT_LM832X_H - -#define TYPE_LM8323 "lm8323" - -void lm832x_key_event(DeviceState *dev, int key, int state); - -#endif diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h deleted file mode 100644 index 00eca17..0000000 --- a/include/hw/input/tsc2xxx.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * TI touchscreen controller - * - * Copyright (c) 2006 Andrzej Zaborowski - * Copyright (C) 2008 Nokia Corporation - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef HW_INPUT_TSC2XXX_H -#define HW_INPUT_TSC2XXX_H - -typedef struct MouseTransformInfo { - /* Touchscreen resolution */ - int x; - int y; - /* Calibration values as used/generated by tslib */ - int a[7]; -} MouseTransformInfo; - -typedef struct uWireSlave { - uint16_t (*receive)(void *opaque); - void (*send)(void *opaque, uint16_t data); - void *opaque; -} uWireSlave; - -/* tsc210x.c */ -uWireSlave *tsc2102_init(qemu_irq pint); -uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav); -I2SCodec *tsc210x_codec(uWireSlave *chip); -uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len); -void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info); -void tsc210x_key_event(uWireSlave *chip, int key, int down); - -/* tsc2005.c */ -void *tsc2005_init(qemu_irq pintdav); -uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len); -void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info); - -#endif diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h index 48f6a51..be923f7 100644 --- a/include/hw/intc/arm_gic.h +++ b/include/hw/intc/arm_gic.h @@ -27,6 +27,9 @@ * implement the security extensions * + QOM property "has-virtualization-extensions": set true if the GIC should * implement the virtualization extensions + * + QOM property "first-cpu-index": index of the first cpu attached to the + * GIC (default 0). The CPUs connected to the GIC are assumed to be + * first-cpu-index, first-cpu-index + 1, ... first-cpu-index + num-cpu - 1. * + unnamed GPIO inputs: (where P is number of SPIs, i.e. num-irq - 32) * [0..P-1] SPIs * [P..P+31] PPIs for CPU 0 diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index 97fea41..93a3cc2 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -129,6 +129,8 @@ struct GICState { uint32_t num_lrs; uint32_t num_cpu; + /* cpu_index of the first CPU, attached to this GIC. */ + uint32_t first_cpu_index; MemoryRegion iomem; /* Distributor */ /* This is just so we can have an opaque pointer which identifies diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h index cd09bee..a3d6a0e 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -51,13 +51,13 @@ /* Maximum number of list registers (architectural limit) */ #define GICV3_LR_MAX 16 -/* For some distributor fields we want to model the array of 32-bit +/* + * For some distributor fields we want to model the array of 32-bit * register values which hold various bitmaps corresponding to enabled, - * pending, etc bits. These macros and functions facilitate that; the - * APIs are generally modelled on the generic bitmap.h functions - * (which are unsuitable here because they use 'unsigned long' as the - * underlying storage type, which is very awkward when you need to - * access the data as 32-bit values.) + * pending, etc bits. We use the set_bit32() etc family of functions + * from bitops.h for this. For a few cases we need to implement some + * extra operations. + * * Each bitmap contains a bit for each interrupt. Although there is * space for the PPIs and SGIs, those bits (the first 32) are never * used as that state lives in the redistributor. The unused bits are @@ -65,39 +65,13 @@ * avoids bugs where we forget to subtract GIC_INTERNAL from an * interrupt number. */ -#define GICV3_BMP_SIZE DIV_ROUND_UP(GICV3_MAXIRQ, 32) - -#define GIC_DECLARE_BITMAP(name) \ - uint32_t name[GICV3_BMP_SIZE] - -#define GIC_BIT_MASK(nr) (1U << ((nr) % 32)) -#define GIC_BIT_WORD(nr) ((nr) / 32) - -static inline void gic_bmp_set_bit(int nr, uint32_t *addr) -{ - uint32_t mask = GIC_BIT_MASK(nr); - uint32_t *p = addr + GIC_BIT_WORD(nr); - - *p |= mask; -} - -static inline void gic_bmp_clear_bit(int nr, uint32_t *addr) -{ - uint32_t mask = GIC_BIT_MASK(nr); - uint32_t *p = addr + GIC_BIT_WORD(nr); - - *p &= ~mask; -} - -static inline int gic_bmp_test_bit(int nr, const uint32_t *addr) -{ - return 1U & (addr[GIC_BIT_WORD(nr)] >> (nr & 31)); -} +#define GIC_DECLARE_BITMAP(name) DECLARE_BITMAP32(name, GICV3_MAXIRQ) +#define GICV3_BMP_SIZE BITS_TO_U32S(GICV3_MAXIRQ) static inline void gic_bmp_replace_bit(int nr, uint32_t *addr, int val) { - uint32_t mask = GIC_BIT_MASK(nr); - uint32_t *p = addr + GIC_BIT_WORD(nr); + uint32_t mask = BIT32_MASK(nr); + uint32_t *p = addr + BIT32_WORD(nr); *p &= ~mask; *p |= (val & 1U) << (nr % 32); @@ -106,7 +80,7 @@ static inline void gic_bmp_replace_bit(int nr, uint32_t *addr, int val) /* Return a pointer to the 32-bit word containing the specified bit. */ static inline uint32_t *gic_bmp_ptr32(uint32_t *addr, int nr) { - return addr + GIC_BIT_WORD(nr); + return addr + BIT32_WORD(nr); } typedef struct GICv3State GICv3State; @@ -301,15 +275,15 @@ struct GICv3State { #define GICV3_BITMAP_ACCESSORS(BMP) \ static inline void gicv3_gicd_##BMP##_set(GICv3State *s, int irq) \ { \ - gic_bmp_set_bit(irq, s->BMP); \ + set_bit32(irq, s->BMP); \ } \ static inline int gicv3_gicd_##BMP##_test(GICv3State *s, int irq) \ { \ - return gic_bmp_test_bit(irq, s->BMP); \ + return test_bit32(irq, s->BMP); \ } \ static inline void gicv3_gicd_##BMP##_clear(GICv3State *s, int irq) \ { \ - gic_bmp_clear_bit(irq, s->BMP); \ + clear_bit32(irq, s->BMP); \ } \ static inline void gicv3_gicd_##BMP##_replace(GICv3State *s, \ int irq, int value) \ diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h index 7dc712b..3c7b543 100644 --- a/include/hw/intc/arm_gicv3_its_common.h +++ b/include/hw/intc/arm_gicv3_its_common.h @@ -128,7 +128,7 @@ struct GICv3ITSCommonClass { * Return the ITS class name to use depending on whether KVM acceleration * and KVM CAP_SIGNAL_MSI are supported * - * Returns: class name to use or NULL + * Returns: class name to use */ const char *its_class_name(void); diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 89fe8ae..7b9964f 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -189,21 +189,7 @@ int armv7m_nvic_raw_execution_priority(NVICState *s); * @secure: the security state to test * This corresponds to the pseudocode IsReqExecPriNeg(). */ -#ifndef CONFIG_USER_ONLY bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure); -#else -static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure) -{ - return false; -} -#endif -#ifndef CONFIG_USER_ONLY bool armv7m_nvic_can_take_pending_exception(NVICState *s); -#else -static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s) -{ - return true; -} -#endif #endif diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h index 18cb434..5128838 100644 --- a/include/hw/intc/aspeed_intc.h +++ b/include/hw/intc/aspeed_intc.h @@ -14,10 +14,24 @@ #define TYPE_ASPEED_INTC "aspeed.intc" #define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700" +#define TYPE_ASPEED_2700_INTCIO TYPE_ASPEED_INTC "io-ast2700" +#define TYPE_ASPEED_2700SSP_INTC TYPE_ASPEED_INTC "-ast2700ssp" +#define TYPE_ASPEED_2700SSP_INTCIO TYPE_ASPEED_INTC "io-ast2700ssp" +#define TYPE_ASPEED_2700TSP_INTC TYPE_ASPEED_INTC "-ast2700tsp" +#define TYPE_ASPEED_2700TSP_INTCIO TYPE_ASPEED_INTC "io-ast2700tsp" + OBJECT_DECLARE_TYPE(AspeedINTCState, AspeedINTCClass, ASPEED_INTC) -#define ASPEED_INTC_NR_REGS (0x2000 >> 2) -#define ASPEED_INTC_NR_INTS 9 +#define ASPEED_INTC_MAX_INPINS 10 +#define ASPEED_INTC_MAX_OUTPINS 19 + +typedef struct AspeedINTCIRQ { + int inpin_idx; + int outpin_idx; + int num_outpins; + uint32_t enable_reg; + uint32_t status_reg; +} AspeedINTCIRQ; struct AspeedINTCState { /*< private >*/ @@ -25,20 +39,29 @@ struct AspeedINTCState { /*< public >*/ MemoryRegion iomem; - uint32_t regs[ASPEED_INTC_NR_REGS]; - OrIRQState orgates[ASPEED_INTC_NR_INTS]; - qemu_irq output_pins[ASPEED_INTC_NR_INTS]; + MemoryRegion iomem_container; + + uint32_t *regs; + OrIRQState orgates[ASPEED_INTC_MAX_INPINS]; + qemu_irq output_pins[ASPEED_INTC_MAX_OUTPINS]; - uint32_t enable[ASPEED_INTC_NR_INTS]; - uint32_t mask[ASPEED_INTC_NR_INTS]; - uint32_t pending[ASPEED_INTC_NR_INTS]; + uint32_t enable[ASPEED_INTC_MAX_INPINS]; + uint32_t mask[ASPEED_INTC_MAX_INPINS]; + uint32_t pending[ASPEED_INTC_MAX_INPINS]; }; struct AspeedINTCClass { SysBusDeviceClass parent_class; uint32_t num_lines; - uint32_t num_ints; + uint32_t num_inpins; + uint32_t num_outpins; + uint64_t mem_size; + uint64_t nr_regs; + uint64_t reg_offset; + const MemoryRegionOps *reg_ops; + const AspeedINTCIRQ *irq_table; + int irq_table_count; }; #endif /* ASPEED_INTC_H */ diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h index 626a37d..9be1d73 100644 --- a/include/hw/intc/loongarch_extioi.h +++ b/include/hw/intc/loongarch_extioi.h @@ -5,85 +5,29 @@ * Copyright (C) 2021 Loongson Technology Corporation Limited */ -#include "hw/sysbus.h" -#include "hw/loongarch/virt.h" - #ifndef LOONGARCH_EXTIOI_H #define LOONGARCH_EXTIOI_H -#define LS3A_INTC_IP 8 -#define EXTIOI_IRQS (256) -#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8) -/* irq from EXTIOI is routed to no more than 4 cpus */ -#define EXTIOI_CPUS (4) -/* map to ipnum per 32 irqs */ -#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32) -#define EXTIOI_IRQS_COREMAP_SIZE 256 -#define EXTIOI_IRQS_NODETYPE_COUNT 16 -#define EXTIOI_IRQS_GROUP_COUNT 8 - -#define APIC_OFFSET 0x400 -#define APIC_BASE (0x1000ULL + APIC_OFFSET) +#include "hw/intc/loongarch_extioi_common.h" -#define EXTIOI_NODETYPE_START (0x4a0 - APIC_OFFSET) -#define EXTIOI_NODETYPE_END (0x4c0 - APIC_OFFSET) -#define EXTIOI_IPMAP_START (0x4c0 - APIC_OFFSET) -#define EXTIOI_IPMAP_END (0x4c8 - APIC_OFFSET) -#define EXTIOI_ENABLE_START (0x600 - APIC_OFFSET) -#define EXTIOI_ENABLE_END (0x620 - APIC_OFFSET) -#define EXTIOI_BOUNCE_START (0x680 - APIC_OFFSET) -#define EXTIOI_BOUNCE_END (0x6a0 - APIC_OFFSET) -#define EXTIOI_ISR_START (0x700 - APIC_OFFSET) -#define EXTIOI_ISR_END (0x720 - APIC_OFFSET) -#define EXTIOI_COREISR_START (0x800 - APIC_OFFSET) -#define EXTIOI_COREISR_END (0xB20 - APIC_OFFSET) -#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) -#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) -#define EXTIOI_SIZE 0x800 +#define TYPE_LOONGARCH_EXTIOI "loongarch.extioi" +OBJECT_DECLARE_TYPE(LoongArchExtIOIState, LoongArchExtIOIClass, LOONGARCH_EXTIOI) -#define EXTIOI_VIRT_BASE (0x40000000) -#define EXTIOI_VIRT_SIZE (0x1000) -#define EXTIOI_VIRT_FEATURES (0x0) -#define EXTIOI_HAS_VIRT_EXTENSION (0) -#define EXTIOI_HAS_ENABLE_OPTION (1) -#define EXTIOI_HAS_INT_ENCODE (2) -#define EXTIOI_HAS_CPU_ENCODE (3) -#define EXTIOI_VIRT_HAS_FEATURES (BIT(EXTIOI_HAS_VIRT_EXTENSION) \ - | BIT(EXTIOI_HAS_ENABLE_OPTION) \ - | BIT(EXTIOI_HAS_CPU_ENCODE)) -#define EXTIOI_VIRT_CONFIG (0x4) -#define EXTIOI_ENABLE (1) -#define EXTIOI_ENABLE_INT_ENCODE (2) -#define EXTIOI_ENABLE_CPU_ENCODE (3) -#define EXTIOI_VIRT_COREMAP_START (0x40) -#define EXTIOI_VIRT_COREMAP_END (0x240) +struct LoongArchExtIOIState { + LoongArchExtIOICommonState parent_obj; + int dev_fd; +}; -typedef struct ExtIOICore { - uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT]; - DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS); - qemu_irq parent_irq[LS3A_INTC_IP]; -} ExtIOICore; +struct LoongArchExtIOIClass { + LoongArchExtIOICommonClass parent_class; -#define TYPE_LOONGARCH_EXTIOI "loongarch.extioi" -OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI) -struct LoongArchExtIOI { - SysBusDevice parent_obj; - uint32_t num_cpu; - uint32_t features; - uint32_t status; - /* hardware state */ - uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2]; - uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT]; - uint32_t isr[EXTIOI_IRQS / 32]; - uint32_t enable[EXTIOI_IRQS / 32]; - uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4]; - uint32_t coremap[EXTIOI_IRQS / 4]; - uint32_t sw_pending[EXTIOI_IRQS / 32]; - uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; - uint8_t sw_coremap[EXTIOI_IRQS]; - qemu_irq irq[EXTIOI_IRQS]; - ExtIOICore *cpu; - MemoryRegion extioi_system_mem; - MemoryRegion virt_extend; + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; + ResettablePhases parent_phases; }; + +void kvm_extioi_realize(DeviceState *dev, Error **errp); +int kvm_extioi_get(void *opaque); +int kvm_extioi_put(void *opaque, int version_id); + #endif /* LOONGARCH_EXTIOI_H */ diff --git a/include/hw/intc/loongarch_extioi_common.h b/include/hw/intc/loongarch_extioi_common.h new file mode 100644 index 0000000..dca25ff --- /dev/null +++ b/include/hw/intc/loongarch_extioi_common.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch 3A5000 ext interrupt controller definitions + * Copyright (C) 2024 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_EXTIOI_COMMON_H +#define LOONGARCH_EXTIOI_COMMON_H + +#include "qom/object.h" +#include "hw/sysbus.h" +#include "hw/loongarch/virt.h" + +#define LS3A_INTC_IP 8 +#define EXTIOI_IRQS (256) +#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8) +/* irq from EXTIOI is routed to no more than 4 cpus */ +#define EXTIOI_CPUS (4) +/* map to ipnum per 32 irqs */ +#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32) +#define EXTIOI_IRQS_COREMAP_SIZE 256 +#define EXTIOI_IRQS_NODETYPE_COUNT 16 +#define EXTIOI_IRQS_GROUP_COUNT 8 + +#define APIC_OFFSET 0x400 +#define APIC_BASE (0x1000ULL + APIC_OFFSET) +#define EXTIOI_NODETYPE_START (0x4a0 - APIC_OFFSET) +#define EXTIOI_NODETYPE_END (0x4c0 - APIC_OFFSET) +#define EXTIOI_IPMAP_START (0x4c0 - APIC_OFFSET) +#define EXTIOI_IPMAP_END (0x4c8 - APIC_OFFSET) +#define EXTIOI_ENABLE_START (0x600 - APIC_OFFSET) +#define EXTIOI_ENABLE_END (0x620 - APIC_OFFSET) +#define EXTIOI_BOUNCE_START (0x680 - APIC_OFFSET) +#define EXTIOI_BOUNCE_END (0x6a0 - APIC_OFFSET) +#define EXTIOI_ISR_START (0x700 - APIC_OFFSET) +#define EXTIOI_ISR_END (0x720 - APIC_OFFSET) +#define EXTIOI_COREISR_START (0x800 - APIC_OFFSET) +#define EXTIOI_COREISR_END (0x820 - APIC_OFFSET) +#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET) +#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET) +#define EXTIOI_SIZE 0x800 + +#define EXTIOI_VIRT_BASE (0x40000000) +#define EXTIOI_VIRT_SIZE (0x1000) +#define EXTIOI_VIRT_FEATURES (0x0) +#define EXTIOI_HAS_VIRT_EXTENSION (0) +#define EXTIOI_HAS_ENABLE_OPTION (1) +#define EXTIOI_HAS_INT_ENCODE (2) +#define EXTIOI_HAS_CPU_ENCODE (3) +#define EXTIOI_VIRT_HAS_FEATURES (BIT(EXTIOI_HAS_VIRT_EXTENSION) \ + | BIT(EXTIOI_HAS_ENABLE_OPTION) \ + | BIT(EXTIOI_HAS_CPU_ENCODE)) +#define EXTIOI_VIRT_CONFIG (0x4) +#define EXTIOI_ENABLE (1) +#define EXTIOI_ENABLE_INT_ENCODE (2) +#define EXTIOI_ENABLE_CPU_ENCODE (3) +#define EXTIOI_VIRT_COREMAP_START (0x40) +#define EXTIOI_VIRT_COREMAP_END (0x240) + +#define TYPE_LOONGARCH_EXTIOI_COMMON "loongarch_extioi_common" +OBJECT_DECLARE_TYPE(LoongArchExtIOICommonState, + LoongArchExtIOICommonClass, LOONGARCH_EXTIOI_COMMON) + +typedef struct ExtIOICore { + uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT]; + DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS); + qemu_irq parent_irq[LS3A_INTC_IP]; + uint64_t arch_id; + CPUState *cpu; +} ExtIOICore; + +struct LoongArchExtIOICommonState { + SysBusDevice parent_obj; + uint32_t num_cpu; + uint32_t features; + uint32_t status; + /* hardware state */ + uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2]; + uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT]; + uint32_t isr[EXTIOI_IRQS / 32]; + uint32_t enable[EXTIOI_IRQS / 32]; + uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4]; + uint32_t coremap[EXTIOI_IRQS / 4]; + uint32_t sw_pending[EXTIOI_IRQS / 32]; + uint8_t sw_ipmap[EXTIOI_IRQS_IPMAP_SIZE]; + uint8_t sw_coremap[EXTIOI_IRQS]; + qemu_irq irq[EXTIOI_IRQS]; + ExtIOICore *cpu; + MemoryRegion extioi_system_mem; + MemoryRegion virt_extend; +}; + +struct LoongArchExtIOICommonClass { + SysBusDeviceClass parent_class; + + DeviceRealize parent_realize; + ResettablePhases parent_phases; + int (*pre_save)(void *s); + int (*post_load)(void *s, int version_id); +}; +#endif /* LOONGARCH_EXTIOI_H */ diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h new file mode 100644 index 0000000..5175a6b --- /dev/null +++ b/include/hw/intc/loongarch_ipi.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch IPI interrupt header files + * + * Copyright (C) 2024 Loongson Technology Corporation Limited + */ + +#ifndef HW_LOONGARCH_IPI_H +#define HW_LOONGARCH_IPI_H + +#include "qom/object.h" +#include "hw/intc/loongson_ipi_common.h" + +#define TYPE_LOONGARCH_IPI "loongarch_ipi" +OBJECT_DECLARE_TYPE(LoongarchIPIState, LoongarchIPIClass, LOONGARCH_IPI) + +struct LoongarchIPIState { + LoongsonIPICommonState parent_obj; + int dev_fd; +}; + +struct LoongarchIPIClass { + LoongsonIPICommonClass parent_class; + DeviceRealize parent_realize; + ResettablePhases parent_phases; +}; + +void kvm_ipi_realize(DeviceState *dev, Error **errp); +int kvm_ipi_get(void *opaque); +int kvm_ipi_put(void *opaque, int version_id); + +#endif diff --git a/include/hw/intc/loongarch_pch_pic.h b/include/hw/intc/loongarch_pch_pic.h index d5437e8..a46b6f8 100644 --- a/include/hw/intc/loongarch_pch_pic.h +++ b/include/hw/intc/loongarch_pch_pic.h @@ -5,65 +5,29 @@ * Copyright (c) 2021 Loongson Technology Corporation Limited */ -#include "hw/sysbus.h" +#ifndef HW_LOONGARCH_PCH_PIC_H +#define HW_LOONGARCH_PCH_PIC_H -#define TYPE_LOONGARCH_PCH_PIC "loongarch_pch_pic" -#define PCH_PIC_NAME(name) TYPE_LOONGARCH_PCH_PIC#name -OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHPIC, LOONGARCH_PCH_PIC) +#include "hw/intc/loongarch_pic_common.h" -#define PCH_PIC_INT_ID_VAL 0x7000000UL -#define PCH_PIC_INT_ID_VER 0x1UL +#define TYPE_LOONGARCH_PIC "loongarch_pic" +#define PCH_PIC_NAME(name) TYPE_LOONGARCH_PIC#name +OBJECT_DECLARE_TYPE(LoongarchPICState, LoongarchPICClass, LOONGARCH_PIC) -#define PCH_PIC_INT_ID_LO 0x00 -#define PCH_PIC_INT_ID_HI 0x04 -#define PCH_PIC_INT_MASK_LO 0x20 -#define PCH_PIC_INT_MASK_HI 0x24 -#define PCH_PIC_HTMSI_EN_LO 0x40 -#define PCH_PIC_HTMSI_EN_HI 0x44 -#define PCH_PIC_INT_EDGE_LO 0x60 -#define PCH_PIC_INT_EDGE_HI 0x64 -#define PCH_PIC_INT_CLEAR_LO 0x80 -#define PCH_PIC_INT_CLEAR_HI 0x84 -#define PCH_PIC_AUTO_CTRL0_LO 0xc0 -#define PCH_PIC_AUTO_CTRL0_HI 0xc4 -#define PCH_PIC_AUTO_CTRL1_LO 0xe0 -#define PCH_PIC_AUTO_CTRL1_HI 0xe4 -#define PCH_PIC_ROUTE_ENTRY_OFFSET 0x100 -#define PCH_PIC_ROUTE_ENTRY_END 0x13f -#define PCH_PIC_HTMSI_VEC_OFFSET 0x200 -#define PCH_PIC_HTMSI_VEC_END 0x23f -#define PCH_PIC_INT_STATUS_LO 0x3a0 -#define PCH_PIC_INT_STATUS_HI 0x3a4 -#define PCH_PIC_INT_POL_LO 0x3e0 -#define PCH_PIC_INT_POL_HI 0x3e4 - -#define STATUS_LO_START 0 -#define STATUS_HI_START 0x4 -#define POL_LO_START 0x40 -#define POL_HI_START 0x44 -struct LoongArchPCHPIC { - SysBusDevice parent_obj; - qemu_irq parent_irq[64]; - uint64_t int_mask; /*0x020 interrupt mask register*/ - uint64_t htmsi_en; /*0x040 1=msi*/ - uint64_t intedge; /*0x060 edge=1 level =0*/ - uint64_t intclr; /*0x080 for clean edge int,set 1 clean,set 0 is noused*/ - uint64_t auto_crtl0; /*0x0c0*/ - uint64_t auto_crtl1; /*0x0e0*/ - uint64_t last_intirr; /* edge detection */ - uint64_t intirr; /* 0x380 interrupt request register */ - uint64_t intisr; /* 0x3a0 interrupt service register */ - /* - * 0x3e0 interrupt level polarity selection - * register 0 for high level trigger - */ - uint64_t int_polarity; +struct LoongarchPICState { + LoongArchPICCommonState parent_obj; + int dev_fd; +}; - uint8_t route_entry[64]; /*0x100 - 0x138*/ - uint8_t htmsi_vector[64]; /*0x200 - 0x238*/ +struct LoongarchPICClass { + LoongArchPICCommonClass parent_class; - MemoryRegion iomem32_low; - MemoryRegion iomem32_high; - MemoryRegion iomem8; - unsigned int irq_num; + DeviceRealize parent_realize; + ResettablePhases parent_phases; }; + +void kvm_pic_realize(DeviceState *dev, Error **errp); +int kvm_pic_get(void *opaque); +int kvm_pic_put(void *opaque, int version_id); + +#endif /* HW_LOONGARCH_PCH_PIC_H */ diff --git a/include/hw/intc/loongarch_pic_common.h b/include/hw/intc/loongarch_pic_common.h new file mode 100644 index 0000000..f774c97 --- /dev/null +++ b/include/hw/intc/loongarch_pic_common.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch 7A1000 I/O interrupt controller definitions + * Copyright (c) 2024 Loongson Technology Corporation Limited + */ + +#ifndef HW_LOONGARCH_PIC_COMMON_H +#define HW_LOONGARCH_PIC_COMMON_H + +#include "hw/pci-host/ls7a.h" +#include "hw/sysbus.h" + +#define PCH_PIC_INT_ID 0x00 +#define PCH_PIC_INT_ID_VAL 0x7 +#define PCH_PIC_INT_ID_VER 0x1 +#define PCH_PIC_INT_MASK 0x20 +#define PCH_PIC_HTMSI_EN 0x40 +#define PCH_PIC_INT_EDGE 0x60 +#define PCH_PIC_INT_CLEAR 0x80 +#define PCH_PIC_AUTO_CTRL0 0xc0 +#define PCH_PIC_AUTO_CTRL1 0xe0 +#define PCH_PIC_ROUTE_ENTRY 0x100 +#define PCH_PIC_ROUTE_ENTRY_END 0x13f +#define PCH_PIC_HTMSI_VEC 0x200 +#define PCH_PIC_HTMSI_VEC_END 0x23f +#define PCH_PIC_INT_REQUEST 0x380 +#define PCH_PIC_INT_STATUS 0x3a0 +#define PCH_PIC_INT_POL 0x3e0 + +#define TYPE_LOONGARCH_PIC_COMMON "loongarch_pic_common" +OBJECT_DECLARE_TYPE(LoongArchPICCommonState, + LoongArchPICCommonClass, LOONGARCH_PIC_COMMON) + +union LoongArchPIC_ID { + struct { + uint8_t _reserved_0[3]; + uint8_t id; + uint8_t version; + uint8_t _reserved_1; + uint8_t irq_num; + uint8_t _reserved_2; + } QEMU_PACKED desc; + uint64_t data; +}; + +struct LoongArchPICCommonState { + SysBusDevice parent_obj; + + qemu_irq parent_irq[64]; + union LoongArchPIC_ID id; /* 0x00 interrupt ID register */ + uint64_t int_mask; /* 0x020 interrupt mask register */ + uint64_t htmsi_en; /* 0x040 1=msi */ + uint64_t intedge; /* 0x060 edge=1 level=0 */ + uint64_t intclr; /* 0x080 clean edge int, set 1 clean, 0 noused */ + uint64_t auto_crtl0; /* 0x0c0 */ + uint64_t auto_crtl1; /* 0x0e0 */ + uint64_t last_intirr; /* edge detection */ + uint64_t intirr; /* 0x380 interrupt request register */ + uint64_t intisr; /* 0x3a0 interrupt service register */ + /* + * 0x3e0 interrupt level polarity selection + * register 0 for high level trigger + */ + uint64_t int_polarity; + + uint8_t route_entry[64]; /* 0x100 - 0x138 */ + uint8_t htmsi_vector[64]; /* 0x200 - 0x238 */ + + MemoryRegion iomem; + unsigned int irq_num; +}; + +struct LoongArchPICCommonClass { + SysBusDeviceClass parent_class; + + DeviceRealize parent_realize; + ResettablePhases parent_phases; + int (*pre_save)(LoongArchPICCommonState *s); + int (*post_load)(LoongArchPICCommonState *s, int version_id); +}; +#endif /* HW_LOONGARCH_PIC_COMMON_H */ diff --git a/include/hw/intc/loongson_ipi.h b/include/hw/intc/loongson_ipi.h index 3f795ed..4e517cc 100644 --- a/include/hw/intc/loongson_ipi.h +++ b/include/hw/intc/loongson_ipi.h @@ -8,49 +8,24 @@ #ifndef HW_LOONGSON_IPI_H #define HW_LOONGSON_IPI_H +#include "qom/object.h" +#include "hw/intc/loongson_ipi_common.h" #include "hw/sysbus.h" -/* Mainy used by iocsr read and write */ -#define SMP_IPI_MAILBOX 0x1000ULL -#define CORE_STATUS_OFF 0x0 -#define CORE_EN_OFF 0x4 -#define CORE_SET_OFF 0x8 -#define CORE_CLEAR_OFF 0xc -#define CORE_BUF_20 0x20 -#define CORE_BUF_28 0x28 -#define CORE_BUF_30 0x30 -#define CORE_BUF_38 0x38 -#define IOCSR_IPI_SEND 0x40 -#define IOCSR_MAIL_SEND 0x48 -#define IOCSR_ANY_SEND 0x158 - -#define MAIL_SEND_ADDR (SMP_IPI_MAILBOX + IOCSR_MAIL_SEND) -#define MAIL_SEND_OFFSET 0 -#define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND) - -#define IPI_MBX_NUM 4 - #define TYPE_LOONGSON_IPI "loongson_ipi" -OBJECT_DECLARE_SIMPLE_TYPE(LoongsonIPI, LOONGSON_IPI) +OBJECT_DECLARE_TYPE(LoongsonIPIState, LoongsonIPIClass, LOONGSON_IPI) + +struct LoongsonIPIClass { + LoongsonIPICommonClass parent_class; + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +}; + +struct LoongsonIPIState { + LoongsonIPICommonState parent_obj; -typedef struct IPICore { - LoongsonIPI *ipi; MemoryRegion *ipi_mmio_mem; - uint32_t status; - uint32_t en; - uint32_t set; - uint32_t clear; - /* 64bit buf divide into 2 32bit buf */ - uint32_t buf[IPI_MBX_NUM * 2]; - qemu_irq irq; -} IPICore; - -struct LoongsonIPI { - SysBusDevice parent_obj; - MemoryRegion ipi_iocsr_mem; - MemoryRegion ipi64_iocsr_mem; - uint32_t num_cpu; - IPICore *cpu; }; #endif diff --git a/include/hw/intc/loongson_ipi_common.h b/include/hw/intc/loongson_ipi_common.h new file mode 100644 index 0000000..e58ce2a --- /dev/null +++ b/include/hw/intc/loongson_ipi_common.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Loongson ipi interrupt header files + * + * Copyright (C) 2021 Loongson Technology Corporation Limited + */ + +#ifndef HW_LOONGSON_IPI_COMMON_H +#define HW_LOONGSON_IPI_COMMON_H + +#include "qom/object.h" +#include "hw/sysbus.h" +#include "exec/memattrs.h" + +#define IPI_MBX_NUM 4 + +#define TYPE_LOONGSON_IPI_COMMON "loongson_ipi_common" +OBJECT_DECLARE_TYPE(LoongsonIPICommonState, + LoongsonIPICommonClass, LOONGSON_IPI_COMMON) + +typedef struct IPICore { + LoongsonIPICommonState *ipi; + uint32_t status; + uint32_t en; + uint32_t set; + uint32_t clear; + /* 64bit buf divide into 2 32-bit buf */ + uint32_t buf[IPI_MBX_NUM * 2]; + qemu_irq irq; + uint64_t arch_id; + CPUState *cpu; +} IPICore; + +struct LoongsonIPICommonState { + SysBusDevice parent_obj; + + MemoryRegion ipi_iocsr_mem; + MemoryRegion ipi64_iocsr_mem; + uint32_t num_cpu; + IPICore *cpu; +}; + +struct LoongsonIPICommonClass { + SysBusDeviceClass parent_class; + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; + AddressSpace *(*get_iocsr_as)(CPUState *cpu); + int (*cpu_by_arch_id)(LoongsonIPICommonState *lics, int64_t id, + int *index, CPUState **pcs); + int (*pre_save)(void *opaque); + int (*post_load)(void *opaque, int version_id); +}; + +MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr, uint64_t *data, + unsigned size, MemTxAttrs attrs); +MemTxResult loongson_ipi_core_writel(void *opaque, hwaddr addr, uint64_t val, + unsigned size, MemTxAttrs attrs); + +/* Mainy used by iocsr read and write */ +#define SMP_IPI_MAILBOX 0x1000ULL + +#define CORE_STATUS_OFF 0x0 +#define CORE_EN_OFF 0x4 +#define CORE_SET_OFF 0x8 +#define CORE_CLEAR_OFF 0xc +#define CORE_BUF_20 0x20 +#define CORE_BUF_28 0x28 +#define CORE_BUF_30 0x30 +#define CORE_BUF_38 0x38 +#define IOCSR_IPI_SEND 0x40 +#define IOCSR_MAIL_SEND 0x48 +#define IOCSR_ANY_SEND 0x158 + +#define MAIL_SEND_ADDR (SMP_IPI_MAILBOX + IOCSR_MAIL_SEND) +#define MAIL_SEND_OFFSET 0 +#define ANY_SEND_OFFSET (IOCSR_ANY_SEND - IOCSR_MAIL_SEND) + +#endif diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h index de8532f..489b913 100644 --- a/include/hw/intc/riscv_aplic.h +++ b/include/hw/intc/riscv_aplic.h @@ -68,9 +68,17 @@ struct RISCVAPLICState { uint32_t num_irqs; bool msimode; bool mmode; + + /* To support KVM aia=aplic-imsic with irqchip split mode */ + bool kvm_splitmode; + uint32_t kvm_msicfgaddr; + uint32_t kvm_msicfgaddrH; }; void riscv_aplic_add_child(DeviceState *parent, DeviceState *child); +bool riscv_is_kvm_aia_aplic_imsic(bool msimode); +bool riscv_use_emulated_aplic(bool msimode); +void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr); DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size, uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources, diff --git a/include/hw/ipack/ipack.h b/include/hw/ipack/ipack.h index cbcdda5..00f397f 100644 --- a/include/hw/ipack/ipack.h +++ b/include/hw/ipack/ipack.h @@ -12,6 +12,7 @@ #define QEMU_IPACK_H #include "hw/qdev-core.h" +#include "hw/irq.h" #include "qom/object.h" @@ -19,10 +20,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(IPackBus, IPACK_BUS) struct IPackBus { - /*< private >*/ BusState parent_obj; - /* All fields are private */ uint8_t n_slots; uint8_t free_slot; qemu_irq_handler set_irq; @@ -58,13 +57,11 @@ struct IPackDeviceClass { }; struct IPackDevice { - /*< private >*/ DeviceState parent_obj; - /*< public >*/ int32_t slot; /* IRQ objects for the IndustryPack INT0# and INT1# */ - qemu_irq *irq; + IRQState irq[2]; }; extern const VMStateDescription vmstate_ipack_device; diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h index 77a7213..cd581aa 100644 --- a/include/hw/ipmi/ipmi.h +++ b/include/hw/ipmi/ipmi.h @@ -25,7 +25,7 @@ #ifndef HW_IPMI_H #define HW_IPMI_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "qom/object.h" @@ -41,6 +41,15 @@ enum ipmi_op { IPMI_SEND_NMI }; +/* Channel properties */ +#define IPMI_CHANNEL_IPMB 0x00 +#define IPMI_CHANNEL_SYSTEM 0x0f +#define IPMI_CHANNEL_MEDIUM_IPMB 0x01 +#define IPMI_CHANNEL_MEDIUM_SYSTEM 0x0c +#define IPMI_CHANNEL_PROTOCOL_IPMB 0x01 +#define IPMI_CHANNEL_PROTOCOL_KCS 0x05 +#define IPMI_CHANNEL_PROTOCOL_BT_15 0x08 + #define IPMI_CC_INVALID_CMD 0xc1 #define IPMI_CC_COMMAND_INVALID_FOR_LUN 0xc2 #define IPMI_CC_TIMEOUT 0xc3 @@ -76,6 +85,7 @@ typedef struct IPMIFwInfo { int interface_type; uint8_t ipmi_spec_major_revision; uint8_t ipmi_spec_minor_revision; + uint8_t ipmi_channel_protocol; uint8_t i2c_slave_address; uint32_t uuid; @@ -91,6 +101,11 @@ typedef struct IPMIFwInfo { int interrupt_number; enum { + IPMI_NO_IRQ = 0, + IPMI_ISA_IRQ, + IPMI_PCI_IRQ, + } irq_source; + enum { IPMI_LEVEL_IRQ, IPMI_EDGE_IRQ } irq_type; diff --git a/include/hw/irq.h b/include/hw/irq.h index 645b73d..b301223 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -1,9 +1,20 @@ #ifndef QEMU_IRQ_H #define QEMU_IRQ_H +#include "qom/object.h" + /* Generic IRQ/GPIO pin infrastructure. */ #define TYPE_IRQ "irq" +OBJECT_DECLARE_SIMPLE_TYPE(IRQState, IRQ) + +struct IRQState { + Object parent_obj; + + qemu_irq_handler handler; + void *opaque; + int n; +}; void qemu_set_irq(qemu_irq irq, int level); @@ -23,6 +34,24 @@ static inline void qemu_irq_pulse(qemu_irq irq) qemu_set_irq(irq, 0); } +/* + * Init a single IRQ. The irq is assigned with a handler, an opaque data + * and the interrupt number. + */ +void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque, + int n); + +/** + * qemu_init_irqs: Initialize an array of IRQs. + * + * @irq: Array of IRQs to initialize + * @count: number of IRQs to initialize + * @handler: handler to assign to each IRQ + * @opaque: opaque data to pass to @handler + */ +void qemu_init_irqs(IRQState irq[], size_t count, + qemu_irq_handler handler, void *opaque); + /* Returns an array of N IRQs. Each IRQ is assigned the argument handler and * opaque data. */ diff --git a/include/hw/isa/apm.h b/include/hw/isa/apm.h index b6e070c..0834539 100644 --- a/include/hw/isa/apm.h +++ b/include/hw/isa/apm.h @@ -1,7 +1,7 @@ #ifndef APM_H #define APM_H -#include "exec/memory.h" +#include "system/memory.h" #define APM_CNT_IOPORT 0xb2 #define ACPI_PORT_SMI_CMD APM_CNT_IOPORT diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index 40d6224..a82c5f1 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -3,8 +3,8 @@ /* ISA bus */ -#include "exec/memory.h" -#include "exec/ioport.h" +#include "system/memory.h" +#include "system/ioport.h" #include "hw/qdev-core.h" #include "qom/object.h" diff --git a/include/hw/isa/superio.h b/include/hw/isa/superio.h index 0dc4510..14d0513 100644 --- a/include/hw/isa/superio.h +++ b/include/hw/isa/superio.h @@ -10,7 +10,7 @@ #ifndef HW_ISA_SUPERIO_H #define HW_ISA_SUPERIO_H -#include "sysemu/sysemu.h" +#include "system/system.h" #include "hw/isa/isa.h" #include "qom/object.h" diff --git a/include/hw/loader-fit.h b/include/hw/loader-fit.h index 0832e37..9a43490 100644 --- a/include/hw/loader-fit.h +++ b/include/hw/loader-fit.h @@ -30,12 +30,27 @@ struct fit_loader_match { struct fit_loader { const struct fit_loader_match *matches; hwaddr (*addr_to_phys)(void *opaque, uint64_t addr); - const void *(*fdt_filter)(void *opaque, const void *fdt, - const void *match_data, hwaddr *load_addr); + void *(*fdt_filter)(void *opaque, const void *fdt, + const void *match_data, hwaddr *load_addr); const void *(*kernel_filter)(void *opaque, const void *kernel, hwaddr *load_addr, hwaddr *entry_addr); }; -int load_fit(const struct fit_loader *ldr, const char *filename, void *opaque); +/** + * load_fit: load a FIT format image + * @ldr: structure defining board specific properties and hooks + * @filename: image to load + * @pfdt: pointer to update with address of FDT blob + * @opaque: opaque value passed back to the hook functions in @ldr + * Returns: 0 on success, or a negative errno on failure + * + * @pfdt is used to tell the caller about the FDT blob. On return, it + * has been set to point to the FDT blob, and it is now the caller's + * responsibility to free that memory with g_free(). Usually the caller + * will want to pass in &machine->fdt here, to record the FDT blob for + * the dumpdtb option and QMP/HMP commands. + */ +int load_fit(const struct fit_loader *ldr, const char *filename, void **pfdt, + void *opaque); #endif /* HW_LOADER_FIT_H */ diff --git a/include/hw/loader.h b/include/hw/loader.h index 7f6d06b..c96b5e1 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -101,7 +101,7 @@ ssize_t load_image_gzipped_buffer(const char *filename, uint64_t max_sz, * Returns the size of the decompressed payload if decompression was performed * successfully. */ -ssize_t unpack_efi_zboot_image(uint8_t **buffer, int *size); +ssize_t unpack_efi_zboot_image(uint8_t **buffer, ssize_t *size); #define ELF_LOAD_FAILED -1 #define ELF_LOAD_NOT_ELF -2 @@ -120,7 +120,7 @@ const char *load_elf_strerror(ssize_t error); * @lowaddr: Populated with lowest loaded address. Ignored if NULL. * @highaddr: Populated with highest loaded address. Ignored if NULL. * @pflags: Populated with ELF processor-specific flags. Ignore if NULL. - * @bigendian: Expected ELF endianness. 0 for LE otherwise BE + * @elf_data_order: Expected ELF endianness (ELFDATA2LSB or ELFDATA2MSB). * @elf_machine: Expected ELF machine type * @clear_lsb: Set to mask off LSB of addresses (Some architectures use * this for non-address data) @@ -151,30 +151,18 @@ ssize_t load_elf_ram_sym(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, - uint32_t *pflags, int big_endian, int elf_machine, + uint32_t *pflags, int elf_data_order, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as, bool load_rom, symbol_fn_t sym_cb); -/** load_elf_ram: - * Same as load_elf_ram_sym(), but doesn't allow the caller to specify a - * symbol callback function - */ -ssize_t load_elf_ram(const char *filename, - uint64_t (*elf_note_fn)(void *, void *, bool), - uint64_t (*translate_fn)(void *, uint64_t), - void *translate_opaque, uint64_t *pentry, - uint64_t *lowaddr, uint64_t *highaddr, uint32_t *pflags, - int big_endian, int elf_machine, int clear_lsb, - int data_swab, AddressSpace *as, bool load_rom); - /** load_elf_as: - * Same as load_elf_ram(), but always loads the elf as ROM + * Same as load_elf_ram_sym(), but always loads the elf as ROM */ ssize_t load_elf_as(const char *filename, uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, - uint64_t *highaddr, uint32_t *pflags, int big_endian, + uint64_t *highaddr, uint32_t *pflags, int elf_data_order, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as); @@ -186,7 +174,7 @@ ssize_t load_elf(const char *filename, uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, - uint64_t *highaddr, uint32_t *pflags, int big_endian, + uint64_t *highaddr, uint32_t *pflags, int elf_data_order, int elf_machine, int clear_lsb, int data_swab); /** load_elf_hdr: @@ -202,7 +190,7 @@ ssize_t load_elf(const char *filename, void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp); ssize_t load_aout(const char *filename, hwaddr addr, int max_sz, - int bswap_needed, hwaddr target_page_size); + bool big_endian, hwaddr target_page_size); #define LOAD_UIMAGE_LOADADDR_INVALID (-1) @@ -282,8 +270,6 @@ int rom_add_elf_program(const char *name, GMappedFile *mapped_file, void *data, AddressSpace *as); int rom_check_and_register_reset(void); void rom_set_fw(FWCfgState *f); -void rom_set_order_override(int order); -void rom_reset_order_override(void); /** * rom_transaction_begin: diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h index b3b870d..9819f7f 100644 --- a/include/hw/loongarch/boot.h +++ b/include/hw/loongarch/boot.h @@ -102,11 +102,10 @@ struct loongarch_boot_info { const char *kernel_cmdline; const char *initrd_filename; uint64_t a0, a1, a2; + uint64_t initrd_addr; + uint64_t initrd_size; }; -extern struct memmap_entry *memmap_table; -extern unsigned memmap_entries; - struct memmap_entry { uint64_t address; uint64_t length; diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h index 603c1ce..602feab 100644 --- a/include/hw/loongarch/virt.h +++ b/include/hw/loongarch/virt.h @@ -8,10 +8,8 @@ #ifndef HW_LOONGARCH_H #define HW_LOONGARCH_H -#include "target/loongarch/cpu.h" #include "hw/boards.h" #include "qemu/queue.h" -#include "hw/intc/loongson_ipi.h" #include "hw/block/flash.h" #include "hw/loongarch/boot.h" @@ -32,6 +30,7 @@ #define VIRT_GED_EVT_ADDR 0x100e0000 #define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN) #define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN) +#define VIRT_GED_CPUHP_ADDR (VIRT_GED_REG_ADDR + ACPI_GED_REG_COUNT) #define COMMAND_LINE_SIZE 512 @@ -62,9 +61,23 @@ struct LoongArchVirtMachineState { MemoryRegion iocsr_mem; AddressSpace as_iocsr; struct loongarch_boot_info bootinfo; + DeviceState *ipi; + DeviceState *extioi; + struct memmap_entry *memmap_table; + unsigned int memmap_entries; }; #define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt") OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE) -void loongarch_acpi_setup(LoongArchVirtMachineState *lvms); +void virt_acpi_setup(LoongArchVirtMachineState *lvms); +void virt_fdt_setup(LoongArchVirtMachineState *lvms); + +static inline bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms) +{ + if (lvms->veiointc == ON_OFF_AUTO_OFF) { + return false; + } + return true; +} + #endif diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h index 34365c9..9caaed9 100644 --- a/include/hw/m68k/q800.h +++ b/include/hw/m68k/q800.h @@ -26,7 +26,7 @@ #include "hw/boards.h" #include "qom/object.h" #include "target/m68k/cpu-qom.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/m68k/q800-glue.h" #include "hw/misc/mac_via.h" #include "hw/net/dp8393x.h" diff --git a/include/hw/mem/npcm7xx_mc.h b/include/hw/mem/npcm7xx_mc.h index 7ed38be..568cc35 100644 --- a/include/hw/mem/npcm7xx_mc.h +++ b/include/hw/mem/npcm7xx_mc.h @@ -16,7 +16,7 @@ #ifndef NPCM7XX_MC_H #define NPCM7XX_MC_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" /** diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index fe0f3ea..e0dbdd4 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -16,7 +16,7 @@ #ifndef QEMU_PC_DIMM_H #define QEMU_PC_DIMM_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "qom/object.h" diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h index 04d6362..05ef9f7 100644 --- a/include/hw/mips/cps.h +++ b/include/hw/mips/cps.h @@ -38,6 +38,7 @@ struct MIPSCPSState { uint32_t num_vp; uint32_t num_irq; char *cpu_type; + bool cpu_is_bigendian; MemoryRegion container; MIPSGCRState gcr; diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h index 101799f..1f3672b 100644 --- a/include/hw/mips/mips.h +++ b/include/hw/mips/mips.h @@ -7,7 +7,7 @@ /* Kernels can be configured with 64KB pages */ #define INITRD_PAGE_SIZE (64 * KiB) -#include "exec/memory.h" +#include "system/memory.h" /* bonito.c */ PCIBus *bonito_init(qemu_irq *pic); diff --git a/include/hw/misc/aspeed_hace.h b/include/hw/misc/aspeed_hace.h index ecb1b67..d5d07c6 100644 --- a/include/hw/misc/aspeed_hace.h +++ b/include/hw/misc/aspeed_hace.h @@ -1,6 +1,7 @@ /* * ASPEED Hash and Crypto Engine * + * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates * Copyright (C) 2021 IBM Corp. * * SPDX-License-Identifier: GPL-2.0-or-later @@ -10,16 +11,17 @@ #define ASPEED_HACE_H #include "hw/sysbus.h" +#include "crypto/hash.h" #define TYPE_ASPEED_HACE "aspeed.hace" #define TYPE_ASPEED_AST2400_HACE TYPE_ASPEED_HACE "-ast2400" #define TYPE_ASPEED_AST2500_HACE TYPE_ASPEED_HACE "-ast2500" #define TYPE_ASPEED_AST2600_HACE TYPE_ASPEED_HACE "-ast2600" #define TYPE_ASPEED_AST1030_HACE TYPE_ASPEED_HACE "-ast1030" +#define TYPE_ASPEED_AST2700_HACE TYPE_ASPEED_HACE "-ast2700" OBJECT_DECLARE_TYPE(AspeedHACEState, AspeedHACEClass, ASPEED_HACE) -#define ASPEED_HACE_NR_REGS (0x64 >> 2) #define ASPEED_HACE_MAX_SG 256 /* max number of entries */ struct AspeedHACEState { @@ -28,23 +30,30 @@ struct AspeedHACEState { MemoryRegion iomem; qemu_irq irq; - struct iovec iov_cache[ASPEED_HACE_MAX_SG]; - uint32_t regs[ASPEED_HACE_NR_REGS]; + uint32_t *regs; uint32_t total_req_len; - uint32_t iov_count; MemoryRegion *dram_mr; AddressSpace dram_as; + + QCryptoHash *hash_ctx; }; struct AspeedHACEClass { SysBusDeviceClass parent_class; + const MemoryRegionOps *reg_ops; uint32_t src_mask; uint32_t dest_mask; uint32_t key_mask; uint32_t hash_mask; + uint64_t nr_regs; + bool raise_crypt_interrupt_workaround; + uint32_t src_hi_mask; + uint32_t dest_hi_mask; + uint32_t key_hi_mask; + bool has_dma64; }; #endif /* ASPEED_HACE_H */ diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h index 356be95..684b48b 100644 --- a/include/hw/misc/aspeed_scu.h +++ b/include/hw/misc/aspeed_scu.h @@ -54,6 +54,8 @@ struct AspeedSCUState { #define AST2700_A0_SILICON_REV 0x06000103U #define AST2720_A0_SILICON_REV 0x06000203U #define AST2750_A0_SILICON_REV 0x06000003U +#define AST2700_A1_SILICON_REV 0x06010103U +#define AST2750_A1_SILICON_REV 0x06010003U #define ASPEED_IS_AST2500(si_rev) ((((si_rev) >> 24) & 0xff) == 0x04) diff --git a/include/hw/misc/auxbus.h b/include/hw/misc/auxbus.h index 03cacde..ccd18ce 100644 --- a/include/hw/misc/auxbus.h +++ b/include/hw/misc/auxbus.h @@ -25,7 +25,7 @@ #ifndef HW_MISC_AUXBUS_H #define HW_MISC_AUXBUS_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "qom/object.h" diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h deleted file mode 100644 index 5334984..0000000 --- a/include/hw/misc/cbus.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma / - * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms. - * Based on reverse-engineering of a linux driver. - * - * Copyright (C) 2008 Nokia Corporation - * Written by Andrzej Zaborowski - * - * This work is licensed under the terms of the GNU GPL, version 2 or later. - * See the COPYING file in the top-level directory. - */ - -#ifndef HW_MISC_CBUS_H -#define HW_MISC_CBUS_H - - -typedef struct { - qemu_irq clk; - qemu_irq dat; - qemu_irq sel; -} CBus; - -CBus *cbus_init(qemu_irq dat_out); -void cbus_attach(CBus *bus, void *slave_opaque); - -void *retu_init(qemu_irq irq, int vilma); -void *tahvo_init(qemu_irq irq, int betty); - -void retu_key_event(void *retu, int state); - -#endif diff --git a/include/hw/misc/imx8mp_analog.h b/include/hw/misc/imx8mp_analog.h new file mode 100644 index 0000000..955f032 --- /dev/null +++ b/include/hw/misc/imx8mp_analog.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025 Bernhard Beschow <shentey@gmail.com> + * + * i.MX8MP ANALOG IP block emulation code + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef IMX8MP_ANALOG_H +#define IMX8MP_ANALOG_H + +#include "qom/object.h" +#include "hw/sysbus.h" + +enum IMX8MPAnalogRegisters { + ANALOG_AUDIO_PLL1_GEN_CTRL = 0x000 / 4, + ANALOG_AUDIO_PLL1_FDIV_CTL0 = 0x004 / 4, + ANALOG_AUDIO_PLL1_FDIV_CTL1 = 0x008 / 4, + ANALOG_AUDIO_PLL1_SSCG_CTRL = 0x00c / 4, + ANALOG_AUDIO_PLL1_MNIT_CTRL = 0x010 / 4, + ANALOG_AUDIO_PLL2_GEN_CTRL = 0x014 / 4, + ANALOG_AUDIO_PLL2_FDIV_CTL0 = 0x018 / 4, + ANALOG_AUDIO_PLL2_FDIV_CTL1 = 0x01c / 4, + ANALOG_AUDIO_PLL2_SSCG_CTRL = 0x020 / 4, + ANALOG_AUDIO_PLL2_MNIT_CTRL = 0x024 / 4, + ANALOG_VIDEO_PLL1_GEN_CTRL = 0x028 / 4, + ANALOG_VIDEO_PLL1_FDIV_CTL0 = 0x02c / 4, + ANALOG_VIDEO_PLL1_FDIV_CTL1 = 0x030 / 4, + ANALOG_VIDEO_PLL1_SSCG_CTRL = 0x034 / 4, + ANALOG_VIDEO_PLL1_MNIT_CTRL = 0x038 / 4, + ANALOG_DRAM_PLL_GEN_CTRL = 0x050 / 4, + ANALOG_DRAM_PLL_FDIV_CTL0 = 0x054 / 4, + ANALOG_DRAM_PLL_FDIV_CTL1 = 0x058 / 4, + ANALOG_DRAM_PLL_SSCG_CTRL = 0x05c / 4, + ANALOG_DRAM_PLL_MNIT_CTRL = 0x060 / 4, + ANALOG_GPU_PLL_GEN_CTRL = 0x064 / 4, + ANALOG_GPU_PLL_FDIV_CTL0 = 0x068 / 4, + ANALOG_GPU_PLL_LOCKD_CTRL = 0x06c / 4, + ANALOG_GPU_PLL_MNIT_CTRL = 0x070 / 4, + ANALOG_VPU_PLL_GEN_CTRL = 0x074 / 4, + ANALOG_VPU_PLL_FDIV_CTL0 = 0x078 / 4, + ANALOG_VPU_PLL_LOCKD_CTRL = 0x07c / 4, + ANALOG_VPU_PLL_MNIT_CTRL = 0x080 / 4, + ANALOG_ARM_PLL_GEN_CTRL = 0x084 / 4, + ANALOG_ARM_PLL_FDIV_CTL0 = 0x088 / 4, + ANALOG_ARM_PLL_LOCKD_CTRL = 0x08c / 4, + ANALOG_ARM_PLL_MNIT_CTRL = 0x090 / 4, + ANALOG_SYS_PLL1_GEN_CTRL = 0x094 / 4, + ANALOG_SYS_PLL1_FDIV_CTL0 = 0x098 / 4, + ANALOG_SYS_PLL1_LOCKD_CTRL = 0x09c / 4, + ANALOG_SYS_PLL1_MNIT_CTRL = 0x100 / 4, + ANALOG_SYS_PLL2_GEN_CTRL = 0x104 / 4, + ANALOG_SYS_PLL2_FDIV_CTL0 = 0x108 / 4, + ANALOG_SYS_PLL2_LOCKD_CTRL = 0x10c / 4, + ANALOG_SYS_PLL2_MNIT_CTRL = 0x110 / 4, + ANALOG_SYS_PLL3_GEN_CTRL = 0x114 / 4, + ANALOG_SYS_PLL3_FDIV_CTL0 = 0x118 / 4, + ANALOG_SYS_PLL3_LOCKD_CTRL = 0x11c / 4, + ANALOG_SYS_PLL3_MNIT_CTRL = 0x120 / 4, + ANALOG_OSC_MISC_CFG = 0x124 / 4, + ANALOG_ANAMIX_PLL_MNIT_CTL = 0x128 / 4, + + ANALOG_DIGPROG = 0x800 / 4, + ANALOG_MAX, +}; + +#define TYPE_IMX8MP_ANALOG "imx8mp.analog" +OBJECT_DECLARE_SIMPLE_TYPE(IMX8MPAnalogState, IMX8MP_ANALOG) + +struct IMX8MPAnalogState { + SysBusDevice parent_obj; + + struct { + MemoryRegion container; + MemoryRegion analog; + } mmio; + + uint32_t analog[ANALOG_MAX]; +}; + +#endif /* IMX8MP_ANALOG_H */ diff --git a/include/hw/misc/imx8mp_ccm.h b/include/hw/misc/imx8mp_ccm.h new file mode 100644 index 0000000..685c858 --- /dev/null +++ b/include/hw/misc/imx8mp_ccm.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025 Bernhard Beschow <shentey@gmail.com> + * + * i.MX 8M Plus CCM IP block emulation code + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef IMX8MP_CCM_H +#define IMX8MP_CCM_H + +#include "hw/misc/imx_ccm.h" +#include "qom/object.h" + +enum IMX8MPCCMRegisters { + CCM_MAX = 0xc6fc / sizeof(uint32_t) + 1, +}; + +#define TYPE_IMX8MP_CCM "imx8mp.ccm" +OBJECT_DECLARE_SIMPLE_TYPE(IMX8MPCCMState, IMX8MP_CCM) + +struct IMX8MPCCMState { + IMXCCMState parent_obj; + + MemoryRegion iomem; + + uint32_t ccm[CCM_MAX]; +}; + +#endif /* IMX8MP_CCM_H */ diff --git a/include/hw/misc/ivshmem-flat.h b/include/hw/misc/ivshmem-flat.h new file mode 100644 index 0000000..3eca990 --- /dev/null +++ b/include/hw/misc/ivshmem-flat.h @@ -0,0 +1,86 @@ +/* + * Inter-VM Shared Memory Flat Device + * + * SPDX-License-Identifier: GPL-2.0-or-later + * Copyright (c) 2023 Linaro Ltd. + * Authors: + * Gustavo Romero + * + */ + +#ifndef IVSHMEM_FLAT_H +#define IVSHMEM_FLAT_H + +#include "qemu/queue.h" +#include "qemu/event_notifier.h" +#include "chardev/char-fe.h" +#include "system/memory.h" +#include "qom/object.h" +#include "hw/sysbus.h" + +#define IVSHMEM_MAX_VECTOR_NUM 64 + +/* + * QEMU interface: + * + QOM property "chardev" is the character device id of the ivshmem server + * socket + * + QOM property "shmem-size" sets the size of the RAM region shared between + * the device and the ivshmem server + * + sysbus MMIO region 0: device I/O mapped registers + * + sysbus MMIO region 1: shared memory with ivshmem server + * + sysbus IRQ 0: single output interrupt + */ + +#define TYPE_IVSHMEM_FLAT "ivshmem-flat" +typedef struct IvshmemFTState IvshmemFTState; + +DECLARE_INSTANCE_CHECKER(IvshmemFTState, IVSHMEM_FLAT, TYPE_IVSHMEM_FLAT) + +/* Ivshmem registers. See docs/specs/ivshmem-spec.rst for details. */ +enum ivshmem_registers { + INTMASK = 0, + INTSTATUS = 4, + IVPOSITION = 8, + DOORBELL = 12, +}; + +typedef struct VectorInfo { + EventNotifier event_notifier; + uint16_t id; +} VectorInfo; + +typedef struct IvshmemPeer { + QTAILQ_ENTRY(IvshmemPeer) next; + VectorInfo vector[IVSHMEM_MAX_VECTOR_NUM]; + int vector_counter; + uint16_t id; +} IvshmemPeer; + +struct IvshmemFTState { + SysBusDevice parent_obj; + + uint64_t msg_buf; + int msg_buffered_bytes; + + QTAILQ_HEAD(, IvshmemPeer) peer; + IvshmemPeer own; + + CharBackend server_chr; + + /* IRQ */ + qemu_irq irq; + + /* I/O registers */ + MemoryRegion iomem; + uint32_t intmask; + uint32_t intstatus; + uint32_t ivposition; + uint32_t doorbell; + + /* Shared memory */ + MemoryRegion shmem; + int shmem_fd; + uint32_t shmem_size; +}; + +#endif /* IVSHMEM_FLAT_H */ diff --git a/include/hw/misc/lasi.h b/include/hw/misc/lasi.h index f01c0f6..0bdfb11 100644 --- a/include/hw/misc/lasi.h +++ b/include/hw/misc/lasi.h @@ -12,7 +12,7 @@ #ifndef LASI_H #define LASI_H -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/pci/pci_host.h" #include "hw/boards.h" diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h index 63cdcf7..6a15228 100644 --- a/include/hw/misc/mac_via.h +++ b/include/hw/misc/mac_via.h @@ -9,7 +9,7 @@ #ifndef HW_MISC_MAC_VIA_H #define HW_MISC_MAC_VIA_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" #include "hw/misc/mos6522.h" #include "hw/input/adb.h" diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h index fba4566..920871a 100644 --- a/include/hw/misc/mos6522.h +++ b/include/hw/misc/mos6522.h @@ -154,7 +154,7 @@ struct MOS6522State { OBJECT_DECLARE_TYPE(MOS6522State, MOS6522DeviceClass, MOS6522) struct MOS6522DeviceClass { - DeviceClass parent_class; + SysBusDeviceClass parent_class; ResettablePhases parent_phases; void (*portB_write)(MOS6522State *dev); diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h index d638438..e4b997a 100644 --- a/include/hw/misc/npcm7xx_mft.h +++ b/include/hw/misc/npcm7xx_mft.h @@ -16,7 +16,7 @@ #ifndef NPCM7XX_MFT_H #define NPCM7XX_MFT_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/clock.h" #include "hw/irq.h" #include "hw/sysbus.h" diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm_clk.h index 5ed4a46..52e972f 100644 --- a/include/hw/misc/npcm7xx_clk.h +++ b/include/hw/misc/npcm_clk.h @@ -1,5 +1,5 @@ /* - * Nuvoton NPCM7xx Clock Control Registers. + * Nuvoton NPCM7xx/8xx Clock Control Registers. * * Copyright 2020 Google LLC * @@ -13,18 +13,20 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ -#ifndef NPCM7XX_CLK_H -#define NPCM7XX_CLK_H +#ifndef NPCM_CLK_H +#define NPCM_CLK_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/clock.h" #include "hw/sysbus.h" +#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t)) +#define NPCM8XX_CLK_NR_REGS (0xc4 / sizeof(uint32_t)) /* - * Number of registers in our device state structure. Don't change this without - * incrementing the version_id in the vmstate. + * Number of maximum registers in NPCM device state structure. Don't change + * this without incrementing the version_id in the vmstate. */ -#define NPCM7XX_CLK_NR_REGS (0x70 / sizeof(uint32_t)) +#define NPCM_CLK_MAX_NR_REGS NPCM8XX_CLK_NR_REGS #define NPCM7XX_WATCHDOG_RESET_GPIO_IN "npcm7xx-clk-watchdog-reset-gpio-in" @@ -80,7 +82,7 @@ typedef enum NPCM7xxClockDivider { NPCM7XX_CLOCK_NR_DIVIDERS, } NPCM7xxClockConverter; -typedef struct NPCM7xxCLKState NPCM7xxCLKState; +typedef struct NPCMCLKState NPCMCLKState; /** * struct NPCM7xxClockPLLState - A PLL module in CLK module. @@ -94,7 +96,7 @@ typedef struct NPCM7xxClockPLLState { DeviceState parent; const char *name; - NPCM7xxCLKState *clk; + NPCMCLKState *clk; Clock *clock_in; Clock *clock_out; @@ -115,7 +117,7 @@ typedef struct NPCM7xxClockSELState { DeviceState parent; const char *name; - NPCM7xxCLKState *clk; + NPCMCLKState *clk; uint8_t input_size; Clock *clock_in[NPCM7XX_CLK_SEL_MAX_INPUT]; Clock *clock_out; @@ -140,7 +142,7 @@ typedef struct NPCM7xxClockDividerState { DeviceState parent; const char *name; - NPCM7xxCLKState *clk; + NPCMCLKState *clk; Clock *clock_in; Clock *clock_out; @@ -155,17 +157,21 @@ typedef struct NPCM7xxClockDividerState { }; } NPCM7xxClockDividerState; -struct NPCM7xxCLKState { +struct NPCMCLKState { SysBusDevice parent; MemoryRegion iomem; /* Clock converters */ + /* + * TODO: Implement unique clock converters for NPCM8xx. + * NPCM8xx adds a few more clock outputs. + */ NPCM7xxClockPLLState plls[NPCM7XX_CLOCK_NR_PLLS]; NPCM7xxClockSELState sels[NPCM7XX_CLOCK_NR_SELS]; NPCM7xxClockDividerState dividers[NPCM7XX_CLOCK_NR_DIVIDERS]; - uint32_t regs[NPCM7XX_CLK_NR_REGS]; + uint32_t regs[NPCM_CLK_MAX_NR_REGS]; /* Time reference for SECCNT and CNTR25M, initialized by power on reset */ int64_t ref_ns; @@ -174,7 +180,16 @@ struct NPCM7xxCLKState { Clock *clkref; }; +typedef struct NPCMCLKClass { + SysBusDeviceClass parent; + + size_t nr_regs; + const uint32_t *cold_reset_values; +} NPCMCLKClass; + +#define TYPE_NPCM_CLK "npcm-clk" +OBJECT_DECLARE_TYPE(NPCMCLKState, NPCMCLKClass, NPCM_CLK) #define TYPE_NPCM7XX_CLK "npcm7xx-clk" -OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxCLKState, NPCM7XX_CLK) +#define TYPE_NPCM8XX_CLK "npcm8xx-clk" -#endif /* NPCM7XX_CLK_H */ +#endif /* NPCM_CLK_H */ diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm_gcr.h index c0bbdda..702e7fd 100644 --- a/include/hw/misc/npcm7xx_gcr.h +++ b/include/hw/misc/npcm_gcr.h @@ -1,5 +1,5 @@ /* - * Nuvoton NPCM7xx System Global Control Registers. + * Nuvoton NPCM7xx/8xx System Global Control Registers. * * Copyright 2020 Google LLC * @@ -13,11 +13,12 @@ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ -#ifndef NPCM7XX_GCR_H -#define NPCM7XX_GCR_H +#ifndef NPCM_GCR_H +#define NPCM_GCR_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" +#include "qom/object.h" /* * NPCM7XX PWRON STRAP bit fields @@ -53,21 +54,33 @@ * Number of registers in our device state structure. Don't change this without * incrementing the version_id in the vmstate. */ +#define NPCM_GCR_MAX_NR_REGS NPCM8XX_GCR_NR_REGS #define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t)) +#define NPCM8XX_GCR_NR_REGS (0xf80 / sizeof(uint32_t)) -struct NPCM7xxGCRState { +typedef struct NPCMGCRState { SysBusDevice parent; MemoryRegion iomem; - uint32_t regs[NPCM7XX_GCR_NR_REGS]; + uint32_t regs[NPCM_GCR_MAX_NR_REGS]; uint32_t reset_pwron; uint32_t reset_mdlr; uint32_t reset_intcr3; -}; + uint32_t reset_scrpad_b; +} NPCMGCRState; +typedef struct NPCMGCRClass { + SysBusDeviceClass parent; + + size_t nr_regs; + const uint32_t *cold_reset_values; +} NPCMGCRClass; + +#define TYPE_NPCM_GCR "npcm-gcr" #define TYPE_NPCM7XX_GCR "npcm7xx-gcr" -OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxGCRState, NPCM7XX_GCR) +#define TYPE_NPCM8XX_GCR "npcm8xx-gcr" +OBJECT_DECLARE_TYPE(NPCMGCRState, NPCMGCRClass, NPCM_GCR) -#endif /* NPCM7XX_GCR_H */ +#endif /* NPCM_GCR_H */ diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h index 9a71a5a..5098693 100644 --- a/include/hw/misc/pvpanic.h +++ b/include/hw/misc/pvpanic.h @@ -15,7 +15,7 @@ #ifndef HW_MISC_PVPANIC_H #define HW_MISC_PVPANIC_H -#include "exec/memory.h" +#include "system/memory.h" #include "qom/object.h" #include "standard-headers/misc/pvpanic.h" @@ -26,6 +26,7 @@ #define TYPE_PVPANIC_ISA_DEVICE "pvpanic" #define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci" +#define TYPE_PVPANIC_MMIO_DEVICE "pvpanic-mmio" #define PVPANIC_IOPORT_PROP "ioport" diff --git a/include/hw/misc/stm32_rcc.h b/include/hw/misc/stm32_rcc.h new file mode 100644 index 0000000..ffbdf20 --- /dev/null +++ b/include/hw/misc/stm32_rcc.h @@ -0,0 +1,91 @@ +/* + * STM32 RCC (only reset and enable registers are implemented) + * + * Copyright (c) 2024 Román Cárdenas <rcardenas.rod@gmail.com> + * + * 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 HW_STM32_RCC_H +#define HW_STM32_RCC_H + +#include "hw/sysbus.h" +#include "qom/object.h" + +#define STM32_RCC_CR 0x00 +#define STM32_RCC_PLL_CFGR 0x04 +#define STM32_RCC_CFGR 0x08 +#define STM32_RCC_CIR 0x0C +#define STM32_RCC_AHB1_RSTR 0x10 +#define STM32_RCC_AHB2_RSTR 0x14 +#define STM32_RCC_AHB3_RSTR 0x18 + +#define STM32_RCC_APB1_RSTR 0x20 +#define STM32_RCC_APB2_RSTR 0x24 + +#define STM32_RCC_AHB1_ENR 0x30 +#define STM32_RCC_AHB2_ENR 0x34 +#define STM32_RCC_AHB3_ENR 0x38 + +#define STM32_RCC_APB1_ENR 0x40 +#define STM32_RCC_APB2_ENR 0x44 + +#define STM32_RCC_AHB1_LPENR 0x50 +#define STM32_RCC_AHB2_LPENR 0x54 +#define STM32_RCC_AHB3_LPENR 0x58 + +#define STM32_RCC_APB1_LPENR 0x60 +#define STM32_RCC_APB2_LPENR 0x64 + +#define STM32_RCC_BDCR 0x70 +#define STM32_RCC_CSR 0x74 + +#define STM32_RCC_SSCGR 0x80 +#define STM32_RCC_PLLI2SCFGR 0x84 +#define STM32_RCC_PLLSAI_CFGR 0x88 +#define STM32_RCC_DCKCFGR 0x8C +#define STM32_RCC_CKGATENR 0x90 +#define STM32_RCC_DCKCFGR2 0x94 + +#define STM32_RCC_NREGS ((STM32_RCC_DCKCFGR2 >> 2) + 1) +#define STM32_RCC_PERIPHERAL_SIZE 0x400 +#define STM32_RCC_NIRQS (32 * 5) /* 32 bits per reg, 5 en/rst regs */ + +#define STM32_RCC_GPIO_IRQ_OFFSET 0 + +#define TYPE_STM32_RCC "stm32.rcc" + +typedef struct STM32RccState STM32RccState; + +DECLARE_INSTANCE_CHECKER(STM32RccState, STM32_RCC, TYPE_STM32_RCC) + +#define NUM_GPIO_EVENT_IN_LINES 16 + +struct STM32RccState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + + uint32_t regs[STM32_RCC_NREGS]; + + qemu_irq enable_irq[STM32_RCC_NIRQS]; + qemu_irq reset_irq[STM32_RCC_NIRQS]; +}; + +#endif /* HW_STM32_RCC_H */ diff --git a/include/hw/misc/stm32l4x5_syscfg.h b/include/hw/misc/stm32l4x5_syscfg.h index 23bb564..c450df2 100644 --- a/include/hw/misc/stm32l4x5_syscfg.h +++ b/include/hw/misc/stm32l4x5_syscfg.h @@ -48,6 +48,7 @@ struct Stm32l4x5SyscfgState { uint32_t swpr2; qemu_irq gpio_out[GPIO_NUM_PINS]; + Clock *clk; }; #endif diff --git a/include/hw/misc/vmcoreinfo.h b/include/hw/misc/vmcoreinfo.h index 0b7b55d..1aa4477 100644 --- a/include/hw/misc/vmcoreinfo.h +++ b/include/hw/misc/vmcoreinfo.h @@ -16,10 +16,9 @@ #include "standard-headers/linux/qemu_fw_cfg.h" #include "qom/object.h" -#define VMCOREINFO_DEVICE "vmcoreinfo" +#define TYPE_VMCOREINFO "vmcoreinfo" typedef struct VMCoreInfoState VMCoreInfoState; -DECLARE_INSTANCE_CHECKER(VMCoreInfoState, VMCOREINFO, - VMCOREINFO_DEVICE) +DECLARE_INSTANCE_CHECKER(VMCoreInfoState, VMCOREINFO, TYPE_VMCOREINFO) typedef struct fw_cfg_vmcoreinfo FWCfgVMCoreInfo; @@ -33,7 +32,7 @@ struct VMCoreInfoState { /* returns NULL unless there is exactly one device */ static inline VMCoreInfoState *vmcoreinfo_find(void) { - Object *o = object_resolve_path_type("", VMCOREINFO_DEVICE, NULL); + Object *o = object_resolve_path_type("", TYPE_VMCOREINFO, NULL); return o ? VMCOREINFO(o) : NULL; } diff --git a/include/hw/misc/xlnx-versal-trng.h b/include/hw/misc/xlnx-versal-trng.h index 0bcef8a..d96f8f9 100644 --- a/include/hw/misc/xlnx-versal-trng.h +++ b/include/hw/misc/xlnx-versal-trng.h @@ -50,6 +50,7 @@ typedef struct XlnxVersalTRng { uint64_t forced_prng_count; uint64_t tst_seed[2]; + RegisterInfoArray *reg_array; uint32_t regs[RMAX_XLNX_VERSAL_TRNG]; RegisterInfo regs_info[RMAX_XLNX_VERSAL_TRNG]; } XlnxVersalTRng; diff --git a/include/hw/net/dp8393x.h b/include/hw/net/dp8393x.h index 4a3f747..24273dc 100644 --- a/include/hw/net/dp8393x.h +++ b/include/hw/net/dp8393x.h @@ -22,7 +22,7 @@ #include "hw/sysbus.h" #include "net/net.h" -#include "exec/memory.h" +#include "system/memory.h" #define SONIC_REG_COUNT 0x40 diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h index 2d13290..83b2163 100644 --- a/include/hw/net/imx_fec.h +++ b/include/hw/net/imx_fec.h @@ -31,6 +31,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC) #define TYPE_IMX_ENET "imx.enet" #include "hw/sysbus.h" +#include "hw/net/lan9118_phy.h" +#include "hw/irq.h" #include "net/net.h" #define ENET_EIR 1 @@ -264,11 +266,8 @@ struct IMXFECState { uint32_t tx_descriptor[ENET_TX_RING_NUM]; uint32_t tx_ring_num; - uint32_t phy_status; - uint32_t phy_control; - uint32_t phy_advertise; - uint32_t phy_int; - uint32_t phy_int_mask; + Lan9118PhyState mii; + IRQState mii_irq; uint32_t phy_num; bool phy_connected; struct IMXFECState *phy_consumer; diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h new file mode 100644 index 0000000..af12fc3 --- /dev/null +++ b/include/hw/net/lan9118_phy.h @@ -0,0 +1,37 @@ +/* + * SMSC LAN9118 PHY emulation + * + * Copyright (c) 2009 CodeSourcery, LLC. + * Written by Paul Brook + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_NET_LAN9118_PHY_H +#define HW_NET_LAN9118_PHY_H + +#include "qom/object.h" +#include "hw/sysbus.h" + +#define TYPE_LAN9118_PHY "lan9118-phy" +OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY) + +typedef struct Lan9118PhyState { + SysBusDevice parent_obj; + + uint16_t status; + uint16_t control; + uint16_t advertise; + uint16_t ints; + uint16_t int_mask; + qemu_irq irq; + bool link_down; +} Lan9118PhyState; + +void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down); +void lan9118_phy_reset(Lan9118PhyState *s); +uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg); +void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val); + +#endif diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h index f7feddac..55bf7c9 100644 --- a/include/hw/net/mii.h +++ b/include/hw/net/mii.h @@ -71,6 +71,7 @@ #define MII_BMSR_JABBER (1 << 1) /* Jabber detected */ #define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */ +#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */ #define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */ #define MII_ANAR_PAUSE (1 << 10) /* Try for pause */ #define MII_ANAR_TXFD (1 << 8) @@ -78,6 +79,7 @@ #define MII_ANAR_10FD (1 << 6) #define MII_ANAR_10 (1 << 5) #define MII_ANAR_CSMACD (1 << 0) +#define MII_ANAR_SELECT (0x001f) /* Selector bits */ #define MII_ANLPAR_ACK (1 << 14) #define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */ @@ -112,6 +114,10 @@ #define RTL8201CP_PHYID1 0x0000 #define RTL8201CP_PHYID2 0x8201 +/* SMSC LAN9118 */ +#define SMSCLAN9118_PHYID1 0x0007 +#define SMSCLAN9118_PHYID2 0xc0d1 + /* RealTek 8211E */ #define RTL8211E_PHYID1 0x001c #define RTL8211E_PHYID2 0xc915 diff --git a/include/hw/net/msf2-emac.h b/include/hw/net/msf2-emac.h index 846ba6e..b5d9127 100644 --- a/include/hw/net/msf2-emac.h +++ b/include/hw/net/msf2-emac.h @@ -23,7 +23,7 @@ */ #include "hw/sysbus.h" -#include "exec/memory.h" +#include "system/memory.h" #include "net/net.h" #include "net/eth.h" #include "qom/object.h" diff --git a/include/hw/net/npcm_pcs.h b/include/hw/net/npcm_pcs.h new file mode 100644 index 0000000..d5c481a --- /dev/null +++ b/include/hw/net/npcm_pcs.h @@ -0,0 +1,42 @@ +/* + * Nuvoton NPCM8xx PCS Module + * + * Copyright 2022 Google LLC + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef NPCM_PCS_H +#define NPCM_PCS_H + +#include "hw/sysbus.h" + +#define NPCM_PCS_NR_SR_CTLS (0x12 / sizeof(uint16_t)) +#define NPCM_PCS_NR_SR_MIIS (0x20 / sizeof(uint16_t)) +#define NPCM_PCS_NR_SR_TIMS (0x22 / sizeof(uint16_t)) +#define NPCM_PCS_NR_VR_MIIS (0x1c6 / sizeof(uint16_t)) + +struct NPCMPCSState { + SysBusDevice parent; + + MemoryRegion iomem; + + uint16_t indirect_access_base; + uint16_t sr_ctl[NPCM_PCS_NR_SR_CTLS]; + uint16_t sr_mii[NPCM_PCS_NR_SR_MIIS]; + uint16_t sr_tim[NPCM_PCS_NR_SR_TIMS]; + uint16_t vr_mii[NPCM_PCS_NR_VR_MIIS]; +}; + +#define TYPE_NPCM_PCS "npcm-pcs" +OBJECT_DECLARE_SIMPLE_TYPE(NPCMPCSState, NPCM_PCS) + +#endif /* NPCM_PCS_H */ diff --git a/include/hw/nubus/nubus.h b/include/hw/nubus/nubus.h index fee79b7..7825840 100644 --- a/include/hw/nubus/nubus.h +++ b/include/hw/nubus/nubus.h @@ -11,7 +11,7 @@ #include "hw/qdev-properties.h" #include "hw/sysbus.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qom/object.h" #include "qemu/units.h" diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index d173998..d41b932 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -4,7 +4,7 @@ #include "exec/hwaddr.h" #include "standard-headers/linux/qemu_fw_cfg.h" #include "hw/sysbus.h" -#include "sysemu/dma.h" +#include "system/dma.h" #include "qom/object.h" #define TYPE_FW_CFG "fw_cfg" @@ -30,8 +30,9 @@ struct FWCfgDataGeneratorClass { * @obj: the object implementing this interface * @errp: pointer to a NULL-initialized error object * - * Returns: reference to a byte array containing the data on success, - * or NULL on error. + * Returns: A byte array containing data to add, or NULL without + * @errp set if no data is required, or NULL with @errp + * set on failure. * * The caller should release the reference when no longer * required. @@ -41,14 +42,6 @@ struct FWCfgDataGeneratorClass { typedef struct fw_cfg_file FWCfgFile; -#define FW_CFG_ORDER_OVERRIDE_VGA 70 -#define FW_CFG_ORDER_OVERRIDE_NIC 80 -#define FW_CFG_ORDER_OVERRIDE_USER 100 -#define FW_CFG_ORDER_OVERRIDE_DEVICE 110 - -void fw_cfg_set_order_override(FWCfgState *fw_cfg, int order); -void fw_cfg_reset_order_override(FWCfgState *fw_cfg); - typedef struct FWCfgFiles { uint32_t count; FWCfgFile f[]; @@ -74,8 +67,6 @@ struct FWCfgState { uint32_t cur_offset; Notifier machine_ready; - int fw_cfg_order_override; - bool dma_enabled; dma_addr_t dma_addr; AddressSpace *dma_as; @@ -291,37 +282,31 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data, size_t len); /** - * fw_cfg_add_from_generator: + * fw_cfg_add_file_from_generator: * @s: fw_cfg device being modified * @filename: name of new fw_cfg file item - * @gen_id: name of object implementing FW_CFG_DATA_GENERATOR interface + * @part: name of object implementing FW_CFG_DATA_GENERATOR interface + * @parent: the object in which to resolve the @part * @errp: pointer to a NULL initialized error object * - * Add a new NAMED fw_cfg item with the content generated from the - * @gen_id object. The data generated by the @gen_id object is copied - * into the data structure of the fw_cfg device. + * If the @part object generates content, add a new NAMED fw_cfg item with it. + * The data generated by the @part object is copied into the data structure of + * the fw_cfg device. * The next available (unused) selector key starting at FW_CFG_FILE_FIRST * will be used; also, a new entry will be added to the file directory * structure residing at key value FW_CFG_FILE_DIR, containing the item name, * data size, and assigned selector key value. * - * Returns: %true on success, %false on error. - */ -bool fw_cfg_add_from_generator(FWCfgState *s, const char *filename, - const char *gen_id, Error **errp); - -/** - * fw_cfg_add_extra_pci_roots: - * @bus: main pci root bus to be scanned from - * @s: fw_cfg device being modified + * If the @part object does not generate content, no fw_cfg item is added. * - * Add a new fw_cfg item... + * Returns: %true on success, %false on error. */ -void fw_cfg_add_extra_pci_roots(PCIBus *bus, FWCfgState *s); +bool fw_cfg_add_file_from_generator(FWCfgState *s, + Object *parent, const char *part, + const char *filename, Error **errp); FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase, AddressSpace *dma_as); -FWCfgState *fw_cfg_init_io(uint32_t iobase); FWCfgState *fw_cfg_init_mem(hwaddr ctl_addr, hwaddr data_addr); FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr, hwaddr data_addr, uint32_t data_width, diff --git a/include/hw/nvram/fw_cfg_acpi.h b/include/hw/nvram/fw_cfg_acpi.h index b39eb04..dfd2a44 100644 --- a/include/hw/nvram/fw_cfg_acpi.h +++ b/include/hw/nvram/fw_cfg_acpi.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * ACPI support for fw_cfg * diff --git a/include/hw/nvram/mac_nvram.h b/include/hw/nvram/mac_nvram.h index 0c4dfae..e9d8398 100644 --- a/include/hw/nvram/mac_nvram.h +++ b/include/hw/nvram/mac_nvram.h @@ -26,7 +26,7 @@ #ifndef MAC_NVRAM_H #define MAC_NVRAM_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" #define MACIO_NVRAM_SIZE 0x2000 diff --git a/include/hw/nvram/npcm7xx_otp.h b/include/hw/nvram/npcm7xx_otp.h index ea4b5d0..77b05f8 100644 --- a/include/hw/nvram/npcm7xx_otp.h +++ b/include/hw/nvram/npcm7xx_otp.h @@ -16,7 +16,7 @@ #ifndef NPCM7XX_OTP_H #define NPCM7XX_OTP_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" /* Each OTP module holds 8192 bits of one-time programmable storage */ diff --git a/include/hw/nvram/xlnx-bbram.h b/include/hw/nvram/xlnx-bbram.h index 6fc13f8..58acbe9 100644 --- a/include/hw/nvram/xlnx-bbram.h +++ b/include/hw/nvram/xlnx-bbram.h @@ -26,7 +26,7 @@ #ifndef XLNX_BBRAM_H #define XLNX_BBRAM_H -#include "sysemu/block-backend.h" +#include "system/block-backend.h" #include "hw/qdev-core.h" #include "hw/irq.h" #include "hw/sysbus.h" @@ -47,6 +47,7 @@ struct XlnxBBRam { bool bbram8_wo; bool blk_ro; + RegisterInfoArray *reg_array; uint32_t regs[RMAX_XLNX_BBRAM]; RegisterInfo regs_info[RMAX_XLNX_BBRAM]; }; diff --git a/include/hw/nvram/xlnx-efuse.h b/include/hw/nvram/xlnx-efuse.h index cff7924..ef14fb0 100644 --- a/include/hw/nvram/xlnx-efuse.h +++ b/include/hw/nvram/xlnx-efuse.h @@ -27,7 +27,7 @@ #ifndef XLNX_EFUSE_H #define XLNX_EFUSE_H -#include "sysemu/block-backend.h" +#include "system/block-backend.h" #include "hw/qdev-core.h" #define TYPE_XLNX_EFUSE "xlnx-efuse" diff --git a/include/hw/nvram/xlnx-versal-efuse.h b/include/hw/nvram/xlnx-versal-efuse.h index 86e2261..afa4f4f 100644 --- a/include/hw/nvram/xlnx-versal-efuse.h +++ b/include/hw/nvram/xlnx-versal-efuse.h @@ -44,6 +44,7 @@ struct XlnxVersalEFuseCtrl { void *extra_pg0_lock_spec; /* Opaque property */ uint32_t extra_pg0_lock_n16; + RegisterInfoArray *reg_array; uint32_t regs[XLNX_VERSAL_EFUSE_CTRL_R_MAX]; RegisterInfo regs_info[XLNX_VERSAL_EFUSE_CTRL_R_MAX]; }; diff --git a/include/hw/nvram/xlnx-zynqmp-efuse.h b/include/hw/nvram/xlnx-zynqmp-efuse.h index f5beacc..7fb12df 100644 --- a/include/hw/nvram/xlnx-zynqmp-efuse.h +++ b/include/hw/nvram/xlnx-zynqmp-efuse.h @@ -37,6 +37,7 @@ struct XlnxZynqMPEFuse { qemu_irq irq; XlnxEFuse *efuse; + RegisterInfoArray *reg_array; uint32_t regs[XLNX_ZYNQMP_EFUSE_R_MAX]; RegisterInfo regs_info[XLNX_ZYNQMP_EFUSE_R_MAX]; }; diff --git a/include/hw/openrisc/boot.h b/include/hw/openrisc/boot.h index 25a313d..9b4d880 100644 --- a/include/hw/openrisc/boot.h +++ b/include/hw/openrisc/boot.h @@ -20,6 +20,7 @@ #define OPENRISC_BOOT_H #include "exec/cpu-defs.h" +#include "hw/boards.h" hwaddr openrisc_load_kernel(ram_addr_t ram_size, const char *kernel_filename, @@ -28,7 +29,7 @@ hwaddr openrisc_load_kernel(ram_addr_t ram_size, hwaddr openrisc_load_initrd(void *fdt, const char *filename, hwaddr load_start, uint64_t mem_size); -uint32_t openrisc_load_fdt(void *fdt, hwaddr load_start, +uint32_t openrisc_load_fdt(MachineState *ms, void *fdt, hwaddr load_start, uint64_t mem_size); #endif /* OPENRISC_BOOT_H */ diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bridge/cxl_upstream_port.h index 1263513..f208397 100644 --- a/include/hw/pci-bridge/cxl_upstream_port.h +++ b/include/hw/pci-bridge/cxl_upstream_port.h @@ -12,6 +12,10 @@ typedef struct CXLUpstreamPort { /*< public >*/ CXLComponentState cxl_cstate; CXLCCI swcci; + + PCIExpLinkSpeed speed; + PCIExpLinkWidth width; + DOECap doe_cdat; uint64_t sn; } CXLUpstreamPort; diff --git a/include/hw/pci-host/astro.h b/include/hw/pci-host/astro.h index e296691..832125a 100644 --- a/include/hw/pci-host/astro.h +++ b/include/hw/pci-host/astro.h @@ -24,6 +24,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(ElroyState, ELROY_PCI_HOST_BRIDGE) #define LMMIO_DIST_BASE_ADDR 0xf4000000ULL #define LMMIO_DIST_BASE_SIZE 0x4000000ULL +#define LMMIO_DIRECT_RANGES 4 + #define IOS_DIST_BASE_ADDR 0xfffee00000ULL #define IOS_DIST_BASE_SIZE 0x10000ULL @@ -83,9 +85,7 @@ struct AstroState { struct ElroyState *elroy[ELROY_NUM]; MemoryRegion this_mem; - - MemoryRegion pci_mmio; - MemoryRegion pci_io; + MemoryRegion lmmio_direct[LMMIO_DIRECT_RANGES]; IOMMUMemoryRegion iommu; AddressSpace iommu_as; diff --git a/include/hw/pci-host/designware.h b/include/hw/pci-host/designware.h index 908f3d9..a35a3bd 100644 --- a/include/hw/pci-host/designware.h +++ b/include/hw/pci-host/designware.h @@ -25,13 +25,18 @@ #include "hw/pci/pci_bridge.h" #include "qom/object.h" +#define TYPE_DESIGNWARE_PCIE_ROOT_BUS "designware-pcie-root-BUS" +OBJECT_DECLARE_SIMPLE_TYPE(DesignwarePCIERootBus, DESIGNWARE_PCIE_ROOT_BUS) + #define TYPE_DESIGNWARE_PCIE_HOST "designware-pcie-host" OBJECT_DECLARE_SIMPLE_TYPE(DesignwarePCIEHost, DESIGNWARE_PCIE_HOST) #define TYPE_DESIGNWARE_PCIE_ROOT "designware-pcie-root" OBJECT_DECLARE_SIMPLE_TYPE(DesignwarePCIERoot, DESIGNWARE_PCIE_ROOT) -struct DesignwarePCIERoot; +struct DesignwarePCIERootBus { + PCIBus parent; +}; typedef struct DesignwarePCIEViewport { DesignwarePCIERoot *root; @@ -88,6 +93,7 @@ struct DesignwarePCIEHost { MemoryRegion io; qemu_irq irqs[4]; + qemu_irq msi; } pci; MemoryRegion mmio; diff --git a/include/hw/pci-host/dino.h b/include/hw/pci-host/dino.h index fd7975c..5dc8cdf 100644 --- a/include/hw/pci-host/dino.h +++ b/include/hw/pci-host/dino.h @@ -109,10 +109,6 @@ static const uint32_t reg800_keep_bits[DINO800_REGS] = { struct DinoState { PCIHostState parent_obj; - /* - * PCI_CONFIG_ADDR is parent_obj.config_reg, via pci_host_conf_be_ops, - * so that we can map PCI_CONFIG_DATA to pci_host_data_be_ops. - */ uint32_t config_reg_dino; /* keep original copy, including 2 lowest bits */ uint32_t iar0; diff --git a/include/hw/pci-host/fsl_imx8m_phy.h b/include/hw/pci-host/fsl_imx8m_phy.h new file mode 100644 index 0000000..5f1b212 --- /dev/null +++ b/include/hw/pci-host/fsl_imx8m_phy.h @@ -0,0 +1,28 @@ +/* + * i.MX8 PCIe PHY emulation + * + * Copyright (c) 2025 Bernhard Beschow <shentey@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_PCIHOST_FSLIMX8MPCIEPHY_H +#define HW_PCIHOST_FSLIMX8MPCIEPHY_H + +#include "hw/sysbus.h" +#include "qom/object.h" +#include "system/memory.h" + +#define TYPE_FSL_IMX8M_PCIE_PHY "fsl-imx8m-pcie-phy" +OBJECT_DECLARE_SIMPLE_TYPE(FslImx8mPciePhyState, FSL_IMX8M_PCIE_PHY) + +#define FSL_IMX8M_PCIE_PHY_DATA_SIZE 0x800 + +struct FslImx8mPciePhyState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + uint8_t data[FSL_IMX8M_PCIE_PHY_DATA_SIZE]; +}; + +#endif diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h index dce8835..8447153 100644 --- a/include/hw/pci-host/gpex.h +++ b/include/hw/pci-host/gpex.h @@ -32,8 +32,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(GPEXHost, GPEX_HOST) #define TYPE_GPEX_ROOT_DEVICE "gpex-root" OBJECT_DECLARE_SIMPLE_TYPE(GPEXRootState, GPEX_ROOT_DEVICE) -#define GPEX_NUM_IRQS 4 - struct GPEXRootState { /*< private >*/ PCIDevice parent_obj; @@ -49,6 +47,7 @@ struct GPEXConfig { PCIBus *bus; }; +typedef struct GPEXIrq GPEXIrq; struct GPEXHost { /*< private >*/ PCIExpressHost parent_obj; @@ -60,8 +59,8 @@ struct GPEXHost { MemoryRegion io_mmio; MemoryRegion io_ioport_window; MemoryRegion io_mmio_window; - qemu_irq irq[GPEX_NUM_IRQS]; - int irq_num[GPEX_NUM_IRQS]; + GPEXIrq *irq; + uint8_t num_irqs; bool allow_unmapped_accesses; diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h index cd7c9ec..79d4ea8 100644 --- a/include/hw/pci-host/ls7a.h +++ b/include/hw/pci-host/ls7a.h @@ -36,17 +36,18 @@ #define VIRT_PCH_PIC_IRQ_NUM 32 #define VIRT_GSI_BASE 64 #define VIRT_DEVICE_IRQS 16 +#define VIRT_UART_COUNT 4 #define VIRT_UART_IRQ (VIRT_GSI_BASE + 2) #define VIRT_UART_BASE 0x1fe001e0 -#define VIRT_UART_SIZE 0X100 -#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 3) +#define VIRT_UART_SIZE 0x100 +#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 6) #define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000) #define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100) #define VIRT_RTC_LEN 0x100 -#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 4) +#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 7) #define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000 #define VIRT_PLATFORM_BUS_SIZE 0x2000000 #define VIRT_PLATFORM_BUS_NUM_IRQS 2 -#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 5) +#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 8) #endif diff --git a/include/hw/pci-host/pam.h b/include/hw/pci-host/pam.h index 005916f..44f3908 100644 --- a/include/hw/pci-host/pam.h +++ b/include/hw/pci-host/pam.h @@ -50,7 +50,7 @@ * 0xf0000 - 0xfffff System BIOS Area Memory Segments */ -#include "exec/memory.h" +#include "system/memory.h" #define SMRAM_C_BASE 0xa0000 #define SMRAM_C_END 0xc0000 diff --git a/include/hw/pci-host/pnv_phb4.h b/include/hw/pci-host/pnv_phb4.h index 8abee78..8a80c0c 100644 --- a/include/hw/pci-host/pnv_phb4.h +++ b/include/hw/pci-host/pnv_phb4.h @@ -13,6 +13,7 @@ #include "hw/pci-host/pnv_phb.h" #include "hw/pci/pci_bus.h" #include "hw/ppc/pnv.h" +#include "hw/ppc/pnv_nest_pervasive.h" #include "hw/ppc/xive.h" #include "qom/object.h" @@ -174,6 +175,9 @@ struct PnvPhb4PecState { uint32_t index; uint32_t chip_id; + /* Pervasive chiplet control */ + PnvNestChipletPervasive nest_pervasive; + /* Nest registers, excuding per-stack */ #define PHB4_PEC_NEST_REGS_COUNT 0xf uint64_t nest_regs[PHB4_PEC_NEST_REGS_COUNT]; @@ -196,6 +200,7 @@ struct PnvPhb4PecState { struct PnvPhb4PecClass { DeviceClass parent_class; + uint32_t (*xscom_cplt_base)(PnvPhb4PecState *pec); uint32_t (*xscom_nest_base)(PnvPhb4PecState *pec); uint32_t xscom_nest_size; uint32_t (*xscom_pci_base)(PnvPhb4PecState *pec); diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 22fadfa..ddafc3f 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -181,8 +181,6 @@ struct Q35PCIHost { #define MCH_PCIE_DEV 1 #define MCH_PCIE_FUNC 0 -uint64_t mch_mcfg_base(void); - /* * Arbitrary but unique BNF number for IOAPIC device. * diff --git a/include/hw/pci-host/remote.h b/include/hw/pci-host/remote.h index 690a01f..5264c35 100644 --- a/include/hw/pci-host/remote.h +++ b/include/hw/pci-host/remote.h @@ -11,7 +11,7 @@ #ifndef PCI_HOST_REMOTE_H #define PCI_HOST_REMOTE_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/pci/pcie_host.h" #define TYPE_REMOTE_PCIHOST "remote-pcihost" diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 3778aac..0db87f1 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -53,7 +53,6 @@ struct SpaprPhbState { uint32_t index; uint64_t buid; char *dtbusname; - bool dr_enabled; MemoryRegion memspace, iospace; hwaddr mem_win_addr, mem_win_size, mem64_win_addr, mem64_win_size; @@ -84,10 +83,6 @@ struct SpaprPhbState { bool pcie_ecs; /* Allow access to PCIe extended config space? */ /* Fields for migration compatibility hacks */ - bool pre_2_8_migration; - uint32_t mig_liobn; - hwaddr mig_mem_win_addr, mig_mem_win_size; - hwaddr mig_io_win_addr, mig_io_win_size; bool pre_5_1_assoc; }; diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h index 0e6f257..11ef945 100644 --- a/include/hw/pci/msix.h +++ b/include/hw/pci/msix.h @@ -32,6 +32,7 @@ int msix_present(PCIDevice *dev); bool msix_is_masked(PCIDevice *dev, unsigned vector); void msix_set_pending(PCIDevice *dev, unsigned vector); void msix_clr_pending(PCIDevice *dev, int vector); +int msix_is_pending(PCIDevice *dev, unsigned vector); void msix_vector_use(PCIDevice *dev, unsigned vector); void msix_vector_unuse(PCIDevice *dev, unsigned vector); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index eb26cac..df3cc7b 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -1,9 +1,9 @@ #ifndef QEMU_PCI_H #define QEMU_PCI_H -#include "exec/memory.h" -#include "sysemu/dma.h" -#include "sysemu/host_iommu_device.h" +#include "system/memory.h" +#include "system/dma.h" +#include "system/host_iommu_device.h" /* PCI includes legacy ISA access. */ #include "hw/isa/isa.h" @@ -16,13 +16,17 @@ extern bool pci_available; #define PCI_BUS_NUM(x) (((x) >> 8) & 0xff) #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) #define PCI_FUNC(devfn) ((devfn) & 0x07) -#define PCI_BUILD_BDF(bus, devfn) ((bus << 8) | (devfn)) +#define PCI_BUILD_BDF(bus, devfn) (((bus) << 8) | (devfn)) #define PCI_BDF_TO_DEVFN(x) ((x) & 0xff) #define PCI_BUS_MAX 256 #define PCI_DEVFN_MAX 256 #define PCI_SLOT_MAX 32 #define PCI_FUNC_MAX 8 +#define PCI_SBDF(seg, bus, dev, func) \ + ((((uint32_t)(seg)) << 16) | \ + (PCI_BUILD_BDF(bus, PCI_DEVFN(dev, func)))) + /* Class, Vendor and Device IDs from Linux's pci_ids.h */ #include "hw/pci/pci_ids.h" @@ -116,6 +120,7 @@ extern bool pci_available; #define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011 #define PCI_DEVICE_ID_REDHAT_ACPI_ERST 0x0012 #define PCI_DEVICE_ID_REDHAT_UFS 0x0013 +#define PCI_DEVICE_ID_REDHAT_RISCV_IOMMU 0x0014 #define PCI_DEVICE_ID_REDHAT_QXL 0x0100 #define FMT_PCIBUS PRIx64 @@ -213,6 +218,12 @@ enum { QEMU_PCIE_ERR_UNC_MASK = (1 << QEMU_PCIE_ERR_UNC_MASK_BITNR), #define QEMU_PCIE_ARI_NEXTFN_1_BITNR 12 QEMU_PCIE_ARI_NEXTFN_1 = (1 << QEMU_PCIE_ARI_NEXTFN_1_BITNR), +#define QEMU_PCIE_EXT_TAG_BITNR 13 + QEMU_PCIE_EXT_TAG = (1 << QEMU_PCIE_EXT_TAG_BITNR), +#define QEMU_PCI_CAP_PM_BITNR 14 + QEMU_PCI_CAP_PM = (1 << QEMU_PCI_CAP_PM_BITNR), +#define QEMU_PCI_SKIP_RESET_ON_CPR_BITNR 15 + QEMU_PCI_SKIP_RESET_ON_CPR = (1 << QEMU_PCI_SKIP_RESET_ON_CPR_BITNR), }; typedef struct PCIINTxRoute { @@ -294,6 +305,9 @@ int pci_bus_get_irq_level(PCIBus *bus, int irq_num); uint32_t pci_bus_get_slot_reserved_mask(PCIBus *bus); void pci_bus_set_slot_reserved_mask(PCIBus *bus, uint32_t mask); void pci_bus_clear_slot_reserved_mask(PCIBus *bus, uint32_t mask); +bool pci_bus_add_fw_cfg_extra_pci_roots(FWCfgState *fw_cfg, + PCIBus *bus, + Error **errp); /* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */ static inline int pci_swizzle(int slot, int pin) { @@ -363,6 +377,28 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range); void pci_device_deassert_intx(PCIDevice *dev); +/* Page Request Interface */ +typedef enum { + IOMMU_PRI_RESP_SUCCESS, + IOMMU_PRI_RESP_INVALID_REQUEST, + IOMMU_PRI_RESP_FAILURE, +} IOMMUPRIResponseCode; + +typedef struct IOMMUPRIResponse { + IOMMUPRIResponseCode response_code; + uint16_t prgi; +} IOMMUPRIResponse; + +struct IOMMUPRINotifier; + +typedef void (*IOMMUPRINotify)(struct IOMMUPRINotifier *notifier, + IOMMUPRIResponse *response); + +typedef struct IOMMUPRINotifier { + IOMMUPRINotify notify; +} IOMMUPRINotifier; + +#define PCI_PRI_PRGI_MASK 0x1ffU /** * struct PCIIOMMUOps: callbacks structure for specific IOMMU handlers @@ -417,6 +453,179 @@ typedef struct PCIIOMMUOps { * @devfn: device and function number of the PCI device. */ void (*unset_iommu_device)(PCIBus *bus, void *opaque, int devfn); + /** + * @get_iotlb_info: get properties required to initialize a device IOTLB. + * + * Callback required if devices are allowed to cache translations. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @addr_width: the address width of the IOMMU (output parameter). + * + * @min_page_size: the page size of the IOMMU (output parameter). + */ + void (*get_iotlb_info)(void *opaque, uint8_t *addr_width, + uint32_t *min_page_size); + /** + * @init_iotlb_notifier: initialize an IOMMU notifier. + * + * Optional callback. + * + * @bus: the #PCIBus of the PCI device. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @devfn: device and function number of the PCI device. + * + * @n: the notifier to be initialized. + * + * @fn: the callback to be installed. + * + * @user_opaque: a user pointer that can be used to track a state. + */ + void (*init_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn, + IOMMUNotifier *n, IOMMUNotify fn, + void *user_opaque); + /** + * @register_iotlb_notifier: setup an IOTLB invalidation notifier. + * + * Callback required if devices are allowed to cache translations. + * + * @bus: the #PCIBus of the PCI device. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @devfn: device and function number of the PCI device. + * + * @pasid: the pasid of the address space to watch. + * + * @n: the notifier to register. + */ + void (*register_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn, + uint32_t pasid, IOMMUNotifier *n); + /** + * @unregister_iotlb_notifier: remove an IOTLB invalidation notifier. + * + * Callback required if devices are allowed to cache translations. + * + * @bus: the #PCIBus of the PCI device. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @devfn: device and function number of the PCI device. + * + * @pasid: the pasid of the address space to stop watching. + * + * @n: the notifier to unregister. + */ + void (*unregister_iotlb_notifier)(PCIBus *bus, void *opaque, int devfn, + uint32_t pasid, IOMMUNotifier *n); + /** + * @ats_request_translation: issue an ATS request. + * + * Callback required if devices are allowed to use the address + * translation service. + * + * @bus: the #PCIBus of the PCI device. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @devfn: device and function number of the PCI device. + * + * @pasid: the pasid of the address space to use for the request. + * + * @priv_req: privileged mode bit (PASID TLP). + * + * @exec_req: execute request bit (PASID TLP). + * + * @addr: start address of the memory range to be translated. + * + * @length: length of the memory range in bytes. + * + * @no_write: request a read-only translation (if supported). + * + * @result: buffer in which the TLB entries will be stored. + * + * @result_length: result buffer length. + * + * @err_count: number of untranslated subregions. + * + * Returns: the number of translations stored in the result buffer, or + * -ENOMEM if the buffer is not large enough. + */ + ssize_t (*ats_request_translation)(PCIBus *bus, void *opaque, int devfn, + uint32_t pasid, bool priv_req, + bool exec_req, hwaddr addr, + size_t length, bool no_write, + IOMMUTLBEntry *result, + size_t result_length, + uint32_t *err_count); + /** + * @pri_register_notifier: setup the PRI completion callback. + * + * Callback required if devices are allowed to use the page request + * interface. + * + * @bus: the #PCIBus of the PCI device. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @devfn: device and function number of the PCI device. + * + * @pasid: the pasid of the address space to track. + * + * @notifier: the notifier to register. + */ + void (*pri_register_notifier)(PCIBus *bus, void *opaque, int devfn, + uint32_t pasid, IOMMUPRINotifier *notifier); + /** + * @pri_unregister_notifier: remove the PRI completion callback. + * + * Callback required if devices are allowed to use the page request + * interface. + * + * @bus: the #PCIBus of the PCI device. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @devfn: device and function number of the PCI device. + * + * @pasid: the pasid of the address space to stop tracking. + */ + void (*pri_unregister_notifier)(PCIBus *bus, void *opaque, int devfn, + uint32_t pasid); + /** + * @pri_request_page: issue a PRI request. + * + * Callback required if devices are allowed to use the page request + * interface. + * + * @bus: the #PCIBus of the PCI device. + * + * @opaque: the data passed to pci_setup_iommu(). + * + * @devfn: device and function number of the PCI device. + * + * @pasid: the pasid of the address space to use for the request. + * + * @priv_req: privileged mode bit (PASID TLP). + * + * @exec_req: execute request bit (PASID TLP). + * + * @addr: untranslated address of the requested page. + * + * @lpig: last page in group. + * + * @prgi: page request group index. + * + * @is_read: request read access. + * + * @is_write: request write access. + */ + int (*pri_request_page)(PCIBus *bus, void *opaque, int devfn, + uint32_t pasid, bool priv_req, bool exec_req, + hwaddr addr, bool lpig, uint16_t prgi, bool is_read, + bool is_write); } PCIIOMMUOps; AddressSpace *pci_device_iommu_address_space(PCIDevice *dev); @@ -425,6 +634,126 @@ bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod, void pci_device_unset_iommu_device(PCIDevice *dev); /** + * pci_iommu_get_iotlb_info: get properties required to initialize a + * device IOTLB. + * + * Returns 0 on success, or a negative errno otherwise. + * + * @dev: the device that wants to get the information. + * @addr_width: the address width of the IOMMU (output parameter). + * @min_page_size: the page size of the IOMMU (output parameter). + */ +int pci_iommu_get_iotlb_info(PCIDevice *dev, uint8_t *addr_width, + uint32_t *min_page_size); + +/** + * pci_iommu_init_iotlb_notifier: initialize an IOMMU notifier. + * + * This function is used by devices before registering an IOTLB notifier. + * + * @dev: the device. + * @n: the notifier to be initialized. + * @fn: the callback to be installed. + * @opaque: a user pointer that can be used to track a state. + */ +int pci_iommu_init_iotlb_notifier(PCIDevice *dev, IOMMUNotifier *n, + IOMMUNotify fn, void *opaque); + +/** + * pci_ats_request_translation: perform an ATS request. + * + * Returns the number of translations stored in @result in case of success, + * a negative error code otherwise. + * -ENOMEM is returned when the result buffer is not large enough to store + * all the translations. + * + * @dev: the ATS-capable PCI device. + * @pasid: the pasid of the address space in which the translation will be done. + * @priv_req: privileged mode bit (PASID TLP). + * @exec_req: execute request bit (PASID TLP). + * @addr: start address of the memory range to be translated. + * @length: length of the memory range in bytes. + * @no_write: request a read-only translation (if supported). + * @result: buffer in which the TLB entries will be stored. + * @result_length: result buffer length. + * @err_count: number of untranslated subregions. + */ +ssize_t pci_ats_request_translation(PCIDevice *dev, uint32_t pasid, + bool priv_req, bool exec_req, + hwaddr addr, size_t length, + bool no_write, IOMMUTLBEntry *result, + size_t result_length, + uint32_t *err_count); + +/** + * pci_pri_request_page: perform a PRI request. + * + * Returns 0 if the PRI request has been sent to the guest OS, + * an error code otherwise. + * + * @dev: the PRI-capable PCI device. + * @pasid: the pasid of the address space in which the translation will be done. + * @priv_req: privileged mode bit (PASID TLP). + * @exec_req: execute request bit (PASID TLP). + * @addr: untranslated address of the requested page. + * @lpig: last page in group. + * @prgi: page request group index. + * @is_read: request read access. + * @is_write: request write access. + */ +int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req, + bool exec_req, hwaddr addr, bool lpig, + uint16_t prgi, bool is_read, bool is_write); + +/** + * pci_pri_register_notifier: register the PRI callback for a given address + * space. + * + * Returns 0 on success, an error code otherwise. + * + * @dev: the PRI-capable PCI device. + * @pasid: the pasid of the address space to track. + * @notifier: the notifier to register. + */ +int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid, + IOMMUPRINotifier *notifier); + +/** + * pci_pri_unregister_notifier: remove the PRI callback from a given address + * space. + * + * @dev: the PRI-capable PCI device. + * @pasid: the pasid of the address space to stop tracking. + */ +void pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid); + +/** + * pci_iommu_register_iotlb_notifier: register a notifier for changes to + * IOMMU translation entries in a specific address space. + * + * Returns 0 on success, or a negative errno otherwise. + * + * @dev: the device that wants to get notified. + * @pasid: the pasid of the address space to track. + * @n: the notifier to register. + */ +int pci_iommu_register_iotlb_notifier(PCIDevice *dev, uint32_t pasid, + IOMMUNotifier *n); + +/** + * pci_iommu_unregister_iotlb_notifier: unregister a notifier that has been + * registerd with pci_iommu_register_iotlb_notifier. + * + * Returns 0 on success, or a negative errno otherwise. + * + * @dev: the device that wants to stop notifications. + * @pasid: the pasid of the address space to stop tracking. + * @n: the notifier to unregister. + */ +int pci_iommu_unregister_iotlb_notifier(PCIDevice *dev, uint32_t pasid, + IOMMUNotifier *n); + +/** * pci_setup_iommu: Initialize specific IOMMU handlers for a PCIBus * * Let PCI host bridges define specific operations. @@ -656,6 +985,7 @@ void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev); qemu_irq pci_allocate_irq(PCIDevice *pci_dev); void pci_set_irq(PCIDevice *pci_dev, int level); +int pci_irq_disabled(PCIDevice *d); static inline void pci_irq_assert(PCIDevice *pci_dev) { @@ -667,17 +997,9 @@ static inline void pci_irq_deassert(PCIDevice *pci_dev) pci_set_irq(pci_dev, 0); } -/* - * FIXME: PCI does not work this way. - * All the callers to this method should be fixed. - */ -static inline void pci_irq_pulse(PCIDevice *pci_dev) -{ - pci_irq_assert(pci_dev); - pci_irq_deassert(pci_dev); -} - MSIMessage pci_get_msi_message(PCIDevice *dev, int vector); +void pci_set_enabled(PCIDevice *pci_dev, bool state); void pci_set_power(PCIDevice *pci_dev, bool state); +int pci_pm_init(PCIDevice *pci_dev, uint8_t offset, Error **errp); #endif diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h index 5cd4521..8cdacbc 100644 --- a/include/hw/pci/pci_bridge.h +++ b/include/hw/pci/pci_bridge.h @@ -14,8 +14,8 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see + * <https://www.gnu.org/licenses/>. * * split out pci bus specific stuff from pci.[hc] to pci_bridge.[hc] * Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp> @@ -72,6 +72,8 @@ struct PCIBridge { */ MemoryRegion address_space_mem; MemoryRegion address_space_io; + AddressSpace as_mem; + AddressSpace as_io; PCIBridgeWindows windows; @@ -102,6 +104,7 @@ typedef struct PXBPCIEDev { PXBDev parent_obj; } PXBPCIEDev; +#define TYPE_PXB_CXL_BUS "pxb-cxl-bus" #define TYPE_PXB_DEV "pxb" OBJECT_DECLARE_SIMPLE_TYPE(PXBDev, PXB_DEV) diff --git a/include/hw/pci/pci_device.h b/include/hw/pci/pci_device.h index 15694f2..eee0338 100644 --- a/include/hw/pci/pci_device.h +++ b/include/hw/pci/pci_device.h @@ -38,6 +38,8 @@ struct PCIDeviceClass { uint16_t subsystem_id; /* only for header type = 0 */ const char *romfile; /* rom bar */ + + bool sriov_vf_user_creatable; }; enum PCIReqIDType { @@ -57,7 +59,7 @@ typedef struct PCIReqIDCache PCIReqIDCache; struct PCIDevice { DeviceState qdev; bool partially_hotplugged; - bool has_power; + bool enabled; /* PCI config space */ uint8_t *config; @@ -88,6 +90,7 @@ struct PCIDevice { char name[64]; PCIIORegion io_regions[PCI_NUM_REGIONS]; AddressSpace bus_master_as; + bool is_master; MemoryRegion bus_master_container_region; MemoryRegion bus_master_enable_region; @@ -105,6 +108,9 @@ struct PCIDevice { /* Capability bits */ uint32_t cap_present; + /* Offset of PM capability in config space */ + uint8_t pm_cap; + /* Offset of MSI-X capability in config space */ uint8_t msix_cap; @@ -148,7 +154,7 @@ struct PCIDevice { uint32_t romsize; bool has_rom; MemoryRegion rom; - uint32_t rom_bar; + int32_t rom_bar; /* INTx routing notifier */ PCIINTxRoutingNotifier intx_routing_notifier; @@ -167,6 +173,15 @@ struct PCIDevice { /* ID of standby device in net_failover pair */ char *failover_pair_id; uint32_t acpi_index; + + /* + * Indirect DMA region bounce buffer size as configured for the device. This + * is a configuration parameter that is reflected into bus_master_as when + * realizing the device. + */ + uint32_t max_bounce_buffer_size; + + char *sriov_pf; }; static inline int pci_intx(PCIDevice *pci_dev) @@ -199,7 +214,7 @@ static inline int pci_is_express_downstream_port(const PCIDevice *d) static inline int pci_is_vf(const PCIDevice *d) { - return d->exp.sriov_vf.pf != NULL; + return d->sriov_pf || d->exp.sriov_vf.pf != NULL; } static inline uint32_t pci_config_size(const PCIDevice *d) diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h index e52d8ec..954dd44 100644 --- a/include/hw/pci/pci_host.h +++ b/include/hw/pci/pci_host.h @@ -68,6 +68,5 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, unsigned len); extern const MemoryRegionOps pci_host_conf_le_ops; extern const MemoryRegionOps pci_host_conf_be_ops; extern const MemoryRegionOps pci_host_data_le_ops; -extern const MemoryRegionOps pci_host_data_be_ops; #endif /* PCI_HOST_H */ diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index f1a53fe..33e2898 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -191,6 +191,7 @@ #define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020 #define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021 +#define PCI_DEVICE_ID_APPLE_VIRTIO_BLK 0x1a00 #define PCI_VENDOR_ID_SUN 0x108e #define PCI_DEVICE_ID_SUN_EBUS 0x1000 diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index 5eddb90..ff6ce08 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -58,8 +58,6 @@ typedef enum { struct PCIExpressDevice { /* Offset of express capability in config space */ uint8_t exp_cap; - /* Offset of Power Management capability in config space */ - uint8_t pm_cap; /* SLOT */ bool hpev_notified; /* Logical AND of conditions for hot plug event. @@ -72,8 +70,10 @@ struct PCIExpressDevice { uint16_t aer_cap; PCIEAERLog aer_log; - /* Offset of ATS capability in config space */ + /* Offset of ATS, PRI and PASID capabilities in config space */ uint16_t ats_cap; + uint16_t pasid_cap; + uint16_t pri_cap; /* ACS */ uint16_t acs_cap; @@ -141,6 +141,8 @@ void pcie_acs_reset(PCIDevice *dev); void pcie_ari_init(PCIDevice *dev, uint16_t offset); void pcie_dev_ser_num_init(PCIDevice *dev, uint16_t offset, uint64_t ser_num); void pcie_ats_init(PCIDevice *dev, uint16_t offset, bool aligned); +void pcie_cap_fill_link_ep_usp(PCIDevice *dev, PCIExpLinkWidth width, + PCIExpLinkSpeed speed); void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); @@ -150,4 +152,13 @@ void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); + +void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width, + bool exec_perm, bool priv_mod); +void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap, + bool prg_response_pasid_req); + +bool pcie_pri_enabled(const PCIDevice *dev); +bool pcie_pasid_enabled(const PCIDevice *dev); +bool pcie_ats_enabled(const PCIDevice *dev); #endif /* QEMU_PCIE_H */ diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index 82d9217..f09de76 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -22,7 +22,7 @@ #define PCIE_HOST_H #include "hw/pci/pci_host.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qom/object.h" #define TYPE_PCIE_HOST_BRIDGE "pcie-host-bridge" diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index 90e6cf4..7cd7af8 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -72,7 +72,6 @@ struct PCIESlot { }; void pcie_chassis_create(uint8_t chassis_number); -PCIESlot *pcie_chassis_find_slot(uint8_t chassis, uint16_t slot); int pcie_chassis_add_slot(struct PCIESlot *slot); void pcie_chassis_del_slot(PCIESlot *s); diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h index 9d3b686..33a2222 100644 --- a/include/hw/pci/pcie_regs.h +++ b/include/hw/pci/pcie_regs.h @@ -86,6 +86,14 @@ typedef enum PCIExpLinkWidth { #define PCI_ARI_VER 1 #define PCI_ARI_SIZEOF 8 +/* PASID */ +#define PCI_PASID_VER 1 +#define PCI_EXT_CAP_PASID_MAX_WIDTH 20 +#define PCI_PASID_CAP_WIDTH_SHIFT 8 + +/* PRI */ +#define PCI_PRI_VER 1 + /* AER */ #define PCI_ERR_VER 2 #define PCI_ERR_SIZEOF 0x48 diff --git a/include/hw/pci/pcie_sriov.h b/include/hw/pci/pcie_sriov.h index 450cbef..aeaa38c 100644 --- a/include/hw/pci/pcie_sriov.h +++ b/include/hw/pci/pcie_sriov.h @@ -16,10 +16,9 @@ #include "hw/pci/pci.h" typedef struct PCIESriovPF { - uint16_t num_vfs; /* Number of virtual functions created */ uint8_t vf_bar_type[PCI_NUM_REGIONS]; /* Store type for each VF bar */ - const char *vfname; /* Reference to the device type used for the VFs */ PCIDevice **vf; /* Pointer to an array of num_vfs VF devices */ + bool vf_user_created; /* If VFs are created by user */ } PCIESriovPF; typedef struct PCIESriovVF { @@ -27,10 +26,11 @@ typedef struct PCIESriovVF { uint16_t vf_number; /* Logical VF number of this function */ } PCIESriovVF; -void pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset, +bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset, const char *vfname, uint16_t vf_dev_id, uint16_t init_vfs, uint16_t total_vfs, - uint16_t vf_offset, uint16_t vf_stride); + uint16_t vf_offset, uint16_t vf_stride, + Error **errp); void pcie_sriov_pf_exit(PCIDevice *dev); /* Set up a VF bar in the SR/IOV bar area */ @@ -41,6 +41,26 @@ void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num, void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num, MemoryRegion *memory); +/** + * pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created + * VFs, adding ARI to PF + * @dev: A PCIe device being realized. + * @offset: The offset of the SR-IOV capability. + * @errp: pointer to Error*, to store an error if it happens. + * + * Initializes a PF with user-created VFs, adding the ARI extended capability to + * the PF. The VFs should call pcie_ari_init() to form an ARI device. + * + * Return: The size of added capabilities. 0 if the user did not create VFs. + * -1 if failed. + */ +int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev, + uint16_t offset, + Error **errp); + +bool pcie_sriov_register_device(PCIDevice *dev, Error **errp); +void pcie_sriov_unregister_device(PCIDevice *dev); + /* * Default (minimal) page size support values * as required by the SR/IOV standard: @@ -58,6 +78,8 @@ void pcie_sriov_pf_add_sup_pgsize(PCIDevice *dev, uint16_t opt_sup_pgsize); void pcie_sriov_config_write(PCIDevice *dev, uint32_t address, uint32_t val, int len); +void pcie_sriov_pf_post_load(PCIDevice *dev); + /* Reset SR/IOV */ void pcie_sriov_pf_reset(PCIDevice *dev); diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h index a0789df..ad10895 100644 --- a/include/hw/pci/shpc.h +++ b/include/hw/pci/shpc.h @@ -1,7 +1,7 @@ #ifndef SHPC_H #define SHPC_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/hotplug.h" #include "hw/pci/pci_device.h" #include "migration/vmstate.h" diff --git a/include/hw/pcmcia.h b/include/hw/pcmcia.h deleted file mode 100644 index ab26802..0000000 --- a/include/hw/pcmcia.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef HW_PCMCIA_H -#define HW_PCMCIA_H - -/* PCMCIA/Cardbus */ - -#include "hw/qdev-core.h" -#include "qom/object.h" - -typedef struct PCMCIASocket { - qemu_irq irq; - bool attached; -} PCMCIASocket; - -#define TYPE_PCMCIA_CARD "pcmcia-card" -OBJECT_DECLARE_TYPE(PCMCIACardState, PCMCIACardClass, PCMCIA_CARD) - -struct PCMCIACardState { - /*< private >*/ - DeviceState parent_obj; - /*< public >*/ - - PCMCIASocket *slot; -}; - -struct PCMCIACardClass { - /*< private >*/ - DeviceClass parent_class; - /*< public >*/ - - int (*attach)(PCMCIACardState *state); - int (*detach)(PCMCIACardState *state); - - const uint8_t *cis; - int cis_len; - - /* Only valid if attached */ - uint8_t (*attr_read)(PCMCIACardState *card, uint32_t address); - void (*attr_write)(PCMCIACardState *card, uint32_t address, uint8_t value); - uint16_t (*common_read)(PCMCIACardState *card, uint32_t address); - void (*common_write)(PCMCIACardState *card, - uint32_t address, uint16_t value); - uint16_t (*io_read)(PCMCIACardState *card, uint32_t address); - void (*io_write)(PCMCIACardState *card, uint32_t address, uint16_t value); -}; - -#define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */ -#define CISTPL_NO_LINK 0x14 /* No Link Tuple */ -#define CISTPL_VERS_1 0x15 /* Level 1 Version Tuple */ -#define CISTPL_JEDEC_C 0x18 /* JEDEC ID Tuple */ -#define CISTPL_JEDEC_A 0x19 /* JEDEC ID Tuple */ -#define CISTPL_CONFIG 0x1a /* Configuration Tuple */ -#define CISTPL_CFTABLE_ENTRY 0x1b /* 16-bit PCCard Configuration */ -#define CISTPL_DEVICE_OC 0x1c /* Additional Device Information */ -#define CISTPL_DEVICE_OA 0x1d /* Additional Device Information */ -#define CISTPL_DEVICE_GEO 0x1e /* Additional Device Information */ -#define CISTPL_DEVICE_GEO_A 0x1f /* Additional Device Information */ -#define CISTPL_MANFID 0x20 /* Manufacture ID Tuple */ -#define CISTPL_FUNCID 0x21 /* Function ID Tuple */ -#define CISTPL_FUNCE 0x22 /* Function Extension Tuple */ -#define CISTPL_END 0xff /* Tuple End */ -#define CISTPL_ENDMARK 0xff - -/* dscm1xxxx.c */ -PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv); - -#endif diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h index 4a3f644..896ee4a 100644 --- a/include/hw/ppc/mac_dbdma.h +++ b/include/hw/ppc/mac_dbdma.h @@ -23,9 +23,9 @@ #ifndef HW_MAC_DBDMA_H #define HW_MAC_DBDMA_H -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/iov.h" -#include "sysemu/dma.h" +#include "system/dma.h" #include "hw/sysbus.h" #include "qom/object.h" @@ -44,10 +44,6 @@ struct DBDMA_io { DBDMA_end dma_end; /* DMA is in progress, don't start another one */ bool processing; - /* DMA request */ - void *dma_mem; - dma_addr_t dma_len; - DMADirection dir; }; /* diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index fcb6699..d8fca07 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -205,9 +205,8 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor); #define PNV9_OCC_SENSOR_BASE(chip) (PNV9_OCC_COMMON_AREA_BASE + \ PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id)) -#define PNV9_HOMER_SIZE 0x0000000000400000ull #define PNV9_HOMER_BASE(chip) \ - (0x203ffd800000ull + ((uint64_t)(chip)->chip_id) * PNV9_HOMER_SIZE) + (0x203ffd800000ull + ((uint64_t)(chip)->chip_id) * PNV_HOMER_SIZE) /* * POWER10 MMIO base addresses - 16TB stride per chip @@ -250,8 +249,7 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor); #define PNV10_OCC_SENSOR_BASE(chip) (PNV10_OCC_COMMON_AREA_BASE + \ PNV_OCC_SENSOR_DATA_BLOCK_BASE((chip)->chip_id)) -#define PNV10_HOMER_SIZE 0x0000000000400000ull #define PNV10_HOMER_BASE(chip) \ - (0x300ffd800000ll + ((uint64_t)(chip)->chip_id) * PNV10_HOMER_SIZE) + (0x300ffd800000ll + ((uint64_t)(chip)->chip_id) * PNV_HOMER_SIZE) #endif /* PPC_PNV_H */ diff --git a/include/hw/ppc/pnv_homer.h b/include/hw/ppc/pnv_homer.h index b1c5d49..a6f2710 100644 --- a/include/hw/ppc/pnv_homer.h +++ b/include/hw/ppc/pnv_homer.h @@ -41,19 +41,21 @@ struct PnvHomer { PnvChip *chip; MemoryRegion pba_regs; - MemoryRegion regs; + MemoryRegion mem; + hwaddr base; }; struct PnvHomerClass { DeviceClass parent_class; + /* Get base address of HOMER memory */ + hwaddr (*get_base)(PnvChip *chip); + /* Size of HOMER memory */ + int size; + int pba_size; const MemoryRegionOps *pba_ops; - int homer_size; - const MemoryRegionOps *homer_ops; - - hwaddr core_max_base; }; #endif /* PPC_PNV_HOMER_H */ diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h index 174add4..266d562 100644 --- a/include/hw/ppc/pnv_lpc.h +++ b/include/hw/ppc/pnv_lpc.h @@ -20,7 +20,7 @@ #ifndef PPC_PNV_LPC_H #define PPC_PNV_LPC_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/ppc/pnv.h" #include "hw/qdev-core.h" #include "hw/isa/isa.h" /* For ISA_NUM_IRQS */ diff --git a/include/hw/ppc/pnv_occ.h b/include/hw/ppc/pnv_occ.h index df32124..013ea2e 100644 --- a/include/hw/ppc/pnv_occ.h +++ b/include/hw/ppc/pnv_occ.h @@ -20,7 +20,7 @@ #ifndef PPC_PNV_OCC_H #define PPC_PNV_OCC_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #define TYPE_PNV_OCC "pnv-occ" @@ -41,11 +41,17 @@ DECLARE_INSTANCE_CHECKER(PnvOCC, PNV10_OCC, TYPE_PNV10_OCC) struct PnvOCC { DeviceState xd; + /* OCC dynamic model is driven by this timer. */ + QEMUTimer state_machine_timer; + /* OCC Misc interrupt */ uint64_t occmisc; qemu_irq psi_irq; + /* OCCs operate on regions of HOMER memory */ + PnvHomer *homer; + MemoryRegion xscom_regs; MemoryRegion sram_regs; }; @@ -53,6 +59,9 @@ struct PnvOCC { struct PnvOCCClass { DeviceClass parent_class; + hwaddr opal_shared_memory_offset; /* offset in HOMER */ + uint8_t opal_shared_memory_version; + int xscom_size; const MemoryRegionOps *xscom_ops; }; diff --git a/include/hw/ppc/pnv_pnor.h b/include/hw/ppc/pnv_pnor.h index 2e37ac8..b44cafe 100644 --- a/include/hw/ppc/pnv_pnor.h +++ b/include/hw/ppc/pnv_pnor.h @@ -13,9 +13,11 @@ #include "hw/sysbus.h" /* - * PNOR offset on the LPC FW address space + * PNOR offset on the LPC FW address space. For now this should be 0 because + * skiboot 7.1 has a bug where IDSEL > 0 (LPC FW address > 256MB) access is + * not performed correctly. */ -#define PNOR_SPI_OFFSET 0x0c000000UL +#define PNOR_SPI_OFFSET 0x00000000UL #define TYPE_PNV_PNOR "pnv-pnor" OBJECT_DECLARE_SIMPLE_TYPE(PnvPnor, PNV_PNOR) @@ -26,6 +28,7 @@ struct PnvPnor { BlockBackend *blk; uint8_t *storage; + uint32_t lpc_address; /* Offset within LPC FW space */ int64_t size; MemoryRegion mmio; }; diff --git a/include/hw/ppc/pnv_sbe.h b/include/hw/ppc/pnv_sbe.h index b6b378a..48a8b86 100644 --- a/include/hw/ppc/pnv_sbe.h +++ b/include/hw/ppc/pnv_sbe.h @@ -20,7 +20,7 @@ #ifndef PPC_PNV_SBE_H #define PPC_PNV_SBE_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #define TYPE_PNV_SBE "pnv-sbe" diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h index 648388a..b14549d 100644 --- a/include/hw/ppc/pnv_xscom.h +++ b/include/hw/ppc/pnv_xscom.h @@ -20,7 +20,7 @@ #ifndef PPC_PNV_XSCOM_H #define PPC_PNV_XSCOM_H -#include "exec/memory.h" +#include "system/memory.h" typedef struct PnvXScomInterface PnvXScomInterface; typedef struct PnvChip PnvChip; @@ -126,6 +126,8 @@ struct PnvXScomInterfaceClass { #define PNV9_XSCOM_PEC_PCI_BASE 0xd010800 #define PNV9_XSCOM_PEC_PCI_SIZE 0x200 +#define PNV9_XSCOM_PEC_NEST_CPLT_BASE 0x0d000000 + /* XSCOM PCI "pass-through" window to PHB SCOM */ #define PNV9_XSCOM_PEC_PCI_STK0 0x100 #define PNV9_XSCOM_PEC_PCI_STK1 0x140 @@ -197,6 +199,8 @@ struct PnvXScomInterfaceClass { #define PNV10_XSCOM_PEC_NEST_BASE 0x3011800 /* index goes downwards ... */ #define PNV10_XSCOM_PEC_NEST_SIZE 0x100 +#define PNV10_XSCOM_PEC_NEST_CPLT_BASE 0x08000000 + #define PNV10_XSCOM_PEC_PCI_BASE 0x8010800 /* index goes upwards ... */ #define PNV10_XSCOM_PEC_PCI_SIZE 0x200 diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h index d5d119e..8a14d62 100644 --- a/include/hw/ppc/ppc.h +++ b/include/hw/ppc/ppc.h @@ -116,6 +116,13 @@ enum { #define PPC_SERIAL_MM_BAUDBASE 399193 +#ifndef CONFIG_USER_ONLY +void booke206_set_tlb(ppcmas_tlb_t *tlb, target_ulong va, hwaddr pa, + hwaddr len); +void booke_set_tlb(ppcemb_tlb_t *tlb, target_ulong va, hwaddr pa, + target_ulong size); +#endif + /* ppc_booke.c */ void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags); #endif diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h index 1bd9b88..2e94b00 100644 --- a/include/hw/ppc/ppc4xx.h +++ b/include/hw/ppc/ppc4xx.h @@ -26,7 +26,7 @@ #define PPC4XX_H #include "hw/ppc/ppc.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" /* diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index f6de3e9..39bd5bd 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -2,7 +2,7 @@ #define HW_SPAPR_H #include "qemu/units.h" -#include "sysemu/dma.h" +#include "system/dma.h" #include "hw/boards.h" #include "hw/ppc/spapr_drc.h" #include "hw/mem/pc-dimm.h" @@ -83,8 +83,10 @@ typedef enum { #define SPAPR_CAP_AIL_MODE_3 0x0C /* Nested PAPR */ #define SPAPR_CAP_NESTED_PAPR 0x0D +/* DAWR1 */ +#define SPAPR_CAP_DAWR1 0x0E /* Num Caps */ -#define SPAPR_CAP_NUM (SPAPR_CAP_NESTED_PAPR + 1) +#define SPAPR_CAP_NUM (SPAPR_CAP_DAWR1 + 1) /* * Capability Values @@ -141,11 +143,8 @@ struct SpaprMachineClass { MachineClass parent_class; /*< public >*/ - bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ bool dr_phb_enabled; /* enable dynamic-reconfig/hotplug of PHBs */ bool update_dt_enabled; /* enable KVMPPC_H_UPDATE_DT */ - bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ - bool pre_2_10_has_unused_icps; bool legacy_irq_allocation; uint32_t nr_xirqs; bool broken_host_serial_model; /* present real host info to the guest */ @@ -204,6 +203,7 @@ struct SpaprMachineState { uint32_t fdt_initial_size; void *fdt_blob; uint8_t fdt_rng_seed[32]; + uint64_t hashpkey_val; long kernel_size; bool kernel_le; uint64_t kernel_addr; @@ -409,6 +409,7 @@ struct SpaprMachineState { #define H_SET_MODE_RESOURCE_SET_DAWR0 2 #define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 #define H_SET_MODE_RESOURCE_LE 4 +#define H_SET_MODE_RESOURCE_SET_DAWR1 5 /* Flags for H_SET_MODE_RESOURCE_LE */ #define H_SET_MODE_ENDIAN_BIG 0 @@ -1006,6 +1007,7 @@ extern const VMStateDescription vmstate_spapr_cap_fwnmi; extern const VMStateDescription vmstate_spapr_cap_rpt_invalidate; extern const VMStateDescription vmstate_spapr_cap_ail_mode_3; extern const VMStateDescription vmstate_spapr_wdt; +extern const VMStateDescription vmstate_spapr_cap_dawr1; static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap) { diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 69a52e3..68f7083 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -28,7 +28,6 @@ struct SpaprCpuCore { /*< public >*/ PowerPCCPU **threads; int node_id; - bool pre_3_0_migration; /* older machine don't know about SpaprCpuState */ }; struct SpaprCpuCoreClass { diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index 02a63b3..9ff4290 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -15,7 +15,7 @@ #include <libfdt.h> #include "qom/object.h" -#include "sysemu/runstate.h" +#include "system/runstate.h" #include "hw/qdev-core.h" #include "qapi/error.h" diff --git a/include/hw/ppc/spapr_nested.h b/include/hw/ppc/spapr_nested.h index 93ef14a..f7be0d5 100644 --- a/include/hw/ppc/spapr_nested.h +++ b/include/hw/ppc/spapr_nested.h @@ -11,7 +11,13 @@ #define GSB_TB_OFFSET 0x0004 /* Timebase Offset */ #define GSB_PART_SCOPED_PAGETBL 0x0005 /* Partition Scoped Page Table */ #define GSB_PROCESS_TBL 0x0006 /* Process Table */ - /* RESERVED 0x0007 - 0x0BFF */ + /* RESERVED 0x0007 - 0x07FF */ +#define GSB_L0_GUEST_HEAP_INUSE 0x0800 /* Guest Management Heap Size */ +#define GSB_L0_GUEST_HEAP_MAX 0x0801 /* Guest Management Heap Max Size */ +#define GSB_L0_GUEST_PGTABLE_SIZE_INUSE 0x0802 /* Guest Pagetable Size */ +#define GSB_L0_GUEST_PGTABLE_SIZE_MAX 0x0803 /* Guest Pagetable Max Size */ +#define GSB_L0_GUEST_PGTABLE_RECLAIMED 0x0804 /* Pagetable Reclaim in bytes */ + /* RESERVED 0x0805 - 0xBFF */ #define GSB_VCPU_IN_BUFFER 0x0C00 /* Run VCPU Input Buffer */ #define GSB_VCPU_OUT_BUFFER 0x0C01 /* Run VCPU Out Buffer */ #define GSB_VCPU_VPA 0x0C02 /* HRA to Guest VCPU VPA */ @@ -99,7 +105,8 @@ #define GSB_VCPU_SPR_HASHKEYR 0x1050 #define GSB_VCPU_SPR_HASHPKEYR 0x1051 #define GSB_VCPU_SPR_CTRL 0x1052 - /* RESERVED 0x1053 - 0x1FFF */ +#define GSB_VCPU_SPR_DPDES 0x1053 + /* RESERVED 0x1054 - 0x1FFF */ #define GSB_VCPU_SPR_CR 0x2000 #define GSB_VCPU_SPR_PIDR 0x2001 #define GSB_VCPU_SPR_DSISR 0x2002 @@ -195,6 +202,38 @@ typedef struct SpaprMachineStateNested { #define NESTED_API_PAPR 2 bool capabilities_set; uint32_t pvr_base; + + /** + * l0_guest_heap_inuse: The currently used bytes in the Hypervisor's Guest + * Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_heap_inuse; + + /** + * host_heap_max: The maximum bytes available in the Hypervisor's Guest + * Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_heap_max; + + /** + * host_pagetable: The currently used bytes in the Hypervisor's Guest + * Page Table Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_pgtable_size_inuse; + + /** + * host_pagetable_max: The maximum bytes available in the Hypervisor's Guest + * Page Table Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_pgtable_size_max; + + /** + * host_pagetable_reclaim: The amount of space in bytes that has been + * reclaimed due to overcommit in the Hypervisor's Guest Page Table + * Management Space associated with the Host Partition. + **/ + uint64_t l0_guest_pgtable_reclaimed; + GHashTable *guests; } SpaprMachineStateNested; @@ -210,11 +249,14 @@ typedef struct SpaprMachineStateNestedGuest { #define H_GUEST_CAPABILITIES_COPY_MEM 0x8000000000000000 #define H_GUEST_CAPABILITIES_P9_MODE 0x4000000000000000 #define H_GUEST_CAPABILITIES_P10_MODE 0x2000000000000000 -#define H_GUEST_CAP_VALID_MASK (H_GUEST_CAPABILITIES_P10_MODE | \ +#define H_GUEST_CAPABILITIES_P11_MODE 0x1000000000000000 +#define H_GUEST_CAP_VALID_MASK (H_GUEST_CAPABILITIES_P11_MODE | \ + H_GUEST_CAPABILITIES_P10_MODE | \ H_GUEST_CAPABILITIES_P9_MODE) #define H_GUEST_CAP_COPY_MEM_BMAP 0 #define H_GUEST_CAP_P9_MODE_BMAP 1 #define H_GUEST_CAP_P10_MODE_BMAP 2 +#define H_GUEST_CAP_P11_MODE_BMAP 3 #define PAPR_NESTED_GUEST_MAX 4096 #define H_GUEST_DELETE_ALL_FLAG 0x8000000000000000ULL #define PAPR_NESTED_GUEST_VCPU_MAX 2048 @@ -225,9 +267,15 @@ typedef struct SpaprMachineStateNestedGuest { #define HVMASK_HDEXCR 0x00000000FFFFFFFF #define HVMASK_TB_OFFSET 0x000000FFFFFFFFFF #define GSB_MAX_BUF_SIZE (1024 * 1024) -#define H_GUEST_GETSET_STATE_FLAG_GUEST_WIDE 0x8000000000000000 -#define GUEST_STATE_REQUEST_GUEST_WIDE 0x1 -#define GUEST_STATE_REQUEST_SET 0x2 +#define H_GUEST_GET_STATE_FLAGS_MASK 0xC000000000000000ULL +#define H_GUEST_SET_STATE_FLAGS_MASK 0x8000000000000000ULL +#define H_GUEST_SET_STATE_FLAGS_GUEST_WIDE 0x8000000000000000ULL +#define H_GUEST_GET_STATE_FLAGS_GUEST_WIDE 0x8000000000000000ULL +#define H_GUEST_GET_STATE_FLAGS_HOST_WIDE 0x4000000000000000ULL + +#define GUEST_STATE_REQUEST_GUEST_WIDE 0x1 +#define GUEST_STATE_REQUEST_HOST_WIDE 0x2 +#define GUEST_STATE_REQUEST_SET 0x4 /* * As per ISA v3.1B, following bits are reserved: @@ -247,6 +295,15 @@ typedef struct SpaprMachineStateNestedGuest { .copy = (c) \ } +#define GSBE_NESTED_MACHINE_DW(i, f) { \ + .id = (i), \ + .size = 8, \ + .location = get_machine_ptr, \ + .offset = offsetof(struct SpaprMachineStateNested, f), \ + .copy = copy_state_8to8, \ + .mask = HVMASK_DEFAULT \ +} + #define GSBE_NESTED(i, sz, f, c) { \ .id = (i), \ .size = (sz), \ @@ -505,9 +562,11 @@ struct guest_state_element_type { uint16_t id; int size; #define GUEST_STATE_ELEMENT_TYPE_FLAG_GUEST_WIDE 0x1 -#define GUEST_STATE_ELEMENT_TYPE_FLAG_READ_ONLY 0x2 +#define GUEST_STATE_ELEMENT_TYPE_FLAG_HOST_WIDE 0x2 +#define GUEST_STATE_ELEMENT_TYPE_FLAG_READ_ONLY 0x4 uint16_t flags; - void *(*location)(SpaprMachineStateNestedGuest *, target_ulong); + void *(*location)(struct SpaprMachineState *, SpaprMachineStateNestedGuest *, + target_ulong); size_t offset; void (*copy)(void *, void *, bool); uint64_t mask; diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index 7eae1a4..b8de4b0 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -23,7 +23,7 @@ */ #include "hw/ppc/spapr.h" -#include "sysemu/dma.h" +#include "system/dma.h" #include "hw/irq.h" #include "qom/object.h" diff --git a/include/hw/ppc/vof.h b/include/hw/ppc/vof.h index d3f293d..3a0fbff 100644 --- a/include/hw/ppc/vof.h +++ b/include/hw/ppc/vof.h @@ -7,8 +7,8 @@ #define HW_VOF_H #include "qom/object.h" -#include "exec/address-spaces.h" -#include "exec/memory.h" +#include "system/address-spaces.h" +#include "system/memory.h" #include "exec/cpu-defs.h" typedef struct Vof { diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index e94d534..097fcdf 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -28,7 +28,7 @@ #ifndef XICS_H #define XICS_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "qom/object.h" diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 28c181f..538f438 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -130,17 +130,15 @@ * TCTX Thread interrupt Context * * - * Copyright (c) 2017-2018, IBM Corporation. - * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * Copyright (c) 2017-2024, IBM Corporation. * + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE_H #define PPC_XIVE_H -#include "sysemu/kvm.h" +#include "system/kvm.h" #include "hw/sysbus.h" #include "hw/ppc/xive_regs.h" #include "qom/object.h" @@ -218,7 +216,7 @@ static inline bool xive_source_esb_has_2page(XiveSource *xsrc) xsrc->esb_shift == XIVE_ESB_4K_2PAGE; } -static inline size_t xive_source_esb_len(XiveSource *xsrc) +static inline uint64_t xive_source_esb_len(XiveSource *xsrc) { return (1ull << xsrc->esb_shift) * xsrc->nr_irqs; } @@ -424,6 +422,7 @@ void xive_router_end_notify(XiveRouter *xrtr, XiveEAS *eas); typedef struct XiveTCTXMatch { XiveTCTX *tctx; uint8_t ring; + bool precluded; } XiveTCTXMatch; #define TYPE_XIVE_PRESENTER "xive-presenter" @@ -439,10 +438,13 @@ struct XivePresenterClass { InterfaceClass parent; int (*match_nvt)(XivePresenter *xptr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match); bool (*in_kernel)(const XivePresenter *xptr); uint32_t (*get_config)(XivePresenter *xptr); + int (*broadcast)(XivePresenter *xptr, + uint8_t nvt_blk, uint32_t nvt_idx, + bool crowd, bool cam_ignore, uint8_t priority); }; int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, @@ -451,8 +453,10 @@ int xive_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, bool cam_ignore, uint32_t logic_serv); bool xive_presenter_notify(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, - uint32_t logic_serv); + bool crowd, bool cam_ignore, uint8_t priority, + uint32_t logic_serv, bool *precluded); + +uint32_t xive_get_vpgroup_size(uint32_t nvp_index); /* * XIVE Fabric (Interface between Interrupt Controller and Machine) @@ -469,8 +473,10 @@ struct XiveFabricClass { InterfaceClass parent; int (*match_nvt)(XiveFabric *xfb, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint8_t priority, + bool crowd, bool cam_ignore, uint8_t priority, uint32_t logic_serv, XiveTCTXMatch *match); + int (*broadcast)(XiveFabric *xfb, uint8_t nvt_blk, uint32_t nvt_idx, + bool crowd, bool cam_ignore, uint8_t priority); }; /* @@ -510,6 +516,21 @@ static inline uint8_t xive_priority_to_ipb(uint8_t priority) 0 : 1 << (XIVE_PRIORITY_MAX - priority); } +static inline uint8_t xive_priority_to_pipr(uint8_t priority) +{ + return priority > XIVE_PRIORITY_MAX ? 0xFF : priority; +} + +/* + * Convert an Interrupt Pending Buffer (IPB) register to a Pending + * Interrupt Priority Register (PIPR), which contains the priority of + * the most favored pending notification. + */ +static inline uint8_t xive_ipb_to_pipr(uint8_t ibp) +{ + return ibp ? clz32((uint32_t)ibp << 24) : 0xff; +} + /* * XIVE Thread Interrupt Management Aera (TIMA) * @@ -532,8 +553,10 @@ void xive_tctx_pic_print_info(XiveTCTX *tctx, GString *buf); Object *xive_tctx_create(Object *cpu, XivePresenter *xptr, Error **errp); void xive_tctx_reset(XiveTCTX *tctx); void xive_tctx_destroy(XiveTCTX *tctx); -void xive_tctx_ipb_update(XiveTCTX *tctx, uint8_t ring, uint8_t ipb); -void xive_tctx_reset_os_signal(XiveTCTX *tctx); +void xive_tctx_pipr_update(XiveTCTX *tctx, uint8_t ring, uint8_t priority, + uint8_t group_level); +void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring); +void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring, uint8_t group_level); /* * KVM XIVE device helpers diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h index ab68f8d..8cdf819 100644 --- a/include/hw/ppc/xive2.h +++ b/include/hw/ppc/xive2.h @@ -1,11 +1,9 @@ /* * QEMU PowerPC XIVE2 interrupt controller model (POWER10) * - * Copyright (c) 2019-2022, IBM Corporation. - * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * Copyright (c) 2019-2024, IBM Corporation. * + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE2_H @@ -53,6 +51,12 @@ typedef struct Xive2RouterClass { Xive2Nvp *nvp); int (*write_nvp)(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx, Xive2Nvp *nvp, uint8_t word_number); + int (*get_nvgc)(Xive2Router *xrtr, bool crowd, + uint8_t nvgc_blk, uint32_t nvgc_idx, + Xive2Nvgc *nvgc); + int (*write_nvgc)(Xive2Router *xrtr, bool crowd, + uint8_t nvgc_blk, uint32_t nvgc_idx, + Xive2Nvgc *nvgc); uint8_t (*get_block_id)(Xive2Router *xrtr); uint32_t (*get_config)(Xive2Router *xrtr); } Xive2RouterClass; @@ -67,6 +71,12 @@ int xive2_router_get_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx, Xive2Nvp *nvp); int xive2_router_write_nvp(Xive2Router *xrtr, uint8_t nvp_blk, uint32_t nvp_idx, Xive2Nvp *nvp, uint8_t word_number); +int xive2_router_get_nvgc(Xive2Router *xrtr, bool crowd, + uint8_t nvgc_blk, uint32_t nvgc_idx, + Xive2Nvgc *nvgc); +int xive2_router_write_nvgc(Xive2Router *xrtr, bool crowd, + uint8_t nvgc_blk, uint32_t nvgc_idx, + Xive2Nvgc *nvgc); uint32_t xive2_router_get_config(Xive2Router *xrtr); void xive2_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked); @@ -78,7 +88,17 @@ void xive2_router_notify(XiveNotifier *xn, uint32_t lisn, bool pq_checked); int xive2_presenter_tctx_match(XivePresenter *xptr, XiveTCTX *tctx, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, - bool cam_ignore, uint32_t logic_serv); + bool crowd, bool cam_ignore, + uint32_t logic_serv); + +uint64_t xive2_presenter_nvp_backlog_op(XivePresenter *xptr, + uint8_t blk, uint32_t idx, + uint16_t offset); + +uint64_t xive2_presenter_nvgc_backlog_op(XivePresenter *xptr, + bool crowd, + uint8_t blk, uint32_t idx, + uint16_t offset, uint16_t val); /* * XIVE2 END ESBs (POWER10) @@ -103,9 +123,21 @@ typedef struct Xive2EndSource { * XIVE2 Thread Interrupt Management Area (POWER10) */ +void xive2_tm_set_hv_cppr(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size); +void xive2_tm_set_os_cppr(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size); void xive2_tm_push_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, uint64_t value, unsigned size); uint64_t xive2_tm_pull_os_ctx(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, unsigned size); +void xive2_tm_pull_os_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size); +bool xive2_tm_irq_precluded(XiveTCTX *tctx, int ring, uint8_t priority); +void xive2_tm_set_lsmfb(XiveTCTX *tctx, int ring, uint8_t priority); +void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size); +void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx, + hwaddr offset, uint64_t value, unsigned size); #endif /* PPC_XIVE2_H */ diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h index 4349d00..b11395c 100644 --- a/include/hw/ppc/xive2_regs.h +++ b/include/hw/ppc/xive2_regs.h @@ -1,10 +1,9 @@ /* * QEMU PowerPC XIVE2 internal structure definitions (POWER10) * - * Copyright (c) 2019-2022, IBM Corporation. + * Copyright (c) 2019-2024, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE2_REGS_H @@ -19,16 +18,18 @@ * mode (P10), the CAM line is slightly different as the VP space was * increased. */ -#define TM2_QW0W2_VU PPC_BIT32(0) +#define TM2_W2_VALID PPC_BIT32(0) +#define TM2_W2_HW PPC_BIT32(1) +#define TM2_QW0W2_VU TM2_W2_VALID #define TM2_QW0W2_LOGIC_SERV PPC_BITMASK32(4, 31) -#define TM2_QW1W2_VO PPC_BIT32(0) -#define TM2_QW1W2_HO PPC_BIT32(1) +#define TM2_QW1W2_VO TM2_W2_VALID +#define TM2_QW1W2_HO TM2_W2_HW #define TM2_QW1W2_OS_CAM PPC_BITMASK32(4, 31) -#define TM2_QW2W2_VP PPC_BIT32(0) -#define TM2_QW2W2_HP PPC_BIT32(1) +#define TM2_QW2W2_VP TM2_W2_VALID +#define TM2_QW2W2_HP TM2_W2_HW #define TM2_QW2W2_POOL_CAM PPC_BITMASK32(4, 31) -#define TM2_QW3W2_VT PPC_BIT32(0) -#define TM2_QW3W2_HT PPC_BIT32(1) +#define TM2_QW3W2_VT TM2_W2_VALID +#define TM2_QW3W2_HT TM2_W2_HW #define TM2_QW3W2_LP PPC_BIT32(6) #define TM2_QW3W2_LE PPC_BIT32(7) @@ -150,7 +151,11 @@ typedef struct Xive2Nvp { uint32_t w0; #define NVP2_W0_VALID PPC_BIT32(0) #define NVP2_W0_HW PPC_BIT32(7) +#define NVP2_W0_L PPC_BIT32(8) +#define NVP2_W0_G PPC_BIT32(9) +#define NVP2_W0_T PPC_BIT32(10) #define NVP2_W0_ESC_END PPC_BIT32(25) /* 'N' bit 0:ESB 1:END */ +#define NVP2_W0_PGOFIRST PPC_BITMASK32(26, 31) uint32_t w1; #define NVP2_W1_CO PPC_BIT32(13) #define NVP2_W1_CO_PRIV PPC_BITMASK32(14, 15) @@ -160,6 +165,8 @@ typedef struct Xive2Nvp { #define NVP2_W2_CPPR PPC_BITMASK32(0, 7) #define NVP2_W2_IPB PPC_BITMASK32(8, 15) #define NVP2_W2_LSMFB PPC_BITMASK32(16, 23) +#define NVP2_W2_T PPC_BIT32(27) +#define NVP2_W2_LGS PPC_BITMASK32(28, 31) uint32_t w3; uint32_t w4; #define NVP2_W4_ESC_ESB_BLOCK PPC_BITMASK32(0, 3) /* N:0 */ @@ -171,7 +178,9 @@ typedef struct Xive2Nvp { #define NVP2_W5_VP_END_BLOCK PPC_BITMASK32(4, 7) #define NVP2_W5_VP_END_INDEX PPC_BITMASK32(8, 31) uint32_t w6; +#define NVP2_W6_REPORTING_LINE PPC_BITMASK32(4, 31) uint32_t w7; +#define NVP2_W7_REPORTING_LINE PPC_BITMASK32(0, 23) } Xive2Nvp; #define xive2_nvp_is_valid(nvp) (be32_to_cpu((nvp)->w0) & NVP2_W0_VALID) @@ -209,6 +218,7 @@ void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf); typedef struct Xive2Nvgc { uint32_t w0; #define NVGC2_W0_VALID PPC_BIT32(0) +#define NVGC2_W0_PGONEXT PPC_BITMASK32(26, 31) uint32_t w1; uint32_t w2; uint32_t w3; @@ -218,4 +228,16 @@ typedef struct Xive2Nvgc { uint32_t w7; } Xive2Nvgc; +#define xive2_nvgc_is_valid(nvgc) (be32_to_cpu((nvgc)->w0) & NVGC2_W0_VALID) + +void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, uint32_t nvgc_idx, + GString *buf); + +#define NVx_BACKLOG_OP PPC_BITMASK(52, 53) +#define NVx_BACKLOG_PRIO PPC_BITMASK(57, 59) + +/* split the 6-bit crowd/group level */ +#define NVx_CROWD_LVL(level) ((level >> 4) & 0b11) +#define NVx_GROUP_LVL(level) (level & 0b1111) + #endif /* PPC_XIVE2_REGS_H */ diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index b9db7ab..54bc6c5 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -7,10 +7,9 @@ * access to the different fields. * * - * Copyright (c) 2016-2018, IBM Corporation. + * Copyright (c) 2016-2024, IBM Corporation. * - * This code is licensed under the GPL version 2 or later. See the - * COPYING file in the top-level directory. + * SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef PPC_XIVE_REGS_H @@ -77,8 +76,11 @@ #define TM_LSMFB 0x3 /* - + + + */ #define TM_ACK_CNT 0x4 /* - + - - */ #define TM_INC 0x5 /* - + - + */ +#define TM_LGS 0x5 /* + + + + */ /* Rename P10 */ #define TM_AGE 0x6 /* - + - + */ +#define TM_T 0x6 /* - + - + */ /* Rename P10 */ #define TM_PIPR 0x7 /* - + - + */ +#define TM_OGEN 0xF /* - + - - */ /* P10 only */ #define TM_WORD0 0x0 #define TM_WORD1 0x4 @@ -98,6 +100,7 @@ #define TM_QW3W2_LP PPC_BIT32(6) #define TM_QW3W2_LE PPC_BIT32(7) #define TM_QW3W2_T PPC_BIT32(31) +#define TM_QW3B8_VT PPC_BIT8(0) /* * In addition to normal loads to "peek" and writes (only when invalid) @@ -114,26 +117,42 @@ * Then we have all these "special" CI ops at these offset that trigger * all sorts of side effects: */ -#define TM_SPC_ACK_EBB 0x800 /* Load8 ack EBB to reg*/ -#define TM_SPC_ACK_OS_REG 0x810 /* Load16 ack OS irq to reg */ +#define TM_SPC_ACK_EBB 0x800 /* Load8 ack EBB to reg */ +#define TM_SPC_ACK_OS_REG 0x810 /* Load16 ack OS irq to reg */ #define TM_SPC_PUSH_USR_CTX 0x808 /* Store32 Push/Validate user context */ -#define TM_SPC_PULL_USR_CTX 0x808 /* Load32 Pull/Invalidate user - * context */ -#define TM_SPC_SET_OS_PENDING 0x812 /* Store8 Set OS irq pending bit */ -#define TM_SPC_PULL_OS_CTX 0x818 /* Load32/Load64 Pull/Invalidate OS - * context to reg */ -#define TM_SPC_PULL_POOL_CTX 0x828 /* Load32/Load64 Pull/Invalidate Pool - * context to reg*/ -#define TM_SPC_ACK_HV_REG 0x830 /* Load16 ack HV irq to reg */ -#define TM_SPC_PULL_USR_CTX_OL 0xc08 /* Store8 Pull/Inval usr ctx to odd - * line */ -#define TM_SPC_ACK_OS_EL 0xc10 /* Store8 ack OS irq to even line */ -#define TM_SPC_ACK_HV_POOL_EL 0xc20 /* Store8 ack HV evt pool to even - * line */ -#define TM_SPC_ACK_HV_EL 0xc30 /* Store8 ack HV irq to even line */ +#define TM_SPC_PULL_USR_CTX 0x808 /* Load32 Pull/Invalidate user */ + /* context */ +#define TM_SPC_SET_OS_PENDING 0x812 /* Store8 Set OS irq pending bit */ +#define TM_SPC_PULL_OS_CTX_G2 0x810 /* Load32/Load64 Pull/Invalidate OS */ + /* context to reg */ +#define TM_SPC_PULL_OS_CTX 0x818 /* Load32/Load64 Pull/Invalidate OS */ + /* context to reg */ +#define TM_SPC_PULL_POOL_CTX_G2 0x820 /* Load32/Load64 Pull/Invalidate Pool */ + /* context to reg */ +#define TM_SPC_PULL_POOL_CTX 0x828 /* Load32/Load64 Pull/Invalidate Pool */ + /* context to reg */ +#define TM_SPC_ACK_HV_REG 0x830 /* Load16 ack HV irq to reg */ +#define TM_SPC_PULL_PHYS_CTX_G2 0x830 /* Load32 Pull phys ctx to reg */ +#define TM_SPC_PULL_PHYS_CTX 0x838 /* Load8 Pull phys ctx to reg */ +#define TM_SPC_PULL_USR_CTX_OL 0xc08 /* Store8 Pull/Inval usr ctx to odd */ + /* line */ +#define TM_SPC_ACK_OS_EL 0xc10 /* Store8 ack OS irq to even line */ +#define TM_SPC_PULL_OS_CTX_OL 0xc18 /* Pull/Invalidate OS context to */ + /* odd Thread reporting line */ +#define TM_SPC_ACK_HV_POOL_EL 0xc20 /* Store8 ack HV evt pool to even */ + /* line */ +#define TM_SPC_ACK_HV_EL 0xc30 /* Store8 ack HV irq to even line */ +#define TM_SPC_PULL_PHYS_CTX_OL 0xc38 /* Pull phys ctx to odd cache line */ /* XXX more... */ -/* NSR fields for the various QW ack types */ +/* + * NSR fields for the various QW ack types + * + * P10 has an extra bit in QW3 for the group level instead of the + * reserved 'i' bit. Since it is not used and we don't support group + * interrupts on P9, we use the P10 definition for the group level so + * that we can have common macros for the NSR + */ #define TM_QW0_NSR_EB PPC_BIT8(0) #define TM_QW1_NSR_EO PPC_BIT8(0) #define TM_QW3_NSR_HE PPC_BITMASK8(0, 1) @@ -141,8 +160,15 @@ #define TM_QW3_NSR_HE_POOL 1 #define TM_QW3_NSR_HE_PHYS 2 #define TM_QW3_NSR_HE_LSI 3 -#define TM_QW3_NSR_I PPC_BIT8(2) -#define TM_QW3_NSR_GRP_LVL PPC_BIT8(3, 7) +#define TM_NSR_GRP_LVL PPC_BITMASK8(2, 7) +/* + * On P10, the format of the 6-bit group level is: 2 bits for the + * crowd size and 4 bits for the group size. Since group/crowd size is + * always a power of 2, we encode the log. For example, group_level=4 + * means crowd size = 0 and group size = 16 (2^4) + * Same encoding is used in the NVP and NVGC structures for + * PGoFirst and PGoNext fields + */ /* * EAS (Event Assignment Structure) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 77bfcbd..530f3da 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -95,6 +95,7 @@ typedef void (*DeviceUnrealize)(DeviceState *dev); typedef void (*DeviceReset)(DeviceState *dev); typedef void (*BusRealize)(BusState *bus, Error **errp); typedef void (*BusUnrealize)(BusState *bus); +typedef int (*DeviceSyncConfig)(DeviceState *dev, Error **errp); /** * struct DeviceClass - The base class for all devices. @@ -103,6 +104,9 @@ typedef void (*BusUnrealize)(BusState *bus); * property is changed to %true. * @unrealize: Callback function invoked when the #DeviceState:realized * property is changed to %false. + * @sync_config: Callback function invoked when QMP command device-sync-config + * is called. Should synchronize device configuration from host to guest part + * and notify the guest about the change. * @hotpluggable: indicates if #DeviceClass is hotpluggable, available * as readonly "hotpluggable" property of #DeviceState instance * @@ -132,7 +136,13 @@ struct DeviceClass { * ensures a compile-time error if someone attempts to assign * dc->props directly. */ - Property *props_; + const Property *props_; + + /** + * @props_count_: number of elements in @props_; should only be + * assigned by using device_class_set_props(). + */ + uint16_t props_count_; /** * @user_creatable: Can user instantiate with -device / device_add? @@ -152,16 +162,17 @@ struct DeviceClass { /* callbacks */ /** - * @reset: deprecated device reset method pointer + * @legacy_reset: deprecated device reset method pointer * * Modern code should use the ResettableClass interface to * implement a multi-phase reset. * * TODO: remove once every reset callback is unused */ - DeviceReset reset; + DeviceReset legacy_reset; DeviceRealize realize; DeviceUnrealize unrealize; + DeviceSyncConfig sync_config; /** * @vmsd: device state serialisation description for @@ -238,10 +249,6 @@ struct DeviceState { */ int64_t pending_deleted_expires_ms; /** - * @opts: QDict of options for the device - */ - QDict *opts; - /** * @hotplugged: was device added after PHASE_MACHINE_READY? */ int hotplugged; @@ -533,7 +540,8 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, int required_for_version); HotplugHandler *qdev_get_bus_hotplug_handler(DeviceState *dev); HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev); -bool qdev_hotplug_allowed(DeviceState *dev, Error **errp); +bool qdev_hotplug_allowed(DeviceState *dev, BusState *bus, Error **errp); +bool qdev_hotunplug_allowed(DeviceState *dev, Error **errp); /** * qdev_get_hotplug_handler() - Get handler responsible for device wiring @@ -547,6 +555,7 @@ bool qdev_hotplug_allowed(DeviceState *dev, Error **errp); */ HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev); void qdev_unplug(DeviceState *dev, Error **errp); +int qdev_sync_config(DeviceState *dev, Error **errp); void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp); void qdev_machine_creation_done(void); @@ -929,29 +938,38 @@ char *qdev_get_own_fw_dev_path_from_handler(BusState *bus, DeviceState *dev); /** * device_class_set_props(): add a set of properties to an device * @dc: the parent DeviceClass all devices inherit - * @props: an array of properties, terminate by DEFINE_PROP_END_OF_LIST() + * @props: an array of properties * * This will add a set of properties to the object. It will fault if * you attempt to add an existing property defined by a parent class. * To modify an inherited property you need to use???? + * + * Validate that @props has at least one Property. + * Validate that @props is an array, not a pointer, via ARRAY_SIZE. + * Validate that the array does not have a legacy terminator at compile-time; + * requires -O2 and the array to be const. */ -void device_class_set_props(DeviceClass *dc, Property *props); +#define device_class_set_props(dc, props) \ + do { \ + QEMU_BUILD_BUG_ON(sizeof(props) == 0); \ + size_t props_count_ = ARRAY_SIZE(props); \ + if ((props)[props_count_ - 1].name == NULL) { \ + qemu_build_not_reached(); \ + } \ + device_class_set_props_n((dc), (props), props_count_); \ + } while (0) /** - * device_class_set_parent_reset() - legacy set device reset handlers - * @dc: device class - * @dev_reset: function pointer to reset handler - * @parent_reset: function pointer to parents reset handler - * - * Modern code should use the ResettableClass interface to - * implement a multi-phase reset instead. + * device_class_set_props_n(): add a set of properties to an device + * @dc: the parent DeviceClass all devices inherit + * @props: an array of properties + * @n: ARRAY_SIZE(@props) * - * TODO: remove the function when DeviceClass's reset method - * is not used anymore. + * This will add a set of properties to the object. It will fault if + * you attempt to add an existing property defined by a parent class. + * To modify an inherited property you need to use???? */ -void device_class_set_parent_reset(DeviceClass *dc, - DeviceReset dev_reset, - DeviceReset *parent_reset); +void device_class_set_props_n(DeviceClass *dc, const Property *props, size_t n); /** * device_class_set_parent_realize() - set up for chaining realize fns @@ -969,6 +987,19 @@ void device_class_set_parent_realize(DeviceClass *dc, DeviceRealize dev_realize, DeviceRealize *parent_realize); +/** + * device_class_set_legacy_reset(): set the DeviceClass::reset method + * @dc: The device class + * @dev_reset: the reset function + * + * This function sets the DeviceClass::reset method. This is widely + * used in existing code, but new code should prefer to use the + * Resettable API as documented in docs/devel/reset.rst. + * In addition, devices which need to chain to their parent class's + * reset methods or which need to be subclassed must use Resettable. + */ +void device_class_set_legacy_reset(DeviceClass *dc, + DeviceReset dev_reset); /** * device_class_set_parent_unrealize() - set up for chaining unrealize fns @@ -994,6 +1025,26 @@ void qdev_assert_realized_properly(void); Object *qdev_get_machine(void); /** + * qdev_create_fake_machine(): Create a fake machine container. + * + * .. note:: + * This function is a kludge for user emulation (USER_ONLY) + * because when thread (TYPE_CPU) are realized, qdev_realize() + * access a machine container. + */ +void qdev_create_fake_machine(void); + +/** + * machine_get_container: + * @name: The name of container to lookup + * + * Get a container of the machine (QOM path "/machine/NAME"). + * + * Returns: the machine container object. + */ +Object *machine_get_container(const char *name); + +/** * qdev_get_human_name() - Return a human-readable name for a device * @dev: The device. Must be a valid and non-NULL pointer. * diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h index 438f653..b921392 100644 --- a/include/hw/qdev-properties-system.h +++ b/include/hw/qdev-properties-system.h @@ -3,6 +3,9 @@ #include "hw/qdev-properties.h" +bool qdev_prop_sanitize_s390x_loadparm(uint8_t *loadparm, const char *str, + Error **errp); + extern const PropertyInfo qdev_prop_chr; extern const PropertyInfo qdev_prop_macaddr; extern const PropertyInfo qdev_prop_reserved_region; @@ -27,6 +30,8 @@ extern const PropertyInfo qdev_prop_pcie_link_speed; extern const PropertyInfo qdev_prop_pcie_link_width; extern const PropertyInfo qdev_prop_cpus390entitlement; extern const PropertyInfo qdev_prop_iothread_vq_mapping_list; +extern const PropertyInfo qdev_prop_endian_mode; +extern const PropertyInfo qdev_prop_vmapple_virtio_blk_variant; #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) @@ -88,10 +93,21 @@ extern const PropertyInfo qdev_prop_iothread_vq_mapping_list; #define DEFINE_PROP_CPUS390ENTITLEMENT(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_cpus390entitlement, \ - CpuS390Entitlement) + S390CpuEntitlement) #define DEFINE_PROP_IOTHREAD_VQ_MAPPING_LIST(_name, _state, _field) \ DEFINE_PROP(_name, _state, _field, qdev_prop_iothread_vq_mapping_list, \ IOThreadVirtQueueMappingList *) +#define DEFINE_PROP_ENDIAN(_name, _state, _field, _default) \ + DEFINE_PROP_UNSIGNED(_name, _state, _field, _default, \ + qdev_prop_endian_mode, EndianMode) +#define DEFINE_PROP_ENDIAN_NODEFAULT(_name, _state, _field) \ + DEFINE_PROP_ENDIAN(_name, _state, _field, ENDIAN_MODE_UNSPECIFIED) + +#define DEFINE_PROP_VMAPPLE_VIRTIO_BLK_VARIANT(_name, _state, _fld, _default) \ + DEFINE_PROP_UNSIGNED(_name, _state, _fld, _default, \ + qdev_prop_vmapple_virtio_blk_variant, \ + VMAppleVirtioBlkVariant) + #endif diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 09aa04c..2c99856 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -16,28 +16,28 @@ struct Property { const char *name; const PropertyInfo *info; ptrdiff_t offset; - uint8_t bitnr; + const char *link_type; uint64_t bitmask; - bool set_default; union { int64_t i; uint64_t u; } defval; - int arrayoffset; const PropertyInfo *arrayinfo; + int arrayoffset; int arrayfieldsize; - const char *link_type; + uint8_t bitnr; + bool set_default; }; struct PropertyInfo { - const char *name; + const char *type; const char *description; const QEnumLookup *enum_table; bool realized_set_allowed; /* allow setting property on realized device */ - int (*print)(Object *obj, Property *prop, char *dest, size_t len); + int (*print)(Object *obj, const Property *prop, char *dest, size_t len); void (*set_default_value)(ObjectProperty *op, const Property *prop); ObjectProperty *(*create)(ObjectClass *oc, const char *name, - Property *prop); + const Property *prop); ObjectPropertyAccessor *get; ObjectPropertyAccessor *set; ObjectPropertyRelease *release; @@ -49,10 +49,10 @@ struct PropertyInfo { extern const PropertyInfo qdev_prop_bit; extern const PropertyInfo qdev_prop_bit64; extern const PropertyInfo qdev_prop_bool; -extern const PropertyInfo qdev_prop_enum; extern const PropertyInfo qdev_prop_uint8; extern const PropertyInfo qdev_prop_uint16; extern const PropertyInfo qdev_prop_uint32; +extern const PropertyInfo qdev_prop_usize; extern const PropertyInfo qdev_prop_int32; extern const PropertyInfo qdev_prop_uint64; extern const PropertyInfo qdev_prop_uint64_checkmask; @@ -171,9 +171,6 @@ extern const PropertyInfo qdev_prop_link; #define DEFINE_PROP_SIZE32(_n, _s, _f, _d) \ DEFINE_PROP_UNSIGNED(_n, _s, _f, _d, qdev_prop_size32, uint32_t) -#define DEFINE_PROP_END_OF_LIST() \ - {} - /* * Set properties between creation and realization. * @@ -204,7 +201,7 @@ void qdev_prop_set_enum(DeviceState *dev, const char *name, int value); /* Takes ownership of @values */ void qdev_prop_set_array(DeviceState *dev, const char *name, QList *values); -void *object_field_prop_ptr(Object *obj, Property *prop); +void *object_field_prop_ptr(Object *obj, const Property *prop); void qdev_prop_register_global(GlobalProperty *prop); const GlobalProperty *qdev_find_global_prop(Object *obj, @@ -223,7 +220,7 @@ void error_set_from_qdev_prop_error(Error **errp, int ret, Object *obj, * On error, store error in @errp. Static properties access data in a struct. * The type of the QOM property is derived from prop->info. */ -void qdev_property_add_static(DeviceState *dev, Property *prop); +void qdev_property_add_static(DeviceState *dev, const Property *prop); /** * qdev_alias_all_properties: Create aliases on source for all target properties diff --git a/include/hw/register.h b/include/hw/register.h index 6a076cf..a913c52 100644 --- a/include/hw/register.h +++ b/include/hw/register.h @@ -12,7 +12,7 @@ #define REGISTER_H #include "hw/qdev-core.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/registerfields.h" #include "qom/object.h" diff --git a/include/hw/remote/iohub.h b/include/hw/remote/iohub.h index 6a8444f..09ee6c7 100644 --- a/include/hw/remote/iohub.h +++ b/include/hw/remote/iohub.h @@ -37,6 +37,5 @@ void remote_iohub_set_irq(void *opaque, int pirq, int level); void process_set_irqfd_msg(PCIDevice *pci_dev, MPQemuMsg *msg); void remote_iohub_init(RemoteIOHubState *iohub); -void remote_iohub_finalize(RemoteIOHubState *iohub); #endif diff --git a/include/hw/remote/proxy-memory-listener.h b/include/hw/remote/proxy-memory-listener.h index c4f3efb..ec516d8 100644 --- a/include/hw/remote/proxy-memory-listener.h +++ b/include/hw/remote/proxy-memory-listener.h @@ -9,7 +9,7 @@ #ifndef PROXY_MEMORY_LISTENER_H #define PROXY_MEMORY_LISTENER_H -#include "exec/memory.h" +#include "system/memory.h" #include "io/channel.h" typedef struct ProxyMemoryListener { diff --git a/include/hw/resettable.h b/include/hw/resettable.h index 7e249de..fd862f1 100644 --- a/include/hw/resettable.h +++ b/include/hw/resettable.h @@ -29,6 +29,7 @@ typedef struct ResettableState ResettableState; * Types of reset. * * + Cold: reset resulting from a power cycle of the object. + * + Wakeup: reset resulting from a wake-up from a suspended state. * * TODO: Support has to be added to handle more types. In particular, * ResettableState structure needs to be expanded. @@ -36,6 +37,9 @@ typedef struct ResettableState ResettableState; typedef enum ResetType { RESET_TYPE_COLD, RESET_TYPE_SNAPSHOT_LOAD, + RESET_TYPE_WAKEUP, + RESET_TYPE_S390_CPU_INITIAL, + RESET_TYPE_S390_CPU_NORMAL, } ResetType; /* @@ -88,14 +92,6 @@ typedef enum ResetType { * @get_state: Mandatory method which must return a pointer to a * ResettableState. * - * @get_transitional_function: transitional method to handle Resettable objects - * not yet fully moved to this interface. It will be removed as soon as it is - * not needed anymore. This method is optional and may return a pointer to a - * function to be used instead of the phases. If the method exists and returns - * a non-NULL function pointer then that function is executed as a replacement - * of the 'hold' phase method taking the object as argument. The two other phase - * methods are not executed. - * * @child_foreach: Executes a given callback on every Resettable child. Child * in this context means a child in the qbus tree, so the children of a qbus * are the devices on it, and the children of a device are all the buses it @@ -107,8 +103,6 @@ typedef void (*ResettableEnterPhase)(Object *obj, ResetType type); typedef void (*ResettableHoldPhase)(Object *obj, ResetType type); typedef void (*ResettableExitPhase)(Object *obj, ResetType type); typedef ResettableState * (*ResettableGetState)(Object *obj); -typedef void (*ResettableTrFunction)(Object *obj); -typedef ResettableTrFunction (*ResettableGetTrFunction)(Object *obj); typedef void (*ResettableChildCallback)(Object *, void *opaque, ResetType type); typedef void (*ResettableChildForeach)(Object *obj, @@ -128,9 +122,6 @@ struct ResettableClass { /* State access method */ ResettableGetState get_state; - /* Transitional method for legacy reset compatibility */ - ResettableGetTrFunction get_transitional_function; - /* Hierarchy handling method */ ResettableChildForeach child_foreach; }; diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index a2e4ae9..7d59b2e 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -27,36 +27,50 @@ #define RISCV32_BIOS_BIN "opensbi-riscv32-generic-fw_dynamic.bin" #define RISCV64_BIOS_BIN "opensbi-riscv64-generic-fw_dynamic.bin" +typedef struct RISCVBootInfo { + ssize_t kernel_size; + hwaddr image_low_addr; + hwaddr image_high_addr; + + hwaddr initrd_start; + ssize_t initrd_size; + + bool is_32bit; +} RISCVBootInfo; + bool riscv_is_32bit(RISCVHartArrayState *harts); char *riscv_plic_hart_config_string(int hart_count); -target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts, +void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts); +target_ulong riscv_calc_kernel_start_addr(RISCVBootInfo *info, target_ulong firmware_end_addr); target_ulong riscv_find_and_load_firmware(MachineState *machine, const char *default_machine_firmware, - hwaddr firmware_load_addr, + hwaddr *firmware_load_addr, symbol_fn_t sym_cb); const char *riscv_default_firmware_name(RISCVHartArrayState *harts); char *riscv_find_firmware(const char *firmware_filename, const char *default_machine_firmware); target_ulong riscv_load_firmware(const char *firmware_filename, - hwaddr firmware_load_addr, + hwaddr *firmware_load_addr, symbol_fn_t sym_cb); -target_ulong riscv_load_kernel(MachineState *machine, - RISCVHartArrayState *harts, - target_ulong firmware_end_addr, - bool load_initrd, - symbol_fn_t sym_cb); -uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size, - MachineState *ms); +void riscv_load_kernel(MachineState *machine, + RISCVBootInfo *info, + target_ulong kernel_start_addr, + bool load_initrd, + symbol_fn_t sym_cb); +uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size, + MachineState *ms, RISCVBootInfo *info); void riscv_load_fdt(hwaddr fdt_addr, void *fdt); void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, hwaddr saddr, hwaddr rom_base, hwaddr rom_size, uint64_t kernel_entry, uint64_t fdt_load_addr); -void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base, +void riscv_rom_copy_firmware_info(MachineState *machine, + RISCVHartArrayState *harts, + hwaddr rom_base, hwaddr rom_size, uint32_t reset_vec_size, uint64_t kernel_entry); diff --git a/include/hw/riscv/boot_opensbi.h b/include/hw/riscv/boot_opensbi.h index 1b74966..18664a1 100644 --- a/include/hw/riscv/boot_opensbi.h +++ b/include/hw/riscv/boot_opensbi.h @@ -58,4 +58,33 @@ struct fw_dynamic_info { target_long boot_hart; }; +/** Representation dynamic info passed by previous booting stage */ +struct fw_dynamic_info32 { + /** Info magic */ + int32_t magic; + /** Info version */ + int32_t version; + /** Next booting stage address */ + int32_t next_addr; + /** Next booting stage mode */ + int32_t next_mode; + /** Options for OpenSBI library */ + int32_t options; + /** + * Preferred boot HART id + * + * It is possible that the previous booting stage uses same link + * address as the FW_DYNAMIC firmware. In this case, the relocation + * lottery mechanism can potentially overwrite the previous booting + * stage while other HARTs are still running in the previous booting + * stage leading to boot-time crash. To avoid this boot-time crash, + * the previous booting stage can specify last HART that will jump + * to the FW_DYNAMIC firmware as the preferred boot HART. + * + * To avoid specifying a preferred boot HART, the previous booting + * stage can set it to -1UL which will force the FW_DYNAMIC firmware + * to use the relocation lottery mechanism. + */ + int32_t boot_hart; +}; #endif diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h new file mode 100644 index 0000000..8a8acfc --- /dev/null +++ b/include/hw/riscv/iommu.h @@ -0,0 +1,42 @@ +/* + * QEMU emulation of an RISC-V IOMMU + * + * Copyright (C) 2022-2023 Rivos Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_RISCV_IOMMU_H +#define HW_RISCV_IOMMU_H + +#include "qemu/osdep.h" +#include "qom/object.h" + +#define TYPE_RISCV_IOMMU "riscv-iommu" +OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUState, RISCV_IOMMU) +typedef struct RISCVIOMMUState RISCVIOMMUState; + +#define TYPE_RISCV_IOMMU_MEMORY_REGION "riscv-iommu-mr" +typedef struct RISCVIOMMUSpace RISCVIOMMUSpace; + +#define TYPE_RISCV_IOMMU_PCI "riscv-iommu-pci" +OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI) +typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci; + +#define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device" +OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS) +typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys; + +#define FDT_IRQ_TYPE_EDGE_LOW 1 + +#endif diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h index daef086..7ca9b97 100644 --- a/include/hw/riscv/microchip_pfsoc.h +++ b/include/hw/riscv/microchip_pfsoc.h @@ -67,6 +67,7 @@ typedef struct MicrochipIcicleKitState { MachineState parent_obj; /*< public >*/ + uint32_t clint_timebase_freq; MicrochipPFSoCState soc; } MicrochipIcicleKitState; diff --git a/include/hw/riscv/numa.h b/include/hw/riscv/numa.h index 8f52802..147f016 100644 --- a/include/hw/riscv/numa.h +++ b/include/hw/riscv/numa.h @@ -21,7 +21,7 @@ #include "hw/boards.h" #include "hw/sysbus.h" -#include "sysemu/numa.h" +#include "system/numa.h" /** * riscv_socket_count: diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h index 912b4a2..a6ed73a 100644 --- a/include/hw/riscv/riscv_hart.h +++ b/include/hw/riscv/riscv_hart.h @@ -38,6 +38,10 @@ struct RISCVHartArrayState { uint32_t hartid_base; char *cpu_type; uint64_t resetvec; + uint32_t num_rnmi_irqvec; + uint64_t *rnmi_irqvec; + uint32_t num_rnmi_excpvec; + uint64_t *rnmi_excpvec; RISCVCPU *harts; }; diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index c0dc41f..7b4c2c8 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -62,6 +62,8 @@ struct RISCVVirtState { OnOffAuto acpi; const MemMapEntry *memmap; struct GPEXHost *gpex_host; + OnOffAuto iommu_sys; + uint16_t pci_iommu_bdf; }; enum { @@ -84,7 +86,8 @@ enum { VIRT_PCIE_MMIO, VIRT_PCIE_PIO, VIRT_PLATFORM_BUS, - VIRT_PCIE_ECAM + VIRT_PCIE_ECAM, + VIRT_IOMMU_SYS, }; enum { @@ -93,6 +96,7 @@ enum { VIRTIO_IRQ = 1, /* 1 to 8 */ VIRTIO_COUNT = 8, PCIE_IRQ = 0x20, /* 32 to 35 */ + IOMMU_SYS_IRQ = 0x24, /* 36-39 */ VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */ }; @@ -129,6 +133,7 @@ enum { 1 + FDT_APLIC_INT_CELLS) bool virt_is_acpi_enabled(RISCVVirtState *s); +bool virt_is_iommu_sys_enabled(RISCVVirtState *s); void virt_acpi_setup(RISCVVirtState *vms); uint32_t imsic_num_bits(uint32_t count); diff --git a/include/hw/s390x/ap-bridge.h b/include/hw/s390x/ap-bridge.h index 470e439..7efc529 100644 --- a/include/hw/s390x/ap-bridge.h +++ b/include/hw/s390x/ap-bridge.h @@ -16,4 +16,43 @@ void s390_init_ap(void); +typedef struct ChscSeiNt0Res { + uint16_t length; + uint16_t code; + uint8_t reserved1; + uint16_t reserved2; + uint8_t nt; +#define PENDING_EVENT_INFO_BITMASK 0x80; + uint8_t flags; + uint8_t reserved3; + uint8_t rs; + uint8_t cc; +} QEMU_PACKED ChscSeiNt0Res; + +#define NT0_RES_RESPONSE_CODE 1 +#define NT0_RES_NT_DEFAULT 0 +#define NT0_RES_RS_AP_CHANGE 5 +#define NT0_RES_CC_AP_CHANGE 3 + +#define EVENT_INFORMATION_NOT_STORED 1 +#define EVENT_INFORMATION_STORED 0 + +/** + * ap_chsc_sei_nt0_get_event - Retrieve the next pending AP config + * change event + * @res: Pointer to a ChscSeiNt0Res struct to be filled with event + * data + * + * This function checks for any pending AP config change events and, + * if present, populates the provided response structure with the + * appropriate SEI NT0 fields. + * + * Return: + * EVENT_INFORMATION_STORED - An event was available and written to @res + * EVENT_INFORMATION_NOT_STORED - No event was available + */ +int ap_chsc_sei_nt0_get_event(void *res); + +bool ap_chsc_sei_nt0_have_event(void); + #endif diff --git a/include/hw/s390x/cpu-topology.h b/include/hw/s390x/cpu-topology.h index c064f42..d5e9aa4 100644 --- a/include/hw/s390x/cpu-topology.h +++ b/include/hw/s390x/cpu-topology.h @@ -13,7 +13,7 @@ #include "qemu/queue.h" #include "hw/boards.h" -#include "qapi/qapi-types-machine-target.h" +#include "qapi/qapi-types-machine-s390x.h" #define S390_TOPOLOGY_CPU_IFL 0x03 @@ -37,7 +37,7 @@ typedef struct S390TopologyEntry { typedef struct S390Topology { uint8_t *cores_per_socket; - CpuS390Polarization polarization; + S390CpuPolarization polarization; } S390Topology; typedef QTAILQ_HEAD(, S390TopologyEntry) S390TopologyList; @@ -57,7 +57,7 @@ static inline void s390_topology_setup_cpu(MachineState *ms, static inline void s390_topology_reset(void) { /* Unreachable, CPU topology not implemented for TCG */ - assert(false); + g_assert_not_reached(); } #endif diff --git a/include/hw/s390x/css-bridge.h b/include/hw/s390x/css-bridge.h index deb606d..4f874ed 100644 --- a/include/hw/s390x/css-bridge.h +++ b/include/hw/s390x/css-bridge.h @@ -19,7 +19,6 @@ /* virtual css bridge */ struct VirtualCssBridge { SysBusDevice sysbus_dev; - bool css_dev_path; }; #define TYPE_VIRTUAL_CSS_BRIDGE "virtual-css-bridge" diff --git a/include/hw/s390x/css.h b/include/hw/s390x/css.h index 8289e45..0b0400a 100644 --- a/include/hw/s390x/css.h +++ b/include/hw/s390x/css.h @@ -15,7 +15,7 @@ #include "hw/s390x/adapter.h" #include "hw/s390x/s390_flic.h" #include "hw/s390x/ioinst.h" -#include "sysemu/kvm.h" +#include "system/kvm.h" #include "target/s390x/cpu-qom.h" /* Channel subsystem constants. */ @@ -238,7 +238,6 @@ uint32_t css_get_adapter_id(CssIoAdapterType type, uint8_t isc); void css_register_io_adapters(CssIoAdapterType type, bool swap, bool maskable, uint8_t flags, Error **errp); -#ifndef CONFIG_USER_ONLY SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid, uint16_t schid); bool css_subch_visible(SubchDev *sch); @@ -262,7 +261,6 @@ int css_enable_mss(void); IOInstEnding css_do_rsch(SubchDev *sch); int css_do_rchp(uint8_t cssid, uint8_t chpid); bool css_present(uint8_t cssid); -#endif extern const PropertyInfo css_devid_ro_propinfo; @@ -333,10 +331,4 @@ static inline int ccw_dstream_read_buf(CcwDataStream *cds, void *buff, int len) #define ccw_dstream_read(cds, v) ccw_dstream_read_buf((cds), &(v), sizeof(v)) #define ccw_dstream_write(cds, v) ccw_dstream_write_buf((cds), &(v), sizeof(v)) -/** - * true if (vmstate based) migration of the channel subsystem - * is enabled, false if it is disabled. - */ -extern bool css_migration_enabled; - #endif diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index ff874e7..eac7a51 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -25,6 +25,7 @@ #define SCLP_EVENT_MESSAGE 0x02 #define SCLP_EVENT_CONFIG_MGT_DATA 0x04 #define SCLP_EVENT_PMSGCMD 0x09 +#define SCLP_EVENT_CTRL_PGM_ID 0x0b #define SCLP_EVENT_ASCII_CONSOLE_DATA 0x1a #define SCLP_EVENT_SIGNAL_QUIESCE 0x1d @@ -35,6 +36,7 @@ #define SCLP_EVENT_MASK_MSG SCLP_EVMASK(SCLP_EVENT_MESSAGE) #define SCLP_EVENT_MASK_CONFIG_MGT_DATA SCLP_EVMASK(SCLP_EVENT_CONFIG_MGT_DATA) #define SCLP_EVENT_MASK_PMSGCMD SCLP_EVMASK(SCLP_EVENT_PMSGCMD) +#define SCLP_EVENT_MASK_CTRL_PGM_ID SCLP_EVMASK(SCLP_EVENT_CTRL_PGM_ID) #define SCLP_EVENT_MASK_MSG_ASCII SCLP_EVMASK(SCLP_EVENT_ASCII_CONSOLE_DATA) #define SCLP_EVENT_MASK_SIGNAL_QUIESCE SCLP_EVMASK(SCLP_EVENT_SIGNAL_QUIESCE) @@ -191,6 +193,21 @@ struct SCLPEventClass { bool (*can_handle_event)(uint8_t type); }; +#define TYPE_SCLP_EVENT_CPI "sclpcpi" +typedef struct SCLPEventCPIClass SCLPEventCPIClass; +typedef struct SCLPEventCPI SCLPEventCPI; +OBJECT_DECLARE_TYPE(SCLPEventCPI, SCLPEventCPIClass, + SCLP_EVENT_CPI) + +struct SCLPEventCPI { + SCLPEvent event; + uint8_t system_type[8]; + uint8_t system_name[8]; + uint64_t system_level; + uint8_t sysplex_name[8]; + uint64_t timestamp; +}; + #define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility" typedef struct SCLPEventFacility SCLPEventFacility; typedef struct SCLPEventFacilityClass SCLPEventFacilityClass; diff --git a/include/hw/s390x/ipl/qipl.h b/include/hw/s390x/ipl/qipl.h new file mode 100644 index 0000000..6824391 --- /dev/null +++ b/include/hw/s390x/ipl/qipl.h @@ -0,0 +1,127 @@ +/* + * S/390 boot structures + * + * Copyright 2024 IBM Corp. + * Author(s): Jared Rossi <jrossi@linux.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#ifndef S390X_QIPL_H +#define S390X_QIPL_H + +/* Boot Menu flags */ +#define QIPL_FLAG_BM_OPTS_CMD 0x80 +#define QIPL_FLAG_BM_OPTS_ZIPL 0x40 + +#define QIPL_ADDRESS 0xcc +#define LOADPARM_LEN 8 +#define NO_LOADPARM "\0\0\0\0\0\0\0\0" + +/* + * The QEMU IPL Parameters will be stored at absolute address + * 204 (0xcc) which means it is 32-bit word aligned but not + * double-word aligned. Placement of 64-bit data fields in this + * area must account for their alignment needs. + * The total size of the struct must never exceed 28 bytes. + */ +struct QemuIplParameters { + uint8_t qipl_flags; + uint8_t index; + uint8_t reserved1[2]; + uint64_t reserved2; + uint32_t boot_menu_timeout; + uint8_t reserved3[2]; + uint16_t chain_len; + uint64_t next_iplb; +} QEMU_PACKED; +typedef struct QemuIplParameters QemuIplParameters; + +struct IPLBlockPVComp { + uint64_t tweak_pref; + uint64_t addr; + uint64_t size; +} QEMU_PACKED; +typedef struct IPLBlockPVComp IPLBlockPVComp; + +struct IPLBlockPV { + uint8_t reserved18[87]; /* 0x18 */ + uint8_t version; /* 0x6f */ + uint32_t reserved70; /* 0x70 */ + uint32_t num_comp; /* 0x74 */ + uint64_t pv_header_addr; /* 0x78 */ + uint64_t pv_header_len; /* 0x80 */ + struct IPLBlockPVComp components[0]; +} QEMU_PACKED; +typedef struct IPLBlockPV IPLBlockPV; + +struct IplBlockCcw { + uint8_t reserved0[85]; + uint8_t ssid; + uint16_t devno; + uint8_t vm_flags; + uint8_t reserved3[3]; + uint32_t vm_parm_len; + uint8_t nss_name[8]; + uint8_t vm_parm[64]; + uint8_t reserved4[8]; +} QEMU_PACKED; +typedef struct IplBlockCcw IplBlockCcw; + +struct IplBlockFcp { + uint8_t reserved1[305 - 1]; + uint8_t opt; + uint8_t reserved2[3]; + uint16_t reserved3; + uint16_t devno; + uint8_t reserved4[4]; + uint64_t wwpn; + uint64_t lun; + uint32_t bootprog; + uint8_t reserved5[12]; + uint64_t br_lba; + uint32_t scp_data_len; + uint8_t reserved6[260]; + uint8_t scp_data[0]; +} QEMU_PACKED; +typedef struct IplBlockFcp IplBlockFcp; + +struct IplBlockQemuScsi { + uint32_t lun; + uint16_t target; + uint16_t channel; + uint8_t reserved0[77]; + uint8_t ssid; + uint16_t devno; +} QEMU_PACKED; +typedef struct IplBlockQemuScsi IplBlockQemuScsi; + +union IplParameterBlock { + struct { + uint32_t len; + uint8_t reserved0[3]; + uint8_t version; + uint32_t blk0_len; + uint8_t pbt; + uint8_t flags; + uint16_t reserved01; + uint8_t loadparm[LOADPARM_LEN]; + union { + IplBlockCcw ccw; + IplBlockFcp fcp; + IPLBlockPV pv; + IplBlockQemuScsi scsi; + }; + } QEMU_PACKED; + struct { + uint8_t reserved1[110]; + uint16_t devno; + uint8_t reserved2[88]; + uint8_t reserved_ext[4096 - 200]; + } QEMU_PACKED; +} QEMU_PACKED; +typedef union IplParameterBlock IplParameterBlock; + +#endif diff --git a/include/hw/s390x/s390-pci-bus.h b/include/hw/s390x/s390-pci-bus.h index 2c43ea1..04944d4 100644 --- a/include/hw/s390x/s390-pci-bus.h +++ b/include/hw/s390x/s390-pci-bus.h @@ -277,6 +277,7 @@ struct S390PCIIOMMU { AddressSpace as; MemoryRegion mr; IOMMUMemoryRegion iommu_mr; + MemoryRegion *dm_mr; bool enabled; uint64_t g_iota; uint64_t pba; @@ -362,6 +363,7 @@ struct S390PCIBusDevice { bool interp; bool forwarding_assist; bool aif; + bool rtr_avail; QTAILQ_ENTRY(S390PCIBusDevice) link; }; @@ -389,6 +391,7 @@ int pci_chsc_sei_nt2_have_event(void); void s390_pci_sclp_configure(SCCB *sccb); void s390_pci_sclp_deconfigure(SCCB *sccb); void s390_pci_iommu_enable(S390PCIIOMMU *iommu); +void s390_pci_iommu_direct_map_enable(S390PCIIOMMU *iommu); void s390_pci_iommu_disable(S390PCIIOMMU *iommu); void s390_pci_generate_error_event(uint16_t pec, uint32_t fh, uint32_t fid, uint64_t faddr, uint32_t e); diff --git a/include/hw/s390x/s390-pci-clp.h b/include/hw/s390x/s390-pci-clp.h index 03b7f9b..6a635d6 100644 --- a/include/hw/s390x/s390-pci-clp.h +++ b/include/hw/s390x/s390-pci-clp.h @@ -158,6 +158,7 @@ typedef struct ClpRspQueryPciGrp { #define CLP_RSP_QPCIG_MASK_NOI 0xfff uint16_t i; uint8_t version; +#define CLP_RSP_QPCIG_MASK_RTR 0x20 #define CLP_RSP_QPCIG_MASK_FRAME 0x2 #define CLP_RSP_QPCIG_MASK_REFRESH 0x1 uint8_t fr; diff --git a/include/hw/s390x/s390-pci-inst.h b/include/hw/s390x/s390-pci-inst.h index a55c448..5cb8da5 100644 --- a/include/hw/s390x/s390-pci-inst.h +++ b/include/hw/s390x/s390-pci-inst.h @@ -15,7 +15,7 @@ #define HW_S390_PCI_INST_H #include "s390-pci-bus.h" -#include "sysemu/dma.h" +#include "system/dma.h" /* Load/Store status codes */ #define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4 diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h index 996864a..526078a 100644 --- a/include/hw/s390x/s390-virtio-ccw.h +++ b/include/hw/s390x/s390-virtio-ccw.h @@ -29,10 +29,19 @@ struct S390CcwMachineState { bool dea_key_wrap; bool pv; uint8_t loadparm[8]; + uint64_t memory_limit; + uint64_t max_pagesize; SCLPDevice *sclp; }; +static inline uint64_t s390_get_memory_limit(S390CcwMachineState *s390ms) +{ + /* We expect to be called only after the limit was set. */ + assert(s390ms->memory_limit); + return s390ms->memory_limit; +} + #define S390_PTF_REASON_NONE (0x00 << 8) #define S390_PTF_REASON_DONE (0x01 << 8) #define S390_PTF_REASON_BUSY (0x02 << 8) @@ -44,17 +53,8 @@ struct S390CcwMachineClass { MachineClass parent_class; /*< public >*/ - bool ri_allowed; - bool cpu_model_allowed; - bool hpage_1m_allowed; int max_threads; + bool use_cpi; }; -/* runtime-instrumentation allowed by the machine */ -bool ri_allowed(void); -/* cpu model allowed by the machine */ -bool cpu_model_allowed(void); -/* 1M huge page mappings allowed by the machine */ -bool hpage_1m_allowed(void); - #endif diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h index 4d66c5e..91edaac 100644 --- a/include/hw/s390x/s390_flic.h +++ b/include/hw/s390x/s390_flic.h @@ -41,10 +41,7 @@ OBJECT_DECLARE_TYPE(S390FLICState, S390FLICStateClass, struct S390FLICState { SysBusDevice parent_obj; - /* to limit AdapterRoutes.num_routes for compat */ - uint32_t adapter_routes_max_batch; bool ais_supported; - bool migration_enabled; }; diff --git a/include/hw/s390x/storage-attributes.h b/include/hw/s390x/storage-attributes.h index 8921a04..b5c6d8f 100644 --- a/include/hw/s390x/storage-attributes.h +++ b/include/hw/s390x/storage-attributes.h @@ -25,7 +25,6 @@ OBJECT_DECLARE_TYPE(S390StAttribState, S390StAttribClass, S390_STATTRIB) struct S390StAttribState { DeviceState parent_obj; uint64_t migration_cur_gfn; - bool migration_enabled; }; diff --git a/include/hw/s390x/storage-keys.h b/include/hw/s390x/storage-keys.h index 976ffb2..ac30300 100644 --- a/include/hw/s390x/storage-keys.h +++ b/include/hw/s390x/storage-keys.h @@ -21,8 +21,6 @@ OBJECT_DECLARE_TYPE(S390SKeysState, S390SKeysClass, S390_SKEYS) struct S390SKeysState { DeviceState parent_obj; - bool migration_enabled; - }; @@ -124,7 +122,23 @@ int s390_skeys_set(S390SKeysState *ks, uint64_t start_gfn, S390SKeysState *s390_get_skeys_device(void); +void s390_qmp_dump_skeys(const char *filename, Error **errp); void hmp_dump_skeys(Monitor *mon, const QDict *qdict); void hmp_info_skeys(Monitor *mon, const QDict *qdict); +#define TYPE_DUMP_SKEYS_INTERFACE "dump-skeys-interface" + +typedef struct DumpSKeysInterface DumpSKeysInterface; +DECLARE_CLASS_CHECKERS(DumpSKeysInterface, DUMP_SKEYS_INTERFACE, + TYPE_DUMP_SKEYS_INTERFACE) + +struct DumpSKeysInterface { + InterfaceClass parent_class; + + /** + * @qmp_dump_skeys: Callback to dump guest's storage keys to @filename. + */ + void (*qmp_dump_skeys)(const char *filename, Error **errp); +}; + #endif /* S390_STORAGE_KEYS_H */ diff --git a/include/hw/s390x/vfio-ccw.h b/include/hw/s390x/vfio-ccw.h index 4209d27..1e0922d 100644 --- a/include/hw/s390x/vfio-ccw.h +++ b/include/hw/s390x/vfio-ccw.h @@ -14,7 +14,7 @@ #ifndef HW_VFIO_CCW_H #define HW_VFIO_CCW_H -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" #include "hw/s390x/s390-ccw.h" #include "hw/s390x/ccw-device.h" #include "qom/object.h" diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index c3d5e17..90ee192 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -24,6 +24,7 @@ struct SCSIRequest { SCSIBus *bus; SCSIDevice *dev; const SCSIReqOps *ops; + AioContext *ctx; uint32_t refcount; uint32_t tag; uint32_t lun; @@ -48,6 +49,8 @@ struct SCSIRequest { bool dma_started; BlockAIOCB *aiocb; QEMUSGList *sg; + + /* Protected by SCSIDevice->requests_lock */ QTAILQ_ENTRY(SCSIRequest) next; }; @@ -76,10 +79,7 @@ struct SCSIDevice uint8_t sense[SCSI_SENSE_BUF_SIZE]; uint32_t sense_len; - /* - * The requests list is only accessed from the AioContext that executes - * requests or from the main loop when IOThread processing is stopped. - */ + QemuMutex requests_lock; /* protects the requests list */ QTAILQ_HEAD(, SCSIRequest) requests; uint32_t channel; diff --git a/include/hw/sd/aspeed_sdhci.h b/include/hw/sd/aspeed_sdhci.h index 057bc5f..4ef1770 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/hw/sd/sd.h b/include/hw/sd/sd.h index d35a839..d6bad17 100644 --- a/include/hw/sd/sd.h +++ b/include/hw/sd/sd.h @@ -75,14 +75,6 @@ typedef enum { UHS_III = 3, /* currently not supported */ } sd_uhs_mode_t; -typedef enum { - sd_spi, - sd_bc, /* broadcast -- no response */ - sd_bcr, /* broadcast with response */ - sd_ac, /* addressed -- no data transfer */ - sd_adtc, /* addressed with data transfer */ -} sd_cmd_type_t; - typedef struct { uint8_t cmd; uint32_t arg; @@ -127,7 +119,6 @@ struct SDCardClass { void (*set_voltage)(SDState *sd, uint16_t millivolts); uint8_t (*get_dat_lines)(SDState *sd); bool (*get_cmd_line)(SDState *sd); - void (*enable)(SDState *sd, bool enable); bool (*get_inserted)(SDState *sd); bool (*get_readonly)(SDState *sd); void (*set_cid)(SDState *sd); diff --git a/include/hw/sd/sdcard_legacy.h b/include/hw/sd/sdcard_legacy.h deleted file mode 100644 index 0dc3889..0000000 --- a/include/hw/sd/sdcard_legacy.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SD Memory Card emulation (deprecated legacy API) - * - * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef HW_SDCARD_LEGACY_H -#define HW_SDCARD_LEGACY_H - -#include "hw/sd/sd.h" - -/* Legacy functions to be used only by non-qdevified callers */ -SDState *sd_init(BlockBackend *blk, bool is_spi); -int sd_do_command(SDState *card, SDRequest *request, uint8_t *response); -void sd_write_byte(SDState *card, uint8_t value); -uint8_t sd_read_byte(SDState *card); -void sd_set_cb(SDState *card, qemu_irq readonly, qemu_irq insert); - -/* sd_enable should not be used -- it is only used on the nseries boards, - * where it is part of a broken implementation of the MMC card slot switch - * (there should be two card slots which are multiplexed to a single MMC - * controller, but instead we model it with one card and controller and - * disable the card when the second slot is selected, so it looks like the - * second slot is always empty). - */ -void sd_enable(SDState *card, bool enable); - -#endif /* HW_SDCARD_LEGACY_H */ diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index 6cd2822..51fb30e 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -100,11 +100,16 @@ struct SDHCIState { uint8_t sd_spec_version; uint8_t uhs_mode; uint8_t vendor; /* For vendor specific functionality */ + /* + * Write Protect pin default active low for detecting SD card + * to be protected. Set wp_inverted to invert the signal. + */ + bool wp_inverted; }; typedef struct SDHCIState SDHCIState; #define SDHCI_VENDOR_NONE 0 -#define SDHCI_VENDOR_IMX 1 +#define SDHCI_VENDOR_FSL 2 /* * Controller does not provide transfer-complete interrupt when not diff --git a/include/hw/sh4/sh.h b/include/hw/sh4/sh.h index ec716cd..c82feef 100644 --- a/include/hw/sh4/sh.h +++ b/include/hw/sh4/sh.h @@ -38,29 +38,10 @@ struct SH7750State; struct SH7750State *sh7750_init(SuperHCPU *cpu, MemoryRegion *sysmem); -typedef struct { - /* The callback will be triggered if any of the designated lines change */ - uint16_t portamask_trigger; - uint16_t portbmask_trigger; - /* Return 0 if no action was taken */ - int (*port_change_cb) (uint16_t porta, uint16_t portb, - uint16_t *periph_pdtra, - uint16_t *periph_portdira, - uint16_t *periph_pdtrb, - uint16_t *periph_portdirb); -} sh7750_io_device; - -int sh7750_register_io_device(struct SH7750State *s, - sh7750_io_device *device); - -/* sh_serial.c */ #define TYPE_SH_SERIAL "sh-serial" #define SH_SERIAL_FEAT_SCIF (1 << 0) /* sh7750.c */ qemu_irq sh7750_irl(struct SH7750State *s); -/* tc58128.c */ -int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2); - #endif diff --git a/include/hw/sh4/sh_intc.h b/include/hw/sh4/sh_intc.h index f62d5c5..94f1831 100644 --- a/include/hw/sh4/sh_intc.h +++ b/include/hw/sh4/sh_intc.h @@ -1,7 +1,7 @@ #ifndef SH_INTC_H #define SH_INTC_H -#include "exec/memory.h" +#include "system/memory.h" typedef unsigned char intc_enum; diff --git a/include/hw/southbridge/ich9.h b/include/hw/southbridge/ich9.h index fd01649..1e231e8 100644 --- a/include/hw/southbridge/ich9.h +++ b/include/hw/southbridge/ich9.h @@ -7,7 +7,7 @@ #include "hw/pci/pci.h" #include "hw/pci/pci_device.h" #include "hw/rtc/mc146818rtc.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/notify.h" #include "qom/object.h" @@ -196,8 +196,12 @@ struct ICH9LPCState { #define ICH9_PMIO_GPE0_LEN 16 #define ICH9_PMIO_SMI_EN 0x30 #define ICH9_PMIO_SMI_EN_APMC_EN (1 << 5) +#define ICH9_PMIO_SMI_EN_SWSMI_EN (1 << 6) #define ICH9_PMIO_SMI_EN_TCO_EN (1 << 13) +#define ICH9_PMIO_SMI_EN_PERIODIC_EN (1 << 14) #define ICH9_PMIO_SMI_STS 0x34 +#define ICH9_PMIO_SMI_STS_SWSMI_STS (1 << 6) +#define ICH9_PMIO_SMI_STS_PERIODIC_STS (1 << 14) #define ICH9_PMIO_TCO_RLD 0x60 #define ICH9_PMIO_TCO_LEN 32 diff --git a/include/hw/ssi/allwinner-a10-spi.h b/include/hw/ssi/allwinner-a10-spi.h new file mode 100644 index 0000000..da46e29 --- /dev/null +++ b/include/hw/ssi/allwinner-a10-spi.h @@ -0,0 +1,57 @@ +/* + * Allwinner SPI Bus Serial Interface registers definition + * + * Copyright (C) 2024 Strahinja Jankovic. <strahinja.p.jankovic@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef ALLWINNER_A10_SPI_H +#define ALLWINNER_A10_SPI_H + +#include "hw/ssi/ssi.h" +#include "hw/sysbus.h" +#include "qemu/fifo8.h" +#include "qom/object.h" + +/** Size of register I/O address space used by SPI device */ +#define AW_A10_SPI_IOSIZE (0x1000) + +/** Total number of known registers */ +#define AW_A10_SPI_REGS_NUM (AW_A10_SPI_IOSIZE / sizeof(uint32_t)) +#define AW_A10_SPI_FIFO_SIZE (64) +#define AW_A10_SPI_CS_LINES_NR (4) + +#define TYPE_AW_A10_SPI "allwinner.spi" +OBJECT_DECLARE_SIMPLE_TYPE(AWA10SPIState, AW_A10_SPI) + +struct AWA10SPIState { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + SSIBus *bus; + qemu_irq irq; + qemu_irq cs_lines[AW_A10_SPI_CS_LINES_NR]; + + uint32_t regs[AW_A10_SPI_REGS_NUM]; + + Fifo8 rx_fifo; + Fifo8 tx_fifo; +}; + +#endif /* ALLWINNER_A10_SPI_H */ diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h index 234dca3..25b95e7 100644 --- a/include/hw/ssi/aspeed_smc.h +++ b/include/hw/ssi/aspeed_smc.h @@ -82,6 +82,7 @@ struct AspeedSMCState { uint8_t snoop_index; uint8_t snoop_dummies; + bool unselect; }; typedef struct AspeedSegments { diff --git a/include/hw/ssi/npcm7xx_fiu.h b/include/hw/ssi/npcm7xx_fiu.h index a3a1704..7ebd422 100644 --- a/include/hw/ssi/npcm7xx_fiu.h +++ b/include/hw/ssi/npcm7xx_fiu.h @@ -60,6 +60,7 @@ struct NPCM7xxFIUState { int32_t cs_count; int32_t active_cs; qemu_irq *cs_lines; + uint64_t flash_size; NPCM7xxFIUFlash *flash; SSIBus *spi; diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h index 8815f67..c591a06 100644 --- a/include/hw/ssi/pnv_spi.h +++ b/include/hw/ssi/pnv_spi.h @@ -23,6 +23,7 @@ #include "hw/ssi/ssi.h" #include "hw/sysbus.h" +#include "qemu/fifo8.h" #define TYPE_PNV_SPI "pnv-spi" OBJECT_DECLARE_SIMPLE_TYPE(PnvSpi, PNV_SPI) @@ -30,15 +31,19 @@ OBJECT_DECLARE_SIMPLE_TYPE(PnvSpi, PNV_SPI) #define PNV_SPI_REG_SIZE 8 #define PNV_SPI_REGS 7 -#define TYPE_PNV_SPI_BUS "pnv-spi-bus" +#define TYPE_PNV_SPI_BUS "spi" typedef struct PnvSpi { SysBusDevice parent_obj; SSIBus *ssi_bus; qemu_irq *cs_line; MemoryRegion xscom_spic_regs; + Fifo8 tx_fifo; + Fifo8 rx_fifo; + uint8_t fail_count; /* RDR Match failure counter */ /* SPI object number */ uint32_t spic_num; + uint32_t chip_id; uint8_t transfer_len; uint8_t responder_select; /* To verify if shift_n1 happens prior to shift_n2 */ diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index 3cb29a4..7dc88aa 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -4,7 +4,7 @@ /* Devices attached directly to the main system bus. */ #include "hw/qdev-core.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qom/object.h" #define QDEV_MAX_MMIO 32 @@ -19,6 +19,8 @@ DECLARE_INSTANCE_CHECKER(BusState, SYSTEM_BUS, OBJECT_DECLARE_TYPE(SysBusDevice, SysBusDeviceClass, SYS_BUS_DEVICE) +#define TYPE_DYNAMIC_SYS_BUS_DEVICE "dynamic-sysbus-device" + /** * SysBusDeviceClass: * @@ -82,7 +84,6 @@ qemu_irq sysbus_get_connected_irq(SysBusDevice *dev, int n); void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr); void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr, int priority); -void sysbus_mmio_unmap(SysBusDevice *dev, int n); bool sysbus_realize(SysBusDevice *dev, Error **errp); bool sysbus_realize_and_unref(SysBusDevice *dev, Error **errp); diff --git a/include/hw/timer/aspeed_timer.h b/include/hw/timer/aspeed_timer.h index 07dc6b6..a850625 100644 --- a/include/hw/timer/aspeed_timer.h +++ b/include/hw/timer/aspeed_timer.h @@ -16,8 +16,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * with this program; if not, see <https://www.gnu.org/licenses/>. */ #ifndef ASPEED_TIMER_H #define ASPEED_TIMER_H @@ -32,6 +31,7 @@ OBJECT_DECLARE_TYPE(AspeedTimerCtrlState, AspeedTimerClass, ASPEED_TIMER) #define TYPE_ASPEED_2500_TIMER TYPE_ASPEED_TIMER "-ast2500" #define TYPE_ASPEED_2600_TIMER TYPE_ASPEED_TIMER "-ast2600" #define TYPE_ASPEED_1030_TIMER TYPE_ASPEED_TIMER "-ast1030" +#define TYPE_ASPEED_2700_TIMER TYPE_ASPEED_TIMER "-ast2700" #define ASPEED_TIMER_NR_TIMERS 8 diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h index d17a8d4..c2656f7 100644 --- a/include/hw/timer/hpet.h +++ b/include/hw/timer/hpet.h @@ -58,7 +58,6 @@ #define HPET_TN_CFG_WRITE_MASK 0x7f4e #define HPET_TN_INT_ROUTE_SHIFT 9 #define HPET_TN_INT_ROUTE_CAP_SHIFT 32 -#define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U struct hpet_fw_entry { @@ -74,7 +73,7 @@ struct hpet_fw_config struct hpet_fw_entry hpet[8]; } QEMU_PACKED; -extern struct hpet_fw_config hpet_cfg; +extern struct hpet_fw_config hpet_fw_cfg; #define TYPE_HPET "hpet" diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h index 5a1230d..5488f7e 100644 --- a/include/hw/timer/imx_gpt.h +++ b/include/hw/timer/imx_gpt.h @@ -80,6 +80,7 @@ #define TYPE_IMX6_GPT "imx6.gpt" #define TYPE_IMX6UL_GPT "imx6ul.gpt" #define TYPE_IMX7_GPT "imx7.gpt" +#define TYPE_IMX8MP_GPT "imx8mp.gpt" #define TYPE_IMX_GPT TYPE_IMX25_GPT diff --git a/include/hw/timer/npcm7xx_timer.h b/include/hw/timer/npcm7xx_timer.h index d45c051..e287375 100644 --- a/include/hw/timer/npcm7xx_timer.h +++ b/include/hw/timer/npcm7xx_timer.h @@ -16,7 +16,7 @@ #ifndef NPCM7XX_TIMER_H #define NPCM7XX_TIMER_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" #include "qemu/timer.h" diff --git a/include/hw/tricore/triboard.h b/include/hw/tricore/triboard.h index 4fdd2d7..ca49a0c 100644 --- a/include/hw/tricore/triboard.h +++ b/include/hw/tricore/triboard.h @@ -20,8 +20,8 @@ #include "qapi/error.h" #include "hw/boards.h" -#include "sysemu/sysemu.h" -#include "exec/address-spaces.h" +#include "system/system.h" +#include "system/address-spaces.h" #include "qom/object.h" #include "hw/tricore/tc27x_soc.h" diff --git a/include/hw/tricore/tricore.h b/include/hw/tricore/tricore.h index c19ed3f..4ffc0fe 100644 --- a/include/hw/tricore/tricore.h +++ b/include/hw/tricore/tricore.h @@ -1,7 +1,7 @@ #ifndef HW_TRICORE_H #define HW_TRICORE_H -#include "exec/memory.h" +#include "system/memory.h" struct tricore_boot_info { uint64_t ram_size; diff --git a/include/hw/uefi/hardware-info.h b/include/hw/uefi/hardware-info.h new file mode 100644 index 0000000..94c38cf --- /dev/null +++ b/include/hw/uefi/hardware-info.h @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * pass hardware information to uefi + * + * see OvmfPkg/Library/HardwareInfoLib/ in edk2 + */ +#ifndef QEMU_UEFI_HARDWARE_INFO_H +#define QEMU_UEFI_HARDWARE_INFO_H + +/* data structures */ + +typedef enum { + HardwareInfoTypeUndefined = 0, + HardwareInfoTypeHostBridge = 1, + HardwareInfoQemuUefiVars = 2, +} HARDWARE_INFO_TYPE; + +typedef struct { + union { + uint64_t uint64; + HARDWARE_INFO_TYPE value; + } type; + uint64_t size; +} HARDWARE_INFO_HEADER; + +typedef struct { + uint64_t mmio_address; +} HARDWARE_INFO_SIMPLE_DEVICE; + +/* qemu functions */ + +void hardware_info_register(HARDWARE_INFO_TYPE type, void *info, uint64_t size); + +#endif /* QEMU_UEFI_HARDWARE_INFO_H */ diff --git a/include/hw/uefi/var-service-api.h b/include/hw/uefi/var-service-api.h new file mode 100644 index 0000000..0d71638 --- /dev/null +++ b/include/hw/uefi/var-service-api.h @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * uefi-vars device - API of the virtual device for guest/host communication. + */ +#ifndef QEMU_UEFI_VAR_SERVICE_API_H +#define QEMU_UEFI_VAR_SERVICE_API_H + +/* qom: device names */ +#define TYPE_UEFI_VARS_X64 "uefi-vars-x64" +#define TYPE_UEFI_VARS_SYSBUS "uefi-vars-sysbus" + +/* sysbus: fdt node path */ +#define UEFI_VARS_FDT_NODE "qemu-uefi-vars" +#define UEFI_VARS_FDT_COMPAT "qemu,uefi-vars" + +/* registers */ +#define UEFI_VARS_REG_MAGIC 0x00 /* 16 bit */ +#define UEFI_VARS_REG_CMD_STS 0x02 /* 16 bit */ +#define UEFI_VARS_REG_BUFFER_SIZE 0x04 /* 32 bit */ +#define UEFI_VARS_REG_DMA_BUFFER_ADDR_LO 0x08 /* 32 bit */ +#define UEFI_VARS_REG_DMA_BUFFER_ADDR_HI 0x0c /* 32 bit */ +#define UEFI_VARS_REG_PIO_BUFFER_TRANSFER 0x10 /* 8-64 bit */ +#define UEFI_VARS_REG_PIO_BUFFER_CRC32C 0x18 /* 32 bit (read-only) */ +#define UEFI_VARS_REG_FLAGS 0x1c /* 32 bit */ +#define UEFI_VARS_REGS_SIZE 0x20 + +/* flags register */ +#define UEFI_VARS_FLAG_USE_PIO (1 << 0) + +/* magic value */ +#define UEFI_VARS_MAGIC_VALUE 0xef1 + +/* command values */ +#define UEFI_VARS_CMD_RESET 0x01 +#define UEFI_VARS_CMD_DMA_MM 0x02 +#define UEFI_VARS_CMD_PIO_MM 0x03 +#define UEFI_VARS_CMD_PIO_ZERO_OFFSET 0x04 + +/* status values */ +#define UEFI_VARS_STS_SUCCESS 0x00 +#define UEFI_VARS_STS_BUSY 0x01 +#define UEFI_VARS_STS_ERR_UNKNOWN 0x10 +#define UEFI_VARS_STS_ERR_NOT_SUPPORTED 0x11 +#define UEFI_VARS_STS_ERR_BAD_BUFFER_SIZE 0x12 + + +#endif /* QEMU_UEFI_VAR_SERVICE_API_H */ diff --git a/include/hw/uefi/var-service-edk2.h b/include/hw/uefi/var-service-edk2.h new file mode 100644 index 0000000..c743a8d --- /dev/null +++ b/include/hw/uefi/var-service-edk2.h @@ -0,0 +1,227 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * uefi-vars device - structs and defines from edk2 + * + * Note: The edk2 UINTN type has been mapped to uint64_t, + * so the structs are compatible with 64bit edk2 builds. + */ +#ifndef QEMU_UEFI_VAR_SERVICE_EDK2_H +#define QEMU_UEFI_VAR_SERVICE_EDK2_H + +#include "qemu/uuid.h" + +#define MAX_BIT 0x8000000000000000ULL +#define ENCODE_ERROR(StatusCode) (MAX_BIT | (StatusCode)) +#define EFI_SUCCESS 0 +#define EFI_INVALID_PARAMETER ENCODE_ERROR(2) +#define EFI_UNSUPPORTED ENCODE_ERROR(3) +#define EFI_BAD_BUFFER_SIZE ENCODE_ERROR(4) +#define EFI_BUFFER_TOO_SMALL ENCODE_ERROR(5) +#define EFI_WRITE_PROTECTED ENCODE_ERROR(8) +#define EFI_OUT_OF_RESOURCES ENCODE_ERROR(9) +#define EFI_NOT_FOUND ENCODE_ERROR(14) +#define EFI_ACCESS_DENIED ENCODE_ERROR(15) +#define EFI_ALREADY_STARTED ENCODE_ERROR(20) +#define EFI_SECURITY_VIOLATION ENCODE_ERROR(26) + +#define EFI_VARIABLE_NON_VOLATILE 0x01 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x02 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x04 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x08 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x10 /* deprecated */ +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x20 +#define EFI_VARIABLE_APPEND_WRITE 0x40 + +/* SecureBootEnable */ +#define SECURE_BOOT_ENABLE 1 +#define SECURE_BOOT_DISABLE 0 + +/* SecureBoot */ +#define SECURE_BOOT_MODE_ENABLE 1 +#define SECURE_BOOT_MODE_DISABLE 0 + +/* CustomMode */ +#define CUSTOM_SECURE_BOOT_MODE 1 +#define STANDARD_SECURE_BOOT_MODE 0 + +/* SetupMode */ +#define SETUP_MODE 1 +#define USER_MODE 0 + +typedef uint64_t efi_status; +typedef struct mm_header mm_header; + +/* EFI_MM_COMMUNICATE_HEADER */ +struct mm_header { + QemuUUID guid; + uint64_t length; +}; + +/* --- EfiSmmVariableProtocol ---------------------------------------- */ + +#define SMM_VARIABLE_FUNCTION_GET_VARIABLE 1 +#define SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME 2 +#define SMM_VARIABLE_FUNCTION_SET_VARIABLE 3 +#define SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO 4 +#define SMM_VARIABLE_FUNCTION_READY_TO_BOOT 5 +#define SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE 6 +#define SMM_VARIABLE_FUNCTION_LOCK_VARIABLE 8 +#define SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE 11 + +typedef struct mm_variable mm_variable; +typedef struct mm_variable_access mm_variable_access; +typedef struct mm_next_variable mm_next_variable; +typedef struct mm_next_variable mm_lock_variable; +typedef struct mm_variable_info mm_variable_info; +typedef struct mm_get_payload_size mm_get_payload_size; + +/* SMM_VARIABLE_COMMUNICATE_HEADER */ +struct mm_variable { + uint64_t function; + uint64_t status; +}; + +/* SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE */ +struct QEMU_PACKED mm_variable_access { + QemuUUID guid; + uint64_t data_size; + uint64_t name_size; + uint32_t attributes; + /* Name */ + /* Data */ +}; + +/* SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME */ +struct mm_next_variable { + QemuUUID guid; + uint64_t name_size; + /* Name */ +}; + +/* SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO */ +struct QEMU_PACKED mm_variable_info { + uint64_t max_storage_size; + uint64_t free_storage_size; + uint64_t max_variable_size; + uint32_t attributes; +}; + +/* SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE */ +struct mm_get_payload_size { + uint64_t payload_size; +}; + +/* --- VarCheckPolicyLibMmiHandler ----------------------------------- */ + +#define VAR_CHECK_POLICY_COMMAND_DISABLE 0x01 +#define VAR_CHECK_POLICY_COMMAND_IS_ENABLED 0x02 +#define VAR_CHECK_POLICY_COMMAND_REGISTER 0x03 +#define VAR_CHECK_POLICY_COMMAND_DUMP 0x04 +#define VAR_CHECK_POLICY_COMMAND_LOCK 0x05 + +typedef struct mm_check_policy mm_check_policy; +typedef struct mm_check_policy_is_enabled mm_check_policy_is_enabled; +typedef struct mm_check_policy_dump_params mm_check_policy_dump_params; + +/* VAR_CHECK_POLICY_COMM_HEADER */ +struct QEMU_PACKED mm_check_policy { + uint32_t signature; + uint32_t revision; + uint32_t command; + uint64_t result; +}; + +/* VAR_CHECK_POLICY_COMM_IS_ENABLED_PARAMS */ +struct QEMU_PACKED mm_check_policy_is_enabled { + uint8_t state; +}; + +/* VAR_CHECK_POLICY_COMM_DUMP_PARAMS */ +struct QEMU_PACKED mm_check_policy_dump_params { + uint32_t page_requested; + uint32_t total_size; + uint32_t page_size; + uint8_t has_more; +}; + +/* --- Edk2VariablePolicyProtocol ------------------------------------ */ + +#define VARIABLE_POLICY_ENTRY_REVISION 0x00010000 + +#define VARIABLE_POLICY_TYPE_NO_LOCK 0 +#define VARIABLE_POLICY_TYPE_LOCK_NOW 1 +#define VARIABLE_POLICY_TYPE_LOCK_ON_CREATE 2 +#define VARIABLE_POLICY_TYPE_LOCK_ON_VAR_STATE 3 + +typedef struct variable_policy_entry variable_policy_entry; +typedef struct variable_lock_on_var_state variable_lock_on_var_state; + +/* VARIABLE_POLICY_ENTRY */ +struct variable_policy_entry { + uint32_t version; + uint16_t size; + uint16_t offset_to_name; + QemuUUID namespace; + uint32_t min_size; + uint32_t max_size; + uint32_t attributes_must_have; + uint32_t attributes_cant_have; + uint8_t lock_policy_type; + uint8_t padding[3]; + /* LockPolicy */ + /* Name */ +}; + +/* VARIABLE_LOCK_ON_VAR_STATE_POLICY */ +struct variable_lock_on_var_state { + QemuUUID namespace; + uint8_t value; + uint8_t padding; + /* Name */ +}; + +/* --- variable authentication --------------------------------------- */ + +#define WIN_CERT_TYPE_EFI_GUID 0x0EF1 + +typedef struct efi_time efi_time; +typedef struct efi_siglist efi_siglist; +typedef struct variable_auth_2 variable_auth_2; + +/* EFI_TIME */ +struct efi_time { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t pad1; + uint32_t nanosecond; + int16_t timezone; + uint8_t daylight; + uint8_t pad2; +}; + +/* EFI_SIGNATURE_LIST */ +struct efi_siglist { + QemuUUID guid_type; + uint32_t siglist_size; + uint32_t header_size; + uint32_t sig_size; +}; + +/* EFI_VARIABLE_AUTHENTICATION_2 */ +struct variable_auth_2 { + struct efi_time timestamp; + + /* WIN_CERTIFICATE_UEFI_GUID */ + uint32_t hdr_length; + uint16_t hdr_revision; + uint16_t hdr_cert_type; + QemuUUID guid_cert_type; + uint8_t cert_data[]; +}; + +#endif /* QEMU_UEFI_VAR_SERVICE_EDK2_H */ diff --git a/include/hw/uefi/var-service.h b/include/hw/uefi/var-service.h new file mode 100644 index 0000000..f7ceac4 --- /dev/null +++ b/include/hw/uefi/var-service.h @@ -0,0 +1,191 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * uefi-vars device - state struct and function prototypes + */ +#ifndef QEMU_UEFI_VAR_SERVICE_H +#define QEMU_UEFI_VAR_SERVICE_H + +#include "qemu/uuid.h" +#include "qemu/queue.h" + +#include "hw/uefi/var-service-edk2.h" + +#define MAX_BUFFER_SIZE (64 * 1024) + +typedef struct uefi_variable uefi_variable; +typedef struct uefi_var_policy uefi_var_policy; +typedef struct uefi_vars_state uefi_vars_state; + +typedef struct uefi_vars_cert uefi_vars_cert; +typedef struct uefi_vars_hash uefi_vars_hash; +typedef struct uefi_vars_siglist uefi_vars_siglist; + +struct uefi_variable { + QemuUUID guid; + uint16_t *name; + uint32_t name_size; + uint32_t attributes; + void *data; + uint32_t data_size; + efi_time time; + void *digest; + uint32_t digest_size; + QTAILQ_ENTRY(uefi_variable) next; +}; + +struct uefi_var_policy { + variable_policy_entry *entry; + uint32_t entry_size; + uint16_t *name; + uint32_t name_size; + + /* number of hashmarks (wildcard character) in name */ + uint32_t hashmarks; + + QTAILQ_ENTRY(uefi_var_policy) next; +}; + +struct uefi_vars_state { + MemoryRegion mr; + uint16_t sts; + uint32_t buf_size; + uint32_t buf_addr_lo; + uint32_t buf_addr_hi; + uint8_t *buffer; + QTAILQ_HEAD(, uefi_variable) variables; + QTAILQ_HEAD(, uefi_var_policy) var_policies; + + /* pio transfer buffer */ + uint32_t pio_xfer_offset; + uint8_t *pio_xfer_buffer; + + /* boot phases */ + bool end_of_dxe; + bool ready_to_boot; + bool exit_boot_service; + bool policy_locked; + + /* storage accounting */ + uint64_t max_storage; + uint64_t used_storage; + + /* config options */ + char *jsonfile; + int jsonfd; + bool force_secure_boot; + bool disable_custom_mode; + bool use_pio; +}; + +struct uefi_vars_cert { + QTAILQ_ENTRY(uefi_vars_cert) next; + QemuUUID owner; + uint64_t size; + uint8_t data[]; +}; + +struct uefi_vars_hash { + QTAILQ_ENTRY(uefi_vars_hash) next; + QemuUUID owner; + uint8_t data[]; +}; + +struct uefi_vars_siglist { + QTAILQ_HEAD(, uefi_vars_cert) x509; + QTAILQ_HEAD(, uefi_vars_hash) sha256; +}; + +/* vars-service-guid.c */ +extern const QemuUUID EfiGlobalVariable; +extern const QemuUUID EfiImageSecurityDatabase; +extern const QemuUUID EfiCustomModeEnable; +extern const QemuUUID EfiSecureBootEnableDisable; + +extern const QemuUUID EfiCertSha256Guid; +extern const QemuUUID EfiCertSha384Guid; +extern const QemuUUID EfiCertSha512Guid; +extern const QemuUUID EfiCertRsa2048Guid; +extern const QemuUUID EfiCertX509Guid; +extern const QemuUUID EfiCertTypePkcs7Guid; + +extern const QemuUUID EfiSmmVariableProtocolGuid; +extern const QemuUUID VarCheckPolicyLibMmiHandlerGuid; + +extern const QemuUUID EfiEndOfDxeEventGroupGuid; +extern const QemuUUID EfiEventReadyToBootGuid; +extern const QemuUUID EfiEventExitBootServicesGuid; + +/* vars-service-utils.c */ +gboolean uefi_str_is_valid(const uint16_t *str, size_t len, + gboolean must_be_null_terminated); +size_t uefi_strlen(const uint16_t *str, size_t len); +gboolean uefi_str_equal_ex(const uint16_t *a, size_t alen, + const uint16_t *b, size_t blen, + gboolean wildcards_in_a); +gboolean uefi_str_equal(const uint16_t *a, size_t alen, + const uint16_t *b, size_t blen); +char *uefi_ucs2_to_ascii(const uint16_t *ucs2, uint64_t ucs2_size); +int uefi_time_compare(efi_time *a, efi_time *b); +void uefi_trace_variable(const char *action, QemuUUID guid, + const uint16_t *name, uint64_t name_size); +void uefi_trace_status(const char *action, efi_status status); + +/* vars-service-core.c */ +extern const VMStateDescription vmstate_uefi_vars; +void uefi_vars_init(Object *obj, uefi_vars_state *uv); +void uefi_vars_realize(uefi_vars_state *uv, Error **errp); +void uefi_vars_hard_reset(uefi_vars_state *uv); + +/* vars-service-json.c */ +void uefi_vars_json_init(uefi_vars_state *uv, Error **errp); +void uefi_vars_json_save(uefi_vars_state *uv); +void uefi_vars_json_load(uefi_vars_state *uv, Error **errp); + +/* vars-service-vars.c */ +extern const VMStateDescription vmstate_uefi_variable; +uefi_variable *uefi_vars_find_variable(uefi_vars_state *uv, QemuUUID guid, + const uint16_t *name, + uint64_t name_size); +void uefi_vars_set_variable(uefi_vars_state *uv, QemuUUID guid, + const uint16_t *name, uint64_t name_size, + uint32_t attributes, + void *data, uint64_t data_size); +void uefi_vars_clear_volatile(uefi_vars_state *uv); +void uefi_vars_clear_all(uefi_vars_state *uv); +void uefi_vars_update_storage(uefi_vars_state *uv); +uint32_t uefi_vars_mm_vars_proto(uefi_vars_state *uv); + +/* vars-service-auth.c */ +bool uefi_vars_is_sb_pk(uefi_variable *var); +bool uefi_vars_is_sb_any(uefi_variable *var); +efi_status uefi_vars_check_auth_2(uefi_vars_state *uv, uefi_variable *var, + mm_variable_access *va, void *data); +efi_status uefi_vars_check_secure_boot(uefi_vars_state *uv, uefi_variable *var); +void uefi_vars_auth_init(uefi_vars_state *uv); + +/* vars-service-pkcs7.c */ +efi_status uefi_vars_check_pkcs7_2(uefi_variable *siglist, + void **digest, uint32_t *digest_size, + mm_variable_access *va, void *data); + +/* vars-service-siglist.c */ +void uefi_vars_siglist_init(uefi_vars_siglist *siglist); +void uefi_vars_siglist_free(uefi_vars_siglist *siglist); +void uefi_vars_siglist_parse(uefi_vars_siglist *siglist, + void *data, uint64_t size); +uint64_t uefi_vars_siglist_blob_size(uefi_vars_siglist *siglist); +void uefi_vars_siglist_blob_generate(uefi_vars_siglist *siglist, + void *data, uint64_t size); + +/* vars-service-policy.c */ +extern const VMStateDescription vmstate_uefi_var_policy; +efi_status uefi_vars_policy_check(uefi_vars_state *uv, + uefi_variable *var, + gboolean is_newvar); +void uefi_vars_policies_clear(uefi_vars_state *uv); +uefi_var_policy *uefi_vars_add_policy(uefi_vars_state *uv, + variable_policy_entry *pe); +uint32_t uefi_vars_mm_check_policy_proto(uefi_vars_state *uv); + +#endif /* QEMU_UEFI_VAR_SERVICE_H */ diff --git a/include/hw/usb.h b/include/hw/usb.h index d46d967..26a9f3e 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -25,7 +25,7 @@ * THE SOFTWARE. */ -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "qemu/iov.h" #include "qemu/queue.h" @@ -579,16 +579,6 @@ void usb_pcap_init(FILE *fp); void usb_pcap_ctrl(USBPacket *p, bool setup); void usb_pcap_data(USBPacket *p, bool setup); -static inline USBDevice *usb_new(const char *name) -{ - return USB_DEVICE(qdev_new(name)); -} - -static inline USBDevice *usb_try_new(const char *name) -{ - return USB_DEVICE(qdev_try_new(name)); -} - static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **errp) { return qdev_realize_and_unref(&dev->qdev, &bus->qbus, errp); @@ -596,7 +586,7 @@ static inline bool usb_realize_and_unref(USBDevice *dev, USBBus *bus, Error **er static inline USBDevice *usb_create_simple(USBBus *bus, const char *name) { - USBDevice *dev = usb_new(name); + USBDevice *dev = USB_DEVICE(qdev_new(name)); usb_realize_and_unref(dev, bus, &error_abort); return dev; diff --git a/include/hw/usb/dwc2-regs.h b/include/hw/usb/dwc2-regs.h index 0bf3f2a..b8b4266 100644 --- a/include/hw/usb/dwc2-regs.h +++ b/include/hw/usb/dwc2-regs.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) */ /* * Imported from the Linux kernel file drivers/usb/dwc2/hw.h, commit * a89bae709b3492b478480a2c9734e7e9393b279c ("usb: dwc2: Move @@ -838,7 +838,7 @@ struct dwc2_dma_desc { uint32_t status; uint32_t buf; -} __packed; +} QEMU_PACKED; /* Host Mode DMA descriptor status quadlet */ diff --git a/include/hw/usb/hcd-dwc3.h b/include/hw/usb/hcd-dwc3.h index f752a27..dbdf12b 100644 --- a/include/hw/usb/hcd-dwc3.h +++ b/include/hw/usb/hcd-dwc3.h @@ -35,7 +35,7 @@ #define USB_DWC3(obj) \ OBJECT_CHECK(USBDWC3, (obj), TYPE_USB_DWC3) -#define USB_DWC3_R_MAX ((0x530 / 4) + 1) +#define USB_DWC3_R_MAX (0x600 / 4) #define DWC3_SIZE 0x10000 typedef struct USBDWC3 { diff --git a/include/hw/usb/hcd-musb.h b/include/hw/usb/hcd-musb.h deleted file mode 100644 index 4d4b1ec..0000000 --- a/include/hw/usb/hcd-musb.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * "Inventra" High-speed Dual-Role Controller (MUSB-HDRC), Mentor Graphics, - * USB2.0 OTG compliant core used in various chips. - * - * Only host-mode and non-DMA accesses are currently supported. - * - * Copyright (C) 2008 Nokia Corporation - * Written by Andrzej Zaborowski <balrog@zabor.org> - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#ifndef HW_USB_HCD_MUSB_H -#define HW_USB_HCD_MUSB_H - -#include "exec/hwaddr.h" - -enum musb_irq_source_e { - musb_irq_suspend = 0, - musb_irq_resume, - musb_irq_rst_babble, - musb_irq_sof, - musb_irq_connect, - musb_irq_disconnect, - musb_irq_vbus_request, - musb_irq_vbus_error, - musb_irq_rx, - musb_irq_tx, - musb_set_vbus, - musb_set_session, - /* Add new interrupts here */ - musb_irq_max /* total number of interrupts defined */ -}; - -/* TODO convert hcd-musb to QOM/qdev and remove MUSBReadFunc/MUSBWriteFunc */ -typedef void MUSBWriteFunc(void *opaque, hwaddr addr, uint32_t value); -typedef uint32_t MUSBReadFunc(void *opaque, hwaddr addr); -extern MUSBReadFunc * const musb_read[]; -extern MUSBWriteFunc * const musb_write[]; - -typedef struct MUSBState MUSBState; - -MUSBState *musb_init(DeviceState *parent_device, int gpio_base); -void musb_reset(MUSBState *s); -uint32_t musb_core_intr_get(MUSBState *s); -void musb_core_intr_clear(MUSBState *s, uint32_t mask); -void musb_set_size(MUSBState *s, int epnum, int size, int is_tx); - -#endif diff --git a/include/hw/usb/uhci-regs.h b/include/hw/usb/uhci-regs.h index fd45d29..5b81714 100644 --- a/include/hw/usb/uhci-regs.h +++ b/include/hw/usb/uhci-regs.h @@ -1,6 +1,17 @@ #ifndef HW_USB_UHCI_REGS_H #define HW_USB_UHCI_REGS_H +#define UHCI_USBCMD 0 +#define UHCI_USBSTS 2 +#define UHCI_USBINTR 4 +#define UHCI_USBFRNUM 6 +#define UHCI_USBFLBASEADD 8 +#define UHCI_USBSOF 0x0c +#define UHCI_USBPORTSC1 0x10 +#define UHCI_USBPORTSC2 0x12 +#define UHCI_USBPORTSC3 0x14 +#define UHCI_USBPORTSC4 0x16 + #define UHCI_CMD_FGR (1 << 4) #define UHCI_CMD_EGSM (1 << 3) #define UHCI_CMD_GRESET (1 << 2) diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h deleted file mode 100644 index fed499b..0000000 --- a/include/hw/vfio/vfio-common.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * common header for vfio based device assignment support - * - * Copyright Red Hat, Inc. 2012 - * - * Authors: - * Alex Williamson <alex.williamson@redhat.com> - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - * Based on qemu-kvm device-assignment: - * Adapted for KVM by Qumranet. - * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) - * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) - * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) - * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) - * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) - */ - -#ifndef HW_VFIO_VFIO_COMMON_H -#define HW_VFIO_VFIO_COMMON_H - -#include "exec/memory.h" -#include "qemu/queue.h" -#include "qemu/notify.h" -#include "ui/console.h" -#include "hw/display/ramfb.h" -#ifdef CONFIG_LINUX -#include <linux/vfio.h> -#endif -#include "sysemu/sysemu.h" -#include "hw/vfio/vfio-container-base.h" -#include "sysemu/host_iommu_device.h" -#include "sysemu/iommufd.h" - -#define VFIO_MSG_PREFIX "vfio %s: " - -enum { - VFIO_DEVICE_TYPE_PCI = 0, - VFIO_DEVICE_TYPE_PLATFORM = 1, - VFIO_DEVICE_TYPE_CCW = 2, - VFIO_DEVICE_TYPE_AP = 3, -}; - -typedef struct VFIOMmap { - MemoryRegion mem; - void *mmap; - off_t offset; - size_t size; -} VFIOMmap; - -typedef struct VFIORegion { - struct VFIODevice *vbasedev; - off_t fd_offset; /* offset of region within device fd */ - MemoryRegion *mem; /* slow, read/write access */ - size_t size; - uint32_t flags; /* VFIO region flags (rd/wr/mmap) */ - uint32_t nr_mmaps; - VFIOMmap *mmaps; - uint8_t nr; /* cache the region number for debug */ -} VFIORegion; - -typedef struct VFIOMigration { - struct VFIODevice *vbasedev; - VMChangeStateEntry *vm_state; - NotifierWithReturn migration_state; - uint32_t device_state; - int data_fd; - void *data_buffer; - size_t data_buffer_size; - uint64_t mig_flags; - uint64_t precopy_init_size; - uint64_t precopy_dirty_size; - bool initial_data_sent; -} VFIOMigration; - -struct VFIOGroup; - -typedef struct VFIOContainer { - VFIOContainerBase bcontainer; - int fd; /* /dev/vfio/vfio, empowered by the attached groups */ - unsigned iommu_type; - QLIST_HEAD(, VFIOGroup) group_list; -} VFIOContainer; - -OBJECT_DECLARE_SIMPLE_TYPE(VFIOContainer, VFIO_IOMMU_LEGACY); - -typedef struct VFIOHostDMAWindow { - hwaddr min_iova; - hwaddr max_iova; - uint64_t iova_pgsizes; - QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; -} VFIOHostDMAWindow; - -typedef struct IOMMUFDBackend IOMMUFDBackend; - -typedef struct VFIOIOASHwpt { - uint32_t hwpt_id; - uint32_t hwpt_flags; - QLIST_HEAD(, VFIODevice) device_list; - QLIST_ENTRY(VFIOIOASHwpt) next; -} VFIOIOASHwpt; - -typedef struct VFIOIOMMUFDContainer { - VFIOContainerBase bcontainer; - IOMMUFDBackend *be; - uint32_t ioas_id; - QLIST_HEAD(, VFIOIOASHwpt) hwpt_list; -} VFIOIOMMUFDContainer; - -OBJECT_DECLARE_SIMPLE_TYPE(VFIOIOMMUFDContainer, VFIO_IOMMU_IOMMUFD); - -typedef struct VFIODeviceOps VFIODeviceOps; - -typedef struct VFIODevice { - QLIST_ENTRY(VFIODevice) next; - QLIST_ENTRY(VFIODevice) container_next; - QLIST_ENTRY(VFIODevice) global_next; - struct VFIOGroup *group; - VFIOContainerBase *bcontainer; - char *sysfsdev; - char *name; - DeviceState *dev; - int fd; - int type; - bool mdev; - bool reset_works; - bool needs_reset; - bool no_mmap; - bool ram_block_discard_allowed; - OnOffAuto enable_migration; - bool migration_events; - VFIODeviceOps *ops; - unsigned int num_irqs; - unsigned int num_regions; - unsigned int flags; - VFIOMigration *migration; - Error *migration_blocker; - OnOffAuto pre_copy_dirty_page_tracking; - OnOffAuto device_dirty_page_tracking; - bool dirty_pages_supported; - bool dirty_tracking; - bool iommu_dirty_tracking; - HostIOMMUDevice *hiod; - int devid; - IOMMUFDBackend *iommufd; - VFIOIOASHwpt *hwpt; - QLIST_ENTRY(VFIODevice) hwpt_next; -} VFIODevice; - -struct VFIODeviceOps { - void (*vfio_compute_needs_reset)(VFIODevice *vdev); - int (*vfio_hot_reset_multi)(VFIODevice *vdev); - void (*vfio_eoi)(VFIODevice *vdev); - Object *(*vfio_get_object)(VFIODevice *vdev); - - /** - * @vfio_save_config - * - * Save device config state - * - * @vdev: #VFIODevice for which to save the config - * @f: #QEMUFile where to send the data - * @errp: pointer to Error*, to store an error if it happens. - * - * Returns zero to indicate success and negative for error - */ - int (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f, Error **errp); - - /** - * @vfio_load_config - * - * Load device config state - * - * @vdev: #VFIODevice for which to load the config - * @f: #QEMUFile where to get the data - * - * Returns zero to indicate success and negative for error - */ - int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f); -}; - -typedef struct VFIOGroup { - int fd; - int groupid; - VFIOContainer *container; - QLIST_HEAD(, VFIODevice) device_list; - QLIST_ENTRY(VFIOGroup) next; - QLIST_ENTRY(VFIOGroup) container_next; - bool ram_block_discard_allowed; -} VFIOGroup; - -#define TYPE_HOST_IOMMU_DEVICE_LEGACY_VFIO TYPE_HOST_IOMMU_DEVICE "-legacy-vfio" -#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO \ - TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio" - -typedef struct VFIODMABuf { - QemuDmaBuf *buf; - uint32_t pos_x, pos_y, pos_updates; - uint32_t hot_x, hot_y, hot_updates; - int dmabuf_id; - QTAILQ_ENTRY(VFIODMABuf) next; -} VFIODMABuf; - -typedef struct VFIODisplay { - QemuConsole *con; - RAMFBState *ramfb; - struct vfio_region_info *edid_info; - struct vfio_region_gfx_edid *edid_regs; - uint8_t *edid_blob; - QEMUTimer *edid_link_timer; - struct { - VFIORegion buffer; - DisplaySurface *surface; - } region; - struct { - QTAILQ_HEAD(, VFIODMABuf) bufs; - VFIODMABuf *primary; - VFIODMABuf *cursor; - } dmabuf; -} VFIODisplay; - -VFIOAddressSpace *vfio_get_address_space(AddressSpace *as); -void vfio_put_address_space(VFIOAddressSpace *space); -void vfio_address_space_insert(VFIOAddressSpace *space, - VFIOContainerBase *bcontainer); - -void vfio_disable_irqindex(VFIODevice *vbasedev, int index); -void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index); -void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index); -bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex, - int action, int fd, Error **errp); -void vfio_region_write(void *opaque, hwaddr addr, - uint64_t data, unsigned size); -uint64_t vfio_region_read(void *opaque, - hwaddr addr, unsigned size); -int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region, - int index, const char *name); -int vfio_region_mmap(VFIORegion *region); -void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); -void vfio_region_unmap(VFIORegion *region); -void vfio_region_exit(VFIORegion *region); -void vfio_region_finalize(VFIORegion *region); -void vfio_reset_handler(void *opaque); -struct vfio_device_info *vfio_get_device_info(int fd); -bool vfio_device_is_mdev(VFIODevice *vbasedev); -bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp); -bool vfio_attach_device(char *name, VFIODevice *vbasedev, - AddressSpace *as, Error **errp); -void vfio_detach_device(VFIODevice *vbasedev); - -int vfio_kvm_device_add_fd(int fd, Error **errp); -int vfio_kvm_device_del_fd(int fd, Error **errp); - -bool vfio_cpr_register_container(VFIOContainerBase *bcontainer, Error **errp); -void vfio_cpr_unregister_container(VFIOContainerBase *bcontainer); - -extern const MemoryRegionOps vfio_region_ops; -typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; -typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; -extern VFIOGroupList vfio_group_list; -extern VFIODeviceList vfio_device_list; -extern const MemoryListener vfio_memory_listener; -extern int vfio_kvm_device_fd; - -bool vfio_mig_active(void); -int vfio_block_multiple_devices_migration(VFIODevice *vbasedev, Error **errp); -void vfio_unblock_multiple_devices_migration(void); -bool vfio_viommu_preset(VFIODevice *vbasedev); -int64_t vfio_mig_bytes_transferred(void); -void vfio_reset_bytes_transferred(void); -bool vfio_device_state_is_running(VFIODevice *vbasedev); -bool vfio_device_state_is_precopy(VFIODevice *vbasedev); - -#ifdef CONFIG_LINUX -int vfio_get_region_info(VFIODevice *vbasedev, int index, - struct vfio_region_info **info); -int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, - uint32_t subtype, struct vfio_region_info **info); -bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type); -struct vfio_info_cap_header * -vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id); -bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, - unsigned int *avail); -struct vfio_info_cap_header * -vfio_get_device_info_cap(struct vfio_device_info *info, uint16_t id); -struct vfio_info_cap_header * -vfio_get_cap(void *ptr, uint32_t cap_offset, uint16_t id); -#endif - -bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp); -void vfio_migration_exit(VFIODevice *vbasedev); - -int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size); -bool -vfio_devices_all_running_and_mig_active(const VFIOContainerBase *bcontainer); -bool -vfio_devices_all_device_dirty_tracking(const VFIOContainerBase *bcontainer); -int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp); -int vfio_get_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova, - uint64_t size, ram_addr_t ram_addr, Error **errp); - -/* Returns 0 on success, or a negative errno. */ -bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp); -void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp); -void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, - DeviceState *dev, bool ram_discard); -int vfio_device_get_aw_bits(VFIODevice *vdev); -#endif /* HW_VFIO_VFIO_COMMON_H */ diff --git a/include/hw/vfio/vfio-container-base.h b/include/hw/vfio/vfio-container-base.h index 62a8b60..3cd86ec 100644 --- a/include/hw/vfio/vfio-container-base.h +++ b/include/hw/vfio/vfio-container-base.h @@ -13,7 +13,7 @@ #ifndef HW_VFIO_VFIO_CONTAINER_BASE_H #define HW_VFIO_VFIO_CONTAINER_BASE_H -#include "exec/memory.h" +#include "system/memory.h" typedef struct VFIODevice VFIODevice; typedef struct VFIOIOMMUClass VFIOIOMMUClass; @@ -44,6 +44,7 @@ typedef struct VFIOContainerBase { unsigned long pgsizes; unsigned int dma_max_mappings; bool dirty_pages_supported; + bool dirty_pages_started; /* Protected by BQL */ QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; QLIST_HEAD(, VFIORamDiscardListener) vrdl_list; QLIST_ENTRY(VFIOContainerBase) next; @@ -70,12 +71,17 @@ typedef struct VFIORamDiscardListener { QLIST_ENTRY(VFIORamDiscardListener) next; } VFIORamDiscardListener; +VFIOAddressSpace *vfio_address_space_get(AddressSpace *as); +void vfio_address_space_put(VFIOAddressSpace *space); +void vfio_address_space_insert(VFIOAddressSpace *space, + VFIOContainerBase *bcontainer); + int vfio_container_dma_map(VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly); + void *vaddr, bool readonly, MemoryRegion *mr); int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); + IOMMUTLBEntry *iotlb, bool unmap_all); bool vfio_container_add_section_window(VFIOContainerBase *bcontainer, MemoryRegionSection *section, Error **errp); @@ -83,8 +89,12 @@ void vfio_container_del_section_window(VFIOContainerBase *bcontainer, MemoryRegionSection *section); int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, bool start, Error **errp); +bool vfio_container_dirty_tracking_is_started( + const VFIOContainerBase *bcontainer); +bool vfio_container_devices_dirty_tracking_is_supported( + const VFIOContainerBase *bcontainer); int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp); + uint64_t iova, uint64_t size, ram_addr_t ram_addr, Error **errp); GList *vfio_container_get_iova_ranges(const VFIOContainerBase *bcontainer); @@ -99,25 +109,106 @@ vfio_container_get_page_size_mask(const VFIOContainerBase *bcontainer) #define TYPE_VFIO_IOMMU_LEGACY TYPE_VFIO_IOMMU "-legacy" #define TYPE_VFIO_IOMMU_SPAPR TYPE_VFIO_IOMMU "-spapr" #define TYPE_VFIO_IOMMU_IOMMUFD TYPE_VFIO_IOMMU "-iommufd" +#define TYPE_VFIO_IOMMU_USER TYPE_VFIO_IOMMU "-user" OBJECT_DECLARE_TYPE(VFIOContainerBase, VFIOIOMMUClass, VFIO_IOMMU) struct VFIOIOMMUClass { ObjectClass parent_class; - /* Properties */ - const char *hiod_typename; - - /* basic feature */ + /** + * @setup + * + * Perform basic setup of the container, including configuring IOMMU + * capabilities, IOVA ranges, supported page sizes, etc. + * + * @bcontainer: #VFIOContainerBase + * @errp: pointer to Error*, to store an error if it happens. + * + * Returns true to indicate success and false for error. + */ bool (*setup)(VFIOContainerBase *bcontainer, Error **errp); + + /** + * @listener_begin + * + * Called at the beginning of an address space update transaction. + * See #MemoryListener. + * + * @bcontainer: #VFIOContainerBase + */ + void (*listener_begin)(VFIOContainerBase *bcontainer); + + /** + * @listener_commit + * + * Called at the end of an address space update transaction, + * See #MemoryListener. + * + * @bcontainer: #VFIOContainerBase + */ + void (*listener_commit)(VFIOContainerBase *bcontainer); + + /** + * @dma_map + * + * Map an address range into the container. Note that the memory region is + * referenced within an RCU read lock region across this call. + * + * @bcontainer: #VFIOContainerBase to use + * @iova: start address to map + * @size: size of the range to map + * @vaddr: process virtual address of mapping + * @readonly: true if mapping should be readonly + * @mr: the memory region for this mapping + * + * Returns 0 to indicate success and -errno otherwise. + */ int (*dma_map)(const VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly); + void *vaddr, bool readonly, MemoryRegion *mr); + /** + * @dma_unmap + * + * Unmap an address range from the container. + * + * @bcontainer: #VFIOContainerBase to use for unmap + * @iova: start address to unmap + * @size: size of the range to unmap + * @iotlb: The IOMMU TLB mapping entry (or NULL) + * @unmap_all: if set, unmap the entire address space + * + * Returns 0 to indicate success and -errno otherwise. + */ int (*dma_unmap)(const VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb); + IOMMUTLBEntry *iotlb, bool unmap_all); + + + /** + * @attach_device + * + * Associate the given device with a container and do some related + * initialization of the device context. + * + * @name: name of the device + * @vbasedev: the device + * @as: address space to use + * @errp: pointer to Error*, to store an error if it happens. + * + * Returns true to indicate success and false for error. + */ bool (*attach_device)(const char *name, VFIODevice *vbasedev, AddressSpace *as, Error **errp); + + /* + * @detach_device + * + * Detach the given device from its container and clean up any necessary + * state. + * + * @vbasedev: the device to disassociate + */ void (*detach_device)(VFIODevice *vbasedev); /* migration feature */ @@ -132,7 +223,7 @@ struct VFIOIOMMUClass { * @start: indicates whether to start or stop dirty pages tracking * @errp: pointer to Error*, to store an error if it happens. * - * Returns zero to indicate success and negative for error + * Returns zero to indicate success and negative for error. */ int (*set_dirty_page_tracking)(const VFIOContainerBase *bcontainer, bool start, Error **errp); @@ -147,7 +238,7 @@ struct VFIOIOMMUClass { * @size: size of iova range * @errp: pointer to Error*, to store an error if it happens. * - * Returns zero to indicate success and negative for error + * Returns zero to indicate success and negative for error. */ int (*query_dirty_bitmap)(const VFIOContainerBase *bcontainer, VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp); @@ -162,4 +253,11 @@ struct VFIOIOMMUClass { MemoryRegionSection *section); void (*release)(VFIOContainerBase *bcontainer); }; + +VFIORamDiscardListener *vfio_find_ram_discard_listener( + VFIOContainerBase *bcontainer, MemoryRegionSection *section); + +void vfio_container_region_add(VFIOContainerBase *bcontainer, + MemoryRegionSection *section, bool cpr_remap); + #endif /* HW_VFIO_VFIO_CONTAINER_BASE_H */ diff --git a/include/hw/vfio/vfio-container.h b/include/hw/vfio/vfio-container.h new file mode 100644 index 0000000..21e5807 --- /dev/null +++ b/include/hw/vfio/vfio-container.h @@ -0,0 +1,38 @@ +/* + * VFIO container + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_CONTAINER_H +#define HW_VFIO_CONTAINER_H + +#include "hw/vfio/vfio-container-base.h" +#include "hw/vfio/vfio-cpr.h" + +typedef struct VFIOContainer VFIOContainer; +typedef struct VFIODevice VFIODevice; + +typedef struct VFIOGroup { + int fd; + int groupid; + VFIOContainer *container; + QLIST_HEAD(, VFIODevice) device_list; + QLIST_ENTRY(VFIOGroup) next; + QLIST_ENTRY(VFIOGroup) container_next; + bool ram_block_discard_allowed; +} VFIOGroup; + +typedef struct VFIOContainer { + VFIOContainerBase bcontainer; + int fd; /* /dev/vfio/vfio, empowered by the attached groups */ + unsigned iommu_type; + QLIST_HEAD(, VFIOGroup) group_list; + VFIOContainerCPR cpr; +} VFIOContainer; + +OBJECT_DECLARE_SIMPLE_TYPE(VFIOContainer, VFIO_IOMMU_LEGACY); + +#endif /* HW_VFIO_CONTAINER_H */ diff --git a/include/hw/vfio/vfio-cpr.h b/include/hw/vfio/vfio-cpr.h new file mode 100644 index 0000000..8bf85b9 --- /dev/null +++ b/include/hw/vfio/vfio-cpr.h @@ -0,0 +1,57 @@ +/* + * VFIO CPR + * + * Copyright (c) 2025 Oracle and/or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_CPR_H +#define HW_VFIO_VFIO_CPR_H + +#include "migration/misc.h" +#include "system/memory.h" + +struct VFIOContainer; +struct VFIOContainerBase; +struct VFIOGroup; + +typedef struct VFIOContainerCPR { + Error *blocker; + bool vaddr_unmapped; + NotifierWithReturn transfer_notifier; + MemoryListener remap_listener; + int (*saved_dma_map)(const struct VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + void *vaddr, bool readonly, MemoryRegion *mr); +} VFIOContainerCPR; + +typedef struct VFIODeviceCPR { + Error *mdev_blocker; +} VFIODeviceCPR; + +bool vfio_legacy_cpr_register_container(struct VFIOContainer *container, + Error **errp); +void vfio_legacy_cpr_unregister_container(struct VFIOContainer *container); + +int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier, MigrationEvent *e, + Error **errp); + +bool vfio_cpr_register_container(struct VFIOContainerBase *bcontainer, + Error **errp); +void vfio_cpr_unregister_container(struct VFIOContainerBase *bcontainer); + +int vfio_cpr_group_get_device_fd(int d, const char *name); + +bool vfio_cpr_container_match(struct VFIOContainer *container, + struct VFIOGroup *group, int fd); + +void vfio_cpr_giommu_remap(struct VFIOContainerBase *bcontainer, + MemoryRegionSection *section); + +bool vfio_cpr_ram_discard_register_listener( + struct VFIOContainerBase *bcontainer, MemoryRegionSection *section); + +extern const VMStateDescription vfio_cpr_pci_vmstate; + +#endif /* HW_VFIO_VFIO_CPR_H */ diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h new file mode 100644 index 0000000..c616652 --- /dev/null +++ b/include/hw/vfio/vfio-device.h @@ -0,0 +1,286 @@ +/* + * VFIO Device interface + * + * Copyright Red Hat, Inc. 2012 + * + * Authors: + * Alex Williamson <alex.williamson@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Based on qemu-kvm device-assignment: + * Adapted for KVM by Qumranet. + * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) + * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) + * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) + * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) + * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) + */ + +#ifndef HW_VFIO_VFIO_COMMON_H +#define HW_VFIO_VFIO_COMMON_H + +#include "system/memory.h" +#include "qemu/queue.h" +#ifdef CONFIG_LINUX +#include <linux/vfio.h> +#endif +#include "system/system.h" +#include "hw/vfio/vfio-container-base.h" +#include "hw/vfio/vfio-cpr.h" +#include "system/host_iommu_device.h" +#include "system/iommufd.h" + +#define VFIO_MSG_PREFIX "vfio %s: " + +enum { + VFIO_DEVICE_TYPE_PCI = 0, + VFIO_DEVICE_TYPE_PLATFORM = 1, + VFIO_DEVICE_TYPE_CCW = 2, + VFIO_DEVICE_TYPE_AP = 3, +}; + +typedef struct VFIODeviceOps VFIODeviceOps; +typedef struct VFIODeviceIOOps VFIODeviceIOOps; +typedef struct VFIOMigration VFIOMigration; + +typedef struct IOMMUFDBackend IOMMUFDBackend; +typedef struct VFIOIOASHwpt VFIOIOASHwpt; +typedef struct VFIOUserProxy VFIOUserProxy; + +typedef struct VFIODevice { + QLIST_ENTRY(VFIODevice) next; + QLIST_ENTRY(VFIODevice) container_next; + QLIST_ENTRY(VFIODevice) global_next; + struct VFIOGroup *group; + VFIOContainerBase *bcontainer; + char *sysfsdev; + char *name; + DeviceState *dev; + int fd; + int type; + bool mdev; + bool reset_works; + bool needs_reset; + bool no_mmap; + bool ram_block_discard_allowed; + OnOffAuto enable_migration; + OnOffAuto migration_multifd_transfer; + bool migration_events; + bool use_region_fds; + VFIODeviceOps *ops; + VFIODeviceIOOps *io_ops; + unsigned int num_irqs; + unsigned int num_regions; + unsigned int flags; + VFIOMigration *migration; + Error *migration_blocker; + OnOffAuto pre_copy_dirty_page_tracking; + OnOffAuto device_dirty_page_tracking; + bool dirty_pages_supported; + bool dirty_tracking; /* Protected by BQL */ + bool iommu_dirty_tracking; + HostIOMMUDevice *hiod; + int devid; + IOMMUFDBackend *iommufd; + VFIOIOASHwpt *hwpt; + QLIST_ENTRY(VFIODevice) hwpt_next; + struct vfio_region_info **reginfo; + int *region_fds; + VFIODeviceCPR cpr; + VFIOUserProxy *proxy; +} VFIODevice; + +struct VFIODeviceOps { + void (*vfio_compute_needs_reset)(VFIODevice *vdev); + int (*vfio_hot_reset_multi)(VFIODevice *vdev); + void (*vfio_eoi)(VFIODevice *vdev); + Object *(*vfio_get_object)(VFIODevice *vdev); + + /** + * @vfio_save_config + * + * Save device config state + * + * @vdev: #VFIODevice for which to save the config + * @f: #QEMUFile where to send the data + * @errp: pointer to Error*, to store an error if it happens. + * + * Returns zero to indicate success and negative for error + */ + int (*vfio_save_config)(VFIODevice *vdev, QEMUFile *f, Error **errp); + + /** + * @vfio_load_config + * + * Load device config state + * + * @vdev: #VFIODevice for which to load the config + * @f: #QEMUFile where to get the data + * + * Returns zero to indicate success and negative for error + */ + int (*vfio_load_config)(VFIODevice *vdev, QEMUFile *f); +}; + +/* + * Given a return value of either a short number of bytes read or -errno, + * construct a meaningful error message. + */ +#define strreaderror(ret) \ + (ret < 0 ? strerror(-ret) : "short read") + +/* + * Given a return value of either a short number of bytes written or -errno, + * construct a meaningful error message. + */ +#define strwriteerror(ret) \ + (ret < 0 ? strerror(-ret) : "short write") + +void vfio_device_irq_disable(VFIODevice *vbasedev, int index); +void vfio_device_irq_unmask(VFIODevice *vbasedev, int index); +void vfio_device_irq_mask(VFIODevice *vbasedev, int index); +bool vfio_device_irq_set_signaling(VFIODevice *vbasedev, int index, int subindex, + int action, int fd, Error **errp); + +void vfio_device_reset_handler(void *opaque); +bool vfio_device_is_mdev(VFIODevice *vbasedev); +bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev, + const char *typename, Error **errp); +bool vfio_device_attach(char *name, VFIODevice *vbasedev, + AddressSpace *as, Error **errp); +bool vfio_device_attach_by_iommu_type(const char *iommu_type, char *name, + VFIODevice *vbasedev, AddressSpace *as, + Error **errp); +void vfio_device_detach(VFIODevice *vbasedev); +VFIODevice *vfio_get_vfio_device(Object *obj); + +typedef QLIST_HEAD(VFIODeviceList, VFIODevice) VFIODeviceList; +extern VFIODeviceList vfio_device_list; + +#ifdef CONFIG_LINUX +/* + * How devices communicate with the server. The default option is through + * ioctl() to the kernel VFIO driver, but vfio-user can use a socket to a remote + * process. + */ +struct VFIODeviceIOOps { + /** + * @device_feature + * + * Fill in feature info for the given device. + * + * @vdev: #VFIODevice to use + * @feat: feature information to fill in + * + * Returns 0 on success or -errno. + */ + int (*device_feature)(VFIODevice *vdev, struct vfio_device_feature *feat); + + /** + * @get_region_info + * + * Get the information for a given region on the device. + * + * @vdev: #VFIODevice to use + * @info: set @info->index to the region index to look up; the rest of the + * struct will be filled in on success + * @fd: pointer to the fd for the region; will be -1 if not found + * + * Returns 0 on success or -errno. + */ + int (*get_region_info)(VFIODevice *vdev, + struct vfio_region_info *info, int *fd); + + /** + * @get_irq_info + * + * @vdev: #VFIODevice to use + * @irq: set @irq->index to the IRQ index to look up; the rest of the struct + * will be filled in on success + * + * Returns 0 on success or -errno. + */ + int (*get_irq_info)(VFIODevice *vdev, struct vfio_irq_info *irq); + + /** + * @set_irqs + * + * Configure IRQs. + * + * @vdev: #VFIODevice to use + * @irqs: IRQ configuration as defined by VFIO docs. + * + * Returns 0 on success or -errno. + */ + int (*set_irqs)(VFIODevice *vdev, struct vfio_irq_set *irqs); + + /** + * @region_read + * + * Read part of a region. + * + * @vdev: #VFIODevice to use + * @nr: region index + * @off: offset within the region + * @size: size in bytes to read + * @data: buffer to read into + * + * Returns number of bytes read on success or -errno. + */ + int (*region_read)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size, + void *data); + + /** + * @region_write + * + * Write part of a region. + * + * @vdev: #VFIODevice to use + * @nr: region index + * @off: offset within the region + * @size: size in bytes to write + * @data: buffer to write from + * @post: true if this is a posted write + * + * Returns number of bytes write on success or -errno. + */ + int (*region_write)(VFIODevice *vdev, uint8_t nr, off_t off, uint32_t size, + void *data, bool post); +}; + +void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer, + struct vfio_device_info *info); + +void vfio_device_unprepare(VFIODevice *vbasedev); + +int vfio_device_get_region_info(VFIODevice *vbasedev, int index, + struct vfio_region_info **info); +int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type, + uint32_t subtype, struct vfio_region_info **info); + +/** + * Return the fd for mapping this region. This is either the device's fd (for + * e.g. kernel vfio), or a per-region fd (for vfio-user). + * + * @vbasedev: #VFIODevice to use + * @index: region index + * + * Returns the fd. + */ +int vfio_device_get_region_fd(VFIODevice *vbasedev, int index); + +bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type); + +int vfio_device_get_irq_info(VFIODevice *vbasedev, int index, + struct vfio_irq_info *info); +#endif + +/* Returns 0 on success, or a negative errno. */ +bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp); +void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp); +void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, + DeviceState *dev, bool ram_discard); +int vfio_device_get_aw_bits(VFIODevice *vdev); +#endif /* HW_VFIO_VFIO_COMMON_H */ diff --git a/include/hw/vfio/vfio-migration.h b/include/hw/vfio/vfio-migration.h new file mode 100644 index 0000000..0d4ecd3 --- /dev/null +++ b/include/hw/vfio/vfio-migration.h @@ -0,0 +1,16 @@ +/* + * VFIO migration interface + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_MIGRATION_H +#define HW_VFIO_VFIO_MIGRATION_H + +bool vfio_migration_active(void); +int64_t vfio_migration_bytes_transferred(void); +void vfio_migration_reset_bytes_transferred(void); + +#endif /* HW_VFIO_VFIO_MIGRATION_H */ diff --git a/include/hw/vfio/vfio-platform.h b/include/hw/vfio/vfio-platform.h index c414c3d..256d850 100644 --- a/include/hw/vfio/vfio-platform.h +++ b/include/hw/vfio/vfio-platform.h @@ -17,7 +17,7 @@ #define HW_VFIO_VFIO_PLATFORM_H #include "hw/sysbus.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" #include "qemu/event_notifier.h" #include "qemu/queue.h" #include "qom/object.h" @@ -47,6 +47,8 @@ typedef struct VFIOINTp { /* function type for user side eventfd handler */ typedef void (*eventfd_user_side_handler_t)(VFIOINTp *intp); +typedef struct VFIORegion VFIORegion; + struct VFIOPlatformDevice { SysBusDevice sbdev; VFIODevice vbasedev; /* not a QOM object */ diff --git a/include/hw/vfio/vfio-region.h b/include/hw/vfio/vfio-region.h new file mode 100644 index 0000000..ede6e0c --- /dev/null +++ b/include/hw/vfio/vfio-region.h @@ -0,0 +1,48 @@ +/* + * VFIO region + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_REGION_H +#define HW_VFIO_REGION_H + +#include "system/memory.h" + +typedef struct VFIOMmap { + MemoryRegion mem; + void *mmap; + off_t offset; + size_t size; +} VFIOMmap; + +typedef struct VFIODevice VFIODevice; + +typedef struct VFIORegion { + struct VFIODevice *vbasedev; + off_t fd_offset; /* offset of region within device fd */ + MemoryRegion *mem; /* slow, read/write access */ + size_t size; + uint32_t flags; /* VFIO region flags (rd/wr/mmap) */ + uint32_t nr_mmaps; + VFIOMmap *mmaps; + uint8_t nr; /* cache the region number for debug */ + bool post_wr; /* writes can be posted */ +} VFIORegion; + + +void vfio_region_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size); +uint64_t vfio_region_read(void *opaque, + hwaddr addr, unsigned size); +int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region, + int index, const char *name); +int vfio_region_mmap(VFIORegion *region); +void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); +void vfio_region_unmap(VFIORegion *region); +void vfio_region_exit(VFIORegion *region); +void vfio_region_finalize(VFIORegion *region); + +#endif /* HW_VFIO_REGION_H */ diff --git a/include/hw/virtio/cbor-helpers.h b/include/hw/virtio/cbor-helpers.h new file mode 100644 index 0000000..f25fd48 --- /dev/null +++ b/include/hw/virtio/cbor-helpers.h @@ -0,0 +1,45 @@ +/* + * QEMU CBOR helpers + * + * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + */ + +#ifndef QEMU_VIRTIO_CBOR_HELPERS_H +#define QEMU_VIRTIO_CBOR_HELPERS_H + +#include <cbor.h> + +bool qemu_cbor_map_add(cbor_item_t *map, cbor_item_t *key, cbor_item_t *value); + +bool qemu_cbor_array_push(cbor_item_t *array, cbor_item_t *value); + +bool qemu_cbor_add_bool_to_map(cbor_item_t *map, const char *key, bool value); + +bool qemu_cbor_add_uint8_to_map(cbor_item_t *map, const char *key, + uint8_t value); + +bool qemu_cbor_add_map_to_map(cbor_item_t *map, const char *key, + size_t nested_map_size, + cbor_item_t **nested_map); + +bool qemu_cbor_add_bytestring_to_map(cbor_item_t *map, const char *key, + uint8_t *arr, size_t len); + +bool qemu_cbor_add_null_to_map(cbor_item_t *map, const char *key); + +bool qemu_cbor_add_string_to_map(cbor_item_t *map, const char *key, + const char *value); + +bool qemu_cbor_add_uint8_array_to_map(cbor_item_t *map, const char *key, + uint8_t *arr, size_t len); + +bool qemu_cbor_add_uint8_key_bytestring_to_map(cbor_item_t *map, uint8_t key, + uint8_t *buf, size_t len); + +bool qemu_cbor_add_uint64_to_map(cbor_item_t *map, const char *key, + uint64_t value); +#endif diff --git a/include/hw/virtio/iothread-vq-mapping.h b/include/hw/virtio/iothread-vq-mapping.h new file mode 100644 index 0000000..57335c3 --- /dev/null +++ b/include/hw/virtio/iothread-vq-mapping.h @@ -0,0 +1,45 @@ +/* + * IOThread Virtqueue Mapping + * + * Copyright Red Hat, Inc + * + * SPDX-License-Identifier: GPL-2.0-only + */ + +#ifndef HW_VIRTIO_IOTHREAD_VQ_MAPPING_H +#define HW_VIRTIO_IOTHREAD_VQ_MAPPING_H + +#include "qapi/error.h" +#include "qapi/qapi-types-virtio.h" + +/** + * iothread_vq_mapping_apply: + * @list: The mapping of virtqueues to IOThreads. + * @vq_aio_context: The array of AioContext pointers to fill in. + * @num_queues: The length of @vq_aio_context. + * @errp: If an error occurs, a pointer to the area to store the error. + * + * Fill in the AioContext for each virtqueue in the @vq_aio_context array given + * the iothread-vq-mapping parameter in @list. + * + * iothread_vq_mapping_cleanup() must be called to free IOThread object + * references after this function returns success. + * + * Returns: %true on success, %false on failure. + **/ +bool iothread_vq_mapping_apply( + IOThreadVirtQueueMappingList *list, + AioContext **vq_aio_context, + uint16_t num_queues, + Error **errp); + +/** + * iothread_vq_mapping_cleanup: + * @list: The mapping of virtqueues to IOThreads. + * + * Release IOThread object references that were acquired by + * iothread_vq_mapping_apply(). + */ +void iothread_vq_mapping_cleanup(IOThreadVirtQueueMappingList *list); + +#endif /* HW_VIRTIO_IOTHREAD_VQ_MAPPING_H */ diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h index 70c2e8f..d6df209 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -11,7 +11,7 @@ #ifndef VHOST_BACKEND_H #define VHOST_BACKEND_H -#include "exec/memory.h" +#include "system/memory.h" typedef enum VhostBackendType { VHOST_BACKEND_TYPE_NONE = 0, diff --git a/include/hw/virtio/vhost-scsi-common.h b/include/hw/virtio/vhost-scsi-common.h index c5d2c09..d54d9c9 100644 --- a/include/hw/virtio/vhost-scsi-common.h +++ b/include/hw/virtio/vhost-scsi-common.h @@ -40,7 +40,7 @@ struct VHostSCSICommon { }; int vhost_scsi_common_start(VHostSCSICommon *vsc, Error **errp); -void vhost_scsi_common_stop(VHostSCSICommon *vsc); +int vhost_scsi_common_stop(VHostSCSICommon *vsc); char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus, DeviceState *dev); void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config); diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h index 324cd86..9a3f238 100644 --- a/include/hw/virtio/vhost-user.h +++ b/include/hw/virtio/vhost-user.h @@ -54,6 +54,7 @@ typedef struct VhostUserHostNotifier { void *addr; void *unmap_addr; int idx; + bool destroy; } VhostUserHostNotifier; /** diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h index 0a9575b..449bf5c 100644 --- a/include/hw/virtio/vhost-vdpa.h +++ b/include/hw/virtio/vhost-vdpa.h @@ -43,7 +43,21 @@ typedef struct vhost_vdpa_shared { struct vhost_vdpa_iova_range iova_range; QLIST_HEAD(, vdpa_iommu) iommu_list; - /* IOVA mapping used by the Shadow Virtqueue */ + /* + * IOVA mapping used by the Shadow Virtqueue + * + * It is shared among all ASID for simplicity, whether CVQ shares ASID with + * guest or not: + * - Memory listener need access to guest's memory addresses allocated in + * the IOVA tree. + * - There should be plenty of IOVA address space for both ASID not to + * worry about collisions between them. Guest's translations are still + * validated with virtio virtqueue_pop so there is no risk for the guest + * to access memory that it shouldn't. + * + * To allocate a iova tree per ASID is doable but it complicates the code + * and it is not worth it for the moment. + */ VhostIOVATree *iova_tree; /* Copy of backend features */ @@ -51,6 +65,12 @@ typedef struct vhost_vdpa_shared { bool iotlb_batch_begin_sent; + /* + * The memory listener has been registered, so DMA maps have been sent to + * the device. + */ + bool listener_registered; + /* Vdpa must send shadow addresses as IOTLB key for data queues, not GPA */ bool shadow_data; diff --git a/include/hw/virtio/vhost-vsock-common.h b/include/hw/virtio/vhost-vsock-common.h index 75a74e8..01bf606 100644 --- a/include/hw/virtio/vhost-vsock-common.h +++ b/include/hw/virtio/vhost-vsock-common.h @@ -42,7 +42,7 @@ struct VHostVSockCommon { }; int vhost_vsock_common_start(VirtIODevice *vdev); -void vhost_vsock_common_stop(VirtIODevice *vdev); +int vhost_vsock_common_stop(VirtIODevice *vdev); int vhost_vsock_common_pre_save(void *opaque); int vhost_vsock_common_post_load(void *opaque, int version_id); void vhost_vsock_common_realize(VirtIODevice *vdev); diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h index d75faf4..38800a7 100644 --- a/include/hw/virtio/vhost.h +++ b/include/hw/virtio/vhost.h @@ -3,7 +3,7 @@ #include "hw/virtio/vhost-backend.h" #include "hw/virtio/virtio.h" -#include "exec/memory.h" +#include "system/memory.h" #define VHOST_F_DEVICE_IOTLB 63 #define VHOST_USER_F_PROTOCOL_FEATURES 30 @@ -171,6 +171,10 @@ int vhost_dev_init(struct vhost_dev *hdev, void *opaque, */ void vhost_dev_cleanup(struct vhost_dev *hdev); +void vhost_dev_disable_notifiers_nvqs(struct vhost_dev *hdev, + VirtIODevice *vdev, + unsigned int nvqs); + /** * vhost_dev_enable_notifiers() - enable event notifiers * @hdev: common vhost_dev structure @@ -228,8 +232,10 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings); * Stop the vhost device. After the device is stopped the notifiers * can be disabled (@vhost_dev_disable_notifiers) and the device can * be torn down (@vhost_dev_cleanup). + * + * Return: 0 on success, != 0 on error when stopping dev. */ -void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings); +int vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings); /** * DOC: vhost device configuration handling @@ -329,13 +335,11 @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write); int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev, struct vhost_virtqueue *vq, unsigned idx); -void vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, unsigned idx); +int vhost_virtqueue_stop(struct vhost_dev *dev, struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, unsigned idx); void vhost_dev_reset_inflight(struct vhost_inflight *inflight); void vhost_dev_free_inflight(struct vhost_inflight *inflight); -void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f); -int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f); int vhost_dev_prepare_inflight(struct vhost_dev *hdev, VirtIODevice *vdev); int vhost_dev_set_inflight(struct vhost_dev *dev, struct vhost_inflight *inflight); @@ -363,7 +367,14 @@ static inline int vhost_reset_device(struct vhost_dev *hdev) * Returns true if the device supports these commands, and false if it * does not. */ +#ifdef CONFIG_VHOST bool vhost_supports_device_state(struct vhost_dev *dev); +#else +static inline bool vhost_supports_device_state(struct vhost_dev *dev) +{ + return false; +} +#endif /** * vhost_set_device_state_fd(): Begin transfer of internal state from/to @@ -446,7 +457,15 @@ int vhost_check_device_state(struct vhost_dev *dev, Error **errp); * * Returns 0 on success, and -errno otherwise. */ +#ifdef CONFIG_VHOST int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); +#else +static inline int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, + Error **errp) +{ + return -ENOSYS; +} +#endif /** * vhost_load_backend_state(): High-level function to load a vhost @@ -463,6 +482,14 @@ int vhost_save_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); * * Returns 0 on success, and -errno otherwise. */ +#ifdef CONFIG_VHOST int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, Error **errp); +#else +static inline int vhost_load_backend_state(struct vhost_dev *dev, QEMUFile *f, + Error **errp) +{ + return -ENOSYS; +} +#endif #endif diff --git a/include/hw/virtio/virtio-acpi.h b/include/hw/virtio/virtio-acpi.h index cace2a3..cdfbd94 100644 --- a/include/hw/virtio/virtio-acpi.h +++ b/include/hw/virtio/virtio-acpi.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * ACPI support for virtio */ diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h index 5139cf8..0456c21 100644 --- a/include/hw/virtio/virtio-balloon.h +++ b/include/hw/virtio/virtio-balloon.h @@ -16,8 +16,9 @@ #define QEMU_VIRTIO_BALLOON_H #include "standard-headers/linux/virtio_balloon.h" +#include "hw/resettable.h" #include "hw/virtio/virtio.h" -#include "sysemu/iothread.h" +#include "system/iothread.h" #include "qom/object.h" #define TYPE_VIRTIO_BALLOON "virtio-balloon-device" @@ -71,6 +72,9 @@ struct VirtIOBalloon { bool qemu_4_0_config_size; uint32_t poison_val; + + /* State of the resettable container */ + ResettableState reset_state; }; #endif diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index 5c14110..3d8dee7 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -17,14 +17,14 @@ #include "standard-headers/linux/virtio_blk.h" #include "hw/virtio/virtio.h" #include "hw/block/block.h" -#include "sysemu/iothread.h" -#include "sysemu/block-backend.h" -#include "sysemu/block-ram-registrar.h" +#include "system/iothread.h" +#include "system/block-backend.h" +#include "system/block-ram-registrar.h" #include "qom/object.h" #include "qapi/qapi-types-virtio.h" #define TYPE_VIRTIO_BLK "virtio-blk-device" -OBJECT_DECLARE_SIMPLE_TYPE(VirtIOBlock, VIRTIO_BLK) +OBJECT_DECLARE_TYPE(VirtIOBlock, VirtIOBlkClass, VIRTIO_BLK) /* This is the last element of the write scatter-gather list */ struct virtio_blk_inhdr @@ -100,6 +100,15 @@ typedef struct MultiReqBuffer { bool is_write; } MultiReqBuffer; +typedef struct VirtIOBlkClass { + /*< private >*/ + VirtioDeviceClass parent; + /*< public >*/ + bool (*handle_unknown_request)(VirtIOBlockReq *req, MultiReqBuffer *mrb, + uint32_t type); +} VirtIOBlkClass; + void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq); +void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status); #endif diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h index 348749f..2d56513 100644 --- a/include/hw/virtio/virtio-crypto.h +++ b/include/hw/virtio/virtio-crypto.h @@ -16,8 +16,8 @@ #include "standard-headers/linux/virtio_crypto.h" #include "hw/virtio/virtio.h" -#include "sysemu/iothread.h" -#include "sysemu/cryptodev.h" +#include "system/iothread.h" +#include "system/cryptodev.h" #include "qom/object.h" diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h index 7a59379..a42957c 100644 --- a/include/hw/virtio/virtio-gpu.h +++ b/include/hw/virtio/virtio-gpu.h @@ -19,7 +19,7 @@ #include "ui/console.h" #include "hw/virtio/virtio.h" #include "qemu/log.h" -#include "sysemu/vhost-user-backend.h" +#include "system/vhost-user-backend.h" #include "standard-headers/linux/virtio_gpu.h" #include "standard-headers/linux/virtio_ids.h" @@ -51,9 +51,7 @@ struct virtio_gpu_simple_resource { unsigned int iov_cnt; uint32_t scanout_bitmask; pixman_image_t *image; -#ifdef WIN32 - HANDLE handle; -#endif + qemu_pixman_shareable share_handle; uint64_t hostmem; uint64_t blob_size; @@ -99,6 +97,8 @@ enum virtio_gpu_base_conf_flags { VIRTIO_GPU_FLAG_BLOB_ENABLED, VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED, VIRTIO_GPU_FLAG_RUTABAGA_ENABLED, + VIRTIO_GPU_FLAG_VENUS_ENABLED, + VIRTIO_GPU_FLAG_RESOURCE_UUID_ENABLED, }; #define virtio_gpu_virgl_enabled(_cfg) \ @@ -115,8 +115,12 @@ enum virtio_gpu_base_conf_flags { (_cfg.flags & (1 << VIRTIO_GPU_FLAG_CONTEXT_INIT_ENABLED)) #define virtio_gpu_rutabaga_enabled(_cfg) \ (_cfg.flags & (1 << VIRTIO_GPU_FLAG_RUTABAGA_ENABLED)) +#define virtio_gpu_resource_uuid_enabled(_cfg) \ + (_cfg.flags & (1 << VIRTIO_GPU_FLAG_RESOURCE_UUID_ENABLED)) #define virtio_gpu_hostmem_enabled(_cfg) \ (_cfg.hostmem > 0) +#define virtio_gpu_venus_enabled(_cfg) \ + (_cfg.flags & (1 << VIRTIO_GPU_FLAG_VENUS_ENABLED)) struct virtio_gpu_base_conf { uint32_t max_outputs; @@ -196,8 +200,6 @@ struct VirtIOGPU { uint64_t hostmem; bool processing_cmdq; - QEMUTimer *fence_poll; - QEMUTimer *print_stats; uint32_t inflight; struct { @@ -211,6 +213,8 @@ struct VirtIOGPU { QTAILQ_HEAD(, VGPUDMABuf) bufs; VGPUDMABuf *primary[VIRTIO_GPU_MAX_SCANOUTS]; } dmabuf; + + GArray *capset_ids; }; struct VirtIOGPUClass { @@ -226,11 +230,23 @@ struct VirtIOGPUClass { Error **errp); }; +/* VirtIOGPUGL renderer states */ +typedef enum { + RS_START, /* starting state */ + RS_INIT_FAILED, /* failed initialisation */ + RS_INITED, /* initialised and working */ + RS_RESET, /* inited and reset pending, moves to start after reset */ +} RenderState; + struct VirtIOGPUGL { struct VirtIOGPU parent_obj; - bool renderer_inited; - bool renderer_reset; + RenderState renderer_state; + + QEMUTimer *fence_poll; + QEMUTimer *print_stats; + + QEMUBH *cmdq_resume_bh; }; struct VhostUserGPU { @@ -320,6 +336,21 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g, struct virtio_gpu_scanout *s, uint32_t resource_id); +/** + * virtio_gpu_scanout_blob_to_fb() - fill out fb based on scanout data + * fb: the frame-buffer descriptor to fill out + * ss: the scanout blob data + * blob_size: size of scanout blob data + * + * This will check we have enough space for the frame taking into + * account that stride. + * + * Returns true on success, otherwise logs guest error and returns false + */ +bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb, + struct virtio_gpu_set_scanout_blob *ss, + uint64_t blob_size); + /* virtio-gpu-udmabuf.c */ bool virtio_gpu_have_udmabuf(void); void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res); @@ -330,6 +361,13 @@ int virtio_gpu_update_dmabuf(VirtIOGPU *g, struct virtio_gpu_framebuffer *fb, struct virtio_gpu_rect *r); +void virtio_gpu_update_scanout(VirtIOGPU *g, + uint32_t scanout_id, + struct virtio_gpu_simple_resource *res, + struct virtio_gpu_framebuffer *fb, + struct virtio_gpu_rect *r); +void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id); + /* virtio-gpu-3d.c */ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g, struct virtio_gpu_ctrl_command *cmd); @@ -337,6 +375,6 @@ void virtio_gpu_virgl_fence_poll(VirtIOGPU *g); void virtio_gpu_virgl_reset_scanout(VirtIOGPU *g); void virtio_gpu_virgl_reset(VirtIOGPU *g); int virtio_gpu_virgl_init(VirtIOGPU *g); -int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g); +GArray *virtio_gpu_virgl_get_capsets(VirtIOGPU *g); #endif diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-input.h index e69c0ae..e097b0b 100644 --- a/include/hw/virtio/virtio-input.h +++ b/include/hw/virtio/virtio-input.h @@ -4,7 +4,7 @@ #include "hw/virtio/vhost-user.h" #include "hw/virtio/vhost-user-base.h" #include "ui/input.h" -#include "sysemu/vhost-user-backend.h" +#include "system/vhost-user-backend.h" /* ----------------------------------------------------------------- */ /* virtio input protocol */ diff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h index 7db4210..3b86050 100644 --- a/include/hw/virtio/virtio-iommu.h +++ b/include/hw/virtio/virtio-iommu.h @@ -25,7 +25,7 @@ #include "hw/pci/pci.h" #include "qom/object.h" #include "qapi/qapi-types-virtio.h" -#include "sysemu/host_iommu_device.h" +#include "system/host_iommu_device.h" #define TYPE_VIRTIO_IOMMU "virtio-iommu-device" #define TYPE_VIRTIO_IOMMU_PCI "virtio-iommu-pci" diff --git a/include/hw/virtio/virtio-mem.h b/include/hw/virtio/virtio-mem.h index 5f5b02b..e0ab31b 100644 --- a/include/hw/virtio/virtio-mem.h +++ b/include/hw/virtio/virtio-mem.h @@ -14,9 +14,10 @@ #define HW_VIRTIO_MEM_H #include "standard-headers/linux/virtio_mem.h" +#include "hw/resettable.h" #include "hw/virtio/virtio.h" #include "qapi/qapi-types-misc.h" -#include "sysemu/hostmem.h" +#include "system/hostmem.h" #include "qom/object.h" #define TYPE_VIRTIO_MEM "virtio-mem" @@ -24,6 +25,10 @@ OBJECT_DECLARE_TYPE(VirtIOMEM, VirtIOMEMClass, VIRTIO_MEM) +#define TYPE_VIRTIO_MEM_SYSTEM_RESET "virtio-mem-system-reset" + +OBJECT_DECLARE_SIMPLE_TYPE(VirtioMemSystemReset, VIRTIO_MEM_SYSTEM_RESET) + #define VIRTIO_MEM_MEMDEV_PROP "memdev" #define VIRTIO_MEM_NODE_PROP "node" #define VIRTIO_MEM_SIZE_PROP "size" @@ -115,11 +120,21 @@ struct VirtIOMEM { /* listeners to notify on plug/unplug activity. */ QLIST_HEAD(, RamDiscardListener) rdl_list; + + /* Catch system resets -> qemu_devices_reset() only. */ + VirtioMemSystemReset *system_reset; +}; + +struct VirtioMemSystemReset { + Object parent; + + ResettableState reset_state; + VirtIOMEM *vmem; }; struct VirtIOMEMClass { /* private */ - VirtIODevice parent; + VirtioDeviceClass parent_class; /* public */ void (*fill_device_info)(const VirtIOMEM *vmen, VirtioMEMDeviceInfo *vi); diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 060c23c..b9ea9e8 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -102,7 +102,7 @@ typedef struct VirtioNetRscStat { /* Rsc unit general info used to checking if can coalescing */ typedef struct VirtioNetRscUnit { void *ip; /* ip header */ - uint16_t *ip_plen; /* data len pointer in ip header field */ + void *ip_plen; /* pointer to unaligned uint16_t data len in ip header */ struct tcp_header *tcp; /* tcp header */ uint16_t tcp_hdrlen; /* tcp header len */ uint16_t payload; /* pure payload without virtio/eth/ip/tcp */ diff --git a/include/hw/virtio/virtio-nsm.h b/include/hw/virtio/virtio-nsm.h new file mode 100644 index 0000000..57ddbbb --- /dev/null +++ b/include/hw/virtio/virtio-nsm.h @@ -0,0 +1,49 @@ +/* + * AWS Nitro Secure Module (NSM) device + * + * Copyright (c) 2024 Dorjoy Chowdhury <dorjoychy111@gmail.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + */ + +#ifndef QEMU_VIRTIO_NSM_H +#define QEMU_VIRTIO_NSM_H + +#include "crypto/hash.h" +#include "hw/virtio/virtio.h" +#include "qom/object.h" + +#define NSM_MAX_PCRS 32 + +#define TYPE_VIRTIO_NSM "virtio-nsm-device" +OBJECT_DECLARE_SIMPLE_TYPE(VirtIONSM, VIRTIO_NSM) +#define VIRTIO_NSM_GET_PARENT_CLASS(obj) \ + OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_NSM) + +struct PCRInfo { + bool locked; + uint8_t data[QCRYPTO_HASH_DIGEST_LEN_SHA384]; +}; + +struct VirtIONSM { + VirtIODevice parent_obj; + + /* Only one vq - guest puts request and response buffers on it */ + VirtQueue *vq; + + /* NSM State */ + uint16_t max_pcrs; + struct PCRInfo pcrs[NSM_MAX_PCRS]; + char *digest; + char *module_id; + uint8_t version_major; + uint8_t version_minor; + uint8_t version_patch; + + bool (*extend_pcr)(VirtIONSM *vnsm, int ind, uint8_t *data, uint16_t len); + void (*lock_pcr)(VirtIONSM *vnsm, int ind); +}; + +#endif diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h index 9e67ba3..eab5394 100644 --- a/include/hw/virtio/virtio-pci.h +++ b/include/hw/virtio/virtio-pci.h @@ -32,9 +32,7 @@ DECLARE_OBJ_CHECKERS(VirtioPCIBusState, VirtioPCIBusClass, enum { VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, - VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT, VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT, - VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT, VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT, VIRTIO_PCI_FLAG_ATS_BIT, VIRTIO_PCI_FLAG_INIT_DEVERR_BIT, @@ -54,12 +52,6 @@ enum { * vcpu thread using ioeventfd for some devices. */ #define VIRTIO_PCI_FLAG_USE_IOEVENTFD (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT) -/* virtio version flags */ -#define VIRTIO_PCI_FLAG_DISABLE_PCIE (1 << VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT) - -/* migrate extra state */ -#define VIRTIO_PCI_FLAG_MIGRATE_EXTRA (1 << VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT) - /* have pio notification for modern device ? */ #define VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY \ (1 << VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT) @@ -147,11 +139,15 @@ struct VirtIOPCIProxy { }; MemoryRegion modern_bar; MemoryRegion io_bar; + /* address space for VirtIOPCIRegions */ + AddressSpace modern_cfg_mem_as; + AddressSpace modern_cfg_io_as; uint32_t legacy_io_bar_idx; uint32_t msix_bar_idx; uint32_t modern_io_bar_idx; uint32_t modern_mem_bar_idx; int config_cap; + uint16_t last_pcie_cap_offset; uint32_t flags; bool disable_modern; bool ignore_backend_features; @@ -252,8 +248,8 @@ typedef struct VirtioPCIDeviceTypeInfo { size_t class_size; void (*instance_init)(Object *obj); void (*instance_finalize)(Object *obj); - void (*class_init)(ObjectClass *klass, void *data); - InterfaceInfo *interfaces; + void (*class_init)(ObjectClass *klass, const void *data); + const InterfaceInfo *interfaces; } VirtioPCIDeviceTypeInfo; /* Register virtio-pci type(s). @t must be static. */ diff --git a/include/hw/virtio/virtio-pmem.h b/include/hw/virtio/virtio-pmem.h index fc4fd1f..9cce600 100644 --- a/include/hw/virtio/virtio-pmem.h +++ b/include/hw/virtio/virtio-pmem.h @@ -36,7 +36,7 @@ struct VirtIOPMEM { struct VirtIOPMEMClass { /* private */ - VirtIODevice parent; + VirtioDeviceClass parent_class; /* public */ void (*fill_device_info)(const VirtIOPMEM *pmem, VirtioPMEMDeviceInfo *vi); diff --git a/include/hw/virtio/virtio-rng.h b/include/hw/virtio/virtio-rng.h index 8273425..7e6d27f 100644 --- a/include/hw/virtio/virtio-rng.h +++ b/include/hw/virtio/virtio-rng.h @@ -13,7 +13,7 @@ #define QEMU_VIRTIO_RNG_H #include "hw/virtio/virtio.h" -#include "sysemu/rng.h" +#include "system/rng.h" #include "standard-headers/linux/virtio_rng.h" #include "qom/object.h" diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 7be0105..31e852e 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -22,7 +22,8 @@ #include "hw/virtio/virtio.h" #include "hw/scsi/scsi.h" #include "chardev/char-fe.h" -#include "sysemu/iothread.h" +#include "qapi/qapi-types-virtio.h" +#include "system/iothread.h" #define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common" OBJECT_DECLARE_SIMPLE_TYPE(VirtIOSCSICommon, VIRTIO_SCSI_COMMON) @@ -60,6 +61,7 @@ struct VirtIOSCSIConf { CharBackend chardev; uint32_t boot_tpgt; IOThread *iothread; + IOThreadVirtQueueMappingList *iothread_vq_mapping_list; }; struct VirtIOSCSI; @@ -82,18 +84,14 @@ struct VirtIOSCSI { SCSIBus bus; int resetting; /* written from main loop thread, read from any thread */ + + QemuMutex event_lock; /* protects event_vq and events_dropped */ bool events_dropped; - /* - * TMFs deferred to main loop BH. These fields are protected by - * tmf_bh_lock. - */ - QemuMutex tmf_bh_lock; - QEMUBH *tmf_bh; - QTAILQ_HEAD(, VirtIOSCSIReq) tmf_bh_list; + QemuMutex ctrl_lock; /* protects ctrl_vq */ /* Fields for dataplane below */ - AioContext *ctx; /* one iothread per virtio-scsi-pci for now */ + AioContext **vq_aio_context; /* per-virtqueue AioContext pointer */ bool dataplane_started; bool dataplane_starting; @@ -111,6 +109,7 @@ void virtio_scsi_common_realize(DeviceState *dev, void virtio_scsi_common_unrealize(DeviceState *dev); void virtio_scsi_dataplane_setup(VirtIOSCSI *s, Error **errp); +void virtio_scsi_dataplane_cleanup(VirtIOSCSI *s); int virtio_scsi_dataplane_start(VirtIODevice *s); void virtio_scsi_dataplane_stop(VirtIODevice *s); diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 0fcbc5c..214d4a7 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -14,7 +14,7 @@ #ifndef QEMU_VIRTIO_H #define QEMU_VIRTIO_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "net/net.h" #include "migration/vmstate.h" @@ -186,7 +186,7 @@ struct VirtioDeviceClass { void (*get_config)(VirtIODevice *vdev, uint8_t *config); void (*set_config)(VirtIODevice *vdev, const uint8_t *config); void (*reset)(VirtIODevice *vdev); - void (*set_status)(VirtIODevice *vdev, uint8_t val); + int (*set_status)(VirtIODevice *vdev, uint8_t val); /* Device must validate queue_index. */ void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index); /* Device must validate queue_index. */ @@ -210,6 +210,8 @@ struct VirtioDeviceClass { void (*guest_notifier_mask)(VirtIODevice *vdev, int n, bool mask); int (*start_ioeventfd)(VirtIODevice *vdev); void (*stop_ioeventfd)(VirtIODevice *vdev); + /* Called before loading queues. Useful to add queues before loading. */ + int (*pre_load_queues)(VirtIODevice *vdev); /* Saving and loading of a device; trying to deprecate save/load * use vmsd for new devices. */ @@ -223,6 +225,7 @@ struct VirtioDeviceClass { int (*post_load)(VirtIODevice *vdev); const VMStateDescription *vmsd; bool (*primary_unplug_pending)(void *opaque); + /* May be called even when vdev->vhost_started is false */ struct vhost_dev *(*get_vhost)(VirtIODevice *vdev); void (*toggle_device_iotlb)(VirtIODevice *vdev); }; diff --git a/include/hw/vmapple/vmapple.h b/include/hw/vmapple/vmapple.h new file mode 100644 index 0000000..9c1ad1b --- /dev/null +++ b/include/hw/vmapple/vmapple.h @@ -0,0 +1,23 @@ +/* + * Devices specific to the VMApple machine type + * + * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VMAPPLE_VMAPPLE_H +#define HW_VMAPPLE_VMAPPLE_H + +#define TYPE_APPLE_AES "apple-aes" + +#define TYPE_VMAPPLE_BDIF "vmapple-bdif" + +#define TYPE_VMAPPLE_CFG "vmapple-cfg" + +#define TYPE_VMAPPLE_VIRTIO_BLK_PCI "vmapple-virtio-blk-pci" + +#endif /* HW_VMAPPLE_VMAPPLE_H */ diff --git a/include/hw/xen/arch_hvm.h b/include/hw/xen/arch_hvm.h index c7c5152..df39c81 100644 --- a/include/hw/xen/arch_hvm.h +++ b/include/hw/xen/arch_hvm.h @@ -1,5 +1,5 @@ #if defined(TARGET_I386) || defined(TARGET_X86_64) #include "hw/i386/xen_arch_hvm.h" -#elif defined(TARGET_ARM) || defined(TARGET_ARM_64) +#elif defined(TARGET_ARM) || defined(TARGET_AARCH64) #include "hw/arm/xen_arch_hvm.h" #endif diff --git a/include/hw/xen/interface/io/blkif.h b/include/hw/xen/interface/io/blkif.h index 22f1eef..c552799 100644 --- a/include/hw/xen/interface/io/blkif.h +++ b/include/hw/xen/interface/io/blkif.h @@ -324,7 +324,7 @@ * access (even when it should be read-only). If the frontend hits the * maximum number of allowed persistently mapped grants, it can fallback * to non persistent mode. This will cause a performance degradation, - * since the the backend driver will still try to map those grants + * since the backend driver will still try to map those grants * persistently. Since the persistent grants protocol is compatible with * the previous protocol, a frontend driver can choose to work in * persistent mode even when the backend doesn't support it. diff --git a/include/hw/xen/xen-block.h b/include/hw/xen/xen-block.h index d692ea7..449a7f7 100644 --- a/include/hw/xen/xen-block.h +++ b/include/hw/xen/xen-block.h @@ -11,7 +11,7 @@ #include "hw/xen/xen-bus.h" #include "hw/block/block.h" #include "hw/block/dataplane/xen-block.h" -#include "sysemu/iothread.h" +#include "system/iothread.h" #include "qom/object.h" typedef enum XenBlockVdevType { diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h index d8dcc2f..e991111 100644 --- a/include/hw/xen/xen-bus-helper.h +++ b/include/hw/xen/xen-bus-helper.h @@ -38,6 +38,15 @@ int xs_node_scanf(struct qemu_xs_handle *h, xs_transaction_t tid, const char *fmt, ...) G_GNUC_SCANF(6, 7); +/* + * Unlike other functions here, the printf-formatted path_fmt is for + * the XenStore path, not the contents of the node. + */ +char *xs_node_read(struct qemu_xs_handle *h, xs_transaction_t tid, + unsigned int *len, Error **errp, + const char *path_fmt, ...) + G_GNUC_PRINTF(5, 6); + /* Watch node/key unless node is empty, in which case watch key */ struct qemu_xs_watch *xs_node_watch(struct qemu_xs_handle *h, const char *node, const char *key, xs_watch_fn fn, diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h index 38d40af..bdbf1ed 100644 --- a/include/hw/xen/xen-bus.h +++ b/include/hw/xen/xen-bus.h @@ -8,9 +8,10 @@ #ifndef HW_XEN_BUS_H #define HW_XEN_BUS_H +#include "hw/qdev-core.h" #include "hw/xen/xen_backend_ops.h" -#include "hw/sysbus.h" #include "qemu/notify.h" +#include "qemu/queue.h" #include "qom/object.h" typedef struct XenEventChannel XenEventChannel; @@ -91,6 +92,7 @@ void xen_device_frontend_printf(XenDevice *xendev, const char *key, int xen_device_frontend_scanf(XenDevice *xendev, const char *key, const char *fmt, ...) G_GNUC_SCANF(3, 4); +char *xen_device_frontend_read(XenDevice *xendev, const char *key); void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, Error **errp); diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h index 3d79623..19df560 100644 --- a/include/hw/xen/xen-hvm-common.h +++ b/include/hw/xen/xen-hvm-common.h @@ -1,18 +1,10 @@ #ifndef HW_XEN_HVM_COMMON_H #define HW_XEN_HVM_COMMON_H -#include "qemu/units.h" - -#include "cpu.h" -#include "hw/pci/pci.h" -#include "hw/hw.h" +#include "qemu/queue.h" +#include "exec/hwaddr.h" #include "hw/xen/xen_native.h" -#include "hw/xen/xen-legacy-backend.h" -#include "sysemu/runstate.h" -#include "sysemu/sysemu.h" -#include "sysemu/xen.h" -#include "sysemu/xen-mapcache.h" -#include "qemu/error-report.h" +#include "hw/xen/xen_backend_ops.h" #include <xen/hvm/ioreq.h> extern MemoryRegion xen_memory; @@ -81,6 +73,8 @@ typedef struct XenIOState { QLIST_HEAD(, XenPciDevice) dev_list; DeviceListener device_listener; + bool has_bufioreq; + Notifier exit; } XenIOState; @@ -95,6 +89,7 @@ void xen_device_unrealize(DeviceListener *listener, DeviceState *dev); void xen_hvm_change_state_handler(void *opaque, bool running, RunState rstate); void xen_register_ioreq(XenIOState *state, unsigned int max_cpus, + uint8_t handle_bufioreq, const MemoryListener *xen_memory_listener); void cpu_ioreq_pio(ioreq_t *req); diff --git a/include/hw/xen/xen-legacy-backend.h b/include/hw/xen/xen-legacy-backend.h index 943732b..2d0cbfe 100644 --- a/include/hw/xen/xen-legacy-backend.h +++ b/include/hw/xen/xen-legacy-backend.h @@ -3,7 +3,6 @@ #include "hw/xen/xen_backend_ops.h" #include "hw/xen/xen_pvdev.h" -#include "net/net.h" #include "qom/object.h" #define TYPE_XENSYSDEV "xen-sysdev" @@ -50,10 +49,6 @@ void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs, void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr, uint32_t *refs, unsigned int nr_refs); -int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev, - bool to_domain, XenGrantCopySegment segs[], - unsigned int nr_segs); - static inline void *xen_be_map_grant_ref(struct XenLegacyDevice *xendev, uint32_t ref, int prot) { @@ -70,6 +65,5 @@ static inline void xen_be_unmap_grant_ref(struct XenLegacyDevice *xendev, void xen_config_cleanup(void); int xen_config_dev_vfb(int vdev, const char *type); int xen_config_dev_vkbd(int vdev); -int xen_config_dev_console(int vdev); #endif /* HW_XEN_LEGACY_BACKEND_H */ diff --git a/include/hw/xen/xen-pvh-common.h b/include/hw/xen/xen-pvh-common.h new file mode 100644 index 0000000..5db83d8 --- /dev/null +++ b/include/hw/xen/xen-pvh-common.h @@ -0,0 +1,91 @@ +/* + * QEMU Xen PVH machine - common code. + * + * Copyright (c) 2024 Advanced Micro Devices, Inc. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef XEN_PVH_COMMON_H__ +#define XEN_PVH_COMMON_H__ + +#include "system/memory.h" +#include "qom/object.h" +#include "hw/boards.h" +#include "hw/pci-host/gpex.h" +#include "hw/xen/xen-hvm-common.h" + +#define TYPE_XEN_PVH_MACHINE MACHINE_TYPE_NAME("xen-pvh-base") +OBJECT_DECLARE_TYPE(XenPVHMachineState, XenPVHMachineClass, + XEN_PVH_MACHINE) + +struct XenPVHMachineClass { + MachineClass parent; + + /* PVH implementation specific init. */ + void (*init)(MachineState *state); + + /* + * set_pci_intx_irq - Deliver INTX irqs to the guest. + * + * @opaque: pointer to XenPVHMachineState. + * @irq: IRQ after swizzling, between 0-3. + * @level: IRQ level. + */ + void (*set_pci_intx_irq)(void *opaque, int irq, int level); + + /* + * set_pci_link_route: - optional implementation call to setup + * routing between INTX IRQ (0 - 3) and GSI's. + * + * @line: line the INTx line (0 => A .. 3 => B) + * @irq: GSI + */ + int (*set_pci_link_route)(uint8_t line, uint8_t irq); + + /* Allow implementations to optionally enable buffered ioreqs. */ + uint8_t handle_bufioreq; + + /* + * Each implementation can optionally enable features that it + * supports and are known to work. + */ + bool has_pci; + bool has_tpm; + bool has_virtio_mmio; +}; + +struct XenPVHMachineState { + /*< private >*/ + MachineState parent; + + XenIOState ioreq; + + struct { + MemoryRegion low; + MemoryRegion high; + } ram; + + struct { + GPEXHost gpex; + MemoryRegion mmio_alias; + MemoryRegion mmio_high_alias; + } pci; + + struct { + MemMapEntry ram_low, ram_high; + MemMapEntry tpm; + + /* Virtio-mmio */ + MemMapEntry virtio_mmio; + uint32_t virtio_mmio_num; + uint32_t virtio_mmio_irq_base; + + /* PCI */ + MemMapEntry pci_ecam, pci_mmio, pci_mmio_high; + uint32_t pci_intx_irq_base; + } cfg; +}; + +void xen_pvh_class_setup_common_props(XenPVHMachineClass *xpc); +#endif diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index ecb89ec..e94c6e5 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -24,8 +24,6 @@ #define __XEN_INTERFACE_VERSION__ 0x00040e00 #endif -#include "exec/cpu-common.h" - /* xen-machine.c */ enum xen_mode { XEN_DISABLED = 0, /* xen support disabled (default) */ diff --git a/include/hw/xen/xen_native.h b/include/hw/xen/xen_native.h index 1a5ad69..5caf91a 100644 --- a/include/hw/xen/xen_native.h +++ b/include/hw/xen/xen_native.h @@ -464,10 +464,11 @@ static inline void xen_unmap_pcidev(domid_t dom, } static inline int xen_create_ioreq_server(domid_t dom, + int handle_bufioreq, ioservid_t *ioservid) { int rc = xendevicemodel_create_ioreq_server(xen_dmod, dom, - HVM_IOREQSRV_BUFIOREQ_ATOMIC, + handle_bufioreq, ioservid); if (rc == 0) { diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index 0c98444..629bec9 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -1,7 +1,7 @@ #ifndef QEMU_HW_XEN_PVDEV_H #define QEMU_HW_XEN_PVDEV_H -#include "hw/qdev-core.h" +#include "hw/sysbus.h" #include "hw/xen/xen_backend_ops.h" /* ------------------------------------------------------------- */ @@ -32,7 +32,8 @@ struct XenDevOps { }; struct XenLegacyDevice { - DeviceState qdev; + SysBusDevice parent_obj; + const char *type; int dom; int dev; diff --git a/include/hw/xtensa/mx_pic.h b/include/hw/xtensa/mx_pic.h index 500424c..cd316d8 100644 --- a/include/hw/xtensa/mx_pic.h +++ b/include/hw/xtensa/mx_pic.h @@ -28,7 +28,7 @@ #ifndef XTENSA_MX_PIC_H #define XTENSA_MX_PIC_H -#include "exec/memory.h" +#include "system/memory.h" struct XtensaMxPic; typedef struct XtensaMxPic XtensaMxPic; |