aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/accel/accel-cpu-target.h (renamed from include/hw/core/accel-cpu.h)19
-rw-r--r--include/accel/accel-cpu.h23
-rw-r--r--include/accel/tcg/cpu-ldst-common.h122
-rw-r--r--include/accel/tcg/cpu-ldst.h505
-rw-r--r--include/accel/tcg/cpu-mmu-index.h42
-rw-r--r--include/accel/tcg/cpu-ops.h (renamed from include/hw/core/tcg-cpu-ops.h)103
-rw-r--r--include/accel/tcg/getpc.h20
-rw-r--r--include/accel/tcg/helper-retaddr.h43
-rw-r--r--include/accel/tcg/iommu.h41
-rw-r--r--include/accel/tcg/probe.h122
-rw-r--r--include/accel/tcg/tb-cpu-state.h18
-rw-r--r--include/block/aio.h14
-rw-r--r--include/block/aio_task.h2
-rw-r--r--include/block/block-common.h13
-rw-r--r--include/block/block-copy.h1
-rw-r--r--include/block/block-global-state.h25
-rw-r--r--include/block/block-io.h4
-rw-r--r--include/block/block_int-common.h66
-rw-r--r--include/block/block_int-global-state.h6
-rw-r--r--include/block/block_int-io.h4
-rw-r--r--include/block/blockjob.h2
-rw-r--r--include/block/export.h3
-rw-r--r--include/block/graph-lock.h23
-rw-r--r--include/block/nbd.h24
-rw-r--r--include/block/nvme.h144
-rw-r--r--include/block/qdict.h2
-rw-r--r--include/block/raw-aio.h19
-rw-r--r--include/block/thread-pool.h62
-rw-r--r--include/block/ufs.h19
-rw-r--r--include/chardev/char-fe.h5
-rw-r--r--include/chardev/char-socket.h2
-rw-r--r--include/chardev/char.h1
-rw-r--r--include/crypto/afsplit.h8
-rw-r--r--include/crypto/block.h2
-rw-r--r--include/crypto/cipher.h18
-rw-r--r--include/crypto/hash.h189
-rw-r--r--include/crypto/hmac.h40
-rw-r--r--include/crypto/ivgen.h30
-rw-r--r--include/crypto/pbkdf.h14
-rw-r--r--include/crypto/tlssession.h79
-rw-r--r--include/crypto/x509-utils.h22
-rw-r--r--include/disas/capstone.h2
-rw-r--r--include/disas/dis-asm.h6
-rw-r--r--include/exec/cpu-all.h375
-rw-r--r--include/exec/cpu-common.h73
-rw-r--r--include/exec/cpu-defs.h44
-rw-r--r--include/exec/cpu-interrupt.h70
-rw-r--r--include/exec/cpu_ldst.h382
-rw-r--r--include/exec/cputlb.h263
-rw-r--r--include/exec/exec-all.h599
-rw-r--r--include/exec/gdbstub.h14
-rw-r--r--include/exec/helper-head.h.inc14
-rw-r--r--include/exec/helper-proto-common.h2
-rw-r--r--include/exec/icount.h (renamed from include/sysemu/cpu-timers.h)56
-rw-r--r--include/exec/memattrs.h29
-rw-r--r--include/exec/memop.h59
-rw-r--r--include/exec/memory-internal.h49
-rw-r--r--include/exec/memory_ldst.h.inc4
-rw-r--r--include/exec/memory_ldst_phys.h.inc5
-rw-r--r--include/exec/mmap-lock.h33
-rw-r--r--include/exec/page-vary.h9
-rw-r--r--include/exec/poison.h30
-rw-r--r--include/exec/ramlist.h1
-rw-r--r--include/exec/target_page.h52
-rw-r--r--include/exec/tlb-common.h10
-rw-r--r--include/exec/tlb-flags.h86
-rw-r--r--include/exec/translate-all.h33
-rw-r--r--include/exec/translation-block.h59
-rw-r--r--include/exec/translator.h81
-rw-r--r--include/exec/tswap.h87
-rw-r--r--include/exec/vaddr.h16
-rw-r--r--include/exec/watchpoint.h41
-rw-r--r--include/fpu/softfloat-helpers.h89
-rw-r--r--include/fpu/softfloat-types.h225
-rw-r--r--include/fpu/softfloat.h107
-rw-r--r--include/gdbstub/commands.h108
-rw-r--r--include/gdbstub/helpers.h4
-rw-r--r--include/gdbstub/syscalls.h2
-rw-r--r--include/gdbstub/user.h2
-rw-r--r--include/glib-compat.h7
-rw-r--r--include/hw/acpi/acpi-defs.h7
-rw-r--r--include/hw/acpi/acpi.h5
-rw-r--r--include/hw/acpi/acpi_generic_initiator.h47
-rw-r--r--include/hw/acpi/aml-build.h9
-rw-r--r--include/hw/acpi/cpu.h7
-rw-r--r--include/hw/acpi/generic_event_device.h12
-rw-r--r--include/hw/acpi/ghes.h14
-rw-r--r--include/hw/acpi/ich9.h6
-rw-r--r--include/hw/acpi/ich9_tco.h2
-rw-r--r--include/hw/acpi/ich9_timer.h23
-rw-r--r--include/hw/acpi/pci.h3
-rw-r--r--include/hw/acpi/pcihp.h2
-rw-r--r--include/hw/acpi/tpm.h2
-rw-r--r--include/hw/acpi/vmclock.h34
-rw-r--r--include/hw/adc/aspeed_adc.h1
-rw-r--r--include/hw/adc/max111x.h56
-rw-r--r--include/hw/arm/allwinner-a10.h4
-rw-r--r--include/hw/arm/allwinner-h3.h2
-rw-r--r--include/hw/arm/allwinner-r40.h2
-rw-r--r--include/hw/arm/aspeed.h2
-rw-r--r--include/hw/arm/aspeed_soc.h47
-rw-r--r--include/hw/arm/bcm2835_peripherals.h3
-rw-r--r--include/hw/arm/boot.h7
-rw-r--r--include/hw/arm/bsa.h2
-rw-r--r--include/hw/arm/fsl-imx25.h2
-rw-r--r--include/hw/arm/fsl-imx31.h2
-rw-r--r--include/hw/arm/fsl-imx6.h6
-rw-r--r--include/hw/arm/fsl-imx6ul.h2
-rw-r--r--include/hw/arm/fsl-imx7.h4
-rw-r--r--include/hw/arm/fsl-imx8mp.h284
-rw-r--r--include/hw/arm/npcm7xx.h8
-rw-r--r--include/hw/arm/npcm8xx.h132
-rw-r--r--include/hw/arm/nrf51_soc.h2
-rw-r--r--include/hw/arm/omap.h905
-rw-r--r--include/hw/arm/pxa.h197
-rw-r--r--include/hw/arm/raspberrypi-fw-defs.h2
-rw-r--r--include/hw/arm/sharpsl.h2
-rw-r--r--include/hw/arm/smmu-common.h57
-rw-r--r--include/hw/arm/soc_dma.h4
-rw-r--r--include/hw/arm/stm32f405_soc.h2
-rw-r--r--include/hw/arm/stm32l4x5_soc.h2
-rw-r--r--include/hw/arm/virt.h12
-rw-r--r--include/hw/arm/xlnx-versal.h1
-rw-r--r--include/hw/arm/xlnx-zynqmp.h1
-rw-r--r--include/hw/block/flash.h32
-rw-r--r--include/hw/boards.h388
-rw-r--r--include/hw/char/escc.h3
-rw-r--r--include/hw/char/imx_serial.h2
-rw-r--r--include/hw/char/mchp_pfsoc_mmuart.h2
-rw-r--r--include/hw/char/parallel-isa.h2
-rw-r--r--include/hw/char/parallel.h2
-rw-r--r--include/hw/char/pl011.h6
-rw-r--r--include/hw/char/riscv_htif.h2
-rw-r--r--include/hw/char/serial-isa.h38
-rw-r--r--include/hw/char/serial-mm.h (renamed from include/hw/cris/etraxfs.h)54
-rw-r--r--include/hw/char/serial.h32
-rw-r--r--include/hw/char/sifive_uart.h16
-rw-r--r--include/hw/clock.h8
-rw-r--r--include/hw/core/cpu.h147
-rw-r--r--include/hw/core/resetcontainer.h2
-rw-r--r--include/hw/core/sysemu-cpu-ops.h10
-rw-r--r--include/hw/cris/etraxfs_dma.h36
-rw-r--r--include/hw/cxl/cxl_device.h214
-rw-r--r--include/hw/cxl/cxl_events.h18
-rw-r--r--include/hw/cxl/cxl_mailbox.h19
-rw-r--r--include/hw/display/blizzard.h21
-rw-r--r--include/hw/display/macfb.h2
-rw-r--r--include/hw/display/tc6393xb.h21
-rw-r--r--include/hw/dma/i8257.h2
-rw-r--r--include/hw/dma/xlnx-zdma.h2
-rw-r--r--include/hw/dma/xlnx_dpdma.h3
-rw-r--r--include/hw/fsi/aspeed_apb2opb.h2
-rw-r--r--include/hw/fsi/cfam.h2
-rw-r--r--include/hw/fsi/fsi-master.h2
-rw-r--r--include/hw/fsi/fsi.h2
-rw-r--r--include/hw/fsi/lbus.h2
-rw-r--r--include/hw/gpio/aspeed_gpio.h7
-rw-r--r--include/hw/gpio/npcm7xx_gpio.h2
-rw-r--r--include/hw/hw.h4
-rw-r--r--include/hw/hyperv/hyperv-proto.h12
-rw-r--r--include/hw/hyperv/hyperv.h3
-rw-r--r--include/hw/hyperv/vmbus.h4
-rw-r--r--include/hw/i2c/aspeed_i2c.h37
-rw-r--r--include/hw/i2c/npcm7xx_smbus.h2
-rw-r--r--include/hw/i2c/pm_smbus.h2
-rw-r--r--include/hw/i386/apic_internal.h2
-rw-r--r--include/hw/i386/hostmem-epc.h2
-rw-r--r--include/hw/i386/intel_iommu.h13
-rw-r--r--include/hw/i386/microvm.h2
-rw-r--r--include/hw/i386/nitro_enclave.h62
-rw-r--r--include/hw/i386/pc.h54
-rw-r--r--include/hw/i386/sgx-epc.h1
-rw-r--r--include/hw/i386/tdvf.h45
-rw-r--r--include/hw/i386/topology.h52
-rw-r--r--include/hw/i386/x86.h7
-rw-r--r--include/hw/ide/ahci-pci.h2
-rw-r--r--include/hw/ide/ahci.h4
-rw-r--r--include/hw/ide/ide-bus.h2
-rw-r--r--include/hw/ide/ide-dev.h2
-rw-r--r--include/hw/input/lm832x.h28
-rw-r--r--include/hw/input/tsc2xxx.h41
-rw-r--r--include/hw/intc/arm_gic.h3
-rw-r--r--include/hw/intc/arm_gic_common.h2
-rw-r--r--include/hw/intc/arm_gicv3_common.h54
-rw-r--r--include/hw/intc/armv7m_nvic.h14
-rw-r--r--include/hw/intc/aspeed_intc.h41
-rw-r--r--include/hw/intc/loongarch_extioi.h91
-rw-r--r--include/hw/intc/loongarch_extioi_common.h101
-rw-r--r--include/hw/intc/loongarch_ipi.h32
-rw-r--r--include/hw/intc/loongarch_pch_pic.h76
-rw-r--r--include/hw/intc/loongarch_pic_common.h81
-rw-r--r--include/hw/intc/loongson_ipi.h51
-rw-r--r--include/hw/intc/loongson_ipi_common.h79
-rw-r--r--include/hw/intc/riscv_aplic.h8
-rw-r--r--include/hw/ipack/ipack.h7
-rw-r--r--include/hw/ipmi/ipmi.h17
-rw-r--r--include/hw/irq.h29
-rw-r--r--include/hw/isa/apm.h2
-rw-r--r--include/hw/isa/isa.h4
-rw-r--r--include/hw/isa/superio.h2
-rw-r--r--include/hw/loader-fit.h21
-rw-r--r--include/hw/loader.h33
-rw-r--r--include/hw/loongarch/boot.h5
-rw-r--r--include/hw/loongarch/virt.h21
-rw-r--r--include/hw/m68k/q800.h2
-rw-r--r--include/hw/mem/npcm7xx_mc.h2
-rw-r--r--include/hw/mem/pc-dimm.h2
-rw-r--r--include/hw/mips/cps.h1
-rw-r--r--include/hw/mips/mips.h2
-rw-r--r--include/hw/misc/aspeed_hace.h17
-rw-r--r--include/hw/misc/aspeed_scu.h6
-rw-r--r--include/hw/misc/auxbus.h2
-rw-r--r--include/hw/misc/bcm2835_property.h2
-rw-r--r--include/hw/misc/cbus.h31
-rw-r--r--include/hw/misc/imx8mp_analog.h81
-rw-r--r--include/hw/misc/imx8mp_ccm.h30
-rw-r--r--include/hw/misc/ivshmem-flat.h86
-rw-r--r--include/hw/misc/lasi.h2
-rw-r--r--include/hw/misc/mac_via.h2
-rw-r--r--include/hw/misc/macio/macio.h7
-rw-r--r--include/hw/misc/mos6522.h2
-rw-r--r--include/hw/misc/npcm7xx_mft.h2
-rw-r--r--include/hw/misc/npcm_clk.h (renamed from include/hw/misc/npcm7xx_clk.h)45
-rw-r--r--include/hw/misc/npcm_gcr.h (renamed from include/hw/misc/npcm7xx_gcr.h)31
-rw-r--r--include/hw/misc/pvpanic.h9
-rw-r--r--include/hw/misc/stm32_rcc.h91
-rw-r--r--include/hw/misc/stm32l4x5_exti.h6
-rw-r--r--include/hw/misc/stm32l4x5_syscfg.h1
-rw-r--r--include/hw/misc/vmcoreinfo.h7
-rw-r--r--include/hw/misc/xlnx-cfi-if.h1
-rw-r--r--include/hw/misc/xlnx-versal-trng.h1
-rw-r--r--include/hw/net/dp8393x.h2
-rw-r--r--include/hw/net/ftgmac100.h17
-rw-r--r--include/hw/net/imx_fec.h9
-rw-r--r--include/hw/net/lan9118_phy.h37
-rw-r--r--include/hw/net/mii.h6
-rw-r--r--include/hw/net/msf2-emac.h2
-rw-r--r--include/hw/net/npcm_pcs.h42
-rw-r--r--include/hw/nubus/nubus.h2
-rw-r--r--include/hw/nvram/bcm2835_otp.h68
-rw-r--r--include/hw/nvram/fw_cfg.h45
-rw-r--r--include/hw/nvram/fw_cfg_acpi.h2
-rw-r--r--include/hw/nvram/mac_nvram.h2
-rw-r--r--include/hw/nvram/npcm7xx_otp.h2
-rw-r--r--include/hw/nvram/xlnx-bbram.h3
-rw-r--r--include/hw/nvram/xlnx-efuse.h2
-rw-r--r--include/hw/nvram/xlnx-versal-efuse.h1
-rw-r--r--include/hw/nvram/xlnx-zynqmp-efuse.h1
-rw-r--r--include/hw/openrisc/boot.h3
-rw-r--r--include/hw/pci-bridge/cxl_upstream_port.h4
-rw-r--r--include/hw/pci-host/astro.h6
-rw-r--r--include/hw/pci-host/designware.h8
-rw-r--r--include/hw/pci-host/dino.h4
-rw-r--r--include/hw/pci-host/fsl_imx8m_phy.h28
-rw-r--r--include/hw/pci-host/gpex.h7
-rw-r--r--include/hw/pci-host/ls7a.h9
-rw-r--r--include/hw/pci-host/pam.h2
-rw-r--r--include/hw/pci-host/pnv_phb4.h5
-rw-r--r--include/hw/pci-host/q35.h2
-rw-r--r--include/hw/pci-host/remote.h2
-rw-r--r--include/hw/pci-host/spapr.h5
-rw-r--r--include/hw/pci/msix.h1
-rw-r--r--include/hw/pci/pci.h386
-rw-r--r--include/hw/pci/pci_bridge.h7
-rw-r--r--include/hw/pci/pci_device.h28
-rw-r--r--include/hw/pci/pci_host.h1
-rw-r--r--include/hw/pci/pci_ids.h1
-rw-r--r--include/hw/pci/pcie.h17
-rw-r--r--include/hw/pci/pcie_doe.h5
-rw-r--r--include/hw/pci/pcie_host.h2
-rw-r--r--include/hw/pci/pcie_port.h1
-rw-r--r--include/hw/pci/pcie_regs.h8
-rw-r--r--include/hw/pci/pcie_sriov.h30
-rw-r--r--include/hw/pci/shpc.h2
-rw-r--r--include/hw/pcmcia.h66
-rw-r--r--include/hw/ppc/mac_dbdma.h8
-rw-r--r--include/hw/ppc/pnv.h14
-rw-r--r--include/hw/ppc/pnv_adu.h32
-rw-r--r--include/hw/ppc/pnv_chip.h13
-rw-r--r--include/hw/ppc/pnv_core.h31
-rw-r--r--include/hw/ppc/pnv_homer.h12
-rw-r--r--include/hw/ppc/pnv_lpc.h24
-rw-r--r--include/hw/ppc/pnv_occ.h11
-rw-r--r--include/hw/ppc/pnv_pnor.h7
-rw-r--r--include/hw/ppc/pnv_sbe.h2
-rw-r--r--include/hw/ppc/pnv_xscom.h17
-rw-r--r--include/hw/ppc/ppc.h7
-rw-r--r--include/hw/ppc/ppc4xx.h2
-rw-r--r--include/hw/ppc/spapr.h13
-rw-r--r--include/hw/ppc/spapr_cpu_core.h1
-rw-r--r--include/hw/ppc/spapr_drc.h2
-rw-r--r--include/hw/ppc/spapr_nested.h75
-rw-r--r--include/hw/ppc/spapr_vio.h2
-rw-r--r--include/hw/ppc/vof.h4
-rw-r--r--include/hw/ppc/xics.h2
-rw-r--r--include/hw/ppc/xive.h47
-rw-r--r--include/hw/ppc/xive2.h42
-rw-r--r--include/hw/ppc/xive2_regs.h51
-rw-r--r--include/hw/ppc/xive_regs.h70
-rw-r--r--include/hw/qdev-core.h112
-rw-r--r--include/hw/qdev-properties-system.h18
-rw-r--r--include/hw/qdev-properties.h23
-rw-r--r--include/hw/register.h2
-rw-r--r--include/hw/remote/iohub.h1
-rw-r--r--include/hw/remote/proxy-memory-listener.h2
-rw-r--r--include/hw/resettable.h17
-rw-r--r--include/hw/riscv/boot.h36
-rw-r--r--include/hw/riscv/boot_opensbi.h29
-rw-r--r--include/hw/riscv/iommu.h42
-rw-r--r--include/hw/riscv/microchip_pfsoc.h1
-rw-r--r--include/hw/riscv/numa.h2
-rw-r--r--include/hw/riscv/riscv_hart.h4
-rw-r--r--include/hw/riscv/virt.h8
-rw-r--r--include/hw/s390x/ap-bridge.h39
-rw-r--r--include/hw/s390x/cpu-topology.h6
-rw-r--r--include/hw/s390x/css-bridge.h1
-rw-r--r--include/hw/s390x/css.h10
-rw-r--r--include/hw/s390x/event-facility.h17
-rw-r--r--include/hw/s390x/ipl/qipl.h127
-rw-r--r--include/hw/s390x/s390-pci-bus.h3
-rw-r--r--include/hw/s390x/s390-pci-clp.h1
-rw-r--r--include/hw/s390x/s390-pci-inst.h2
-rw-r--r--include/hw/s390x/s390-virtio-ccw.h20
-rw-r--r--include/hw/s390x/s390_flic.h4
-rw-r--r--include/hw/s390x/storage-attributes.h1
-rw-r--r--include/hw/s390x/storage-keys.h18
-rw-r--r--include/hw/s390x/vfio-ccw.h2
-rw-r--r--include/hw/scsi/scsi.h8
-rw-r--r--include/hw/sd/aspeed_sdhci.h13
-rw-r--r--include/hw/sd/sd.h14
-rw-r--r--include/hw/sd/sdcard_legacy.h50
-rw-r--r--include/hw/sd/sdhci.h7
-rw-r--r--include/hw/sh4/sh.h19
-rw-r--r--include/hw/sh4/sh_intc.h2
-rw-r--r--include/hw/southbridge/ich9.h6
-rw-r--r--include/hw/ssi/allwinner-a10-spi.h57
-rw-r--r--include/hw/ssi/aspeed_smc.h1
-rw-r--r--include/hw/ssi/npcm7xx_fiu.h1
-rw-r--r--include/hw/ssi/pnv_spi.h72
-rw-r--r--include/hw/ssi/pnv_spi_regs.h133
-rw-r--r--include/hw/sysbus.h5
-rw-r--r--include/hw/timer/aspeed_timer.h4
-rw-r--r--include/hw/timer/hpet.h3
-rw-r--r--include/hw/timer/imx_gpt.h1
-rw-r--r--include/hw/timer/npcm7xx_timer.h2
-rw-r--r--include/hw/tricore/triboard.h4
-rw-r--r--include/hw/tricore/tricore.h2
-rw-r--r--include/hw/uefi/hardware-info.h35
-rw-r--r--include/hw/uefi/var-service-api.h48
-rw-r--r--include/hw/uefi/var-service-edk2.h227
-rw-r--r--include/hw/uefi/var-service.h191
-rw-r--r--include/hw/usb.h14
-rw-r--r--include/hw/usb/dwc2-regs.h4
-rw-r--r--include/hw/usb/hcd-dwc3.h2
-rw-r--r--include/hw/usb/hcd-musb.h49
-rw-r--r--include/hw/usb/uhci-regs.h11
-rw-r--r--include/hw/vfio/vfio-common.h286
-rw-r--r--include/hw/vfio/vfio-container-base.h143
-rw-r--r--include/hw/vfio/vfio-container.h38
-rw-r--r--include/hw/vfio/vfio-cpr.h57
-rw-r--r--include/hw/vfio/vfio-device.h286
-rw-r--r--include/hw/vfio/vfio-migration.h16
-rw-r--r--include/hw/vfio/vfio-platform.h4
-rw-r--r--include/hw/vfio/vfio-region.h48
-rw-r--r--include/hw/virtio/cbor-helpers.h45
-rw-r--r--include/hw/virtio/iothread-vq-mapping.h45
-rw-r--r--include/hw/virtio/vhost-backend.h2
-rw-r--r--include/hw/virtio/vhost-scsi-common.h2
-rw-r--r--include/hw/virtio/vhost-user.h4
-rw-r--r--include/hw/virtio/vhost-vdpa.h22
-rw-r--r--include/hw/virtio/vhost-vsock-common.h2
-rw-r--r--include/hw/virtio/vhost.h40
-rw-r--r--include/hw/virtio/virtio-acpi.h2
-rw-r--r--include/hw/virtio/virtio-balloon.h6
-rw-r--r--include/hw/virtio/virtio-blk.h17
-rw-r--r--include/hw/virtio/virtio-crypto.h4
-rw-r--r--include/hw/virtio/virtio-gpu.h56
-rw-r--r--include/hw/virtio/virtio-input.h2
-rw-r--r--include/hw/virtio/virtio-iommu.h3
-rw-r--r--include/hw/virtio/virtio-mem.h19
-rw-r--r--include/hw/virtio/virtio-net.h2
-rw-r--r--include/hw/virtio/virtio-nsm.h49
-rw-r--r--include/hw/virtio/virtio-pci.h21
-rw-r--r--include/hw/virtio/virtio-pmem.h2
-rw-r--r--include/hw/virtio/virtio-rng.h2
-rw-r--r--include/hw/virtio/virtio-scsi.h17
-rw-r--r--include/hw/virtio/virtio.h42
-rw-r--r--include/hw/vmapple/vmapple.h23
-rw-r--r--include/hw/xen/arch_hvm.h2
-rw-r--r--include/hw/xen/interface/io/blkif.h2
-rw-r--r--include/hw/xen/xen-block.h2
-rw-r--r--include/hw/xen/xen-bus-helper.h9
-rw-r--r--include/hw/xen/xen-bus.h4
-rw-r--r--include/hw/xen/xen-hvm-common.h17
-rw-r--r--include/hw/xen/xen-legacy-backend.h6
-rw-r--r--include/hw/xen/xen-pvh-common.h91
-rw-r--r--include/hw/xen/xen.h3
-rw-r--r--include/hw/xen/xen_native.h3
-rw-r--r--include/hw/xen/xen_pvdev.h5
-rw-r--r--include/hw/xtensa/mx_pic.h2
-rw-r--r--include/io/channel-socket.h13
-rw-r--r--include/io/channel-tls.h12
-rw-r--r--include/io/channel.h24
-rw-r--r--include/libdecnumber/dconfig.h5
-rw-r--r--include/libdecnumber/decContext.h5
-rw-r--r--include/libdecnumber/decDPD.h5
-rw-r--r--include/libdecnumber/decNumber.h5
-rw-r--r--include/libdecnumber/decNumberLocal.h5
-rw-r--r--include/libdecnumber/dpd/decimal128.h5
-rw-r--r--include/libdecnumber/dpd/decimal128Local.h5
-rw-r--r--include/libdecnumber/dpd/decimal32.h5
-rw-r--r--include/libdecnumber/dpd/decimal64.h5
-rw-r--r--include/migration/client-options.h4
-rw-r--r--include/migration/cpr.h39
-rw-r--r--include/migration/misc.h45
-rw-r--r--include/migration/register.h67
-rw-r--r--include/migration/vmstate.h15
-rw-r--r--include/monitor/hmp.h3
-rw-r--r--include/net/checksum.h2
-rw-r--r--include/net/eth.h2
-rw-r--r--include/net/net.h4
-rw-r--r--include/net/queue.h4
-rw-r--r--include/qapi/compat-policy.h2
-rw-r--r--include/qapi/error-internal.h35
-rw-r--r--include/qapi/error.h14
-rw-r--r--include/qapi/qmp-registry.h (renamed from include/qapi/qmp/dispatch.h)4
-rw-r--r--include/qapi/qmp/qerror.h6
-rw-r--r--include/qapi/util.h4
-rw-r--r--include/qapi/visitor-impl.h4
-rw-r--r--include/qapi/visitor.h12
-rw-r--r--include/qemu-main.h14
-rw-r--r--include/qemu/accel.h10
-rw-r--r--include/qemu/atomic.h62
-rw-r--r--include/qemu/atomic128.h5
-rw-r--r--include/qemu/bitmap.h8
-rw-r--r--include/qemu/bitops.h172
-rw-r--r--include/qemu/bswap.h12
-rw-r--r--include/qemu/cacheflush.h7
-rw-r--r--include/qemu/clang-tsa.h114
-rw-r--r--include/qemu/co-shared-resource.h7
-rw-r--r--include/qemu/compiler.h171
-rw-r--r--include/qemu/coroutine.h1
-rw-r--r--include/qemu/crc-ccitt.h2
-rw-r--r--include/qemu/cutils.h20
-rw-r--r--include/qemu/datadir.h11
-rw-r--r--include/qemu/envlist.h2
-rw-r--r--include/qemu/fifo8.h82
-rw-r--r--include/qemu/futex.h44
-rw-r--r--include/qemu/help-texts.h2
-rw-r--r--include/qemu/host-pci-mmio.h136
-rw-r--r--include/qemu/host-utils.h9
-rw-r--r--include/qemu/iov.h32
-rw-r--r--include/qemu/iova-tree.h49
-rw-r--r--include/qemu/job.h3
-rw-r--r--include/qemu/lockcnt.h130
-rw-r--r--include/qemu/log.h1
-rw-r--r--include/qemu/main-loop.h25
-rw-r--r--include/qemu/osdep.h48
-rw-r--r--include/qemu/plugin-memory.h1
-rw-r--r--include/qemu/plugin.h7
-rw-r--r--include/qemu/pmem.h1
-rw-r--r--include/qemu/qemu-plugin.h65
-rw-r--r--include/qemu/range.h15
-rw-r--r--include/qemu/rcu.h4
-rw-r--r--include/qemu/rcu_queue.h4
-rw-r--r--include/qemu/reserved-region.h2
-rw-r--r--include/qemu/s390x_pci_mmio.h24
-rw-r--r--include/qemu/sockets.h16
-rw-r--r--include/qemu/target-info-impl.h32
-rw-r--r--include/qemu/target-info.h41
-rw-r--r--include/qemu/thread-posix.h9
-rw-r--r--include/qemu/thread-win32.h6
-rw-r--r--include/qemu/thread.h133
-rw-r--r--include/qemu/timed-average.h4
-rw-r--r--include/qemu/timer.h40
-rw-r--r--include/qemu/typedefs.h7
-rw-r--r--include/qemu/userfaultfd.h1
-rw-r--r--include/qobject/json-parser.h (renamed from include/qapi/qmp/json-parser.h)0
-rw-r--r--include/qobject/json-writer.h (renamed from include/qapi/qmp/json-writer.h)0
-rw-r--r--include/qobject/qbool.h (renamed from include/qapi/qmp/qbool.h)2
-rw-r--r--include/qobject/qdict.h (renamed from include/qapi/qmp/qdict.h)2
-rw-r--r--include/qobject/qjson.h (renamed from include/qapi/qmp/qjson.h)0
-rw-r--r--include/qobject/qlist.h (renamed from include/qapi/qmp/qlist.h)2
-rw-r--r--include/qobject/qlit.h (renamed from include/qapi/qmp/qlit.h)0
-rw-r--r--include/qobject/qnull.h (renamed from include/qapi/qmp/qnull.h)2
-rw-r--r--include/qobject/qnum.h (renamed from include/qapi/qmp/qnum.h)2
-rw-r--r--include/qobject/qobject.h (renamed from include/qapi/qmp/qobject.h)4
-rw-r--r--include/qobject/qstring.h (renamed from include/qapi/qmp/qstring.h)2
-rw-r--r--include/qom/object.h80
-rw-r--r--include/semihosting/console.h2
-rw-r--r--include/semihosting/semihost.h29
-rw-r--r--include/semihosting/syscalls.h3
-rw-r--r--include/semihosting/uaccess.h55
-rw-r--r--include/standard-headers/asm-x86/setup_data.h17
-rw-r--r--include/standard-headers/drm/drm_fourcc.h130
-rw-r--r--include/standard-headers/linux/const.h17
-rw-r--r--include/standard-headers/linux/ethtool.h446
-rw-r--r--include/standard-headers/linux/fuse.h110
-rw-r--r--include/standard-headers/linux/input-event-codes.h6
-rw-r--r--include/standard-headers/linux/pci_regs.h126
-rw-r--r--include/standard-headers/linux/virtio_balloon.h16
-rw-r--r--include/standard-headers/linux/virtio_bt.h1
-rw-r--r--include/standard-headers/linux/virtio_crypto.h1
-rw-r--r--include/standard-headers/linux/virtio_gpu.h4
-rw-r--r--include/standard-headers/linux/virtio_mem.h2
-rw-r--r--include/standard-headers/linux/virtio_net.h156
-rw-r--r--include/standard-headers/linux/virtio_pci.h146
-rw-r--r--include/standard-headers/linux/virtio_snd.h2
-rw-r--r--include/standard-headers/linux/vmclock-abi.h182
-rw-r--r--include/standard-headers/misc/pvpanic.h7
-rw-r--r--include/standard-headers/uefi/uefi.h187
-rw-r--r--include/sysemu/iommufd.h36
-rw-r--r--include/sysemu/xen-mapcache.h71
-rw-r--r--include/system/accel-blocker.h (renamed from include/sysemu/accel-blocker.h)2
-rw-r--r--include/system/accel-ops.h (renamed from include/sysemu/accel-ops.h)3
-rw-r--r--include/system/address-spaces.h (renamed from include/exec/address-spaces.h)8
-rw-r--r--include/system/arch_init.h (renamed from include/sysemu/arch_init.h)5
-rw-r--r--include/system/balloon.h (renamed from include/sysemu/balloon.h)0
-rw-r--r--include/system/block-backend-common.h (renamed from include/sysemu/block-backend-common.h)0
-rw-r--r--include/system/block-backend-global-state.h (renamed from include/sysemu/block-backend-global-state.h)9
-rw-r--r--include/system/block-backend-io.h (renamed from include/sysemu/block-backend-io.h)7
-rw-r--r--include/system/block-backend.h (renamed from include/sysemu/block-backend.h)0
-rw-r--r--include/system/block-ram-registrar.h (renamed from include/sysemu/block-ram-registrar.h)0
-rw-r--r--include/system/blockdev.h (renamed from include/sysemu/blockdev.h)0
-rw-r--r--include/system/confidential-guest-support.h (renamed from include/exec/confidential-guest-support.h)4
-rw-r--r--include/system/cpu-throttle.h (renamed from include/sysemu/cpu-throttle.h)20
-rw-r--r--include/system/cpu-timers-internal.h (renamed from include/sysemu/cpu-timers-internal.h)0
-rw-r--r--include/system/cpu-timers.h46
-rw-r--r--include/system/cpus.h (renamed from include/sysemu/cpus.h)4
-rw-r--r--include/system/cryptodev-vhost-user.h (renamed from include/sysemu/cryptodev-vhost-user.h)2
-rw-r--r--include/system/cryptodev-vhost.h (renamed from include/sysemu/cryptodev-vhost.h)2
-rw-r--r--include/system/cryptodev.h (renamed from include/sysemu/cryptodev.h)2
-rw-r--r--include/system/device_tree.h (renamed from include/sysemu/device_tree.h)2
-rw-r--r--include/system/dirtylimit.h (renamed from include/sysemu/dirtylimit.h)0
-rw-r--r--include/system/dirtyrate.h (renamed from include/sysemu/dirtyrate.h)0
-rw-r--r--include/system/dma.h (renamed from include/sysemu/dma.h)18
-rw-r--r--include/system/dump-arch.h (renamed from include/sysemu/dump-arch.h)0
-rw-r--r--include/system/dump.h (renamed from include/sysemu/dump.h)4
-rw-r--r--include/system/event-loop-base.h (renamed from include/sysemu/event-loop-base.h)0
-rw-r--r--include/system/host_iommu_device.h125
-rw-r--r--include/system/hostmem.h (renamed from include/sysemu/hostmem.h)13
-rw-r--r--include/system/hvf.h (renamed from include/sysemu/hvf.h)18
-rw-r--r--include/system/hvf_int.h (renamed from include/sysemu/hvf_int.h)4
-rw-r--r--include/system/hw_accel.h (renamed from include/sysemu/hw_accel.h)8
-rw-r--r--include/system/iommufd.h120
-rw-r--r--include/system/ioport.h (renamed from include/exec/ioport.h)8
-rw-r--r--include/system/iothread.h (renamed from include/sysemu/iothread.h)2
-rw-r--r--include/system/kvm.h (renamed from include/sysemu/kvm.h)67
-rw-r--r--include/system/kvm_int.h (renamed from include/sysemu/kvm_int.h)60
-rw-r--r--include/system/kvm_xen.h (renamed from include/sysemu/kvm_xen.h)6
-rw-r--r--include/system/memory.h (renamed from include/exec/memory.h)322
-rw-r--r--include/system/memory_mapping.h (renamed from include/sysemu/memory_mapping.h)0
-rw-r--r--include/system/numa.h (renamed from include/sysemu/numa.h)5
-rw-r--r--include/system/nvmm.h (renamed from include/sysemu/nvmm.h)0
-rw-r--r--include/system/os-posix.h (renamed from include/sysemu/os-posix.h)2
-rw-r--r--include/system/os-wasm.h104
-rw-r--r--include/system/os-win32.h (renamed from include/sysemu/os-win32.h)3
-rw-r--r--include/system/qtest.h (renamed from include/sysemu/qtest.h)3
-rw-r--r--include/system/ram_addr.h (renamed from include/exec/ram_addr.h)45
-rw-r--r--include/system/ramblock.h (renamed from include/exec/ramblock.h)32
-rw-r--r--include/system/replay.h (renamed from include/sysemu/replay.h)15
-rw-r--r--include/system/reset.h (renamed from include/sysemu/reset.h)9
-rw-r--r--include/system/rng-random.h (renamed from include/sysemu/rng-random.h)0
-rw-r--r--include/system/rng.h (renamed from include/sysemu/rng.h)0
-rw-r--r--include/system/rtc.h (renamed from include/sysemu/rtc.h)4
-rw-r--r--include/system/runstate-action.h (renamed from include/sysemu/runstate-action.h)0
-rw-r--r--include/system/runstate.h (renamed from include/sysemu/runstate.h)19
-rw-r--r--include/system/seccomp.h (renamed from include/sysemu/seccomp.h)0
-rw-r--r--include/system/spdm-socket.h74
-rw-r--r--include/system/stats.h (renamed from include/sysemu/stats.h)0
-rw-r--r--include/system/system.h (renamed from include/sysemu/sysemu.h)18
-rw-r--r--include/system/tcg.h (renamed from include/sysemu/tcg.h)12
-rw-r--r--include/system/tpm.h (renamed from include/sysemu/tpm.h)0
-rw-r--r--include/system/tpm_backend.h (renamed from include/sysemu/tpm_backend.h)2
-rw-r--r--include/system/tpm_util.h (renamed from include/sysemu/tpm_util.h)8
-rw-r--r--include/system/vhost-user-backend.h (renamed from include/sysemu/vhost-user-backend.h)4
-rw-r--r--include/system/watchdog.h (renamed from include/sysemu/watchdog.h)0
-rw-r--r--include/system/whpx.h (renamed from include/sysemu/whpx.h)0
-rw-r--r--include/system/xen-mapcache.h30
-rw-r--r--include/system/xen.h (renamed from include/sysemu/xen.h)29
-rw-r--r--include/tcg/insn-start-words.h15
-rw-r--r--include/tcg/oversized-guest.h23
-rw-r--r--include/tcg/startup.h6
-rw-r--r--include/tcg/tcg-op-common.h5
-rw-r--r--include/tcg/tcg-op-gvec-common.h63
-rw-r--r--include/tcg/tcg-op.h22
-rw-r--r--include/tcg/tcg-opc.h396
-rw-r--r--include/tcg/tcg-temp-internal.h6
-rw-r--r--include/tcg/tcg.h264
-rw-r--r--include/ui/clipboard.h31
-rw-r--r--include/ui/console.h8
-rw-r--r--include/ui/dmabuf.h20
-rw-r--r--include/ui/egl-helpers.h9
-rw-r--r--include/ui/gtk.h2
-rw-r--r--include/ui/qemu-pixman.h28
-rw-r--r--include/ui/sdl2.h2
-rw-r--r--include/ui/surface.h14
-rw-r--r--include/user/abitypes.h7
-rw-r--r--include/user/cpu_loop.h88
-rw-r--r--include/user/guest-host.h76
-rw-r--r--include/user/mmap.h32
-rw-r--r--include/user/page-protection.h96
-rw-r--r--include/user/signal.h25
603 files changed, 14048 insertions, 6342 deletions
diff --git a/include/hw/core/accel-cpu.h b/include/accel/accel-cpu-target.h
index 24dad45..6feb344 100644
--- a/include/hw/core/accel-cpu.h
+++ b/include/accel/accel-cpu-target.h
@@ -8,8 +8,8 @@
* See the COPYING file in the top-level directory.
*/
-#ifndef ACCEL_CPU_H
-#define ACCEL_CPU_H
+#ifndef ACCEL_CPU_TARGET_H
+#define ACCEL_CPU_TARGET_H
/*
* This header is used to define new accelerator-specific target-specific
@@ -20,19 +20,12 @@
* subclasses in target/, or the accel implementation itself in accel/
*/
+#include "qom/object.h"
+#include "accel/accel-cpu.h"
+#include "cpu.h"
+
#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/accel/accel-cpu.h b/include/accel/accel-cpu.h
new file mode 100644
index 0000000..9e7eede
--- /dev/null
+++ b/include/accel/accel-cpu.h
@@ -0,0 +1,23 @@
+/*
+ * Accelerator interface, specializes CPUClass
+ *
+ * Copyright 2021 SUSE LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ACCEL_CPU_H
+#define ACCEL_CPU_H
+
+#include "qom/object.h"
+#include "hw/core/cpu.h"
+
+typedef struct AccelCPUClass {
+ ObjectClass parent_class;
+
+ 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/accel/tcg/cpu-ldst-common.h b/include/accel/tcg/cpu-ldst-common.h
new file mode 100644
index 0000000..8bf17c2
--- /dev/null
+++ b/include/accel/tcg/cpu-ldst-common.h
@@ -0,0 +1,122 @@
+/*
+ * Software MMU support
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef ACCEL_TCG_CPU_LDST_COMMON_H
+#define ACCEL_TCG_CPU_LDST_COMMON_H
+
+#ifndef CONFIG_TCG
+#error Can only include this header with TCG
+#endif
+
+#include "exec/memopidx.h"
+#include "exec/vaddr.h"
+#include "exec/mmu-access-type.h"
+#include "qemu/int128.h"
+
+uint8_t cpu_ldb_mmu(CPUArchState *env, vaddr ptr, MemOpIdx oi, uintptr_t ra);
+uint16_t cpu_ldw_mmu(CPUArchState *env, vaddr ptr, MemOpIdx oi, uintptr_t ra);
+uint32_t cpu_ldl_mmu(CPUArchState *env, vaddr ptr, MemOpIdx oi, uintptr_t ra);
+uint64_t cpu_ldq_mmu(CPUArchState *env, vaddr ptr, MemOpIdx oi, uintptr_t ra);
+Int128 cpu_ld16_mmu(CPUArchState *env, vaddr addr, MemOpIdx oi, uintptr_t ra);
+
+void cpu_stb_mmu(CPUArchState *env, vaddr ptr, uint8_t val,
+ MemOpIdx oi, uintptr_t ra);
+void cpu_stw_mmu(CPUArchState *env, vaddr ptr, uint16_t val,
+ MemOpIdx oi, uintptr_t ra);
+void cpu_stl_mmu(CPUArchState *env, vaddr ptr, uint32_t val,
+ MemOpIdx oi, uintptr_t ra);
+void cpu_stq_mmu(CPUArchState *env, vaddr ptr, uint64_t val,
+ MemOpIdx oi, uintptr_t ra);
+void cpu_st16_mmu(CPUArchState *env, vaddr addr, Int128 val,
+ MemOpIdx oi, uintptr_t ra);
+
+uint32_t cpu_atomic_cmpxchgb_mmu(CPUArchState *env, vaddr addr,
+ uint32_t cmpv, uint32_t newv,
+ MemOpIdx oi, uintptr_t retaddr);
+uint32_t cpu_atomic_cmpxchgw_le_mmu(CPUArchState *env, vaddr addr,
+ uint32_t cmpv, uint32_t newv,
+ MemOpIdx oi, uintptr_t retaddr);
+uint32_t cpu_atomic_cmpxchgl_le_mmu(CPUArchState *env, vaddr addr,
+ uint32_t cmpv, uint32_t newv,
+ MemOpIdx oi, uintptr_t retaddr);
+uint64_t cpu_atomic_cmpxchgq_le_mmu(CPUArchState *env, vaddr addr,
+ uint64_t cmpv, uint64_t newv,
+ MemOpIdx oi, uintptr_t retaddr);
+uint32_t cpu_atomic_cmpxchgw_be_mmu(CPUArchState *env, vaddr addr,
+ uint32_t cmpv, uint32_t newv,
+ MemOpIdx oi, uintptr_t retaddr);
+uint32_t cpu_atomic_cmpxchgl_be_mmu(CPUArchState *env, vaddr addr,
+ uint32_t cmpv, uint32_t newv,
+ MemOpIdx oi, uintptr_t retaddr);
+uint64_t cpu_atomic_cmpxchgq_be_mmu(CPUArchState *env, vaddr addr,
+ uint64_t cmpv, uint64_t newv,
+ MemOpIdx oi, uintptr_t retaddr);
+
+#define GEN_ATOMIC_HELPER(NAME, TYPE, SUFFIX) \
+TYPE cpu_atomic_ ## NAME ## SUFFIX ## _mmu \
+ (CPUArchState *env, vaddr addr, TYPE val, \
+ MemOpIdx oi, uintptr_t retaddr);
+
+#ifdef CONFIG_ATOMIC64
+#define GEN_ATOMIC_HELPER_ALL(NAME) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, l_be) \
+ GEN_ATOMIC_HELPER(NAME, uint64_t, q_le) \
+ GEN_ATOMIC_HELPER(NAME, uint64_t, q_be)
+#else
+#define GEN_ATOMIC_HELPER_ALL(NAME) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
+ GEN_ATOMIC_HELPER(NAME, uint32_t, l_be)
+#endif
+
+GEN_ATOMIC_HELPER_ALL(fetch_add)
+GEN_ATOMIC_HELPER_ALL(fetch_sub)
+GEN_ATOMIC_HELPER_ALL(fetch_and)
+GEN_ATOMIC_HELPER_ALL(fetch_or)
+GEN_ATOMIC_HELPER_ALL(fetch_xor)
+GEN_ATOMIC_HELPER_ALL(fetch_smin)
+GEN_ATOMIC_HELPER_ALL(fetch_umin)
+GEN_ATOMIC_HELPER_ALL(fetch_smax)
+GEN_ATOMIC_HELPER_ALL(fetch_umax)
+
+GEN_ATOMIC_HELPER_ALL(add_fetch)
+GEN_ATOMIC_HELPER_ALL(sub_fetch)
+GEN_ATOMIC_HELPER_ALL(and_fetch)
+GEN_ATOMIC_HELPER_ALL(or_fetch)
+GEN_ATOMIC_HELPER_ALL(xor_fetch)
+GEN_ATOMIC_HELPER_ALL(smin_fetch)
+GEN_ATOMIC_HELPER_ALL(umin_fetch)
+GEN_ATOMIC_HELPER_ALL(smax_fetch)
+GEN_ATOMIC_HELPER_ALL(umax_fetch)
+
+GEN_ATOMIC_HELPER_ALL(xchg)
+
+#undef GEN_ATOMIC_HELPER_ALL
+#undef GEN_ATOMIC_HELPER
+
+Int128 cpu_atomic_cmpxchgo_le_mmu(CPUArchState *env, vaddr addr,
+ Int128 cmpv, Int128 newv,
+ MemOpIdx oi, uintptr_t retaddr);
+Int128 cpu_atomic_cmpxchgo_be_mmu(CPUArchState *env, vaddr addr,
+ Int128 cmpv, Int128 newv,
+ MemOpIdx oi, uintptr_t retaddr);
+
+uint8_t cpu_ldb_code_mmu(CPUArchState *env, vaddr addr,
+ MemOpIdx oi, uintptr_t ra);
+uint16_t cpu_ldw_code_mmu(CPUArchState *env, vaddr addr,
+ MemOpIdx oi, uintptr_t ra);
+uint32_t cpu_ldl_code_mmu(CPUArchState *env, vaddr addr,
+ MemOpIdx oi, uintptr_t ra);
+uint64_t cpu_ldq_code_mmu(CPUArchState *env, vaddr addr,
+ MemOpIdx oi, uintptr_t ra);
+
+#endif /* ACCEL_TCG_CPU_LDST_COMMON_H */
diff --git a/include/accel/tcg/cpu-ldst.h b/include/accel/tcg/cpu-ldst.h
new file mode 100644
index 0000000..0de7f5e
--- /dev/null
+++ b/include/accel/tcg/cpu-ldst.h
@@ -0,0 +1,505 @@
+/*
+ * Software MMU support (per-target)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*
+ * Generate inline load/store functions for all MMU modes (typically
+ * at least _user and _kernel) as well as _data versions, for all data
+ * sizes.
+ *
+ * Used by target op helpers.
+ *
+ * The syntax for the accessors is:
+ *
+ * load: cpu_ld{sign}{size}{end}_{mmusuffix}(env, ptr)
+ * cpu_ld{sign}{size}{end}_{mmusuffix}_ra(env, ptr, retaddr)
+ * cpu_ld{sign}{size}{end}_mmuidx_ra(env, ptr, mmu_idx, retaddr)
+ * cpu_ld{sign}{size}{end}_mmu(env, ptr, oi, retaddr)
+ *
+ * store: cpu_st{size}{end}_{mmusuffix}(env, ptr, val)
+ * cpu_st{size}{end}_{mmusuffix}_ra(env, ptr, val, retaddr)
+ * cpu_st{size}{end}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr)
+ * cpu_st{size}{end}_mmu(env, ptr, val, oi, retaddr)
+ *
+ * sign is:
+ * (empty): for 32 and 64 bit sizes
+ * u : unsigned
+ * s : signed
+ *
+ * size is:
+ * b: 8 bits
+ * w: 16 bits
+ * l: 32 bits
+ * q: 64 bits
+ *
+ * end is:
+ * (empty): for target native endian, or for 8 bit access
+ * _be: for forced big endian
+ * _le: for forced little endian
+ *
+ * mmusuffix is one of the generic suffixes "data" or "code", or "mmuidx".
+ * The "mmuidx" suffix carries an extra mmu_idx argument that specifies
+ * the index to use; the "data" and "code" suffixes take the index from
+ * cpu_mmu_index().
+ *
+ * The "mmu" suffix carries the full MemOpIdx, with both mmu_idx and the
+ * MemOp including alignment requirements. The alignment will be enforced.
+ */
+#ifndef ACCEL_TCG_CPU_LDST_H
+#define ACCEL_TCG_CPU_LDST_H
+
+#ifndef CONFIG_TCG
+#error Can only include this header with TCG
+#endif
+
+#include "exec/cpu-common.h"
+#include "accel/tcg/cpu-ldst-common.h"
+#include "accel/tcg/cpu-mmu-index.h"
+#include "exec/abi_ptr.h"
+
+#if defined(CONFIG_USER_ONLY)
+#include "user/guest-host.h"
+#endif /* CONFIG_USER_ONLY */
+
+static inline uint32_t
+cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr, int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
+ return cpu_ldb_mmu(env, addr, oi, ra);
+}
+
+static inline int
+cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr, int mmu_idx, uintptr_t ra)
+{
+ return (int8_t)cpu_ldub_mmuidx_ra(env, addr, mmu_idx, ra);
+}
+
+static inline uint32_t
+cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
+ return cpu_ldw_mmu(env, addr, oi, ra);
+}
+
+static inline int
+cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ return (int16_t)cpu_lduw_be_mmuidx_ra(env, addr, mmu_idx, ra);
+}
+
+static inline uint32_t
+cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
+ return cpu_ldl_mmu(env, addr, oi, ra);
+}
+
+static inline uint64_t
+cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
+ return cpu_ldq_mmu(env, addr, oi, ra);
+}
+
+static inline uint32_t
+cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
+ return cpu_ldw_mmu(env, addr, oi, ra);
+}
+
+static inline int
+cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ return (int16_t)cpu_lduw_le_mmuidx_ra(env, addr, mmu_idx, ra);
+}
+
+static inline uint32_t
+cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
+ return cpu_ldl_mmu(env, addr, oi, ra);
+}
+
+static inline uint64_t
+cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
+ return cpu_ldq_mmu(env, addr, oi, ra);
+}
+
+static inline void
+cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
+ cpu_stb_mmu(env, addr, val, oi, ra);
+}
+
+static inline void
+cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_BEUW | MO_UNALN, mmu_idx);
+ cpu_stw_mmu(env, addr, val, oi, ra);
+}
+
+static inline void
+cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_BEUL | MO_UNALN, mmu_idx);
+ cpu_stl_mmu(env, addr, val, oi, ra);
+}
+
+static inline void
+cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_BEUQ | MO_UNALN, mmu_idx);
+ cpu_stq_mmu(env, addr, val, oi, ra);
+}
+
+static inline void
+cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_LEUW | MO_UNALN, mmu_idx);
+ cpu_stw_mmu(env, addr, val, oi, ra);
+}
+
+static inline void
+cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_LEUL | MO_UNALN, mmu_idx);
+ cpu_stl_mmu(env, addr, val, oi, ra);
+}
+
+static inline void
+cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val,
+ int mmu_idx, uintptr_t ra)
+{
+ MemOpIdx oi = make_memop_idx(MO_LEUQ | MO_UNALN, mmu_idx);
+ cpu_stq_mmu(env, addr, val, oi, ra);
+}
+
+/*--------------------------*/
+
+static inline uint32_t
+cpu_ldub_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ return cpu_ldub_mmuidx_ra(env, addr, mmu_index, ra);
+}
+
+static inline int
+cpu_ldsb_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ return (int8_t)cpu_ldub_data_ra(env, addr, ra);
+}
+
+static inline uint32_t
+cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ return cpu_lduw_be_mmuidx_ra(env, addr, mmu_index, ra);
+}
+
+static inline int
+cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ return (int16_t)cpu_lduw_be_data_ra(env, addr, ra);
+}
+
+static inline uint32_t
+cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ return cpu_ldl_be_mmuidx_ra(env, addr, mmu_index, ra);
+}
+
+static inline uint64_t
+cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ return cpu_ldq_be_mmuidx_ra(env, addr, mmu_index, ra);
+}
+
+static inline uint32_t
+cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ return cpu_lduw_le_mmuidx_ra(env, addr, mmu_index, ra);
+}
+
+static inline int
+cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ return (int16_t)cpu_lduw_le_data_ra(env, addr, ra);
+}
+
+static inline uint32_t
+cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ return cpu_ldl_le_mmuidx_ra(env, addr, mmu_index, ra);
+}
+
+static inline uint64_t
+cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr addr, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ return cpu_ldq_le_mmuidx_ra(env, addr, mmu_index, ra);
+}
+
+static inline void
+cpu_stb_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ cpu_stb_mmuidx_ra(env, addr, val, mmu_index, ra);
+}
+
+static inline void
+cpu_stw_be_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ cpu_stw_be_mmuidx_ra(env, addr, val, mmu_index, ra);
+}
+
+static inline void
+cpu_stl_be_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ cpu_stl_be_mmuidx_ra(env, addr, val, mmu_index, ra);
+}
+
+static inline void
+cpu_stq_be_data_ra(CPUArchState *env, abi_ptr addr, uint64_t val, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ cpu_stq_be_mmuidx_ra(env, addr, val, mmu_index, ra);
+}
+
+static inline void
+cpu_stw_le_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ cpu_stw_le_mmuidx_ra(env, addr, val, mmu_index, ra);
+}
+
+static inline void
+cpu_stl_le_data_ra(CPUArchState *env, abi_ptr addr, uint32_t val, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ cpu_stl_le_mmuidx_ra(env, addr, val, mmu_index, ra);
+}
+
+static inline void
+cpu_stq_le_data_ra(CPUArchState *env, abi_ptr addr, uint64_t val, uintptr_t ra)
+{
+ int mmu_index = cpu_mmu_index(env_cpu(env), false);
+ cpu_stq_le_mmuidx_ra(env, addr, val, mmu_index, ra);
+}
+
+/*--------------------------*/
+
+static inline uint32_t
+cpu_ldub_data(CPUArchState *env, abi_ptr addr)
+{
+ return cpu_ldub_data_ra(env, addr, 0);
+}
+
+static inline int
+cpu_ldsb_data(CPUArchState *env, abi_ptr addr)
+{
+ return (int8_t)cpu_ldub_data(env, addr);
+}
+
+static inline uint32_t
+cpu_lduw_be_data(CPUArchState *env, abi_ptr addr)
+{
+ return cpu_lduw_be_data_ra(env, addr, 0);
+}
+
+static inline int
+cpu_ldsw_be_data(CPUArchState *env, abi_ptr addr)
+{
+ return (int16_t)cpu_lduw_be_data(env, addr);
+}
+
+static inline uint32_t
+cpu_ldl_be_data(CPUArchState *env, abi_ptr addr)
+{
+ return cpu_ldl_be_data_ra(env, addr, 0);
+}
+
+static inline uint64_t
+cpu_ldq_be_data(CPUArchState *env, abi_ptr addr)
+{
+ return cpu_ldq_be_data_ra(env, addr, 0);
+}
+
+static inline uint32_t
+cpu_lduw_le_data(CPUArchState *env, abi_ptr addr)
+{
+ return cpu_lduw_le_data_ra(env, addr, 0);
+}
+
+static inline int
+cpu_ldsw_le_data(CPUArchState *env, abi_ptr addr)
+{
+ return (int16_t)cpu_lduw_le_data(env, addr);
+}
+
+static inline uint32_t
+cpu_ldl_le_data(CPUArchState *env, abi_ptr addr)
+{
+ return cpu_ldl_le_data_ra(env, addr, 0);
+}
+
+static inline uint64_t
+cpu_ldq_le_data(CPUArchState *env, abi_ptr addr)
+{
+ return cpu_ldq_le_data_ra(env, addr, 0);
+}
+
+static inline void
+cpu_stb_data(CPUArchState *env, abi_ptr addr, uint32_t val)
+{
+ cpu_stb_data_ra(env, addr, val, 0);
+}
+
+static inline void
+cpu_stw_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
+{
+ cpu_stw_be_data_ra(env, addr, val, 0);
+}
+
+static inline void
+cpu_stl_be_data(CPUArchState *env, abi_ptr addr, uint32_t val)
+{
+ cpu_stl_be_data_ra(env, addr, val, 0);
+}
+
+static inline void
+cpu_stq_be_data(CPUArchState *env, abi_ptr addr, uint64_t val)
+{
+ cpu_stq_be_data_ra(env, addr, val, 0);
+}
+
+static inline void
+cpu_stw_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
+{
+ cpu_stw_le_data_ra(env, addr, val, 0);
+}
+
+static inline void
+cpu_stl_le_data(CPUArchState *env, abi_ptr addr, uint32_t val)
+{
+ cpu_stl_le_data_ra(env, addr, val, 0);
+}
+
+static inline void
+cpu_stq_le_data(CPUArchState *env, abi_ptr addr, uint64_t val)
+{
+ cpu_stq_le_data_ra(env, addr, val, 0);
+}
+
+#if TARGET_BIG_ENDIAN
+# define cpu_lduw_data cpu_lduw_be_data
+# define cpu_ldsw_data cpu_ldsw_be_data
+# define cpu_ldl_data cpu_ldl_be_data
+# define cpu_ldq_data cpu_ldq_be_data
+# define cpu_lduw_data_ra cpu_lduw_be_data_ra
+# define cpu_ldsw_data_ra cpu_ldsw_be_data_ra
+# define cpu_ldl_data_ra cpu_ldl_be_data_ra
+# define cpu_ldq_data_ra cpu_ldq_be_data_ra
+# define cpu_lduw_mmuidx_ra cpu_lduw_be_mmuidx_ra
+# define cpu_ldsw_mmuidx_ra cpu_ldsw_be_mmuidx_ra
+# define cpu_ldl_mmuidx_ra cpu_ldl_be_mmuidx_ra
+# define cpu_ldq_mmuidx_ra cpu_ldq_be_mmuidx_ra
+# define cpu_stw_data cpu_stw_be_data
+# define cpu_stl_data cpu_stl_be_data
+# define cpu_stq_data cpu_stq_be_data
+# define cpu_stw_data_ra cpu_stw_be_data_ra
+# define cpu_stl_data_ra cpu_stl_be_data_ra
+# define cpu_stq_data_ra cpu_stq_be_data_ra
+# define cpu_stw_mmuidx_ra cpu_stw_be_mmuidx_ra
+# define cpu_stl_mmuidx_ra cpu_stl_be_mmuidx_ra
+# define cpu_stq_mmuidx_ra cpu_stq_be_mmuidx_ra
+#else
+# define cpu_lduw_data cpu_lduw_le_data
+# define cpu_ldsw_data cpu_ldsw_le_data
+# define cpu_ldl_data cpu_ldl_le_data
+# define cpu_ldq_data cpu_ldq_le_data
+# define cpu_lduw_data_ra cpu_lduw_le_data_ra
+# define cpu_ldsw_data_ra cpu_ldsw_le_data_ra
+# define cpu_ldl_data_ra cpu_ldl_le_data_ra
+# define cpu_ldq_data_ra cpu_ldq_le_data_ra
+# define cpu_lduw_mmuidx_ra cpu_lduw_le_mmuidx_ra
+# define cpu_ldsw_mmuidx_ra cpu_ldsw_le_mmuidx_ra
+# define cpu_ldl_mmuidx_ra cpu_ldl_le_mmuidx_ra
+# define cpu_ldq_mmuidx_ra cpu_ldq_le_mmuidx_ra
+# define cpu_stw_data cpu_stw_le_data
+# define cpu_stl_data cpu_stl_le_data
+# define cpu_stq_data cpu_stq_le_data
+# define cpu_stw_data_ra cpu_stw_le_data_ra
+# define cpu_stl_data_ra cpu_stl_le_data_ra
+# define cpu_stq_data_ra cpu_stq_le_data_ra
+# define cpu_stw_mmuidx_ra cpu_stw_le_mmuidx_ra
+# define cpu_stl_mmuidx_ra cpu_stl_le_mmuidx_ra
+# define cpu_stq_mmuidx_ra cpu_stq_le_mmuidx_ra
+#endif
+
+static inline uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr)
+{
+ CPUState *cs = env_cpu(env);
+ MemOpIdx oi = make_memop_idx(MO_UB, cpu_mmu_index(cs, true));
+ return cpu_ldb_code_mmu(env, addr, oi, 0);
+}
+
+static inline uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr)
+{
+ CPUState *cs = env_cpu(env);
+ MemOpIdx oi = make_memop_idx(MO_TEUW, cpu_mmu_index(cs, true));
+ return cpu_ldw_code_mmu(env, addr, oi, 0);
+}
+
+static inline uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr)
+{
+ CPUState *cs = env_cpu(env);
+ MemOpIdx oi = make_memop_idx(MO_TEUL, cpu_mmu_index(cs, true));
+ return cpu_ldl_code_mmu(env, addr, oi, 0);
+}
+
+static inline uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr)
+{
+ CPUState *cs = env_cpu(env);
+ MemOpIdx oi = make_memop_idx(MO_TEUQ, cpu_mmu_index(cs, true));
+ return cpu_ldq_code_mmu(env, addr, oi, 0);
+}
+
+#endif /* ACCEL_TCG_CPU_LDST_H */
diff --git a/include/accel/tcg/cpu-mmu-index.h b/include/accel/tcg/cpu-mmu-index.h
new file mode 100644
index 0000000..e681a90
--- /dev/null
+++ b/include/accel/tcg/cpu-mmu-index.h
@@ -0,0 +1,42 @@
+/*
+ * cpu_mmu_index()
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef ACCEL_TCG_CPU_MMU_INDEX_H
+#define ACCEL_TCG_CPU_MMU_INDEX_H
+
+#include "hw/core/cpu.h"
+#include "accel/tcg/cpu-ops.h"
+#include "tcg/debug-assert.h"
+#ifdef COMPILING_PER_TARGET
+# ifdef CONFIG_USER_ONLY
+# include "cpu.h"
+# endif
+#endif
+
+/**
+ * cpu_mmu_index:
+ * @env: The cpu environment
+ * @ifetch: True for code access, false for data access.
+ *
+ * Return the core mmu index for the current translation regime.
+ * This function is used by generic TCG code paths.
+ */
+static inline int cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+#ifdef COMPILING_PER_TARGET
+# ifdef CONFIG_USER_ONLY
+ return MMU_USER_IDX;
+# endif
+#endif
+
+ int ret = cs->cc->tcg_ops->mmu_index(cs, ifetch);
+ tcg_debug_assert(ret >= 0 && ret < NB_MMU_MODES);
+ return ret;
+}
+
+#endif /* ACCEL_TCG_CPU_MMU_INDEX_H */
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/accel/tcg/cpu-ops.h
index 099de33..dd8ea30 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/accel/tcg/cpu-ops.h
@@ -13,17 +13,61 @@
#include "exec/breakpoint.h"
#include "exec/hwaddr.h"
#include "exec/memattrs.h"
+#include "exec/memop.h"
#include "exec/mmu-access-type.h"
#include "exec/vaddr.h"
+#include "accel/tcg/tb-cpu-state.h"
+#include "tcg/tcg-mo.h"
struct TCGCPUOps {
/**
+ * mttcg_supported: multi-threaded TCG is supported
+ *
+ * Target (TCG frontend) supports:
+ * - atomic instructions
+ * - memory ordering primitives (barriers)
+ */
+ bool mttcg_supported;
+
+ /**
+ * @precise_smc: Stores which modify code within the current TB force
+ * the TB to exit; the next executed instruction will see
+ * the result of the store.
+ */
+ bool precise_smc;
+
+ /**
+ * @guest_default_memory_order: default barrier that is required
+ * for the guest memory ordering.
+ */
+ TCGBar guest_default_memory_order;
+
+ /**
* @initialize: Initialize TCG state
*
* Called when the first CPU is realized.
*/
void (*initialize)(void);
/**
+ * @translate_code: Translate guest instructions to TCGOps
+ * @cpu: cpu context
+ * @tb: translation block
+ * @max_insns: max number of instructions to translate
+ * @pc: guest virtual program counter address
+ * @host_pc: host physical program counter address
+ *
+ * This function must be provided by the target, which should create
+ * the target-specific DisasContext, and then invoke translator_loop.
+ */
+ void (*translate_code)(CPUState *cpu, TranslationBlock *tb,
+ int *max_insns, vaddr pc, void *host_pc);
+ /**
+ * @get_tb_cpu_state: Extract CPU state for a TCG #TranslationBlock
+ *
+ * Fill in all data required to select or compile a TranslationBlock.
+ */
+ TCGTBCPUState (*get_tb_cpu_state)(CPUState *cs);
+ /**
* @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock
*
* This is called when we abandon execution of a TB before starting it,
@@ -53,6 +97,9 @@ struct TCGCPUOps {
/** @debug_excp_handler: Callback for handling debug exceptions */
void (*debug_excp_handler)(CPUState *cpu);
+ /** @mmu_index: Callback for choosing softmmu mmu index */
+ int (*mmu_index)(CPUState *cpu, bool ifetch);
+
#ifdef CONFIG_USER_ONLY
/**
* @fake_user_interrupt: Callback for 'fake exception' handling.
@@ -110,11 +157,20 @@ struct TCGCPUOps {
*/
void (*record_sigbus)(CPUState *cpu, vaddr addr,
MMUAccessType access_type, uintptr_t ra);
+
+ /**
+ * untagged_addr: Remove an ignored tag from an address
+ * @cpu: cpu context
+ * @addr: tagged guest address
+ */
+ vaddr (*untagged_addr)(CPUState *cs, vaddr addr);
#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_reset: Callback for reset in cpu_exec. */
+ void (*cpu_exec_reset)(CPUState *cpu);
/**
* @cpu_exec_halt: Callback for handling halt in cpu_exec.
*
@@ -122,13 +178,41 @@ struct TCGCPUOps {
* 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.
+ * if it should remain in the halted state. (This should generally
+ * be the same value that cpu_has_work() would return.)
*
- * If this method is not provided, the default is to do nothing, and
- * to leave halt if cpu_has_work() returns true.
+ * This method must be provided. If the target does not need to
+ * do anything special for halt, the same function used for its
+ * SysemuCPUOps::has_work method can be used here, as they have the
+ * same function signature.
*/
bool (*cpu_exec_halt)(CPUState *cpu);
/**
+ * @tlb_fill_align: Handle a softmmu tlb miss
+ * @cpu: cpu context
+ * @out: output page properties
+ * @addr: virtual address
+ * @access_type: read, write or execute
+ * @mmu_idx: mmu context
+ * @memop: memory operation for the access
+ * @size: memory access size, or 0 for whole page
+ * @probe: test only, no fault
+ * @ra: host return address for exception unwind
+ *
+ * If the access is valid, fill in @out and return true.
+ * Otherwise if probe is true, return false.
+ * Otherwise raise an exception and do not return.
+ *
+ * The alignment check for the access is deferred to this hook,
+ * so that the target can determine the priority of any alignment
+ * fault with respect to other potential faults from paging.
+ * Zero may be passed for @memop to skip any alignment check
+ * for non-memory-access operations such as probing.
+ */
+ bool (*tlb_fill_align)(CPUState *cpu, CPUTLBEntryFull *out, vaddr addr,
+ MMUAccessType access_type, int mmu_idx,
+ MemOp memop, int size, bool probe, uintptr_t ra);
+ /**
* @tlb_fill: Handle a softmmu tlb miss
*
* If the access is valid, call tlb_set_page and return true;
@@ -139,6 +223,13 @@ struct TCGCPUOps {
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
/**
+ * @pointer_wrap:
+ *
+ * We have incremented @base to @result, resulting in a page change.
+ * For the current cpu state, adjust @result for possible overflow.
+ */
+ vaddr (*pointer_wrap)(CPUState *cpu, int mmu_idx, vaddr result, vaddr base);
+ /**
* @do_transaction_failed: Callback for handling failed memory transactions
* (ie bus faults or external aborts; not MMU faults)
*/
@@ -231,6 +322,12 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
*/
int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len);
+/*
+ * Common pointer_wrap implementations.
+ */
+vaddr cpu_pointer_wrap_notreached(CPUState *, int, vaddr, vaddr);
+vaddr cpu_pointer_wrap_uint32(CPUState *, int, vaddr, vaddr);
+
#endif
#endif /* TCG_CPU_OPS_H */
diff --git a/include/accel/tcg/getpc.h b/include/accel/tcg/getpc.h
new file mode 100644
index 0000000..0fc08ad
--- /dev/null
+++ b/include/accel/tcg/getpc.h
@@ -0,0 +1,20 @@
+/*
+ * Get host pc for helper unwinding.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef ACCEL_TCG_GETPC_H
+#define ACCEL_TCG_GETPC_H
+
+/* GETPC is the true target of the return instruction that we'll execute. */
+#ifdef CONFIG_TCG_INTERPRETER
+extern __thread uintptr_t tci_tb_ptr;
+# define GETPC() tci_tb_ptr
+#else
+# define GETPC() \
+ ((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
+#endif
+
+#endif /* ACCEL_TCG_GETPC_H */
diff --git a/include/accel/tcg/helper-retaddr.h b/include/accel/tcg/helper-retaddr.h
new file mode 100644
index 0000000..037fda2
--- /dev/null
+++ b/include/accel/tcg/helper-retaddr.h
@@ -0,0 +1,43 @@
+/*
+ * Get user helper pc for memory unwinding.
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef ACCEL_TCG_HELPER_RETADDR_H
+#define ACCEL_TCG_HELPER_RETADDR_H
+
+/*
+ * For user-only, helpers that use guest to host address translation
+ * must protect the actual host memory access by recording 'retaddr'
+ * for the signal handler. This is required for a race condition in
+ * which another thread unmaps the page between a probe and the
+ * actual access.
+ */
+#ifdef CONFIG_USER_ONLY
+extern __thread uintptr_t helper_retaddr;
+
+static inline void set_helper_retaddr(uintptr_t ra)
+{
+ helper_retaddr = ra;
+ /*
+ * Ensure that this write is visible to the SIGSEGV handler that
+ * may be invoked due to a subsequent invalid memory operation.
+ */
+ signal_barrier();
+}
+
+static inline void clear_helper_retaddr(void)
+{
+ /*
+ * Ensure that previous memory operations have succeeded before
+ * removing the data visible to the signal handler.
+ */
+ signal_barrier();
+ helper_retaddr = 0;
+}
+#else
+#define set_helper_retaddr(ra) do { } while (0)
+#define clear_helper_retaddr() do { } while (0)
+#endif
+
+#endif /* ACCEL_TCG_HELPER_RETADDR_H */
diff --git a/include/accel/tcg/iommu.h b/include/accel/tcg/iommu.h
new file mode 100644
index 0000000..90cfd6c
--- /dev/null
+++ b/include/accel/tcg/iommu.h
@@ -0,0 +1,41 @@
+/*
+ * TCG IOMMU translations.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+#ifndef ACCEL_TCG_IOMMU_H
+#define ACCEL_TCG_IOMMU_H
+
+#ifdef CONFIG_USER_ONLY
+#error Cannot include accel/tcg/iommu.h from user emulation
+#endif
+
+#include "exec/hwaddr.h"
+#include "exec/memattrs.h"
+
+/**
+ * iotlb_to_section:
+ * @cpu: CPU performing the access
+ * @index: TCG CPU IOTLB entry
+ *
+ * Given a TCG CPU IOTLB entry, return the MemoryRegionSection that
+ * it refers to. @index will have been initially created and returned
+ * by memory_region_section_get_iotlb().
+ */
+MemoryRegionSection *iotlb_to_section(CPUState *cpu,
+ hwaddr index, MemTxAttrs attrs);
+
+MemoryRegionSection *address_space_translate_for_iotlb(CPUState *cpu,
+ int asidx,
+ hwaddr addr,
+ hwaddr *xlat,
+ hwaddr *plen,
+ MemTxAttrs attrs,
+ int *prot);
+
+hwaddr memory_region_section_get_iotlb(CPUState *cpu,
+ MemoryRegionSection *section);
+
+#endif
+
diff --git a/include/accel/tcg/probe.h b/include/accel/tcg/probe.h
new file mode 100644
index 0000000..dd9ecbb
--- /dev/null
+++ b/include/accel/tcg/probe.h
@@ -0,0 +1,122 @@
+/*
+ * Probe guest virtual addresses for access permissions.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+#ifndef ACCEL_TCG_PROBE_H
+#define ACCEL_TCG_PROBE_H
+
+#include "exec/mmu-access-type.h"
+#include "exec/vaddr.h"
+
+/**
+ * probe_access:
+ * @env: CPUArchState
+ * @addr: guest virtual address to look up
+ * @size: size of the access
+ * @access_type: read, write or execute permission
+ * @mmu_idx: MMU index to use for lookup
+ * @retaddr: return address for unwinding
+ *
+ * Look up the guest virtual address @addr. Raise an exception if the
+ * page does not satisfy @access_type. Raise an exception if the
+ * access (@addr, @size) hits a watchpoint. For writes, mark a clean
+ * page as dirty.
+ *
+ * Finally, return the host address for a page that is backed by RAM,
+ * or NULL if the page requires I/O.
+ */
+void *probe_access(CPUArchState *env, vaddr addr, int size,
+ MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);
+
+static inline void *probe_write(CPUArchState *env, vaddr addr, int size,
+ int mmu_idx, uintptr_t retaddr)
+{
+ return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
+}
+
+static inline void *probe_read(CPUArchState *env, vaddr addr, int size,
+ int mmu_idx, uintptr_t retaddr)
+{
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
+}
+
+/**
+ * probe_access_flags:
+ * @env: CPUArchState
+ * @addr: guest virtual address to look up
+ * @size: size of the access
+ * @access_type: read, write or execute permission
+ * @mmu_idx: MMU index to use for lookup
+ * @nonfault: suppress the fault
+ * @phost: return value for host address
+ * @retaddr: return address for unwinding
+ *
+ * Similar to probe_access, loosely returning the TLB_FLAGS_MASK for
+ * the page, and storing the host address for RAM in @phost.
+ *
+ * If @nonfault is set, do not raise an exception but return TLB_INVALID_MASK.
+ * Do not handle watchpoints, but include TLB_WATCHPOINT in the returned flags.
+ * Do handle clean pages, so exclude TLB_NOTDIRY from the returned flags.
+ * For simplicity, all "mmio-like" flags are folded to TLB_MMIO.
+ */
+int probe_access_flags(CPUArchState *env, vaddr addr, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool nonfault, void **phost, uintptr_t retaddr);
+
+#ifndef CONFIG_USER_ONLY
+
+/**
+ * probe_access_full:
+ * Like probe_access_flags, except also return into @pfull.
+ *
+ * The CPUTLBEntryFull structure returned via @pfull is transient
+ * and must be consumed or copied immediately, before any further
+ * access or changes to TLB @mmu_idx.
+ *
+ * This function will not fault if @nonfault is set, but will
+ * return TLB_INVALID_MASK if the page is not mapped, or is not
+ * accessible with @access_type.
+ *
+ * This function will return TLB_MMIO in order to force the access
+ * to be handled out-of-line if plugins wish to instrument the access.
+ */
+int probe_access_full(CPUArchState *env, vaddr addr, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool nonfault, void **phost,
+ CPUTLBEntryFull **pfull, uintptr_t retaddr);
+
+/**
+ * probe_access_full_mmu:
+ * Like probe_access_full, except:
+ *
+ * This function is intended to be used for page table accesses by
+ * the target mmu itself. Since such page walking happens while
+ * handling another potential mmu fault, this function never raises
+ * exceptions (akin to @nonfault true for probe_access_full).
+ * Likewise this function does not trigger plugin instrumentation.
+ */
+int probe_access_full_mmu(CPUArchState *env, vaddr addr, int size,
+ MMUAccessType access_type, int mmu_idx,
+ void **phost, CPUTLBEntryFull **pfull);
+
+#endif /* !CONFIG_USER_ONLY */
+
+/**
+ * tlb_vaddr_to_host:
+ * @env: CPUArchState
+ * @addr: guest virtual address to look up
+ * @access_type: 0 for read, 1 for write, 2 for execute
+ * @mmu_idx: MMU index to use for lookup
+ *
+ * Look up the specified guest virtual index in the TCG softmmu TLB.
+ * If we can translate a host virtual address suitable for direct RAM
+ * access, without causing a guest exception, then return it.
+ * Otherwise (TLB entry is for an I/O access, guest software
+ * TLB fill required, etc) return NULL.
+ */
+void *tlb_vaddr_to_host(CPUArchState *env, vaddr addr,
+ MMUAccessType access_type, int mmu_idx);
+
+#endif
diff --git a/include/accel/tcg/tb-cpu-state.h b/include/accel/tcg/tb-cpu-state.h
new file mode 100644
index 0000000..8f91290
--- /dev/null
+++ b/include/accel/tcg/tb-cpu-state.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Definition of TCGTBCPUState.
+ */
+
+#ifndef EXEC_TB_CPU_STATE_H
+#define EXEC_TB_CPU_STATE_H
+
+#include "exec/vaddr.h"
+
+typedef struct TCGTBCPUState {
+ vaddr pc;
+ uint32_t flags;
+ uint32_t cflags;
+ uint64_t cs_base;
+} TCGTBCPUState;
+
+#endif
diff --git a/include/block/aio.h b/include/block/aio.h
index 4ee8193..99ff484 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -20,6 +20,7 @@
#include "qemu/coroutine-core.h"
#include "qemu/queue.h"
#include "qemu/event_notifier.h"
+#include "qemu/lockcnt.h"
#include "qemu/thread.h"
#include "qemu/timer.h"
#include "block/graph-lock.h"
@@ -53,7 +54,7 @@ typedef void QEMUBHFunc(void *opaque);
typedef bool AioPollFn(void *opaque);
typedef void IOHandler(void *opaque);
-struct ThreadPool;
+struct ThreadPoolAio;
struct LinuxAioState;
typedef struct LuringState LuringState;
@@ -122,6 +123,10 @@ struct BHListSlice {
typedef QSLIST_HEAD(, AioHandler) AioHandlerSList;
+typedef struct AioPolledEvent {
+ int64_t ns; /* current polling time in nanoseconds */
+} AioPolledEvent;
+
struct AioContext {
GSource source;
@@ -206,7 +211,7 @@ struct AioContext {
/* Thread pool for performing work and receiving completion callbacks.
* Has its own locking.
*/
- struct ThreadPool *thread_pool;
+ struct ThreadPoolAio *thread_pool;
#ifdef CONFIG_LINUX_AIO
struct LinuxAioState *linux_aio;
@@ -228,7 +233,6 @@ struct AioContext {
int poll_disable_cnt;
/* Polling mode parameters */
- int64_t poll_ns; /* current polling time in nanoseconds */
int64_t poll_max_ns; /* maximum polling time in nanoseconds */
int64_t poll_grow; /* polling time growth factor */
int64_t poll_shrink; /* polling time shrink factor */
@@ -499,8 +503,8 @@ void aio_set_event_notifier_poll(AioContext *ctx,
*/
GSource *aio_get_g_source(AioContext *ctx);
-/* Return the ThreadPool bound to this AioContext */
-struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
+/* Return the ThreadPoolAio bound to this AioContext */
+struct ThreadPoolAio *aio_get_thread_pool(AioContext *ctx);
/* Setup the LinuxAioState bound to this AioContext */
struct LinuxAioState *aio_setup_linux_aio(AioContext *ctx, Error **errp);
diff --git a/include/block/aio_task.h b/include/block/aio_task.h
index 18a9c41..c81d637 100644
--- a/include/block/aio_task.h
+++ b/include/block/aio_task.h
@@ -40,8 +40,6 @@ void aio_task_pool_free(AioTaskPool *);
/* error code of failed task or 0 if all is OK */
int aio_task_pool_status(AioTaskPool *pool);
-bool aio_task_pool_empty(AioTaskPool *pool);
-
/* User provides filled @task, however task->pool will be set automatically */
void coroutine_fn aio_task_pool_start_task(AioTaskPool *pool, AioTask *task);
diff --git a/include/block/block-common.h b/include/block/block-common.h
index 338fe5f..c8c626d 100644
--- a/include/block/block-common.h
+++ b/include/block/block-common.h
@@ -257,6 +257,7 @@ typedef enum {
#define BDRV_OPT_AUTO_READ_ONLY "auto-read-only"
#define BDRV_OPT_DISCARD "discard"
#define BDRV_OPT_FORCE_SHARE "force-share"
+#define BDRV_OPT_ACTIVE "active"
#define BDRV_SECTOR_BITS 9
@@ -332,6 +333,17 @@ typedef enum {
#define BDRV_BLOCK_RECURSE 0x40
#define BDRV_BLOCK_COMPRESSED 0x80
+/*
+ * Block status hints: the bitwise-or of these flags emphasize what
+ * the caller hopes to learn, and some drivers may be able to give
+ * faster answers by doing less work when the hint permits.
+ */
+#define BDRV_WANT_ZERO BDRV_BLOCK_ZERO
+#define BDRV_WANT_OFFSET_VALID BDRV_BLOCK_OFFSET_VALID
+#define BDRV_WANT_ALLOCATED BDRV_BLOCK_ALLOCATED
+#define BDRV_WANT_PRECISE (BDRV_WANT_ZERO | BDRV_WANT_OFFSET_VALID | \
+ BDRV_WANT_OFFSET_VALID)
+
typedef QTAILQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
typedef struct BDRVReopenState {
@@ -355,7 +367,6 @@ typedef enum BlockOpType {
BLOCK_OP_TYPE_CHANGE,
BLOCK_OP_TYPE_COMMIT_SOURCE,
BLOCK_OP_TYPE_COMMIT_TARGET,
- BLOCK_OP_TYPE_DATAPLANE,
BLOCK_OP_TYPE_DRIVE_DEL,
BLOCK_OP_TYPE_EJECT,
BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT,
diff --git a/include/block/block-copy.h b/include/block/block-copy.h
index bdc703b..dd5cc82 100644
--- a/include/block/block-copy.h
+++ b/include/block/block-copy.h
@@ -28,6 +28,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
BlockDriverState *copy_bitmap_bs,
const BdrvDirtyBitmap *bitmap,
bool discard_source,
+ uint64_t min_cluster_size,
Error **errp);
/* Function should be called prior any actual copy request */
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
index bd7cecd..84a2a4e 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -175,21 +175,27 @@ BlockDriverState * GRAPH_RDLOCK
check_to_replace_node(BlockDriverState *parent_bs, const char *node_name,
Error **errp);
+
+bool GRAPH_RDLOCK bdrv_is_inactive(BlockDriverState *bs);
+
int no_coroutine_fn GRAPH_RDLOCK
bdrv_activate(BlockDriverState *bs, Error **errp);
int coroutine_fn no_co_wrapper_bdrv_rdlock
bdrv_co_activate(BlockDriverState *bs, Error **errp);
+int no_coroutine_fn
+bdrv_inactivate(BlockDriverState *bs, Error **errp);
+
void bdrv_activate_all(Error **errp);
int bdrv_inactivate_all(void);
int bdrv_flush_all(void);
void bdrv_close_all(void);
-void bdrv_drain_all_begin(void);
+void GRAPH_UNLOCKED bdrv_drain_all_begin(void);
void bdrv_drain_all_begin_nopoll(void);
void bdrv_drain_all_end(void);
-void bdrv_drain_all(void);
+void GRAPH_UNLOCKED bdrv_drain_all(void);
void bdrv_aio_cancel(BlockAIOCB *acb);
@@ -268,11 +274,16 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag);
int bdrv_debug_resume(BlockDriverState *bs, const char *tag);
bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag);
-bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp);
-int bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
- BdrvChild *ignore_child, Error **errp);
+bool GRAPH_RDLOCK
+bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
+ GHashTable *visited, Transaction *tran,
+ Error **errp);
+int GRAPH_UNLOCKED
+bdrv_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
+ BdrvChild *ignore_child, Error **errp);
+int GRAPH_RDLOCK
+bdrv_try_change_aio_context_locked(BlockDriverState *bs, AioContext *ctx,
+ BdrvChild *ignore_child, Error **errp);
int GRAPH_RDLOCK bdrv_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz);
int bdrv_probe_geometry(BlockDriverState *bs, HDGeometry *geo);
diff --git a/include/block/block-io.h b/include/block/block-io.h
index b49e053..4cf83fb 100644
--- a/include/block/block-io.h
+++ b/include/block/block-io.h
@@ -161,6 +161,8 @@ bdrv_is_allocated_above(BlockDriverState *bs, BlockDriverState *base,
int coroutine_fn GRAPH_RDLOCK
bdrv_co_is_zero_fast(BlockDriverState *bs, int64_t offset, int64_t bytes);
+int coroutine_fn GRAPH_RDLOCK
+bdrv_co_is_all_zeroes(BlockDriverState *bs);
int GRAPH_RDLOCK
bdrv_apply_auto_read_only(BlockDriverState *bs, const char *errmsg,
@@ -429,7 +431,7 @@ bdrv_drain_poll(BlockDriverState *bs, BdrvChild *ignore_parent,
*
* This function can be recursive.
*/
-void bdrv_drained_begin(BlockDriverState *bs);
+void GRAPH_UNLOCKED bdrv_drained_begin(BlockDriverState *bs);
/**
* bdrv_do_drained_begin_quiesce:
diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h
index 7612761..925a3e7 100644
--- a/include/block/block_int-common.h
+++ b/include/block/block_int-common.h
@@ -248,9 +248,6 @@ struct BlockDriver {
int GRAPH_UNLOCKED_PTR (*bdrv_open)(
BlockDriverState *bs, QDict *options, int flags, Error **errp);
- /* Protocol drivers should implement this instead of bdrv_open */
- int GRAPH_UNLOCKED_PTR (*bdrv_file_open)(
- BlockDriverState *bs, QDict *options, int flags, Error **errp);
void (*bdrv_close)(BlockDriverState *bs);
int coroutine_fn GRAPH_UNLOCKED_PTR (*bdrv_co_create)(
@@ -399,9 +396,23 @@ struct BlockDriver {
int GRAPH_RDLOCK_PTR (*bdrv_probe_geometry)(
BlockDriverState *bs, HDGeometry *geo);
+ /**
+ * Hot add a BDS's child. Used in combination with bdrv_del_child, so the
+ * user can take a child offline when it is broken and take a new child
+ * online.
+ *
+ * All block nodes must be drained.
+ */
void GRAPH_WRLOCK_PTR (*bdrv_add_child)(
BlockDriverState *parent, BlockDriverState *child, Error **errp);
+ /**
+ * Hot remove a BDS's child. Used in combination with bdrv_add_child, so the
+ * user can take a child offline when it is broken and take a new child
+ * online.
+ *
+ * All block nodes must be drained.
+ */
void GRAPH_WRLOCK_PTR (*bdrv_del_child)(
BlockDriverState *parent, BdrvChild *child, Error **errp);
@@ -509,10 +520,6 @@ struct BlockDriver {
BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_flush)(
BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque);
- BlockAIOCB * GRAPH_RDLOCK_PTR (*bdrv_aio_pdiscard)(
- BlockDriverState *bs, int64_t offset, int bytes,
- BlockCompletionFunc *cb, void *opaque);
-
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_readv)(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
@@ -611,15 +618,16 @@ struct BlockDriver {
* according to the current layer, and should only need to set
* BDRV_BLOCK_DATA, BDRV_BLOCK_ZERO, BDRV_BLOCK_OFFSET_VALID,
* and/or BDRV_BLOCK_RAW; if the current layer defers to a backing
- * layer, the result should be 0 (and not BDRV_BLOCK_ZERO). See
- * block.h for the overall meaning of the bits. As a hint, the
- * flag want_zero is true if the caller cares more about precise
- * mappings (favor accurate _OFFSET_VALID/_ZERO) or false for
- * overall allocation (favor larger *pnum, perhaps by reporting
- * _DATA instead of _ZERO). The block layer guarantees input
- * clamped to bdrv_getlength() and aligned to request_alignment,
- * as well as non-NULL pnum, map, and file; in turn, the driver
- * must return an error or set pnum to an aligned non-zero value.
+ * layer, the result should be 0 (and not BDRV_BLOCK_ZERO). The
+ * caller will synthesize BDRV_BLOCK_ALLOCATED based on the
+ * non-zero results. See block.h for the overall meaning of the
+ * bits. As a hint, the flags in @mode may include a bitwise-or
+ * of BDRV_WANT_ALLOCATED, BDRV_WANT_OFFSET_VALID, or
+ * BDRV_WANT_ZERO based on what the caller is looking for in the
+ * results. The block layer guarantees input clamped to
+ * bdrv_getlength() and aligned to request_alignment, as well as
+ * non-NULL pnum, map, and file; in turn, the driver must return
+ * an error or set pnum to an aligned non-zero value.
*
* Note that @bytes is just a hint on how big of a region the
* caller wants to inspect. It is not a limit on *pnum.
@@ -631,8 +639,8 @@ struct BlockDriver {
* to clamping *pnum for return to its caller.
*/
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_block_status)(
- BlockDriverState *bs,
- bool want_zero, int64_t offset, int64_t bytes, int64_t *pnum,
+ BlockDriverState *bs, unsigned int mode,
+ int64_t offset, int64_t bytes, int64_t *pnum,
int64_t *map, BlockDriverState **file);
/*
@@ -656,8 +664,8 @@ struct BlockDriver {
QEMUIOVector *qiov, size_t qiov_offset);
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_snapshot_block_status)(
- BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
- int64_t *pnum, int64_t *map, BlockDriverState **file);
+ BlockDriverState *bs, unsigned int mode, int64_t offset,
+ int64_t bytes, int64_t *pnum, int64_t *map, BlockDriverState **file);
int coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_pdiscard_snapshot)(
BlockDriverState *bs, int64_t offset, int64_t bytes);
@@ -989,9 +997,21 @@ struct BdrvChildClass {
bool backing_mask_protocol,
Error **errp);
- bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
- GHashTable *visited, Transaction *tran,
- Error **errp);
+ /*
+ * Notifies the parent that the child is trying to change its AioContext.
+ * The parent may in turn change the AioContext of other nodes in the same
+ * transaction. Returns true if the change is possible and the transaction
+ * can be continued. Returns false and sets @errp if not and the transaction
+ * must be aborted.
+ *
+ * @visited will accumulate all visited BdrvChild objects. The caller is
+ * responsible for freeing the list afterwards.
+ *
+ * Must be called with the affected block nodes drained.
+ */
+ bool GRAPH_RDLOCK_PTR (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
+ GHashTable *visited,
+ Transaction *tran, Error **errp);
/*
* I/O API functions. These functions are thread-safe.
diff --git a/include/block/block_int-global-state.h b/include/block/block_int-global-state.h
index eb2d92a..e7c8f1a 100644
--- a/include/block/block_int-global-state.h
+++ b/include/block/block_int-global-state.h
@@ -139,7 +139,7 @@ BlockJob *commit_active_start(const char *job_id, BlockDriverState *bs,
* @buf_size: The amount of data that can be in flight at one time.
* @mode: Whether to collapse all images in the chain to the target.
* @backing_mode: How to establish the target's backing chain after completion.
- * @zero_target: Whether the target should be explicitly zero-initialized
+ * @target_is_zero: Whether the target already is zero-initialized.
* @on_source_error: The action to take upon error reading from the source.
* @on_target_error: The action to take upon error writing to the target.
* @unmap: Whether to unmap target where source sectors only contain zeroes.
@@ -159,7 +159,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
int creation_flags, int64_t speed,
uint32_t granularity, int64_t buf_size,
MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
- bool zero_target,
+ bool target_is_zero,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
bool unmap, const char *filter_node_name,
@@ -179,6 +179,7 @@ void mirror_start(const char *job_id, BlockDriverState *bs,
* all ".has_*" fields are ignored.
* @on_source_error: The action to take upon error reading from the source.
* @on_target_error: The action to take upon error writing to the target.
+ * @on_cbw_error: The action to take upon error in copy-before-write operations.
* @creation_flags: Flags that control the behavior of the Job lifetime.
* See @BlockJobCreateFlags
* @cb: Completion function for the job.
@@ -198,6 +199,7 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BackupPerf *perf,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
+ OnCbwError on_cbw_error,
int creation_flags,
BlockCompletionFunc *cb, void *opaque,
JobTxn *txn, Error **errp);
diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h
index 4a7cf2b..4f94eb3 100644
--- a/include/block/block_int-io.h
+++ b/include/block/block_int-io.h
@@ -38,8 +38,8 @@
int coroutine_fn GRAPH_RDLOCK bdrv_co_preadv_snapshot(BdrvChild *child,
int64_t offset, int64_t bytes, QEMUIOVector *qiov, size_t qiov_offset);
int coroutine_fn GRAPH_RDLOCK bdrv_co_snapshot_block_status(
- BlockDriverState *bs, bool want_zero, int64_t offset, int64_t bytes,
- int64_t *pnum, int64_t *map, BlockDriverState **file);
+ BlockDriverState *bs, unsigned int mode, int64_t offset,
+ int64_t bytes, int64_t *pnum, int64_t *map, BlockDriverState **file);
int coroutine_fn GRAPH_RDLOCK bdrv_co_pdiscard_snapshot(BlockDriverState *bs,
int64_t offset, int64_t bytes);
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 7061ab7..990f3e1 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -137,6 +137,8 @@ BlockJob *block_job_get_locked(const char *id);
* Add @bs to the list of BlockDriverState that are involved in
* @job. This means that all operations will be blocked on @bs while
* @job exists.
+ *
+ * All block nodes must be drained.
*/
int GRAPH_WRLOCK
block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
diff --git a/include/block/export.h b/include/block/export.h
index f2fe0f8..4bd9531 100644
--- a/include/block/export.h
+++ b/include/block/export.h
@@ -29,6 +29,9 @@ typedef struct BlockExportDriver {
*/
size_t instance_size;
+ /* True if the export type supports running on an inactive node */
+ bool supports_inactive;
+
/* Creates and starts a new block export */
int (*create)(BlockExport *, BlockExportOptions *, Error **);
diff --git a/include/block/graph-lock.h b/include/block/graph-lock.h
index d7545e8..2c26c72 100644
--- a/include/block/graph-lock.h
+++ b/include/block/graph-lock.h
@@ -20,8 +20,6 @@
#ifndef GRAPH_LOCK_H
#define GRAPH_LOCK_H
-#include "qemu/clang-tsa.h"
-
/**
* Graph Lock API
* This API provides a rwlock used to protect block layer
@@ -209,31 +207,38 @@ typedef struct GraphLockable { } GraphLockable;
* unlocked. TSA_ASSERT_SHARED() makes sure that the following calls know that
* we hold the lock while unlocking is left unchecked.
*/
-static inline GraphLockable * TSA_ASSERT_SHARED(graph_lock) TSA_NO_TSA coroutine_fn
+static inline GraphLockable * TSA_ACQUIRE_SHARED(graph_lock) coroutine_fn
graph_lockable_auto_lock(GraphLockable *x)
{
bdrv_graph_co_rdlock();
return x;
}
-static inline void TSA_NO_TSA coroutine_fn
-graph_lockable_auto_unlock(GraphLockable *x)
+static inline void TSA_RELEASE_SHARED(graph_lock) coroutine_fn
+graph_lockable_auto_unlock(GraphLockable **x)
{
bdrv_graph_co_rdunlock();
}
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(GraphLockable, graph_lockable_auto_unlock)
+#define GRAPH_AUTO_UNLOCK __attribute__((cleanup(graph_lockable_auto_unlock)))
+/*
+ * @var is only used to break the loop after the first iteration.
+ * @unlock_var can't be unlocked and then set to NULL because TSA wants the lock
+ * to be held at the start of every iteration of the loop.
+ */
#define WITH_GRAPH_RDLOCK_GUARD_(var) \
- for (g_autoptr(GraphLockable) var = graph_lockable_auto_lock(GML_OBJ_()); \
+ for (GraphLockable *unlock_var GRAPH_AUTO_UNLOCK = \
+ graph_lockable_auto_lock(GML_OBJ_()), \
+ *var = unlock_var; \
var; \
- graph_lockable_auto_unlock(var), var = NULL)
+ var = NULL)
#define WITH_GRAPH_RDLOCK_GUARD() \
WITH_GRAPH_RDLOCK_GUARD_(glue(graph_lockable_auto, __COUNTER__))
#define GRAPH_RDLOCK_GUARD(x) \
- g_autoptr(GraphLockable) \
+ GraphLockable * GRAPH_AUTO_UNLOCK \
glue(graph_lockable_auto, __COUNTER__) G_GNUC_UNUSED = \
graph_lockable_auto_lock(GML_OBJ_())
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4e7bd63..92987c7 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -33,6 +33,19 @@ typedef struct NBDMetaContexts NBDMetaContexts;
extern const BlockExportDriver blk_exp_nbd;
+/*
+ * NBD_DEFAULT_HANDSHAKE_MAX_SECS: Number of seconds in which client must
+ * succeed at NBD_OPT_GO before being forcefully dropped as too slow.
+ */
+#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10
+
+/*
+ * NBD_DEFAULT_MAX_CONNECTIONS: Number of client sockets to allow at
+ * once; must be large enough to allow a MULTI_CONN-aware client like
+ * nbdcopy to create its typical number of 8-16 sockets.
+ */
+#define NBD_DEFAULT_MAX_CONNECTIONS 100
+
/* Handshake phase structs - this struct is passed on the wire */
typedef struct NBDOption {
@@ -403,18 +416,21 @@ AioContext *nbd_export_aio_context(NBDExport *exp);
NBDExport *nbd_export_find(const char *name);
void nbd_client_new(QIOChannelSocket *sioc,
+ uint32_t handshake_max_secs,
QCryptoTLSCreds *tlscreds,
const char *tlsauthz,
- void (*close_fn)(NBDClient *, bool));
+ void (*close_fn)(NBDClient *, bool),
+ void *owner);
+void *nbd_client_owner(NBDClient *client);
void nbd_client_get(NBDClient *client);
void nbd_client_put(NBDClient *client);
void nbd_server_is_qemu_nbd(int max_connections);
bool nbd_server_is_running(void);
int nbd_server_max_connections(void);
-void nbd_server_start(SocketAddress *addr, const char *tls_creds,
- const char *tls_authz, uint32_t max_connections,
- Error **errp);
+void nbd_server_start(SocketAddress *addr, uint32_t handshake_max_secs,
+ const char *tls_creds, const char *tls_authz,
+ uint32_t max_connections, Error **errp);
void nbd_server_start_options(NbdServerOptions *arg, Error **errp);
/* nbd_read
diff --git a/include/block/nvme.h b/include/block/nvme.h
index bb231d0..358e516 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -142,9 +142,9 @@ enum NvmeCapMask {
((cap) |= (uint64_t)((val) & CAP_CMBS_MASK) << CAP_CMBS_SHIFT)
enum NvmeCapCss {
- NVME_CAP_CSS_NVM = 1 << 0,
- NVME_CAP_CSS_CSI_SUPP = 1 << 6,
- NVME_CAP_CSS_ADMIN_ONLY = 1 << 7,
+ NVME_CAP_CSS_NCSS = 1 << 0,
+ NVME_CAP_CSS_IOCSS = 1 << 6,
+ NVME_CAP_CSS_NOIOCSS = 1 << 7,
};
enum NvmeCcShift {
@@ -177,7 +177,7 @@ enum NvmeCcMask {
enum NvmeCcCss {
NVME_CC_CSS_NVM = 0x0,
- NVME_CC_CSS_CSI = 0x6,
+ NVME_CC_CSS_ALL = 0x6,
NVME_CC_CSS_ADMIN_ONLY = 0x7,
};
@@ -799,6 +799,8 @@ typedef struct QEMU_PACKED NvmeDsmRange {
enum {
NVME_COPY_FORMAT_0 = 0x0,
NVME_COPY_FORMAT_1 = 0x1,
+ NVME_COPY_FORMAT_2 = 0x2,
+ NVME_COPY_FORMAT_3 = 0x3,
};
typedef struct QEMU_PACKED NvmeCopyCmd {
@@ -820,25 +822,30 @@ typedef struct QEMU_PACKED NvmeCopyCmd {
uint16_t appmask;
} NvmeCopyCmd;
-typedef struct QEMU_PACKED NvmeCopySourceRangeFormat0 {
- uint8_t rsvd0[8];
+typedef struct QEMU_PACKED NvmeCopySourceRangeFormat0_2 {
+ uint32_t sparams;
+ uint8_t rsvd4[4];
uint64_t slba;
uint16_t nlb;
- uint8_t rsvd18[6];
+ uint8_t rsvd18[4];
+ uint16_t sopt;
uint32_t reftag;
uint16_t apptag;
uint16_t appmask;
-} NvmeCopySourceRangeFormat0;
+} NvmeCopySourceRangeFormat0_2;
-typedef struct QEMU_PACKED NvmeCopySourceRangeFormat1 {
- uint8_t rsvd0[8];
+typedef struct QEMU_PACKED NvmeCopySourceRangeFormat1_3 {
+ uint32_t sparams;
+ uint8_t rsvd4[4];
uint64_t slba;
uint16_t nlb;
- uint8_t rsvd18[8];
+ uint8_t rsvd18[4];
+ uint16_t sopt;
+ uint8_t rsvd24[2];
uint8_t sr[10];
uint16_t apptag;
uint16_t appmask;
-} NvmeCopySourceRangeFormat1;
+} NvmeCopySourceRangeFormat1_3;
enum NvmeAsyncEventRequest {
NVME_AER_TYPE_ERROR = 0,
@@ -899,8 +906,7 @@ enum NvmeStatusCodes {
NVME_SGL_DESCR_TYPE_INVALID = 0x0011,
NVME_INVALID_USE_OF_CMB = 0x0012,
NVME_INVALID_PRP_OFFSET = 0x0013,
- NVME_CMD_SET_CMB_REJECTED = 0x002b,
- NVME_INVALID_CMD_SET = 0x002c,
+ NVME_COMMAND_INTERRUPTED = 0x0021,
NVME_FDP_DISABLED = 0x0029,
NVME_INVALID_PHID_LIST = 0x002a,
NVME_LBA_RANGE = 0x0080,
@@ -933,10 +939,16 @@ enum NvmeStatusCodes {
NVME_INVALID_SEC_CTRL_STATE = 0x0120,
NVME_INVALID_NUM_RESOURCES = 0x0121,
NVME_INVALID_RESOURCE_ID = 0x0122,
+ NVME_IOCS_NOT_SUPPORTED = 0x0129,
+ NVME_IOCS_NOT_ENABLED = 0x012a,
+ NVME_IOCS_COMBINATION_REJECTED = 0x012b,
+ NVME_INVALID_IOCS = 0x012c,
NVME_CONFLICTING_ATTRS = 0x0180,
NVME_INVALID_PROT_INFO = 0x0181,
NVME_WRITE_TO_RO = 0x0182,
NVME_CMD_SIZE_LIMIT = 0x0183,
+ NVME_CMD_INCOMP_NS_OR_FMT = 0x0185,
+ NVME_CMD_OVERLAP_IO_RANGE = 0x0187,
NVME_INVALID_ZONE_OP = 0x01b6,
NVME_NOZRWA = 0x01b7,
NVME_ZONE_BOUNDARY_ERROR = 0x01b8,
@@ -1006,6 +1018,40 @@ typedef struct QEMU_PACKED NvmeSmartLog {
uint8_t reserved2[320];
} NvmeSmartLog;
+typedef struct QEMU_PACKED NvmeSmartLogExtended {
+ uint64_t physical_media_units_written[2];
+ uint64_t physical_media_units_read[2];
+ uint64_t bad_user_blocks;
+ uint64_t bad_system_nand_blocks;
+ uint64_t xor_recovery_count;
+ uint64_t uncorrectable_read_error_count;
+ uint64_t soft_ecc_error_count;
+ uint64_t end2end_correction_counts;
+ uint8_t system_data_percent_used;
+ uint8_t refresh_counts[7];
+ uint64_t user_data_erase_counts;
+ uint16_t thermal_throttling_stat_and_count;
+ uint16_t dssd_spec_version[3];
+ uint64_t pcie_correctable_error_count;
+ uint32_t incomplete_shutdowns;
+ uint32_t rsvd116;
+ uint8_t percent_free_blocks;
+ uint8_t rsvd121[7];
+ uint16_t capacity_health;
+ uint8_t nvme_errata_ver;
+ uint8_t rsvd131[5];
+ uint64_t unaligned_io;
+ uint64_t security_ver_num;
+ uint64_t total_nuse;
+ uint64_t plp_start_count[2];
+ uint64_t endurance_estimate[2];
+ uint64_t pcie_retraining_count;
+ uint64_t power_state_change_count;
+ uint8_t rsvd208[286];
+ uint16_t log_page_version;
+ uint64_t log_page_guid[2];
+} NvmeSmartLogExtended;
+
#define NVME_SMART_WARN_MAX 6
enum NvmeSmartWarn {
NVME_SMART_SPARE = 1 << 0,
@@ -1043,6 +1089,12 @@ enum NvmeLogIdentifier {
NVME_LOG_FDP_RUH_USAGE = 0x21,
NVME_LOG_FDP_STATS = 0x22,
NVME_LOG_FDP_EVENTS = 0x23,
+ NVME_LOG_VENDOR_START = 0xc0,
+ NVME_LOG_VENDOR_END = 0xff,
+};
+
+enum NvmeOcpLogIdentifier {
+ NVME_OCP_EXTENDED_SMART_INFO = 0xc0,
};
typedef struct QEMU_PACKED NvmePSD {
@@ -1068,15 +1120,18 @@ enum NvmeIdCns {
NVME_ID_CNS_CS_NS = 0x05,
NVME_ID_CNS_CS_CTRL = 0x06,
NVME_ID_CNS_CS_NS_ACTIVE_LIST = 0x07,
+ NVME_ID_CNS_CS_IND_NS = 0x08,
NVME_ID_CNS_NS_PRESENT_LIST = 0x10,
NVME_ID_CNS_NS_PRESENT = 0x11,
NVME_ID_CNS_NS_ATTACHED_CTRL_LIST = 0x12,
NVME_ID_CNS_CTRL_LIST = 0x13,
NVME_ID_CNS_PRIMARY_CTRL_CAP = 0x14,
NVME_ID_CNS_SECONDARY_CTRL_LIST = 0x15,
+ NVME_ID_CNS_ENDURANCE_GROUP_LIST = 0x19,
NVME_ID_CNS_CS_NS_PRESENT_LIST = 0x1a,
NVME_ID_CNS_CS_NS_PRESENT = 0x1b,
NVME_ID_CNS_IO_COMMAND_SET = 0x1c,
+ NVME_ID_CNS_CS_IND_NS_ALLOCATED = 0x1f,
};
typedef struct QEMU_PACKED NvmeIdCtrl {
@@ -1155,6 +1210,8 @@ typedef struct NvmeIdCtrlZoned {
uint8_t rsvd1[4095];
} NvmeIdCtrlZoned;
+#define NVME_ID_CTRL_NVM_DMRL_MAX 255
+
typedef struct NvmeIdCtrlNvm {
uint8_t vsl;
uint8_t wzsl;
@@ -1172,6 +1229,7 @@ enum NvmeIdCtrlOaes {
enum NvmeIdCtrlCtratt {
NVME_CTRATT_ENDGRPS = 1 << 4,
NVME_CTRATT_ELBAS = 1 << 15,
+ NVME_CTRATT_MEM = 1 << 16,
NVME_CTRATT_FDPS = 1 << 19,
};
@@ -1179,9 +1237,10 @@ enum NvmeIdCtrlOacs {
NVME_OACS_SECURITY = 1 << 0,
NVME_OACS_FORMAT = 1 << 1,
NVME_OACS_FW = 1 << 2,
- NVME_OACS_NS_MGMT = 1 << 3,
+ NVME_OACS_NMS = 1 << 3,
NVME_OACS_DIRECTIVES = 1 << 5,
- NVME_OACS_DBBUF = 1 << 8,
+ NVME_OACS_VMS = 1 << 7,
+ NVME_OACS_DBCS = 1 << 8,
};
enum NvmeIdCtrlOncs {
@@ -1194,11 +1253,15 @@ enum NvmeIdCtrlOncs {
NVME_ONCS_TIMESTAMP = 1 << 6,
NVME_ONCS_VERIFY = 1 << 7,
NVME_ONCS_COPY = 1 << 8,
+ NVME_ONCS_NVMCSA = 1 << 9,
+ NVME_ONCS_NVMAFC = 1 << 10,
};
enum NvmeIdCtrlOcfs {
NVME_OCFS_COPY_FORMAT_0 = 1 << NVME_COPY_FORMAT_0,
NVME_OCFS_COPY_FORMAT_1 = 1 << NVME_COPY_FORMAT_1,
+ NVME_OCFS_COPY_FORMAT_2 = 1 << NVME_COPY_FORMAT_2,
+ NVME_OCFS_COPY_FORMAT_3 = 1 << NVME_COPY_FORMAT_3,
};
enum NvmeIdctrlVwc {
@@ -1271,6 +1334,8 @@ enum NvmeNsAttachmentOperation {
#define NVME_ERR_REC_TLER(err_rec) (err_rec & 0xffff)
#define NVME_ERR_REC_DULBE(err_rec) (err_rec & 0x10000)
+#define NVME_ID_CTRL_CTRATT_MEM(ctratt) (ctratt & NVME_CTRATT_MEM)
+
enum NvmeFeatureIds {
NVME_ARBITRATION = 0x1,
NVME_POWER_MANAGEMENT = 0x2,
@@ -1332,7 +1397,9 @@ typedef struct NvmeHostBehaviorSupport {
uint8_t acre;
uint8_t etdas;
uint8_t lbafee;
- uint8_t rsvd3[509];
+ uint8_t rsvd3;
+ uint16_t cdfe;
+ uint8_t rsvd6[506];
} NvmeHostBehaviorSupport;
typedef struct QEMU_PACKED NvmeLBAF {
@@ -1397,9 +1464,28 @@ typedef struct QEMU_PACKED NvmeIdNsNvm {
uint8_t pic;
uint8_t rsvd9[3];
uint32_t elbaf[NVME_MAX_NLBAF];
- uint8_t rsvd268[3828];
+ uint32_t npdgl;
+ uint32_t nprg;
+ uint32_t npra;
+ uint32_t nors;
+ uint32_t npdal;
+ uint8_t rsvd288[3808];
} NvmeIdNsNvm;
+typedef struct QEMU_PACKED NvmeIdNsInd {
+ uint8_t nsfeat;
+ uint8_t nmic;
+ uint8_t rescap;
+ uint8_t fpi;
+ uint32_t anagrpid;
+ uint8_t nsattr;
+ uint8_t rsvd9;
+ uint16_t nvmsetid;
+ uint16_t endgrpid;
+ uint8_t nstat;
+ uint8_t rsvd15[4081];
+} NvmeIdNsInd;
+
typedef struct QEMU_PACKED NvmeIdNsDescr {
uint8_t nidt;
uint8_t nidl;
@@ -1420,8 +1506,10 @@ enum NvmeNsIdentifierType {
NVME_NIDT_CSI = 0x04,
};
-enum NvmeIdNsNmic {
- NVME_NMIC_NS_SHARED = 1 << 0,
+enum NvmeIdNsIndependent {
+ NVME_ID_NS_IND_NMIC_SHRNS = 1 << 0,
+ NVME_ID_NS_IND_NMIC_DISNS = 1 << 1,
+ NVME_ID_NS_IND_NSTAT_NRDY = 1 << 0,
};
enum NvmeCsi {
@@ -1499,6 +1587,16 @@ enum NvmeIdNsMc {
NVME_ID_NS_MC_SEPARATE = 1 << 1,
};
+enum NvmeIdNsNsfeat {
+ NVME_ID_NS_NSFEAT_THINP = 1 << 0,
+ NVME_ID_NS_NSFEAT_NSABPNS = 1 << 1,
+ NVME_ID_NS_NSFEAT_DAE = 1 << 2,
+ NVME_ID_NS_NSFEAT_UIDREUSE = 1 << 3,
+ NVME_ID_NS_NSFEAT_OPTPERF_ALL = 3 << 4,
+ NVME_ID_NS_NSFEAT_MAM = 1 << 6,
+ NVME_ID_NS_NSFEAT_OPTRPERF = 1 << 7,
+};
+
#define NVME_ID_NS_DPS_TYPE(dps) (dps & NVME_ID_NS_DPS_TYPE_MASK)
enum NvmePIFormat {
@@ -1832,8 +1930,8 @@ static inline void _nvme_check_size(void)
QEMU_BUILD_BUG_ON(sizeof(NvmeZonedResult) != 8);
QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
- QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRangeFormat0) != 32);
- QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRangeFormat1) != 40);
+ QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRangeFormat0_2) != 32);
+ QEMU_BUILD_BUG_ON(sizeof(NvmeCopySourceRangeFormat1_3) != 40);
QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
QEMU_BUILD_BUG_ON(sizeof(NvmeDeleteQ) != 64);
QEMU_BUILD_BUG_ON(sizeof(NvmeCreateCq) != 64);
@@ -1847,6 +1945,7 @@ static inline void _nvme_check_size(void)
QEMU_BUILD_BUG_ON(sizeof(NvmeErrorLog) != 64);
QEMU_BUILD_BUG_ON(sizeof(NvmeFwSlotInfoLog) != 512);
QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
+ QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLogExtended) != 512);
QEMU_BUILD_BUG_ON(sizeof(NvmeEffectsLog) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrlZoned) != 4096);
@@ -1854,6 +1953,7 @@ static inline void _nvme_check_size(void)
QEMU_BUILD_BUG_ON(sizeof(NvmeLBAF) != 4);
QEMU_BUILD_BUG_ON(sizeof(NvmeLBAFE) != 16);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096);
+ QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsInd) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsNvm) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsZoned) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
diff --git a/include/block/qdict.h b/include/block/qdict.h
index b4c28d9..53c4df4 100644
--- a/include/block/qdict.h
+++ b/include/block/qdict.h
@@ -10,7 +10,7 @@
#ifndef BLOCK_QDICT_H
#define BLOCK_QDICT_H
-#include "qapi/qmp/qdict.h"
+#include "qobject/qdict.h"
QObject *qdict_crumple(const QDict *src, Error **errp);
void qdict_flatten(QDict *qdict);
diff --git a/include/block/raw-aio.h b/include/block/raw-aio.h
index 6267068..6570244 100644
--- a/include/block/raw-aio.h
+++ b/include/block/raw-aio.h
@@ -17,6 +17,7 @@
#define QEMU_RAW_AIO_H
#include "block/aio.h"
+#include "block/block-common.h"
#include "qemu/iov.h"
/* AIO request types */
@@ -58,11 +59,18 @@ void laio_cleanup(LinuxAioState *s);
/* laio_co_submit: submit I/O requests in the thread's current AioContext. */
int coroutine_fn laio_co_submit(int fd, uint64_t offset, QEMUIOVector *qiov,
- int type, uint64_t dev_max_batch);
+ int type, BdrvRequestFlags flags,
+ uint64_t dev_max_batch);
bool laio_has_fdsync(int);
+bool laio_has_fua(void);
void laio_detach_aio_context(LinuxAioState *s, AioContext *old_context);
void laio_attach_aio_context(LinuxAioState *s, AioContext *new_context);
+#else
+static inline bool laio_has_fua(void)
+{
+ return false;
+}
#endif
/* io_uring.c - Linux io_uring implementation */
#ifdef CONFIG_LINUX_IO_URING
@@ -71,9 +79,16 @@ void luring_cleanup(LuringState *s);
/* luring_co_submit: submit I/O requests in the thread's current AioContext. */
int coroutine_fn luring_co_submit(BlockDriverState *bs, int fd, uint64_t offset,
- QEMUIOVector *qiov, int type);
+ QEMUIOVector *qiov, int type,
+ BdrvRequestFlags flags);
void luring_detach_aio_context(LuringState *s, AioContext *old_context);
void luring_attach_aio_context(LuringState *s, AioContext *new_context);
+bool luring_has_fua(void);
+#else
+static inline bool luring_has_fua(void)
+{
+ return false;
+}
#endif
#ifdef _WIN32
diff --git a/include/block/thread-pool.h b/include/block/thread-pool.h
index 948ff5f..dd48cf0 100644
--- a/include/block/thread-pool.h
+++ b/include/block/thread-pool.h
@@ -24,20 +24,70 @@
typedef int ThreadPoolFunc(void *opaque);
-typedef struct ThreadPool ThreadPool;
+typedef struct ThreadPoolAio ThreadPoolAio;
-ThreadPool *thread_pool_new(struct AioContext *ctx);
-void thread_pool_free(ThreadPool *pool);
+ThreadPoolAio *thread_pool_new_aio(struct AioContext *ctx);
+void thread_pool_free_aio(ThreadPoolAio *pool);
/*
- * thread_pool_submit* API: submit I/O requests in the thread's
+ * thread_pool_submit_{aio,co} API: submit I/O requests in the thread's
* current AioContext.
*/
BlockAIOCB *thread_pool_submit_aio(ThreadPoolFunc *func, void *arg,
BlockCompletionFunc *cb, void *opaque);
int coroutine_fn thread_pool_submit_co(ThreadPoolFunc *func, void *arg);
-void thread_pool_submit(ThreadPoolFunc *func, void *arg);
+void thread_pool_update_params(ThreadPoolAio *pool, struct AioContext *ctx);
+
+/* ------------------------------------------- */
+/* Generic thread pool types and methods below */
+typedef struct ThreadPool ThreadPool;
+
+/* Create a new thread pool. Never returns NULL. */
+ThreadPool *thread_pool_new(void);
+
+/*
+ * Free the thread pool.
+ * Waits for all the previously submitted work to complete before performing
+ * the actual freeing operation.
+ */
+void thread_pool_free(ThreadPool *pool);
+
+/*
+ * Submit a new work (task) for the pool.
+ *
+ * @opaque_destroy is an optional GDestroyNotify for the @opaque argument
+ * to the work function at @func.
+ */
+void thread_pool_submit(ThreadPool *pool, ThreadPoolFunc *func,
+ void *opaque, GDestroyNotify opaque_destroy);
+
+/*
+ * Submit a new work (task) for the pool, making sure it starts getting
+ * processed immediately, launching a new thread for it if necessary.
+ *
+ * @opaque_destroy is an optional GDestroyNotify for the @opaque argument
+ * to the work function at @func.
+ */
+void thread_pool_submit_immediate(ThreadPool *pool, ThreadPoolFunc *func,
+ void *opaque, GDestroyNotify opaque_destroy);
+
+/*
+ * Wait for all previously submitted work to complete before returning.
+ *
+ * Can be used as a barrier between two sets of tasks executed on a thread
+ * pool without destroying it or in a performance sensitive path where the
+ * caller just wants to wait for all tasks to complete while deferring the
+ * pool free operation for later, less performance sensitive time.
+ */
+void thread_pool_wait(ThreadPool *pool);
-void thread_pool_update_params(ThreadPool *pool, struct AioContext *ctx);
+/* Set the maximum number of threads in the pool. */
+bool thread_pool_set_max_threads(ThreadPool *pool, int max_threads);
+
+/*
+ * Adjust the maximum number of threads in the pool to give each task its
+ * own thread (exactly one thread per task).
+ */
+bool thread_pool_adjust_max_threads_to_work(ThreadPool *pool);
#endif
diff --git a/include/block/ufs.h b/include/block/ufs.h
index 92da7a8..a3ee62b 100644
--- a/include/block/ufs.h
+++ b/include/block/ufs.h
@@ -461,7 +461,7 @@ typedef struct Attributes {
uint8_t psa_state;
uint32_t psa_data_size;
uint8_t ref_clk_gating_wait_time;
- uint8_t device_case_rough_temperaure;
+ uint8_t device_case_rough_temperature;
uint8_t device_too_high_temp_boundary;
uint8_t device_too_low_temp_boundary;
uint8_t throttling_status;
@@ -764,6 +764,12 @@ typedef struct QEMU_PACKED UtpTaskReqDesc {
#define UFS_WB_EXCEED_LIFETIME 0x0B
/*
+ * The range of valid value of Active ICC attritbute
+ * is from 0x00 to 0x0F.
+ */
+#define UFS_QUERY_ATTR_ACTIVE_ICC_MAXVALUE 0x0F
+
+/*
* In UFS Spec, the Extra Header Segment (EHS) starts from byte 32 in UPIU
* request/response packet
*/
@@ -1067,6 +1073,11 @@ enum health_desc_param {
UFS_HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4,
};
+enum {
+ UFS_DEV_HIGH_TEMP_NOTIF = BIT(4),
+ UFS_DEV_LOW_TEMP_NOTIF = BIT(5),
+};
+
/* WriteBooster buffer mode */
enum {
UFS_WB_BUF_MODE_LU_DEDICATED = 0x0,
@@ -1085,6 +1096,12 @@ enum ufs_lu_wp_type {
UFS_LU_PERM_WP = 0x02,
};
+/* Exception event mask values */
+enum {
+ MASK_EE_TOO_HIGH_TEMP = BIT(3),
+ MASK_EE_TOO_LOW_TEMP = BIT(4),
+};
+
/* UTP QUERY Transaction Specific Fields OpCode */
enum query_opcode {
UFS_UPIU_QUERY_OPCODE_NOP = 0x0,
diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h
index ecef182..8ef05b3 100644
--- a/include/chardev/char-fe.h
+++ b/include/chardev/char-fe.h
@@ -20,7 +20,7 @@ struct CharBackend {
IOReadHandler *chr_read;
BackendChangeHandler *chr_be_change;
void *opaque;
- int tag;
+ unsigned int tag;
bool fe_is_open;
};
@@ -228,6 +228,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition cond,
* is thread-safe.
*
* Returns: the number of bytes consumed (0 if no associated Chardev)
+ * or -1 on error.
*/
int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
@@ -242,6 +243,7 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
* attempted to be written. This function is thread-safe.
*
* Returns: the number of bytes consumed (0 if no associated Chardev)
+ * or -1 on error.
*/
int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
@@ -253,6 +255,7 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
* Read data to a buffer from the back end.
*
* Returns: the number of bytes read (0 if no associated Chardev)
+ * or -1 on error.
*/
int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
diff --git a/include/chardev/char-socket.h b/include/chardev/char-socket.h
index 0708ca6..d6d13ad 100644
--- a/include/chardev/char-socket.h
+++ b/include/chardev/char-socket.h
@@ -74,7 +74,7 @@ struct SocketChardev {
bool is_websock;
GSource *reconnect_timer;
- int64_t reconnect_time;
+ int64_t reconnect_time_ms;
bool connect_err_reported;
QIOTask *connect_task;
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 01df55f..429852f 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -232,6 +232,7 @@ OBJECT_DECLARE_TYPE(Chardev, ChardevClass, CHARDEV)
#define TYPE_CHARDEV_NULL "chardev-null"
#define TYPE_CHARDEV_MUX "chardev-mux"
+#define TYPE_CHARDEV_HUB "chardev-hub"
#define TYPE_CHARDEV_RINGBUF "chardev-ringbuf"
#define TYPE_CHARDEV_PTY "chardev-pty"
#define TYPE_CHARDEV_CONSOLE "chardev-console"
diff --git a/include/crypto/afsplit.h b/include/crypto/afsplit.h
index 4894d64..06f28fe 100644
--- a/include/crypto/afsplit.h
+++ b/include/crypto/afsplit.h
@@ -46,7 +46,7 @@
*
* splitkey = g_new0(uint8_t, nkey * stripes);
*
- * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALG_SHA256,
+ * if (qcrypto_afsplit_encode(QCRYPTO_HASH_ALGO_SHA256,
* nkey, stripes,
* masterkey, splitkey, errp) < 0) {
* g_free(splitkey);
@@ -71,7 +71,7 @@
*
* masterkey = g_new0(uint8_t, nkey);
*
- * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALG_SHA256,
+ * if (qcrypto_afsplit_decode(QCRYPTO_HASH_ALGO_SHA256,
* nkey, stripes,
* splitkey, masterkey, errp) < 0) {
* g_free(splitkey);
@@ -102,7 +102,7 @@
*
* Returns: 0 on success, -1 on error;
*/
-int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash,
+int qcrypto_afsplit_encode(QCryptoHashAlgo hash,
size_t blocklen,
uint32_t stripes,
const uint8_t *in,
@@ -124,7 +124,7 @@ int qcrypto_afsplit_encode(QCryptoHashAlgorithm hash,
*
* Returns: 0 on success, -1 on error;
*/
-int qcrypto_afsplit_decode(QCryptoHashAlgorithm hash,
+int qcrypto_afsplit_decode(QCryptoHashAlgo hash,
size_t blocklen,
uint32_t stripes,
const uint8_t *in,
diff --git a/include/crypto/block.h b/include/crypto/block.h
index 5b5d039..b013d27 100644
--- a/include/crypto/block.h
+++ b/include/crypto/block.h
@@ -287,7 +287,7 @@ QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block);
*
* Returns: the hash algorithm
*/
-QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block);
+QCryptoHashAlgo qcrypto_block_get_kdf_hash(QCryptoBlock *block);
/**
* qcrypto_block_get_payload_offset:
diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h
index 083e12a..9293931 100644
--- a/include/crypto/cipher.h
+++ b/include/crypto/cipher.h
@@ -26,7 +26,7 @@
typedef struct QCryptoCipher QCryptoCipher;
typedef struct QCryptoCipherDriver QCryptoCipherDriver;
-/* See also "QCryptoCipherAlgorithm" and "QCryptoCipherMode"
+/* See also "QCryptoCipherAlgo" and "QCryptoCipherMode"
* enums defined in qapi/crypto.json */
/**
@@ -50,12 +50,12 @@ typedef struct QCryptoCipherDriver QCryptoCipherDriver;
* size_t keylen = 16;
* uint8_t iv = ....;
*
- * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128)) {
+ * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALGO_AES_128)) {
* error_report(errp, "Feature <blah> requires AES cipher support");
* return -1;
* }
*
- * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
+ * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128,
* QCRYPTO_CIPHER_MODE_CBC,
* key, keylen,
* errp);
@@ -78,7 +78,7 @@ typedef struct QCryptoCipherDriver QCryptoCipherDriver;
*/
struct QCryptoCipher {
- QCryptoCipherAlgorithm alg;
+ QCryptoCipherAlgo alg;
QCryptoCipherMode mode;
const QCryptoCipherDriver *driver;
};
@@ -93,7 +93,7 @@ struct QCryptoCipher {
*
* Returns: true if the algorithm is supported, false otherwise
*/
-bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
+bool qcrypto_cipher_supports(QCryptoCipherAlgo alg,
QCryptoCipherMode mode);
/**
@@ -106,7 +106,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
*
* Returns: the block size in bytes
*/
-size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg);
+size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgo alg);
/**
@@ -117,7 +117,7 @@ size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg);
*
* Returns: the key size in bytes
*/
-size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg);
+size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgo alg);
/**
@@ -130,7 +130,7 @@ size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg);
*
* Returns: the IV size in bytes, or 0 if no IV is permitted
*/
-size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg,
+size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgo alg,
QCryptoCipherMode mode);
@@ -156,7 +156,7 @@ size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg,
*
* Returns: a new cipher object, or NULL on error
*/
-QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
+QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgo alg,
QCryptoCipherMode mode,
const uint8_t *key, size_t nkey,
Error **errp);
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index 54d87aa..1868d4a 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -1,6 +1,7 @@
/*
* QEMU Crypto hash algorithms
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (c) 2015 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -23,7 +24,23 @@
#include "qapi/qapi-types-crypto.h"
-/* See also "QCryptoHashAlgorithm" defined in qapi/crypto.json */
+#define QCRYPTO_HASH_DIGEST_LEN_MD5 16
+#define QCRYPTO_HASH_DIGEST_LEN_SHA1 20
+#define QCRYPTO_HASH_DIGEST_LEN_SHA224 28
+#define QCRYPTO_HASH_DIGEST_LEN_SHA256 32
+#define QCRYPTO_HASH_DIGEST_LEN_SHA384 48
+#define QCRYPTO_HASH_DIGEST_LEN_SHA512 64
+#define QCRYPTO_HASH_DIGEST_LEN_RIPEMD160 20
+#define QCRYPTO_HASH_DIGEST_LEN_SM3 32
+
+/* See also "QCryptoHashAlgo" defined in qapi/crypto.json */
+
+typedef struct QCryptoHash QCryptoHash;
+struct QCryptoHash {
+ QCryptoHashAlgo alg;
+ void *opaque;
+ void *driver;
+};
/**
* qcrypto_hash_supports:
@@ -34,7 +51,7 @@
*
* Returns: true if the algorithm is supported, false otherwise
*/
-gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg);
+gboolean qcrypto_hash_supports(QCryptoHashAlgo alg);
/**
@@ -45,7 +62,7 @@ gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg);
*
* Returns: the digest length in bytes
*/
-size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg);
+size_t qcrypto_hash_digest_len(QCryptoHashAlgo alg);
/**
* qcrypto_hash_bytesv:
@@ -57,15 +74,22 @@ size_t qcrypto_hash_digest_len(QCryptoHashAlgorithm alg);
* @errp: pointer to a NULL-initialized error object
*
* Computes the hash across all the memory regions
- * present in @iov. The @result pointer will be
- * filled with raw bytes representing the computed
- * hash, which will have length @resultlen. The
- * memory pointer in @result must be released
- * with a call to g_free() when no longer required.
+ * present in @iov.
+ *
+ * If @result_len is set to a non-zero value by the caller, then
+ * @result must hold a pointer that is @result_len in size, and
+ * @result_len match the size of the hash output. The digest will
+ * be written into @result.
+ *
+ * If @result_len is set to zero, then this function will allocate
+ * a buffer to hold the hash output digest, storing a pointer to
+ * the buffer in @result, and setting @result_len to its size.
+ * The memory referenced in @result must be released with a call
+ * to g_free() when no longer required by the caller.
*
* Returns: 0 on success, -1 on error
*/
-int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
+int qcrypto_hash_bytesv(QCryptoHashAlgo alg,
const struct iovec *iov,
size_t niov,
uint8_t **result,
@@ -82,15 +106,22 @@ int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,
* @errp: pointer to a NULL-initialized error object
*
* Computes the hash across all the memory region
- * @buf of length @len. The @result pointer will be
- * filled with raw bytes representing the computed
- * hash, which will have length @resultlen. The
- * memory pointer in @result must be released
- * with a call to g_free() when no longer required.
+ * @buf of length @len.
+ *
+ * If @result_len is set to a non-zero value by the caller, then
+ * @result must hold a pointer that is @result_len in size, and
+ * @result_len match the size of the hash output. The digest will
+ * be written into @result.
+ *
+ * If @result_len is set to zero, then this function will allocate
+ * a buffer to hold the hash output digest, storing a pointer to
+ * the buffer in @result, and setting @result_len to its size.
+ * The memory referenced in @result must be released with a call
+ * to g_free() when no longer required by the caller.
*
* Returns: 0 on success, -1 on error
*/
-int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
+int qcrypto_hash_bytes(QCryptoHashAlgo alg,
const char *buf,
size_t len,
uint8_t **result,
@@ -114,13 +145,133 @@ int qcrypto_hash_bytes(QCryptoHashAlgorithm alg,
*
* Returns: 0 on success, -1 on error
*/
-int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
+int qcrypto_hash_digestv(QCryptoHashAlgo alg,
const struct iovec *iov,
size_t niov,
char **digest,
Error **errp);
/**
+ * qcrypto_hash_updatev:
+ * @hash: hash object from qcrypto_hash_new
+ * @iov: the array of memory regions to hash
+ * @niov: the length of @iov
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Updates the given hash object with all the memory regions
+ * present in @iov.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_updatev(QCryptoHash *hash,
+ const struct iovec *iov,
+ size_t niov,
+ Error **errp);
+/**
+ * qcrypto_hash_update:
+ * @hash: hash object from qcrypto_hash_new
+ * @buf: the memory region to hash
+ * @len: the length of @buf
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Updates the given hash object with the data from
+ * the given buffer.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_update(QCryptoHash *hash,
+ const char *buf,
+ size_t len,
+ Error **errp);
+
+/**
+ * qcrypto_hash_finalize_digest:
+ * @hash: the hash object to finalize
+ * @digest: pointer to hold output hash
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hash from the given hash object. Hash object
+ * is expected to have its data updated from the qcrypto_hash_update function.
+ * The @digest pointer will be filled with the printable hex digest of the
+ * computed hash, which will be terminated by '\0'. The memory pointer
+ * in @digest must be released with a call to g_free() when
+ * no longer required.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_finalize_digest(QCryptoHash *hash,
+ char **digest,
+ Error **errp);
+
+/**
+ * qcrypto_hash_finalize_base64:
+ * @hash_ctx: hash object to finalize
+ * @base64: pointer to store the hash result in
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hash from the given hash object. Hash object
+ * is expected to have it's data updated from the qcrypto_hash_update function.
+ * The @base64 pointer will be filled with the base64 encoding of the computed
+ * hash, which will be terminated by '\0'. The memory pointer in @base64
+ * must be released with a call to g_free() when no longer required.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_finalize_base64(QCryptoHash *hash,
+ char **base64,
+ Error **errp);
+
+/**
+ * qcrypto_hash_finalize_bytes:
+ * @hash_ctx: hash object to finalize
+ * @result: pointer to store the hash result in
+ * @result_len: Pointer to store the length of the result in
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Computes the hash from the given hash object. Hash object
+ * is expected to have it's data updated from the qcrypto_hash_update function.
+ *
+ * If @result_len is set to a non-zero value by the caller, then
+ * @result must hold a pointer that is @result_len in size, and
+ * @result_len match the size of the hash output. The digest will
+ * be written into @result.
+ *
+ * If @result_len is set to zero, then this function will allocate
+ * a buffer to hold the hash output digest, storing a pointer to
+ * the buffer in @result, and setting @result_len to its size.
+ * The memory referenced in @result must be released with a call
+ * to g_free() when no longer required by the caller.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+int qcrypto_hash_finalize_bytes(QCryptoHash *hash,
+ uint8_t **result,
+ size_t *result_len,
+ Error **errp);
+
+/**
+ * qcrypto_hash_new:
+ * @alg: the hash algorithm
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Creates a new hashing context for the chosen algorithm for
+ * usage with qcrypto_hash_update.
+ *
+ * Returns: New hash object with the given algorithm, or NULL on error.
+ */
+QCryptoHash *qcrypto_hash_new(QCryptoHashAlgo alg, Error **errp);
+
+/**
+ * qcrypto_hash_free:
+ * @hash: hash object to free
+ *
+ * Frees a hashing context for the chosen algorithm.
+ */
+void qcrypto_hash_free(QCryptoHash *hash);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHash, qcrypto_hash_free)
+
+/**
* qcrypto_hash_digest:
* @alg: the hash algorithm
* @buf: the memory region to hash
@@ -137,7 +288,7 @@ int qcrypto_hash_digestv(QCryptoHashAlgorithm alg,
*
* Returns: 0 on success, -1 on error
*/
-int qcrypto_hash_digest(QCryptoHashAlgorithm alg,
+int qcrypto_hash_digest(QCryptoHashAlgo alg,
const char *buf,
size_t len,
char **digest,
@@ -160,7 +311,7 @@ int qcrypto_hash_digest(QCryptoHashAlgorithm alg,
*
* Returns: 0 on success, -1 on error
*/
-int qcrypto_hash_base64v(QCryptoHashAlgorithm alg,
+int qcrypto_hash_base64v(QCryptoHashAlgo alg,
const struct iovec *iov,
size_t niov,
char **base64,
@@ -183,7 +334,7 @@ int qcrypto_hash_base64v(QCryptoHashAlgorithm alg,
*
* Returns: 0 on success, -1 on error
*/
-int qcrypto_hash_base64(QCryptoHashAlgorithm alg,
+int qcrypto_hash_base64(QCryptoHashAlgo alg,
const char *buf,
size_t len,
char **base64,
diff --git a/include/crypto/hmac.h b/include/crypto/hmac.h
index ad4d778..da8a1e3 100644
--- a/include/crypto/hmac.h
+++ b/include/crypto/hmac.h
@@ -16,7 +16,7 @@
typedef struct QCryptoHmac QCryptoHmac;
struct QCryptoHmac {
- QCryptoHashAlgorithm alg;
+ QCryptoHashAlgo alg;
void *opaque;
void *driver;
};
@@ -31,7 +31,7 @@ struct QCryptoHmac {
* Returns:
* true if the algorithm is supported, false otherwise
*/
-bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg);
+bool qcrypto_hmac_supports(QCryptoHashAlgo alg);
/**
* qcrypto_hmac_new:
@@ -52,7 +52,7 @@ bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg);
* Returns:
* a new hmac object, or NULL on error
*/
-QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg,
+QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgo alg,
const uint8_t *key, size_t nkey,
Error **errp);
@@ -77,11 +77,18 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHmac, qcrypto_hmac_free)
* @errp: pointer to a NULL-initialized error object
*
* Computes the hmac across all the memory regions
- * present in @iov. The @result pointer will be
- * filled with raw bytes representing the computed
- * hmac, which will have length @resultlen. The
- * memory pointer in @result must be released
- * with a call to g_free() when no longer required.
+ * present in @iov.
+ *
+ * If @result_len is set to a non-zero value by the caller, then
+ * @result must hold a pointer that is @result_len in size, and
+ * @result_len match the size of the hash output. The digest will
+ * be written into @result.
+ *
+ * If @result_len is set to zero, then this function will allocate
+ * a buffer to hold the hash output digest, storing a pointer to
+ * the buffer in @result, and setting @result_len to its size.
+ * The memory referenced in @result must be released with a call
+ * to g_free() when no longer required by the caller.
*
* Returns:
* 0 on success, -1 on error
@@ -103,11 +110,18 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
* @errp: pointer to a NULL-initialized error object
*
* Computes the hmac across all the memory region
- * @buf of length @len. The @result pointer will be
- * filled with raw bytes representing the computed
- * hmac, which will have length @resultlen. The
- * memory pointer in @result must be released
- * with a call to g_free() when no longer required.
+ * @buf of length @len.
+ *
+ * If @result_len is set to a non-zero value by the caller, then
+ * @result must hold a pointer that is @result_len in size, and
+ * @result_len match the size of the hash output. The digest will
+ * be written into @result.
+ *
+ * If @result_len is set to zero, then this function will allocate
+ * a buffer to hold the hash output digest, storing a pointer to
+ * the buffer in @result, and setting @result_len to its size.
+ * The memory referenced in @result must be released with a call
+ * to g_free() when no longer required by the caller.
*
* Returns:
* 0 on success, -1 on error
diff --git a/include/crypto/ivgen.h b/include/crypto/ivgen.h
index a09d573..bfa5d28 100644
--- a/include/crypto/ivgen.h
+++ b/include/crypto/ivgen.h
@@ -44,22 +44,22 @@
*
* g_assert((ndata % 512) == 0);
*
- * QCryptoIVGen *ivgen = qcrypto_ivgen_new(QCRYPTO_IVGEN_ALG_ESSIV,
- * QCRYPTO_CIPHER_ALG_AES_128,
- * QCRYPTO_HASH_ALG_SHA256,
+ * QCryptoIVGen *ivgen = qcrypto_ivgen_new(QCRYPTO_IV_GEN_ALGO_ESSIV,
+ * QCRYPTO_CIPHER_ALGO_AES_128,
+ * QCRYPTO_HASH_ALGO_SHA256,
* key, nkey, errp);
* if (!ivgen) {
* return -1;
* }
*
- * QCryptoCipher *cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
+ * QCryptoCipher *cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128,
* QCRYPTO_CIPHER_MODE_CBC,
* key, nkey, errp);
* if (!cipher) {
* goto error;
* }
*
- * niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128,
+ * niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALGO_AES_128,
* QCRYPTO_CIPHER_MODE_CBC);
* iv = g_new0(uint8_t, niv);
*
@@ -97,7 +97,7 @@
typedef struct QCryptoIVGen QCryptoIVGen;
-/* See also QCryptoIVGenAlgorithm enum in qapi/crypto.json */
+/* See also QCryptoIVGenAlgo enum in qapi/crypto.json */
/**
@@ -113,19 +113,19 @@ typedef struct QCryptoIVGen QCryptoIVGen;
* are required or not depends on the choice of @alg
* requested.
*
- * - QCRYPTO_IVGEN_ALG_PLAIN
+ * - QCRYPTO_IV_GEN_ALGO_PLAIN
*
* The IVs are generated by the 32-bit truncated sector
* number. This should never be used for block devices
* that are larger than 2^32 sectors in size.
* All the other parameters are unused.
*
- * - QCRYPTO_IVGEN_ALG_PLAIN64
+ * - QCRYPTO_IV_GEN_ALGO_PLAIN64
*
* The IVs are generated by the 64-bit sector number.
* All the other parameters are unused.
*
- * - QCRYPTO_IVGEN_ALG_ESSIV:
+ * - QCRYPTO_IV_GEN_ALGO_ESSIV:
*
* The IVs are generated by encrypting the 64-bit sector
* number with a hash of an encryption key. The @cipheralg,
@@ -133,9 +133,9 @@ typedef struct QCryptoIVGen QCryptoIVGen;
*
* Returns: a new IV generator, or NULL on error
*/
-QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
- QCryptoCipherAlgorithm cipheralg,
- QCryptoHashAlgorithm hash,
+QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgo alg,
+ QCryptoCipherAlgo cipheralg,
+ QCryptoHashAlgo hash,
const uint8_t *key, size_t nkey,
Error **errp);
@@ -167,7 +167,7 @@ int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen,
*
* Returns: the IV generator algorithm
*/
-QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen);
+QCryptoIVGenAlgo qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen);
/**
@@ -179,7 +179,7 @@ QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen);
*
* Returns: the cipher algorithm
*/
-QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen);
+QCryptoCipherAlgo qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen);
/**
@@ -191,7 +191,7 @@ QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen);
*
* Returns: the hash algorithm
*/
-QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen);
+QCryptoHashAlgo qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen);
/**
diff --git a/include/crypto/pbkdf.h b/include/crypto/pbkdf.h
index 2c31a44..cf59fce 100644
--- a/include/crypto/pbkdf.h
+++ b/include/crypto/pbkdf.h
@@ -38,7 +38,7 @@
* ....
*
* char *password = "a-typical-awful-user-password";
- * size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALG_AES_128);
+ * size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALGO_AES_128);
* uint8_t *salt = g_new0(uint8_t, nkey);
* uint8_t *key = g_new0(uint8_t, nkey);
* int iterations;
@@ -50,7 +50,7 @@
* return -1;
* }
*
- * iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALG_SHA256,
+ * iterations = qcrypto_pbkdf2_count_iters(QCRYPTO_HASH_ALGO_SHA256,
* (const uint8_t *)password,
* strlen(password),
* salt, nkey, errp);
@@ -60,7 +60,7 @@
* return -1;
* }
*
- * if (qcrypto_pbkdf2(QCRYPTO_HASH_ALG_SHA256,
+ * if (qcrypto_pbkdf2(QCRYPTO_HASH_ALGO_SHA256,
* (const uint8_t *)password, strlen(password),
* salt, nkey, iterations, key, nkey, errp) < 0) {
* g_free(key);
@@ -70,7 +70,7 @@
*
* g_free(salt);
*
- * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
+ * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALGO_AES_128,
* QCRYPTO_CIPHER_MODE_ECB,
* key, nkey, errp);
* g_free(key);
@@ -92,7 +92,7 @@
*
* Returns true if supported, false otherwise
*/
-bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash);
+bool qcrypto_pbkdf2_supports(QCryptoHashAlgo hash);
/**
@@ -119,7 +119,7 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash);
*
* Returns: 0 on success, -1 on error
*/
-int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
+int qcrypto_pbkdf2(QCryptoHashAlgo hash,
const uint8_t *key, size_t nkey,
const uint8_t *salt, size_t nsalt,
uint64_t iterations,
@@ -147,7 +147,7 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
*
* Returns: number of iterations in 1 second, -1 on error
*/
-uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash,
+uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgo hash,
const uint8_t *key, size_t nkey,
const uint8_t *salt, size_t nsalt,
size_t nout,
diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h
index 571049b..d77ae0d 100644
--- a/include/crypto/tlssession.h
+++ b/include/crypto/tlssession.h
@@ -75,12 +75,14 @@
* GINT_TO_POINTER(fd));
*
* while (1) {
- * if (qcrypto_tls_session_handshake(sess, errp) < 0) {
+ * int ret = qcrypto_tls_session_handshake(sess, errp);
+ *
+ * if (ret < 0) {
* qcrypto_tls_session_free(sess);
* return -1;
* }
*
- * switch(qcrypto_tls_session_get_handshake_status(sess)) {
+ * switch(ret) {
* case QCRYPTO_TLS_HANDSHAKE_COMPLETE:
* if (qcrypto_tls_session_check_credentials(sess, errp) < )) {
* qcrypto_tls_session_free(sess);
@@ -107,6 +109,7 @@
typedef struct QCryptoTLSSession QCryptoTLSSession;
+#define QCRYPTO_TLS_SESSION_ERR_BLOCK -2
/**
* qcrypto_tls_session_new:
@@ -169,7 +172,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoTLSSession, qcrypto_tls_session_free)
*
* Validate the peer's credentials after a successful
* TLS handshake. It is an error to call this before
- * qcrypto_tls_session_get_handshake_status() returns
+ * qcrypto_tls_session_handshake() returns
* QCRYPTO_TLS_HANDSHAKE_COMPLETE
*
* Returns 0 if the credentials validated, -1 on error
@@ -177,12 +180,18 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoTLSSession, qcrypto_tls_session_free)
int qcrypto_tls_session_check_credentials(QCryptoTLSSession *sess,
Error **errp);
+/*
+ * These must return QCRYPTO_TLS_SESSION_ERR_BLOCK if the I/O
+ * would block, but on other errors, must fill 'errp'
+ */
typedef ssize_t (*QCryptoTLSSessionWriteFunc)(const char *buf,
size_t len,
- void *opaque);
+ void *opaque,
+ Error **errp);
typedef ssize_t (*QCryptoTLSSessionReadFunc)(char *buf,
size_t len,
- void *opaque);
+ void *opaque,
+ Error **errp);
/**
* qcrypto_tls_session_set_callbacks:
@@ -212,41 +221,55 @@ void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *sess,
* @sess: the TLS session object
* @buf: the plain text to send
* @len: the length of @buf
+ * @errp: pointer to hold returned error object
*
* Encrypt @len bytes of the data in @buf and send
* it to the remote peer using the callback previously
* registered with qcrypto_tls_session_set_callbacks()
*
* It is an error to call this before
- * qcrypto_tls_session_get_handshake_status() returns
+ * qcrypto_tls_session_handshake() returns
* QCRYPTO_TLS_HANDSHAKE_COMPLETE
*
- * Returns: the number of bytes sent, or -1 on error
+ * Returns: the number of bytes sent,
+ * or QCRYPTO_TLS_SESSION_ERR_BLOCK if the write would block,
+ * or -1 on error.
*/
ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess,
const char *buf,
- size_t len);
+ size_t len,
+ Error **errp);
/**
* qcrypto_tls_session_read:
* @sess: the TLS session object
* @buf: to fill with plain text received
* @len: the length of @buf
+ * @gracefulTermination: treat premature termination as graceful EOF
+ * @errp: pointer to hold returned error object
*
* Receive up to @len bytes of data from the remote peer
* using the callback previously registered with
* qcrypto_tls_session_set_callbacks(), decrypt it and
* store it in @buf.
*
+ * If @gracefulTermination is true, then a premature termination
+ * of the TLS session will be treated as indicating EOF, as
+ * opposed to an error.
+ *
* It is an error to call this before
- * qcrypto_tls_session_get_handshake_status() returns
+ * qcrypto_tls_session_handshake() returns
* QCRYPTO_TLS_HANDSHAKE_COMPLETE
*
- * Returns: the number of bytes received, or -1 on error
+ * Returns: the number of bytes received,
+ * or QCRYPTO_TLS_SESSION_ERR_BLOCK if the receive would block,
+ * or -1 on error.
*/
ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess,
char *buf,
- size_t len);
+ size_t len,
+ bool gracefulTermination,
+ Error **errp);
/**
* qcrypto_tls_session_check_pending:
@@ -268,8 +291,7 @@ size_t qcrypto_tls_session_check_pending(QCryptoTLSSession *sess);
* the underlying data channel is non-blocking, then
* this method may return control before the handshake
* is complete. On non-blocking channels the
- * qcrypto_tls_session_get_handshake_status() method
- * should be used to determine whether the handshake
+ * return value determines whether the handshake
* has completed, or is waiting to send or receive
* data. In the latter cases, the caller should setup
* an event loop watch and call this method again
@@ -285,22 +307,27 @@ typedef enum {
QCRYPTO_TLS_HANDSHAKE_RECVING,
} QCryptoTLSSessionHandshakeStatus;
+typedef enum {
+ QCRYPTO_TLS_BYE_COMPLETE,
+ QCRYPTO_TLS_BYE_SENDING,
+ QCRYPTO_TLS_BYE_RECVING,
+} QCryptoTLSSessionByeStatus;
+
/**
- * qcrypto_tls_session_get_handshake_status:
- * @sess: the TLS session object
- *
- * Check the status of the TLS handshake. This
- * is used with non-blocking data channels to
- * determine whether the handshake is waiting
- * to send or receive further data to/from the
- * remote peer.
+ * qcrypto_tls_session_bye:
+ * @session: the TLS session object
+ * @errp: pointer to a NULL-initialized error object
*
- * Once this returns QCRYPTO_TLS_HANDSHAKE_COMPLETE
- * it is permitted to send/receive payload data on
- * the channel
+ * Start, or continue, a TLS termination sequence. If the underlying
+ * data channel is non-blocking, then this method may return control
+ * before the termination is complete. The return value will indicate
+ * whether the termination has completed, or is waiting to send or
+ * receive data. In the latter cases, the caller should setup an event
+ * loop watch and call this method again once the underlying data
+ * channel is ready to read or write again.
*/
-QCryptoTLSSessionHandshakeStatus
-qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess);
+int
+qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp);
/**
* qcrypto_tls_session_get_key_size:
diff --git a/include/crypto/x509-utils.h b/include/crypto/x509-utils.h
new file mode 100644
index 0000000..1e99661
--- /dev/null
+++ b/include/crypto/x509-utils.h
@@ -0,0 +1,22 @@
+/*
+ * X.509 certificate related 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 QCRYPTO_X509_UTILS_H
+#define QCRYPTO_X509_UTILS_H
+
+#include "crypto/hash.h"
+
+int qcrypto_get_x509_cert_fingerprint(uint8_t *cert, size_t size,
+ QCryptoHashAlgo hash,
+ uint8_t *result,
+ size_t *resultlen,
+ Error **errp);
+
+#endif
diff --git a/include/disas/capstone.h b/include/disas/capstone.h
index e29068d..c43033f 100644
--- a/include/disas/capstone.h
+++ b/include/disas/capstone.h
@@ -3,6 +3,8 @@
#ifdef CONFIG_CAPSTONE
+#define CAPSTONE_AARCH64_COMPAT_HEADER
+#define CAPSTONE_SYSTEMZ_COMPAT_HEADER
#include <capstone.h>
#else
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index a1d26ce..3b50ecf 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -232,10 +232,6 @@ enum bfd_architecture
#define bfd_mach_avrxmega5 105
#define bfd_mach_avrxmega6 106
#define bfd_mach_avrxmega7 107
- bfd_arch_cris, /* Axis CRIS */
-#define bfd_mach_cris_v0_v10 255
-#define bfd_mach_cris_v32 32
-#define bfd_mach_cris_v10_v32 1032
bfd_arch_microblaze, /* Xilinx MicroBlaze. */
bfd_arch_moxie, /* The Moxie core. */
bfd_arch_ia64, /* HP/Intel ia64 */
@@ -448,8 +444,6 @@ int print_insn_w65 (bfd_vma, disassemble_info*);
int print_insn_d10v (bfd_vma, disassemble_info*);
int print_insn_v850 (bfd_vma, disassemble_info*);
int print_insn_tic30 (bfd_vma, disassemble_info*);
-int print_insn_crisv32 (bfd_vma, disassemble_info*);
-int print_insn_crisv10 (bfd_vma, disassemble_info*);
int print_insn_microblaze (bfd_vma, disassemble_info*);
int print_insn_ia64 (bfd_vma, disassemble_info*);
int print_insn_xtensa (bfd_vma, disassemble_info*);
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
deleted file mode 100644
index 6f09b86..0000000
--- a/include/exec/cpu-all.h
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * defines common to all virtual CPUs
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef CPU_ALL_H
-#define CPU_ALL_H
-
-#include "exec/page-protection.h"
-#include "exec/cpu-common.h"
-#include "exec/memory.h"
-#include "exec/tswap.h"
-#include "hw/core/cpu.h"
-
-/* some important defines:
- *
- * HOST_BIG_ENDIAN : whether the host cpu is big endian and
- * otherwise little endian.
- *
- * TARGET_BIG_ENDIAN : same for the target cpu
- */
-
-#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
-#define BSWAP_NEEDED
-#endif
-
-/* Target-endianness CPU memory access functions. These fit into the
- * {ld,st}{type}{sign}{size}{endian}_p naming scheme described in bswap.h.
- */
-#if TARGET_BIG_ENDIAN
-#define lduw_p(p) lduw_be_p(p)
-#define ldsw_p(p) ldsw_be_p(p)
-#define ldl_p(p) ldl_be_p(p)
-#define ldq_p(p) ldq_be_p(p)
-#define stw_p(p, v) stw_be_p(p, v)
-#define stl_p(p, v) stl_be_p(p, v)
-#define stq_p(p, v) stq_be_p(p, v)
-#define ldn_p(p, sz) ldn_be_p(p, sz)
-#define stn_p(p, sz, v) stn_be_p(p, sz, v)
-#else
-#define lduw_p(p) lduw_le_p(p)
-#define ldsw_p(p) ldsw_le_p(p)
-#define ldl_p(p) ldl_le_p(p)
-#define ldq_p(p) ldq_le_p(p)
-#define stw_p(p, v) stw_le_p(p, v)
-#define stl_p(p, v) stl_le_p(p, v)
-#define stq_p(p, v) stq_le_p(p, v)
-#define ldn_p(p, sz) ldn_le_p(p, sz)
-#define stn_p(p, sz, v) stn_le_p(p, sz, v)
-#endif
-
-/* MMU memory access macros */
-
-#if defined(CONFIG_USER_ONLY)
-#include "user/abitypes.h"
-
-/*
- * If non-zero, the guest virtual address space is a contiguous subset
- * of the host virtual address space, i.e. '-R reserved_va' is in effect
- * either from the command-line or by default. The value is the last
- * byte of the guest address space e.g. UINT32_MAX.
- *
- * If zero, the host and guest virtual address spaces are intermingled.
- */
-extern unsigned long reserved_va;
-
-/*
- * Limit the guest addresses as best we can.
- *
- * When not using -R reserved_va, we cannot really limit the guest
- * to less address space than the host. For 32-bit guests, this
- * acts as a sanity check that we're not giving the guest an address
- * that it cannot even represent. For 64-bit guests... the address
- * might not be what the real kernel would give, but it is at least
- * representable in the guest.
- *
- * TODO: Improve address allocation to avoid this problem, and to
- * avoid setting bits at the top of guest addresses that might need
- * to be used for tags.
- */
-#define GUEST_ADDR_MAX_ \
- ((MIN_CONST(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) ? \
- UINT32_MAX : ~0ul)
-#define GUEST_ADDR_MAX (reserved_va ? : GUEST_ADDR_MAX_)
-
-#else
-
-#include "exec/hwaddr.h"
-
-#define SUFFIX
-#define ARG1 as
-#define ARG1_DECL AddressSpace *as
-#define TARGET_ENDIANNESS
-#include "exec/memory_ldst.h.inc"
-
-#define SUFFIX _cached_slow
-#define ARG1 cache
-#define ARG1_DECL MemoryRegionCache *cache
-#define TARGET_ENDIANNESS
-#include "exec/memory_ldst.h.inc"
-
-static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
-{
- address_space_stl_notdirty(as, addr, val,
- MEMTXATTRS_UNSPECIFIED, NULL);
-}
-
-#define SUFFIX
-#define ARG1 as
-#define ARG1_DECL AddressSpace *as
-#define TARGET_ENDIANNESS
-#include "exec/memory_ldst_phys.h.inc"
-
-/* Inline fast path for direct RAM access. */
-#define ENDIANNESS
-#include "exec/memory_ldst_cached.h.inc"
-
-#define SUFFIX _cached
-#define ARG1 cache
-#define ARG1_DECL MemoryRegionCache *cache
-#define TARGET_ENDIANNESS
-#include "exec/memory_ldst_phys.h.inc"
-#endif
-
-/* page related stuff */
-
-#ifdef TARGET_PAGE_BITS_VARY
-# include "exec/page-vary.h"
-extern const TargetPageBits target_page;
-# ifdef CONFIG_DEBUG_TCG
-# define TARGET_PAGE_BITS ({ assert(target_page.decided); \
- target_page.bits; })
-# define TARGET_PAGE_MASK ({ assert(target_page.decided); \
- (target_long)target_page.mask; })
-# else
-# define TARGET_PAGE_BITS target_page.bits
-# define TARGET_PAGE_MASK ((target_long)target_page.mask)
-# endif
-# define TARGET_PAGE_SIZE (-(int)TARGET_PAGE_MASK)
-#else
-# define TARGET_PAGE_BITS_MIN TARGET_PAGE_BITS
-# define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
-# define TARGET_PAGE_MASK ((target_long)-1 << TARGET_PAGE_BITS)
-#endif
-
-#define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE)
-
-#if defined(CONFIG_USER_ONLY)
-void page_dump(FILE *f);
-
-typedef int (*walk_memory_regions_fn)(void *, target_ulong,
- target_ulong, unsigned long);
-int walk_memory_regions(void *, walk_memory_regions_fn);
-
-int page_get_flags(target_ulong address);
-void page_set_flags(target_ulong start, target_ulong last, int flags);
-void page_reset_target_data(target_ulong start, target_ulong last);
-
-/**
- * page_check_range
- * @start: first byte of range
- * @len: length of range
- * @flags: flags required for each page
- *
- * Return true if every page in [@start, @start+@len) has @flags set.
- * Return false if any page is unmapped. Thus testing flags == 0 is
- * equivalent to testing for flags == PAGE_VALID.
- */
-bool page_check_range(target_ulong start, target_ulong last, int flags);
-
-/**
- * page_check_range_empty:
- * @start: first byte of range
- * @last: last byte of range
- * Context: holding mmap lock
- *
- * Return true if the entire range [@start, @last] is unmapped.
- * The memory lock must be held so that the caller will can ensure
- * the result stays true until a new mapping can be installed.
- */
-bool page_check_range_empty(target_ulong start, target_ulong last);
-
-/**
- * page_find_range_empty
- * @min: first byte of search range
- * @max: last byte of search range
- * @len: size of the hole required
- * @align: alignment of the hole required (power of 2)
- *
- * If there is a range [x, x+@len) within [@min, @max] such that
- * x % @align == 0, then return x. Otherwise return -1.
- * The memory lock must be held, as the caller will want to ensure
- * the returned range stays empty until a new mapping can be installed.
- */
-target_ulong page_find_range_empty(target_ulong min, target_ulong max,
- target_ulong len, target_ulong align);
-
-/**
- * page_get_target_data(address)
- * @address: guest virtual address
- *
- * Return TARGET_PAGE_DATA_SIZE bytes of out-of-band data to associate
- * with the guest page at @address, allocating it if necessary. The
- * caller should already have verified that the address is valid.
- *
- * The memory will be freed when the guest page is deallocated,
- * e.g. with the munmap system call.
- */
-void *page_get_target_data(target_ulong address)
- __attribute__((returns_nonnull));
-#endif
-
-CPUArchState *cpu_copy(CPUArchState *env);
-
-/* Flags for use in ENV->INTERRUPT_PENDING.
-
- The numbers assigned here are non-sequential in order to preserve
- binary compatibility with the vmstate dump. Bit 0 (0x0001) was
- previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
- the vmstate dump. */
-
-/* External hardware interrupt pending. This is typically used for
- interrupts from devices. */
-#define CPU_INTERRUPT_HARD 0x0002
-
-/* Exit the current TB. This is typically used when some system-level device
- makes some change to the memory mapping. E.g. the a20 line change. */
-#define CPU_INTERRUPT_EXITTB 0x0004
-
-/* Halt the CPU. */
-#define CPU_INTERRUPT_HALT 0x0020
-
-/* Debug event pending. */
-#define CPU_INTERRUPT_DEBUG 0x0080
-
-/* Reset signal. */
-#define CPU_INTERRUPT_RESET 0x0400
-
-/* Several target-specific external hardware interrupts. Each target/cpu.h
- should define proper names based on these defines. */
-#define CPU_INTERRUPT_TGT_EXT_0 0x0008
-#define CPU_INTERRUPT_TGT_EXT_1 0x0010
-#define CPU_INTERRUPT_TGT_EXT_2 0x0040
-#define CPU_INTERRUPT_TGT_EXT_3 0x0200
-#define CPU_INTERRUPT_TGT_EXT_4 0x1000
-
-/* Several target-specific internal interrupts. These differ from the
- preceding target-specific interrupts in that they are intended to
- originate from within the cpu itself, typically in response to some
- instruction being executed. These, therefore, are not masked while
- single-stepping within the debugger. */
-#define CPU_INTERRUPT_TGT_INT_0 0x0100
-#define CPU_INTERRUPT_TGT_INT_1 0x0800
-#define CPU_INTERRUPT_TGT_INT_2 0x2000
-
-/* First unused bit: 0x4000. */
-
-/* The set of all bits that should be masked when single-stepping. */
-#define CPU_INTERRUPT_SSTEP_MASK \
- (CPU_INTERRUPT_HARD \
- | CPU_INTERRUPT_TGT_EXT_0 \
- | CPU_INTERRUPT_TGT_EXT_1 \
- | CPU_INTERRUPT_TGT_EXT_2 \
- | CPU_INTERRUPT_TGT_EXT_3 \
- | CPU_INTERRUPT_TGT_EXT_4)
-
-#ifdef CONFIG_USER_ONLY
-
-/*
- * Allow some level of source compatibility with softmmu. We do not
- * support any of the more exotic features, so only invalid pages may
- * be signaled by probe_access_flags().
- */
-#define TLB_INVALID_MASK (1 << (TARGET_PAGE_BITS_MIN - 1))
-#define TLB_MMIO (1 << (TARGET_PAGE_BITS_MIN - 2))
-#define TLB_WATCHPOINT 0
-
-static inline int cpu_mmu_index(CPUState *cs, bool ifetch)
-{
- return MMU_USER_IDX;
-}
-#else
-
-/*
- * Flags stored in the low bits of the TLB virtual address.
- * These are defined so that fast path ram access is all zeros.
- * The flags all must be between TARGET_PAGE_BITS and
- * maximum address alignment bit.
- *
- * Use TARGET_PAGE_BITS_MIN so that these bits are constant
- * when TARGET_PAGE_BITS_VARY is in effect.
- *
- * The count, if not the placement of these bits is known
- * to tcg/tcg-op-ldst.c, check_max_alignment().
- */
-/* Zero if TLB entry is valid. */
-#define TLB_INVALID_MASK (1 << (TARGET_PAGE_BITS_MIN - 1))
-/* Set if TLB entry references a clean RAM page. The iotlb entry will
- contain the page physical address. */
-#define TLB_NOTDIRTY (1 << (TARGET_PAGE_BITS_MIN - 2))
-/* Set if TLB entry is an IO callback. */
-#define TLB_MMIO (1 << (TARGET_PAGE_BITS_MIN - 3))
-/* Set if TLB entry writes ignored. */
-#define TLB_DISCARD_WRITE (1 << (TARGET_PAGE_BITS_MIN - 4))
-/* Set if the slow path must be used; more flags in CPUTLBEntryFull. */
-#define TLB_FORCE_SLOW (1 << (TARGET_PAGE_BITS_MIN - 5))
-
-/*
- * Use this mask to check interception with an alignment mask
- * in a TCG backend.
- */
-#define TLB_FLAGS_MASK \
- (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO \
- | TLB_FORCE_SLOW | TLB_DISCARD_WRITE)
-
-/*
- * Flags stored in CPUTLBEntryFull.slow_flags[x].
- * TLB_FORCE_SLOW must be set in CPUTLBEntry.addr_idx[x].
- */
-/* Set if TLB entry requires byte swap. */
-#define TLB_BSWAP (1 << 0)
-/* Set if TLB entry contains a watchpoint. */
-#define TLB_WATCHPOINT (1 << 1)
-/* Set if TLB entry requires aligned accesses. */
-#define TLB_CHECK_ALIGNED (1 << 2)
-
-#define TLB_SLOW_FLAGS_MASK (TLB_BSWAP | TLB_WATCHPOINT | TLB_CHECK_ALIGNED)
-
-/* The two sets of flags must not overlap. */
-QEMU_BUILD_BUG_ON(TLB_FLAGS_MASK & TLB_SLOW_FLAGS_MASK);
-
-/**
- * tlb_hit_page: return true if page aligned @addr is a hit against the
- * TLB entry @tlb_addr
- *
- * @addr: virtual address to test (must be page aligned)
- * @tlb_addr: TLB entry address (a CPUTLBEntry addr_read/write/code value)
- */
-static inline bool tlb_hit_page(uint64_t tlb_addr, vaddr addr)
-{
- return addr == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK));
-}
-
-/**
- * tlb_hit: return true if @addr is a hit against the TLB entry @tlb_addr
- *
- * @addr: virtual address to test (need not be page aligned)
- * @tlb_addr: TLB entry address (a CPUTLBEntry addr_read/write/code value)
- */
-static inline bool tlb_hit(uint64_t tlb_addr, vaddr addr)
-{
- return tlb_hit_page(tlb_addr, addr & TARGET_PAGE_MASK);
-}
-
-#endif /* !CONFIG_USER_ONLY */
-
-/* Validate correct placement of CPUArchState. */
-#include "cpu.h"
-QEMU_BUILD_BUG_ON(offsetof(ArchCPU, parent_obj) != 0);
-QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
-
-#endif /* CPU_ALL_H */
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 815342d..a684855 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -9,9 +9,7 @@
#define CPU_COMMON_H
#include "exec/vaddr.h"
-#ifndef CONFIG_USER_ONLY
#include "exec/hwaddr.h"
-#endif
#include "hw/core/cpu.h"
#include "tcg/debug-assert.h"
#include "exec/page-protection.h"
@@ -35,23 +33,17 @@ void cpu_list_lock(void);
void cpu_list_unlock(void);
unsigned int cpu_list_generation_id_get(void);
+int cpu_get_free_index(void);
+
void tcg_iommu_init_notifier_list(CPUState *cpu);
void tcg_iommu_free_notifier_list(CPUState *cpu);
-#if !defined(CONFIG_USER_ONLY)
-
enum device_endian {
DEVICE_NATIVE_ENDIAN,
DEVICE_BIG_ENDIAN,
DEVICE_LITTLE_ENDIAN,
};
-#if HOST_BIG_ENDIAN
-#define DEVICE_HOST_ENDIAN DEVICE_BIG_ENDIAN
-#else
-#define DEVICE_HOST_ENDIAN DEVICE_LITTLE_ENDIAN
-#endif
-
/* address in the RAM (different from a physical address) */
#if defined(CONFIG_XEN_BACKEND)
typedef uint64_t ram_addr_t;
@@ -65,7 +57,7 @@ typedef uintptr_t ram_addr_t;
/* memory API */
-void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
+void qemu_ram_remap(ram_addr_t addr);
/* This should not be used by devices. */
ram_addr_t qemu_ram_addr_from_host(void *ptr);
ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
@@ -129,6 +121,14 @@ size_t qemu_ram_pagesize_largest(void);
*/
void cpu_address_space_init(CPUState *cpu, int asidx,
const char *prefix, MemoryRegion *mr);
+/**
+ * cpu_address_space_destroy:
+ * @cpu: CPU for which address space needs to be destroyed
+ * @asidx: integer index of this address space
+ *
+ * Note that with KVM only one address space is supported.
+ */
+void cpu_address_space_destroy(CPUState *cpu, int asidx);
void cpu_physical_memory_rw(hwaddr addr, void *buf,
hwaddr len, bool is_write);
@@ -166,8 +166,6 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length);
int ram_block_discard_guest_memfd_range(RAMBlock *rb, uint64_t start,
size_t length);
-#endif
-
/* Returns: 0 on success, -1 on error */
int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
void *ptr, size_t len, bool is_write);
@@ -176,12 +174,7 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
void list_cpus(void);
#ifdef CONFIG_TCG
-
-bool tcg_cflags_has(CPUState *cpu, uint32_t flags);
-void tcg_cflags_set(CPUState *cpu, uint32_t flags);
-
-/* current cflags for hashing/comparison */
-uint32_t curr_cflags(CPUState *cpu);
+#include "qemu/atomic.h"
/**
* cpu_unwind_state_data:
@@ -189,7 +182,7 @@ uint32_t curr_cflags(CPUState *cpu);
* @host_pc: the host pc within the translation
* @data: output data
*
- * Attempt to load the the unwind state for a host pc occurring in
+ * Attempt to load the unwind state for a host pc occurring in
* translated code. If @host_pc is not in translated code, the
* function returns false; otherwise @data is loaded.
* This is the same unwind info as given to restore_state_to_opc.
@@ -208,6 +201,23 @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data);
*/
bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc);
+/**
+ * cpu_loop_exit_requested:
+ * @cpu: The CPU state to be tested
+ *
+ * Indicate if somebody asked for a return of the CPU to the main loop
+ * (e.g., via cpu_exit() or cpu_interrupt()).
+ *
+ * This is helpful for architectures that support interruptible
+ * instructions. After writing back all state to registers/memory, this
+ * call can be used to check if it makes sense to return to the main loop
+ * or to continue executing the interruptible instruction.
+ */
+static inline bool cpu_loop_exit_requested(CPUState *cpu)
+{
+ return (int32_t)qatomic_read(&cpu->neg.icount_decr.u32) < 0;
+}
+
G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu);
G_NORETURN void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc);
#endif /* CONFIG_TCG */
@@ -229,34 +239,25 @@ static inline ArchCPU *env_archcpu(CPUArchState *env)
}
/**
- * env_cpu(env)
+ * env_cpu_const(env)
* @env: The architecture environment
*
* Return the CPUState associated with the environment.
*/
-static inline CPUState *env_cpu(CPUArchState *env)
+static inline const CPUState *env_cpu_const(const CPUArchState *env)
{
return (void *)env - sizeof(CPUState);
}
-#ifndef CONFIG_USER_ONLY
/**
- * cpu_mmu_index:
- * @env: The cpu environment
- * @ifetch: True for code access, false for data access.
- *
- * Return the core mmu index for the current translation regime.
- * This function is used by generic TCG code paths.
+ * env_cpu(env)
+ * @env: The architecture environment
*
- * The user-only version of this function is inline in cpu-all.h,
- * where it always returns MMU_USER_IDX.
+ * Return the CPUState associated with the environment.
*/
-static inline int cpu_mmu_index(CPUState *cs, bool ifetch)
+static inline CPUState *env_cpu(CPUArchState *env)
{
- int ret = cs->cc->mmu_index(cs, ifetch);
- tcg_debug_assert(ret >= 0 && ret < NB_MMU_MODES);
- return ret;
+ return (CPUState *)env_cpu_const(env);
}
-#endif /* !CONFIG_USER_ONLY */
#endif /* CPU_COMMON_H */
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 0dbef30..e01acb7 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -23,14 +23,6 @@
#error cpu.h included from common code
#endif
-#include "qemu/host-utils.h"
-#include "qemu/thread.h"
-#ifndef CONFIG_USER_ONLY
-#include "exec/hwaddr.h"
-#endif
-#include "exec/memattrs.h"
-#include "hw/core/cpu.h"
-
#include "cpu-param.h"
#ifndef TARGET_LONG_BITS
@@ -42,42 +34,10 @@
#ifndef TARGET_VIRT_ADDR_SPACE_BITS
# error TARGET_VIRT_ADDR_SPACE_BITS must be defined in cpu-param.h
#endif
-#ifndef TARGET_PAGE_BITS
-# ifdef TARGET_PAGE_BITS_VARY
-# ifndef TARGET_PAGE_BITS_MIN
-# error TARGET_PAGE_BITS_MIN must be defined in cpu-param.h
-# endif
-# else
-# error TARGET_PAGE_BITS must be defined in cpu-param.h
-# endif
+#if !defined(TARGET_PAGE_BITS) && !defined(TARGET_PAGE_BITS_VARY)
+# error TARGET_PAGE_BITS must be defined in cpu-param.h
#endif
#include "exec/target_long.h"
-#if defined(CONFIG_SOFTMMU) && defined(CONFIG_TCG)
-#define CPU_TLB_DYN_MIN_BITS 6
-#define CPU_TLB_DYN_DEFAULT_BITS 8
-
-# if HOST_LONG_BITS == 32
-/* Make sure we do not require a double-word shift for the TLB load */
-# define CPU_TLB_DYN_MAX_BITS (32 - TARGET_PAGE_BITS)
-# else /* HOST_LONG_BITS == 64 */
-/*
- * Assuming TARGET_PAGE_BITS==12, with 2**22 entries we can cover 2**(22+12) ==
- * 2**34 == 16G of address space. This is roughly what one would expect a
- * TLB to cover in a modern (as of 2018) x86_64 CPU. For instance, Intel
- * Skylake's Level-2 STLB has 16 1G entries.
- * Also, make sure we do not size the TLB past the guest's address space.
- */
-# ifdef TARGET_PAGE_BITS_VARY
-# define CPU_TLB_DYN_MAX_BITS \
- MIN(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
-# else
-# define CPU_TLB_DYN_MAX_BITS \
- MIN_CONST(22, TARGET_VIRT_ADDR_SPACE_BITS - TARGET_PAGE_BITS)
-# endif
-# endif
-
-#endif /* CONFIG_SOFTMMU && CONFIG_TCG */
-
#endif
diff --git a/include/exec/cpu-interrupt.h b/include/exec/cpu-interrupt.h
new file mode 100644
index 0000000..4071519
--- /dev/null
+++ b/include/exec/cpu-interrupt.h
@@ -0,0 +1,70 @@
+/*
+ * Flags for use with cpu_interrupt()
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef CPU_INTERRUPT_H
+#define CPU_INTERRUPT_H
+
+/*
+ * The numbers assigned here are non-sequential in order to preserve binary
+ * compatibility with the vmstate dump. Bit 0 (0x0001) was previously used
+ * for CPU_INTERRUPT_EXIT, and is cleared when loading the vmstate dump.
+ */
+
+/*
+ * External hardware interrupt pending.
+ * This is typically used for interrupts from devices.
+ */
+#define CPU_INTERRUPT_HARD 0x0002
+
+/*
+ * Exit the current TB. This is typically used when some system-level device
+ * makes some change to the memory mapping. E.g. the a20 line change.
+ */
+#define CPU_INTERRUPT_EXITTB 0x0004
+
+/* Halt the CPU. */
+#define CPU_INTERRUPT_HALT 0x0020
+
+/* Debug event pending. */
+#define CPU_INTERRUPT_DEBUG 0x0080
+
+/* Reset signal. */
+#define CPU_INTERRUPT_RESET 0x0400
+
+/*
+ * Several target-specific external hardware interrupts. Each target/cpu.h
+ * should define proper names based on these defines.
+ */
+#define CPU_INTERRUPT_TGT_EXT_0 0x0008
+#define CPU_INTERRUPT_TGT_EXT_1 0x0010
+#define CPU_INTERRUPT_TGT_EXT_2 0x0040
+#define CPU_INTERRUPT_TGT_EXT_3 0x0200
+#define CPU_INTERRUPT_TGT_EXT_4 0x1000
+
+/*
+ * Several target-specific internal interrupts. These differ from the
+ * preceding target-specific interrupts in that they are intended to
+ * originate from within the cpu itself, typically in response to some
+ * instruction being executed. These, therefore, are not masked while
+ * single-stepping within the debugger.
+ */
+#define CPU_INTERRUPT_TGT_INT_0 0x0100
+#define CPU_INTERRUPT_TGT_INT_1 0x0800
+#define CPU_INTERRUPT_TGT_INT_2 0x2000
+
+/* First unused bit: 0x4000. */
+
+/* The set of all bits that should be masked when single-stepping. */
+#define CPU_INTERRUPT_SSTEP_MASK \
+ (CPU_INTERRUPT_HARD \
+ | CPU_INTERRUPT_TGT_EXT_0 \
+ | CPU_INTERRUPT_TGT_EXT_1 \
+ | CPU_INTERRUPT_TGT_EXT_2 \
+ | CPU_INTERRUPT_TGT_EXT_3 \
+ | CPU_INTERRUPT_TGT_EXT_4)
+
+#endif /* CPU_INTERRUPT_H */
diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h
deleted file mode 100644
index 71009f8..0000000
--- a/include/exec/cpu_ldst.h
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Software MMU support (per-target)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*
- * Generate inline load/store functions for all MMU modes (typically
- * at least _user and _kernel) as well as _data versions, for all data
- * sizes.
- *
- * Used by target op helpers.
- *
- * The syntax for the accessors is:
- *
- * load: cpu_ld{sign}{size}{end}_{mmusuffix}(env, ptr)
- * cpu_ld{sign}{size}{end}_{mmusuffix}_ra(env, ptr, retaddr)
- * cpu_ld{sign}{size}{end}_mmuidx_ra(env, ptr, mmu_idx, retaddr)
- * cpu_ld{sign}{size}{end}_mmu(env, ptr, oi, retaddr)
- *
- * store: cpu_st{size}{end}_{mmusuffix}(env, ptr, val)
- * cpu_st{size}{end}_{mmusuffix}_ra(env, ptr, val, retaddr)
- * cpu_st{size}{end}_mmuidx_ra(env, ptr, val, mmu_idx, retaddr)
- * cpu_st{size}{end}_mmu(env, ptr, val, oi, retaddr)
- *
- * sign is:
- * (empty): for 32 and 64 bit sizes
- * u : unsigned
- * s : signed
- *
- * size is:
- * b: 8 bits
- * w: 16 bits
- * l: 32 bits
- * q: 64 bits
- *
- * end is:
- * (empty): for target native endian, or for 8 bit access
- * _be: for forced big endian
- * _le: for forced little endian
- *
- * mmusuffix is one of the generic suffixes "data" or "code", or "mmuidx".
- * The "mmuidx" suffix carries an extra mmu_idx argument that specifies
- * the index to use; the "data" and "code" suffixes take the index from
- * cpu_mmu_index().
- *
- * The "mmu" suffix carries the full MemOpIdx, with both mmu_idx and the
- * MemOp including alignment requirements. The alignment will be enforced.
- */
-#ifndef CPU_LDST_H
-#define CPU_LDST_H
-
-#ifndef CONFIG_TCG
-#error Can only include this header with TCG
-#endif
-
-#include "exec/memopidx.h"
-#include "exec/abi_ptr.h"
-#include "exec/mmu-access-type.h"
-#include "qemu/int128.h"
-
-#if defined(CONFIG_USER_ONLY)
-
-#include "user/guest-base.h"
-
-#ifndef TARGET_TAGGED_ADDRESSES
-static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x)
-{
- return x;
-}
-#endif
-
-/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
-static inline void *g2h_untagged(abi_ptr x)
-{
- return (void *)((uintptr_t)(x) + guest_base);
-}
-
-static inline void *g2h(CPUState *cs, abi_ptr x)
-{
- return g2h_untagged(cpu_untagged_addr(cs, x));
-}
-
-static inline bool guest_addr_valid_untagged(abi_ulong x)
-{
- return x <= GUEST_ADDR_MAX;
-}
-
-static inline bool guest_range_valid_untagged(abi_ulong start, abi_ulong len)
-{
- return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1;
-}
-
-#define h2g_valid(x) \
- (HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \
- (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX)
-
-#define h2g_nocheck(x) ({ \
- uintptr_t __ret = (uintptr_t)(x) - guest_base; \
- (abi_ptr)__ret; \
-})
-
-#define h2g(x) ({ \
- /* Check if given address fits target address space */ \
- assert(h2g_valid(x)); \
- h2g_nocheck(x); \
-})
-
-#endif /* CONFIG_USER_ONLY */
-
-uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr);
-int cpu_ldsb_data(CPUArchState *env, abi_ptr ptr);
-uint32_t cpu_lduw_be_data(CPUArchState *env, abi_ptr ptr);
-int cpu_ldsw_be_data(CPUArchState *env, abi_ptr ptr);
-uint32_t cpu_ldl_be_data(CPUArchState *env, abi_ptr ptr);
-uint64_t cpu_ldq_be_data(CPUArchState *env, abi_ptr ptr);
-uint32_t cpu_lduw_le_data(CPUArchState *env, abi_ptr ptr);
-int cpu_ldsw_le_data(CPUArchState *env, abi_ptr ptr);
-uint32_t cpu_ldl_le_data(CPUArchState *env, abi_ptr ptr);
-uint64_t cpu_ldq_le_data(CPUArchState *env, abi_ptr ptr);
-
-uint32_t cpu_ldub_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-int cpu_ldsb_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-uint32_t cpu_lduw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-int cpu_ldsw_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-uint32_t cpu_ldl_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-uint64_t cpu_ldq_be_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-uint32_t cpu_lduw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-int cpu_ldsw_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-uint32_t cpu_ldl_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-uint64_t cpu_ldq_le_data_ra(CPUArchState *env, abi_ptr ptr, uintptr_t ra);
-
-void cpu_stb_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
-void cpu_stw_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
-void cpu_stl_be_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
-void cpu_stq_be_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
-void cpu_stw_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
-void cpu_stl_le_data(CPUArchState *env, abi_ptr ptr, uint32_t val);
-void cpu_stq_le_data(CPUArchState *env, abi_ptr ptr, uint64_t val);
-
-void cpu_stb_data_ra(CPUArchState *env, abi_ptr ptr,
- uint32_t val, uintptr_t ra);
-void cpu_stw_be_data_ra(CPUArchState *env, abi_ptr ptr,
- uint32_t val, uintptr_t ra);
-void cpu_stl_be_data_ra(CPUArchState *env, abi_ptr ptr,
- uint32_t val, uintptr_t ra);
-void cpu_stq_be_data_ra(CPUArchState *env, abi_ptr ptr,
- uint64_t val, uintptr_t ra);
-void cpu_stw_le_data_ra(CPUArchState *env, abi_ptr ptr,
- uint32_t val, uintptr_t ra);
-void cpu_stl_le_data_ra(CPUArchState *env, abi_ptr ptr,
- uint32_t val, uintptr_t ra);
-void cpu_stq_le_data_ra(CPUArchState *env, abi_ptr ptr,
- uint64_t val, uintptr_t ra);
-
-uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-uint32_t cpu_lduw_be_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-int cpu_ldsw_be_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-uint32_t cpu_ldl_be_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-uint64_t cpu_ldq_be_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-uint32_t cpu_lduw_le_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-int cpu_ldsw_le_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-uint32_t cpu_ldl_le_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-uint64_t cpu_ldq_le_mmuidx_ra(CPUArchState *env, abi_ptr ptr,
- int mmu_idx, uintptr_t ra);
-
-void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr ptr, uint32_t val,
- int mmu_idx, uintptr_t ra);
-void cpu_stw_be_mmuidx_ra(CPUArchState *env, abi_ptr ptr, uint32_t val,
- int mmu_idx, uintptr_t ra);
-void cpu_stl_be_mmuidx_ra(CPUArchState *env, abi_ptr ptr, uint32_t val,
- int mmu_idx, uintptr_t ra);
-void cpu_stq_be_mmuidx_ra(CPUArchState *env, abi_ptr ptr, uint64_t val,
- int mmu_idx, uintptr_t ra);
-void cpu_stw_le_mmuidx_ra(CPUArchState *env, abi_ptr ptr, uint32_t val,
- int mmu_idx, uintptr_t ra);
-void cpu_stl_le_mmuidx_ra(CPUArchState *env, abi_ptr ptr, uint32_t val,
- int mmu_idx, uintptr_t ra);
-void cpu_stq_le_mmuidx_ra(CPUArchState *env, abi_ptr ptr, uint64_t val,
- int mmu_idx, uintptr_t ra);
-
-uint8_t cpu_ldb_mmu(CPUArchState *env, abi_ptr ptr, MemOpIdx oi, uintptr_t ra);
-uint16_t cpu_ldw_mmu(CPUArchState *env, abi_ptr ptr, MemOpIdx oi, uintptr_t ra);
-uint32_t cpu_ldl_mmu(CPUArchState *env, abi_ptr ptr, MemOpIdx oi, uintptr_t ra);
-uint64_t cpu_ldq_mmu(CPUArchState *env, abi_ptr ptr, MemOpIdx oi, uintptr_t ra);
-Int128 cpu_ld16_mmu(CPUArchState *env, abi_ptr addr, MemOpIdx oi, uintptr_t ra);
-
-void cpu_stb_mmu(CPUArchState *env, abi_ptr ptr, uint8_t val,
- MemOpIdx oi, uintptr_t ra);
-void cpu_stw_mmu(CPUArchState *env, abi_ptr ptr, uint16_t val,
- MemOpIdx oi, uintptr_t ra);
-void cpu_stl_mmu(CPUArchState *env, abi_ptr ptr, uint32_t val,
- MemOpIdx oi, uintptr_t ra);
-void cpu_stq_mmu(CPUArchState *env, abi_ptr ptr, uint64_t val,
- MemOpIdx oi, uintptr_t ra);
-void cpu_st16_mmu(CPUArchState *env, abi_ptr addr, Int128 val,
- MemOpIdx oi, uintptr_t ra);
-
-uint32_t cpu_atomic_cmpxchgb_mmu(CPUArchState *env, abi_ptr addr,
- uint32_t cmpv, uint32_t newv,
- MemOpIdx oi, uintptr_t retaddr);
-uint32_t cpu_atomic_cmpxchgw_le_mmu(CPUArchState *env, abi_ptr addr,
- uint32_t cmpv, uint32_t newv,
- MemOpIdx oi, uintptr_t retaddr);
-uint32_t cpu_atomic_cmpxchgl_le_mmu(CPUArchState *env, abi_ptr addr,
- uint32_t cmpv, uint32_t newv,
- MemOpIdx oi, uintptr_t retaddr);
-uint64_t cpu_atomic_cmpxchgq_le_mmu(CPUArchState *env, abi_ptr addr,
- uint64_t cmpv, uint64_t newv,
- MemOpIdx oi, uintptr_t retaddr);
-uint32_t cpu_atomic_cmpxchgw_be_mmu(CPUArchState *env, abi_ptr addr,
- uint32_t cmpv, uint32_t newv,
- MemOpIdx oi, uintptr_t retaddr);
-uint32_t cpu_atomic_cmpxchgl_be_mmu(CPUArchState *env, abi_ptr addr,
- uint32_t cmpv, uint32_t newv,
- MemOpIdx oi, uintptr_t retaddr);
-uint64_t cpu_atomic_cmpxchgq_be_mmu(CPUArchState *env, abi_ptr addr,
- uint64_t cmpv, uint64_t newv,
- MemOpIdx oi, uintptr_t retaddr);
-
-#define GEN_ATOMIC_HELPER(NAME, TYPE, SUFFIX) \
-TYPE cpu_atomic_ ## NAME ## SUFFIX ## _mmu \
- (CPUArchState *env, abi_ptr addr, TYPE val, \
- MemOpIdx oi, uintptr_t retaddr);
-
-#ifdef CONFIG_ATOMIC64
-#define GEN_ATOMIC_HELPER_ALL(NAME) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, l_be) \
- GEN_ATOMIC_HELPER(NAME, uint64_t, q_le) \
- GEN_ATOMIC_HELPER(NAME, uint64_t, q_be)
-#else
-#define GEN_ATOMIC_HELPER_ALL(NAME) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, b) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, w_le) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, w_be) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, l_le) \
- GEN_ATOMIC_HELPER(NAME, uint32_t, l_be)
-#endif
-
-GEN_ATOMIC_HELPER_ALL(fetch_add)
-GEN_ATOMIC_HELPER_ALL(fetch_sub)
-GEN_ATOMIC_HELPER_ALL(fetch_and)
-GEN_ATOMIC_HELPER_ALL(fetch_or)
-GEN_ATOMIC_HELPER_ALL(fetch_xor)
-GEN_ATOMIC_HELPER_ALL(fetch_smin)
-GEN_ATOMIC_HELPER_ALL(fetch_umin)
-GEN_ATOMIC_HELPER_ALL(fetch_smax)
-GEN_ATOMIC_HELPER_ALL(fetch_umax)
-
-GEN_ATOMIC_HELPER_ALL(add_fetch)
-GEN_ATOMIC_HELPER_ALL(sub_fetch)
-GEN_ATOMIC_HELPER_ALL(and_fetch)
-GEN_ATOMIC_HELPER_ALL(or_fetch)
-GEN_ATOMIC_HELPER_ALL(xor_fetch)
-GEN_ATOMIC_HELPER_ALL(smin_fetch)
-GEN_ATOMIC_HELPER_ALL(umin_fetch)
-GEN_ATOMIC_HELPER_ALL(smax_fetch)
-GEN_ATOMIC_HELPER_ALL(umax_fetch)
-
-GEN_ATOMIC_HELPER_ALL(xchg)
-
-#undef GEN_ATOMIC_HELPER_ALL
-#undef GEN_ATOMIC_HELPER
-
-Int128 cpu_atomic_cmpxchgo_le_mmu(CPUArchState *env, abi_ptr addr,
- Int128 cmpv, Int128 newv,
- MemOpIdx oi, uintptr_t retaddr);
-Int128 cpu_atomic_cmpxchgo_be_mmu(CPUArchState *env, abi_ptr addr,
- Int128 cmpv, Int128 newv,
- MemOpIdx oi, uintptr_t retaddr);
-
-#if TARGET_BIG_ENDIAN
-# define cpu_lduw_data cpu_lduw_be_data
-# define cpu_ldsw_data cpu_ldsw_be_data
-# define cpu_ldl_data cpu_ldl_be_data
-# define cpu_ldq_data cpu_ldq_be_data
-# define cpu_lduw_data_ra cpu_lduw_be_data_ra
-# define cpu_ldsw_data_ra cpu_ldsw_be_data_ra
-# define cpu_ldl_data_ra cpu_ldl_be_data_ra
-# define cpu_ldq_data_ra cpu_ldq_be_data_ra
-# define cpu_lduw_mmuidx_ra cpu_lduw_be_mmuidx_ra
-# define cpu_ldsw_mmuidx_ra cpu_ldsw_be_mmuidx_ra
-# define cpu_ldl_mmuidx_ra cpu_ldl_be_mmuidx_ra
-# define cpu_ldq_mmuidx_ra cpu_ldq_be_mmuidx_ra
-# define cpu_stw_data cpu_stw_be_data
-# define cpu_stl_data cpu_stl_be_data
-# define cpu_stq_data cpu_stq_be_data
-# define cpu_stw_data_ra cpu_stw_be_data_ra
-# define cpu_stl_data_ra cpu_stl_be_data_ra
-# define cpu_stq_data_ra cpu_stq_be_data_ra
-# define cpu_stw_mmuidx_ra cpu_stw_be_mmuidx_ra
-# define cpu_stl_mmuidx_ra cpu_stl_be_mmuidx_ra
-# define cpu_stq_mmuidx_ra cpu_stq_be_mmuidx_ra
-#else
-# define cpu_lduw_data cpu_lduw_le_data
-# define cpu_ldsw_data cpu_ldsw_le_data
-# define cpu_ldl_data cpu_ldl_le_data
-# define cpu_ldq_data cpu_ldq_le_data
-# define cpu_lduw_data_ra cpu_lduw_le_data_ra
-# define cpu_ldsw_data_ra cpu_ldsw_le_data_ra
-# define cpu_ldl_data_ra cpu_ldl_le_data_ra
-# define cpu_ldq_data_ra cpu_ldq_le_data_ra
-# define cpu_lduw_mmuidx_ra cpu_lduw_le_mmuidx_ra
-# define cpu_ldsw_mmuidx_ra cpu_ldsw_le_mmuidx_ra
-# define cpu_ldl_mmuidx_ra cpu_ldl_le_mmuidx_ra
-# define cpu_ldq_mmuidx_ra cpu_ldq_le_mmuidx_ra
-# define cpu_stw_data cpu_stw_le_data
-# define cpu_stl_data cpu_stl_le_data
-# define cpu_stq_data cpu_stq_le_data
-# define cpu_stw_data_ra cpu_stw_le_data_ra
-# define cpu_stl_data_ra cpu_stl_le_data_ra
-# define cpu_stq_data_ra cpu_stq_le_data_ra
-# define cpu_stw_mmuidx_ra cpu_stw_le_mmuidx_ra
-# define cpu_stl_mmuidx_ra cpu_stl_le_mmuidx_ra
-# define cpu_stq_mmuidx_ra cpu_stq_le_mmuidx_ra
-#endif
-
-uint8_t cpu_ldb_code_mmu(CPUArchState *env, abi_ptr addr,
- MemOpIdx oi, uintptr_t ra);
-uint16_t cpu_ldw_code_mmu(CPUArchState *env, abi_ptr addr,
- MemOpIdx oi, uintptr_t ra);
-uint32_t cpu_ldl_code_mmu(CPUArchState *env, abi_ptr addr,
- MemOpIdx oi, uintptr_t ra);
-uint64_t cpu_ldq_code_mmu(CPUArchState *env, abi_ptr addr,
- MemOpIdx oi, uintptr_t ra);
-
-uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr);
-uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr);
-uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr);
-uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr);
-
-/**
- * tlb_vaddr_to_host:
- * @env: CPUArchState
- * @addr: guest virtual address to look up
- * @access_type: 0 for read, 1 for write, 2 for execute
- * @mmu_idx: MMU index to use for lookup
- *
- * Look up the specified guest virtual index in the TCG softmmu TLB.
- * If we can translate a host virtual address suitable for direct RAM
- * access, without causing a guest exception, then return it.
- * Otherwise (TLB entry is for an I/O access, guest software
- * TLB fill required, etc) return NULL.
- */
-#ifdef CONFIG_USER_ONLY
-static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
- MMUAccessType access_type, int mmu_idx)
-{
- return g2h(env_cpu(env), addr);
-}
-#else
-void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
- MMUAccessType access_type, int mmu_idx);
-#endif
-
-#endif /* CPU_LDST_H */
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h
index ef18642..03ed7e2 100644
--- a/include/exec/cputlb.h
+++ b/include/exec/cputlb.h
@@ -21,15 +21,266 @@
#define CPUTLB_H
#include "exec/cpu-common.h"
+#include "exec/hwaddr.h"
+#include "exec/memattrs.h"
+#include "exec/vaddr.h"
-#ifdef CONFIG_TCG
-
-#if !defined(CONFIG_USER_ONLY)
-/* cputlb.c */
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
void tlb_protect_code(ram_addr_t ram_addr);
void tlb_unprotect_code(ram_addr_t ram_addr);
#endif
-#endif /* CONFIG_TCG */
-
+#ifndef CONFIG_USER_ONLY
+void tlb_reset_dirty(CPUState *cpu, uintptr_t start, uintptr_t length);
+void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length);
#endif
+
+/**
+ * tlb_set_page_full:
+ * @cpu: CPU context
+ * @mmu_idx: mmu index of the tlb to modify
+ * @addr: virtual address of the entry to add
+ * @full: the details of the tlb entry
+ *
+ * Add an entry to @cpu tlb index @mmu_idx. All of the fields of
+ * @full must be filled, except for xlat_section, and constitute
+ * the complete description of the translated page.
+ *
+ * This is generally called by the target tlb_fill function after
+ * having performed a successful page table walk to find the physical
+ * address and attributes for the translation.
+ *
+ * At most one entry for a given virtual address is permitted. Only a
+ * single TARGET_PAGE_SIZE region is mapped; @full->lg_page_size is only
+ * used by tlb_flush_page.
+ */
+void tlb_set_page_full(CPUState *cpu, int mmu_idx, vaddr addr,
+ CPUTLBEntryFull *full);
+
+/**
+ * tlb_set_page_with_attrs:
+ * @cpu: CPU to add this TLB entry for
+ * @addr: virtual address of page to add entry for
+ * @paddr: physical address of the page
+ * @attrs: memory transaction attributes
+ * @prot: access permissions (PAGE_READ/PAGE_WRITE/PAGE_EXEC bits)
+ * @mmu_idx: MMU index to insert TLB entry for
+ * @size: size of the page in bytes
+ *
+ * Add an entry to this CPU's TLB (a mapping from virtual address
+ * @addr to physical address @paddr) with the specified memory
+ * transaction attributes. This is generally called by the target CPU
+ * specific code after it has been called through the tlb_fill()
+ * entry point and performed a successful page table walk to find
+ * the physical address and attributes for the virtual address
+ * which provoked the TLB miss.
+ *
+ * At most one entry for a given virtual address is permitted. Only a
+ * single TARGET_PAGE_SIZE region is mapped; the supplied @size is only
+ * used by tlb_flush_page.
+ */
+void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
+ hwaddr paddr, MemTxAttrs attrs,
+ int prot, int mmu_idx, vaddr size);
+
+/**
+ * tlb_set_page:
+ *
+ * This function is equivalent to calling tlb_set_page_with_attrs()
+ * with an @attrs argument of MEMTXATTRS_UNSPECIFIED. It's provided
+ * as a convenience for CPUs which don't use memory transaction attributes.
+ */
+void tlb_set_page(CPUState *cpu, vaddr addr,
+ hwaddr paddr, int prot,
+ int mmu_idx, vaddr size);
+
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
+/**
+ * tlb_flush_page:
+ * @cpu: CPU whose TLB should be flushed
+ * @addr: virtual address of page to be flushed
+ *
+ * Flush one page from the TLB of the specified CPU, for all
+ * MMU indexes.
+ */
+void tlb_flush_page(CPUState *cpu, vaddr addr);
+
+/**
+ * tlb_flush_page_all_cpus_synced:
+ * @cpu: src CPU of the flush
+ * @addr: virtual address of page to be flushed
+ *
+ * Flush one page from the TLB of all CPUs, for all
+ * MMU indexes.
+ *
+ * When this function returns, no CPUs will subsequently perform
+ * translations using the flushed TLBs.
+ */
+void tlb_flush_page_all_cpus_synced(CPUState *src, vaddr addr);
+
+/**
+ * tlb_flush:
+ * @cpu: CPU whose TLB should be flushed
+ *
+ * Flush the entire TLB for the specified CPU. Most CPU architectures
+ * allow the implementation to drop entries from the TLB at any time
+ * so this is generally safe. If more selective flushing is required
+ * use one of the other functions for efficiency.
+ */
+void tlb_flush(CPUState *cpu);
+
+/**
+ * tlb_flush_all_cpus_synced:
+ * @cpu: src CPU of the flush
+ *
+ * Flush the entire TLB for all CPUs, for all MMU indexes.
+ *
+ * When this function returns, no CPUs will subsequently perform
+ * translations using the flushed TLBs.
+ */
+void tlb_flush_all_cpus_synced(CPUState *src_cpu);
+
+/**
+ * tlb_flush_page_by_mmuidx:
+ * @cpu: CPU whose TLB should be flushed
+ * @addr: virtual address of page to be flushed
+ * @idxmap: bitmap of MMU indexes to flush
+ *
+ * Flush one page from the TLB of the specified CPU, for the specified
+ * MMU indexes.
+ */
+void tlb_flush_page_by_mmuidx(CPUState *cpu, vaddr addr,
+ uint16_t idxmap);
+
+/**
+ * tlb_flush_page_by_mmuidx_all_cpus_synced:
+ * @cpu: Originating CPU of the flush
+ * @addr: virtual address of page to be flushed
+ * @idxmap: bitmap of MMU indexes to flush
+ *
+ * Flush one page from the TLB of all CPUs, for the specified
+ * MMU indexes.
+ *
+ * When this function returns, no CPUs will subsequently perform
+ * translations using the flushed TLBs.
+ */
+void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *cpu, vaddr addr,
+ uint16_t idxmap);
+
+/**
+ * tlb_flush_by_mmuidx:
+ * @cpu: CPU whose TLB should be flushed
+ * @wait: If true ensure synchronisation by exiting the cpu_loop
+ * @idxmap: bitmap of MMU indexes to flush
+ *
+ * Flush all entries from the TLB of the specified CPU, for the specified
+ * MMU indexes.
+ */
+void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap);
+
+/**
+ * tlb_flush_by_mmuidx_all_cpus_synced:
+ * @cpu: Originating CPU of the flush
+ * @idxmap: bitmap of MMU indexes to flush
+ *
+ * Flush all entries from the TLB of all CPUs, for the specified
+ * MMU indexes.
+ *
+ * When this function returns, no CPUs will subsequently perform
+ * translations using the flushed TLBs.
+ */
+void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, uint16_t idxmap);
+
+/**
+ * tlb_flush_page_bits_by_mmuidx
+ * @cpu: CPU whose TLB should be flushed
+ * @addr: virtual address of page to be flushed
+ * @idxmap: bitmap of mmu indexes to flush
+ * @bits: number of significant bits in address
+ *
+ * Similar to tlb_flush_page_mask, but with a bitmap of indexes.
+ */
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, vaddr addr,
+ uint16_t idxmap, unsigned bits);
+
+/* Similarly, with broadcast and syncing. */
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *cpu, vaddr addr,
+ uint16_t idxmap,
+ unsigned bits);
+
+/**
+ * tlb_flush_range_by_mmuidx
+ * @cpu: CPU whose TLB should be flushed
+ * @addr: virtual address of the start of the range to be flushed
+ * @len: length of range to be flushed
+ * @idxmap: bitmap of mmu indexes to flush
+ * @bits: number of significant bits in address
+ *
+ * For each mmuidx in @idxmap, flush all pages within [@addr,@addr+@len),
+ * comparing only the low @bits worth of each virtual page.
+ */
+void tlb_flush_range_by_mmuidx(CPUState *cpu, vaddr addr,
+ vaddr len, uint16_t idxmap,
+ unsigned bits);
+
+/* Similarly, with broadcast and syncing. */
+void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
+ vaddr addr,
+ vaddr len,
+ uint16_t idxmap,
+ unsigned bits);
+#else
+static inline void tlb_flush_page(CPUState *cpu, vaddr addr)
+{
+}
+static inline void tlb_flush_page_all_cpus_synced(CPUState *src, vaddr addr)
+{
+}
+static inline void tlb_flush(CPUState *cpu)
+{
+}
+static inline void tlb_flush_all_cpus_synced(CPUState *src_cpu)
+{
+}
+static inline void tlb_flush_page_by_mmuidx(CPUState *cpu,
+ vaddr addr, uint16_t idxmap)
+{
+}
+
+static inline void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap)
+{
+}
+static inline void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *cpu,
+ vaddr addr,
+ uint16_t idxmap)
+{
+}
+static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
+ uint16_t idxmap)
+{
+}
+static inline void tlb_flush_page_bits_by_mmuidx(CPUState *cpu,
+ vaddr addr,
+ uint16_t idxmap,
+ unsigned bits)
+{
+}
+static inline void
+tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *cpu, vaddr addr,
+ uint16_t idxmap, unsigned bits)
+{
+}
+static inline void tlb_flush_range_by_mmuidx(CPUState *cpu, vaddr addr,
+ vaddr len, uint16_t idxmap,
+ unsigned bits)
+{
+}
+static inline void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
+ vaddr addr,
+ vaddr len,
+ uint16_t idxmap,
+ unsigned bits)
+{
+}
+#endif /* CONFIG_TCG && !CONFIG_USER_ONLY */
+#endif /* CPUTLB_H */
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
deleted file mode 100644
index b6b46ad..0000000
--- a/include/exec/exec-all.h
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * internal execution defines for qemu
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef EXEC_ALL_H
-#define EXEC_ALL_H
-
-#include "cpu.h"
-#if defined(CONFIG_USER_ONLY)
-#include "exec/abi_ptr.h"
-#include "exec/cpu_ldst.h"
-#endif
-#include "exec/mmu-access-type.h"
-#include "exec/translation-block.h"
-#include "qemu/clang-tsa.h"
-
-/**
- * cpu_loop_exit_requested:
- * @cpu: The CPU state to be tested
- *
- * Indicate if somebody asked for a return of the CPU to the main loop
- * (e.g., via cpu_exit() or cpu_interrupt()).
- *
- * This is helpful for architectures that support interruptible
- * instructions. After writing back all state to registers/memory, this
- * call can be used to check if it makes sense to return to the main loop
- * or to continue executing the interruptible instruction.
- */
-static inline bool cpu_loop_exit_requested(CPUState *cpu)
-{
- return (int32_t)qatomic_read(&cpu->neg.icount_decr.u32) < 0;
-}
-
-#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
-/* cputlb.c */
-/**
- * tlb_init - initialize a CPU's TLB
- * @cpu: CPU whose TLB should be initialized
- */
-void tlb_init(CPUState *cpu);
-/**
- * tlb_destroy - destroy a CPU's TLB
- * @cpu: CPU whose TLB should be destroyed
- */
-void tlb_destroy(CPUState *cpu);
-/**
- * tlb_flush_page:
- * @cpu: CPU whose TLB should be flushed
- * @addr: virtual address of page to be flushed
- *
- * Flush one page from the TLB of the specified CPU, for all
- * MMU indexes.
- */
-void tlb_flush_page(CPUState *cpu, vaddr addr);
-/**
- * tlb_flush_page_all_cpus_synced:
- * @cpu: src CPU of the flush
- * @addr: virtual address of page to be flushed
- *
- * Flush one page from the TLB of all CPUs, for all
- * MMU indexes.
- *
- * When this function returns, no CPUs will subsequently perform
- * translations using the flushed TLBs.
- */
-void tlb_flush_page_all_cpus_synced(CPUState *src, vaddr addr);
-/**
- * tlb_flush:
- * @cpu: CPU whose TLB should be flushed
- *
- * Flush the entire TLB for the specified CPU. Most CPU architectures
- * allow the implementation to drop entries from the TLB at any time
- * so this is generally safe. If more selective flushing is required
- * use one of the other functions for efficiency.
- */
-void tlb_flush(CPUState *cpu);
-/**
- * tlb_flush_all_cpus_synced:
- * @cpu: src CPU of the flush
- *
- * Flush the entire TLB for all CPUs, for all MMU indexes.
- *
- * When this function returns, no CPUs will subsequently perform
- * translations using the flushed TLBs.
- */
-void tlb_flush_all_cpus_synced(CPUState *src_cpu);
-/**
- * tlb_flush_page_by_mmuidx:
- * @cpu: CPU whose TLB should be flushed
- * @addr: virtual address of page to be flushed
- * @idxmap: bitmap of MMU indexes to flush
- *
- * Flush one page from the TLB of the specified CPU, for the specified
- * MMU indexes.
- */
-void tlb_flush_page_by_mmuidx(CPUState *cpu, vaddr addr,
- uint16_t idxmap);
-/**
- * tlb_flush_page_by_mmuidx_all_cpus_synced:
- * @cpu: Originating CPU of the flush
- * @addr: virtual address of page to be flushed
- * @idxmap: bitmap of MMU indexes to flush
- *
- * Flush one page from the TLB of all CPUs, for the specified
- * MMU indexes.
- *
- * When this function returns, no CPUs will subsequently perform
- * translations using the flushed TLBs.
- */
-void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *cpu, vaddr addr,
- uint16_t idxmap);
-/**
- * tlb_flush_by_mmuidx:
- * @cpu: CPU whose TLB should be flushed
- * @wait: If true ensure synchronisation by exiting the cpu_loop
- * @idxmap: bitmap of MMU indexes to flush
- *
- * Flush all entries from the TLB of the specified CPU, for the specified
- * MMU indexes.
- */
-void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap);
-/**
- * tlb_flush_by_mmuidx_all_cpus_synced:
- * @cpu: Originating CPU of the flush
- * @idxmap: bitmap of MMU indexes to flush
- *
- * Flush all entries from the TLB of all CPUs, for the specified
- * MMU indexes.
- *
- * When this function returns, no CPUs will subsequently perform
- * translations using the flushed TLBs.
- */
-void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu, uint16_t idxmap);
-
-/**
- * tlb_flush_page_bits_by_mmuidx
- * @cpu: CPU whose TLB should be flushed
- * @addr: virtual address of page to be flushed
- * @idxmap: bitmap of mmu indexes to flush
- * @bits: number of significant bits in address
- *
- * Similar to tlb_flush_page_mask, but with a bitmap of indexes.
- */
-void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, vaddr addr,
- uint16_t idxmap, unsigned bits);
-
-/* Similarly, with broadcast and syncing. */
-void tlb_flush_page_bits_by_mmuidx_all_cpus_synced
- (CPUState *cpu, vaddr addr, uint16_t idxmap, unsigned bits);
-
-/**
- * tlb_flush_range_by_mmuidx
- * @cpu: CPU whose TLB should be flushed
- * @addr: virtual address of the start of the range to be flushed
- * @len: length of range to be flushed
- * @idxmap: bitmap of mmu indexes to flush
- * @bits: number of significant bits in address
- *
- * For each mmuidx in @idxmap, flush all pages within [@addr,@addr+@len),
- * comparing only the low @bits worth of each virtual page.
- */
-void tlb_flush_range_by_mmuidx(CPUState *cpu, vaddr addr,
- vaddr len, uint16_t idxmap,
- unsigned bits);
-
-/* Similarly, with broadcast and syncing. */
-void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
- vaddr addr,
- vaddr len,
- uint16_t idxmap,
- unsigned bits);
-
-/**
- * tlb_set_page_full:
- * @cpu: CPU context
- * @mmu_idx: mmu index of the tlb to modify
- * @addr: virtual address of the entry to add
- * @full: the details of the tlb entry
- *
- * Add an entry to @cpu tlb index @mmu_idx. All of the fields of
- * @full must be filled, except for xlat_section, and constitute
- * the complete description of the translated page.
- *
- * This is generally called by the target tlb_fill function after
- * having performed a successful page table walk to find the physical
- * address and attributes for the translation.
- *
- * At most one entry for a given virtual address is permitted. Only a
- * single TARGET_PAGE_SIZE region is mapped; @full->lg_page_size is only
- * used by tlb_flush_page.
- */
-void tlb_set_page_full(CPUState *cpu, int mmu_idx, vaddr addr,
- CPUTLBEntryFull *full);
-
-/**
- * tlb_set_page_with_attrs:
- * @cpu: CPU to add this TLB entry for
- * @addr: virtual address of page to add entry for
- * @paddr: physical address of the page
- * @attrs: memory transaction attributes
- * @prot: access permissions (PAGE_READ/PAGE_WRITE/PAGE_EXEC bits)
- * @mmu_idx: MMU index to insert TLB entry for
- * @size: size of the page in bytes
- *
- * Add an entry to this CPU's TLB (a mapping from virtual address
- * @addr to physical address @paddr) with the specified memory
- * transaction attributes. This is generally called by the target CPU
- * specific code after it has been called through the tlb_fill()
- * entry point and performed a successful page table walk to find
- * the physical address and attributes for the virtual address
- * which provoked the TLB miss.
- *
- * At most one entry for a given virtual address is permitted. Only a
- * single TARGET_PAGE_SIZE region is mapped; the supplied @size is only
- * used by tlb_flush_page.
- */
-void tlb_set_page_with_attrs(CPUState *cpu, vaddr addr,
- hwaddr paddr, MemTxAttrs attrs,
- int prot, int mmu_idx, vaddr size);
-/* tlb_set_page:
- *
- * This function is equivalent to calling tlb_set_page_with_attrs()
- * with an @attrs argument of MEMTXATTRS_UNSPECIFIED. It's provided
- * as a convenience for CPUs which don't use memory transaction attributes.
- */
-void tlb_set_page(CPUState *cpu, vaddr addr,
- hwaddr paddr, int prot,
- int mmu_idx, vaddr size);
-#else
-static inline void tlb_init(CPUState *cpu)
-{
-}
-static inline void tlb_destroy(CPUState *cpu)
-{
-}
-static inline void tlb_flush_page(CPUState *cpu, vaddr addr)
-{
-}
-static inline void tlb_flush_page_all_cpus_synced(CPUState *src, vaddr addr)
-{
-}
-static inline void tlb_flush(CPUState *cpu)
-{
-}
-static inline void tlb_flush_all_cpus_synced(CPUState *src_cpu)
-{
-}
-static inline void tlb_flush_page_by_mmuidx(CPUState *cpu,
- vaddr addr, uint16_t idxmap)
-{
-}
-
-static inline void tlb_flush_by_mmuidx(CPUState *cpu, uint16_t idxmap)
-{
-}
-static inline void tlb_flush_page_by_mmuidx_all_cpus_synced(CPUState *cpu,
- vaddr addr,
- uint16_t idxmap)
-{
-}
-static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
- uint16_t idxmap)
-{
-}
-static inline void tlb_flush_page_bits_by_mmuidx(CPUState *cpu,
- vaddr addr,
- uint16_t idxmap,
- unsigned bits)
-{
-}
-static inline void
-tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *cpu, vaddr addr,
- uint16_t idxmap, unsigned bits)
-{
-}
-static inline void tlb_flush_range_by_mmuidx(CPUState *cpu, vaddr addr,
- vaddr len, uint16_t idxmap,
- unsigned bits)
-{
-}
-static inline void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
- vaddr addr,
- vaddr len,
- uint16_t idxmap,
- unsigned bits)
-{
-}
-#endif
-/**
- * probe_access:
- * @env: CPUArchState
- * @addr: guest virtual address to look up
- * @size: size of the access
- * @access_type: read, write or execute permission
- * @mmu_idx: MMU index to use for lookup
- * @retaddr: return address for unwinding
- *
- * Look up the guest virtual address @addr. Raise an exception if the
- * page does not satisfy @access_type. Raise an exception if the
- * access (@addr, @size) hits a watchpoint. For writes, mark a clean
- * page as dirty.
- *
- * Finally, return the host address for a page that is backed by RAM,
- * or NULL if the page requires I/O.
- */
-void *probe_access(CPUArchState *env, vaddr addr, int size,
- MMUAccessType access_type, int mmu_idx, uintptr_t retaddr);
-
-static inline void *probe_write(CPUArchState *env, vaddr addr, int size,
- int mmu_idx, uintptr_t retaddr)
-{
- return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
-}
-
-static inline void *probe_read(CPUArchState *env, vaddr addr, int size,
- int mmu_idx, uintptr_t retaddr)
-{
- return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
-}
-
-/**
- * probe_access_flags:
- * @env: CPUArchState
- * @addr: guest virtual address to look up
- * @size: size of the access
- * @access_type: read, write or execute permission
- * @mmu_idx: MMU index to use for lookup
- * @nonfault: suppress the fault
- * @phost: return value for host address
- * @retaddr: return address for unwinding
- *
- * Similar to probe_access, loosely returning the TLB_FLAGS_MASK for
- * the page, and storing the host address for RAM in @phost.
- *
- * If @nonfault is set, do not raise an exception but return TLB_INVALID_MASK.
- * Do not handle watchpoints, but include TLB_WATCHPOINT in the returned flags.
- * Do handle clean pages, so exclude TLB_NOTDIRY from the returned flags.
- * For simplicity, all "mmio-like" flags are folded to TLB_MMIO.
- */
-int probe_access_flags(CPUArchState *env, vaddr addr, int size,
- MMUAccessType access_type, int mmu_idx,
- bool nonfault, void **phost, uintptr_t retaddr);
-
-#ifndef CONFIG_USER_ONLY
-/**
- * probe_access_full:
- * Like probe_access_flags, except also return into @pfull.
- *
- * The CPUTLBEntryFull structure returned via @pfull is transient
- * and must be consumed or copied immediately, before any further
- * access or changes to TLB @mmu_idx.
- */
-int probe_access_full(CPUArchState *env, vaddr addr, int size,
- MMUAccessType access_type, int mmu_idx,
- bool nonfault, void **phost,
- CPUTLBEntryFull **pfull, uintptr_t retaddr);
-
-/**
- * probe_access_mmu() - Like probe_access_full except cannot fault and
- * doesn't trigger instrumentation.
- *
- * @env: CPUArchState
- * @vaddr: virtual address to probe
- * @size: size of the probe
- * @access_type: read, write or execute permission
- * @mmu_idx: softmmu index
- * @phost: ptr to return value host address or NULL
- * @pfull: ptr to return value CPUTLBEntryFull structure or NULL
- *
- * The CPUTLBEntryFull structure returned via @pfull is transient
- * and must be consumed or copied immediately, before any further
- * access or changes to TLB @mmu_idx.
- *
- * Returns: TLB flags as per probe_access_flags()
- */
-int probe_access_full_mmu(CPUArchState *env, vaddr addr, int size,
- MMUAccessType access_type, int mmu_idx,
- void **phost, CPUTLBEntryFull **pfull);
-
-#endif
-
-static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
-{
-#ifdef CONFIG_USER_ONLY
- return tb->itree.start;
-#else
- return tb->page_addr[0];
-#endif
-}
-
-static inline tb_page_addr_t tb_page_addr1(const TranslationBlock *tb)
-{
-#ifdef CONFIG_USER_ONLY
- tb_page_addr_t next = tb->itree.last & TARGET_PAGE_MASK;
- return next == (tb->itree.start & TARGET_PAGE_MASK) ? -1 : next;
-#else
- return tb->page_addr[1];
-#endif
-}
-
-static inline void tb_set_page_addr0(TranslationBlock *tb,
- tb_page_addr_t addr)
-{
-#ifdef CONFIG_USER_ONLY
- tb->itree.start = addr;
- /*
- * To begin, we record an interval of one byte. When the translation
- * loop encounters a second page, the interval will be extended to
- * include the first byte of the second page, which is sufficient to
- * allow tb_page_addr1() above to work properly. The final corrected
- * interval will be set by tb_page_add() from tb->size before the
- * node is added to the interval tree.
- */
- tb->itree.last = addr;
-#else
- tb->page_addr[0] = addr;
-#endif
-}
-
-static inline void tb_set_page_addr1(TranslationBlock *tb,
- tb_page_addr_t addr)
-{
-#ifdef CONFIG_USER_ONLY
- /* Extend the interval to the first byte of the second page. See above. */
- tb->itree.last = addr;
-#else
- tb->page_addr[1] = addr;
-#endif
-}
-
-/* TranslationBlock invalidate API */
-void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
-void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t last);
-void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr);
-
-/* GETPC is the true target of the return instruction that we'll execute. */
-#if defined(CONFIG_TCG_INTERPRETER)
-extern __thread uintptr_t tci_tb_ptr;
-# define GETPC() tci_tb_ptr
-#else
-# define GETPC() \
- ((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
-#endif
-
-/* The true return address will often point to a host insn that is part of
- the next translated guest insn. Adjust the address backward to point to
- the middle of the call insn. Subtracting one would do the job except for
- several compressed mode architectures (arm, mips) which set the low bit
- to indicate the compressed mode; subtracting two works around that. It
- is also the case that there are no host isas that contain a call insn
- smaller than 4 bytes, so we don't worry about special-casing this. */
-#define GETPC_ADJ 2
-
-#if !defined(CONFIG_USER_ONLY)
-
-/**
- * iotlb_to_section:
- * @cpu: CPU performing the access
- * @index: TCG CPU IOTLB entry
- *
- * Given a TCG CPU IOTLB entry, return the MemoryRegionSection that
- * it refers to. @index will have been initially created and returned
- * by memory_region_section_get_iotlb().
- */
-struct MemoryRegionSection *iotlb_to_section(CPUState *cpu,
- hwaddr index, MemTxAttrs attrs);
-#endif
-
-/**
- * get_page_addr_code_hostp()
- * @env: CPUArchState
- * @addr: guest virtual address of guest code
- *
- * See get_page_addr_code() (full-system version) for documentation on the
- * return value.
- *
- * Sets *@hostp (when @hostp is non-NULL) as follows.
- * If the return value is -1, sets *@hostp to NULL. Otherwise, sets *@hostp
- * to the host address where @addr's content is kept.
- *
- * Note: this function can trigger an exception.
- */
-tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr,
- void **hostp);
-
-/**
- * get_page_addr_code()
- * @env: CPUArchState
- * @addr: guest virtual address of guest code
- *
- * If we cannot translate and execute from the entire RAM page, or if
- * the region is not backed by RAM, returns -1. Otherwise, returns the
- * ram_addr_t corresponding to the guest code at @addr.
- *
- * Note: this function can trigger an exception.
- */
-static inline tb_page_addr_t get_page_addr_code(CPUArchState *env,
- vaddr addr)
-{
- return get_page_addr_code_hostp(env, addr, NULL);
-}
-
-#if defined(CONFIG_USER_ONLY)
-void TSA_NO_TSA mmap_lock(void);
-void TSA_NO_TSA mmap_unlock(void);
-bool have_mmap_lock(void);
-
-static inline void mmap_unlock_guard(void *unused)
-{
- mmap_unlock();
-}
-
-#define WITH_MMAP_LOCK_GUARD() \
- for (int _mmap_lock_iter __attribute__((cleanup(mmap_unlock_guard))) \
- = (mmap_lock(), 0); _mmap_lock_iter == 0; _mmap_lock_iter = 1)
-
-/**
- * adjust_signal_pc:
- * @pc: raw pc from the host signal ucontext_t.
- * @is_write: host memory operation was write, or read-modify-write.
- *
- * Alter @pc as required for unwinding. Return the type of the
- * guest memory access -- host reads may be for guest execution.
- */
-MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
-
-/**
- * handle_sigsegv_accerr_write:
- * @cpu: the cpu context
- * @old_set: the sigset_t from the signal ucontext_t
- * @host_pc: the host pc, adjusted for the signal
- * @host_addr: the host address of the fault
- *
- * Return true if the write fault has been handled, and should be re-tried.
- */
-bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
- uintptr_t host_pc, abi_ptr guest_addr);
-
-/**
- * cpu_loop_exit_sigsegv:
- * @cpu: the cpu context
- * @addr: the guest address of the fault
- * @access_type: access was read/write/execute
- * @maperr: true for invalid page, false for permission fault
- * @ra: host pc for unwinding
- *
- * Use the TCGCPUOps hook to record cpu state, do guest operating system
- * specific things to raise SIGSEGV, and jump to the main cpu loop.
- */
-G_NORETURN void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
- MMUAccessType access_type,
- bool maperr, uintptr_t ra);
-
-/**
- * cpu_loop_exit_sigbus:
- * @cpu: the cpu context
- * @addr: the guest address of the alignment fault
- * @access_type: access was read/write/execute
- * @ra: host pc for unwinding
- *
- * Use the TCGCPUOps hook to record cpu state, do guest operating system
- * specific things to raise SIGBUS, and jump to the main cpu loop.
- */
-G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr,
- MMUAccessType access_type,
- uintptr_t ra);
-
-#else
-static inline void mmap_lock(void) {}
-static inline void mmap_unlock(void) {}
-#define WITH_MMAP_LOCK_GUARD()
-
-void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length);
-void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length);
-
-MemoryRegionSection *
-address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr,
- hwaddr *xlat, hwaddr *plen,
- MemTxAttrs attrs, int *prot);
-hwaddr memory_region_section_get_iotlb(CPUState *cpu,
- MemoryRegionSection *section);
-#endif
-
-#endif
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index 1bd2c4e..0675b0b 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -41,14 +41,26 @@ void gdb_register_coprocessor(CPUState *cpu,
const GDBFeature *feature, int g_pos);
/**
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
+ * @cpu - the CPU associated with registers
+ */
+void gdb_unregister_coprocessor_all(CPUState *cpu);
+
+/**
* gdbserver_start: start the gdb server
* @port_or_device: connection spec for gdb
+ * @errp: error handle
*
* For CONFIG_USER this is either a tcp port or a path to a fifo. For
* system emulation you can use a full chardev spec for your gdbserver
* port.
+ *
+ * The error handle should be either &error_fatal (for start-up) or
+ * &error_warn (for QMP/HMP initiated sessions).
+ *
+ * Returns true when server successfully started.
*/
-int gdbserver_start(const char *port_or_device);
+bool gdbserver_start(const char *port_or_device, Error **errp);
/**
* gdb_feature_builder_init() - Initialize GDBFeatureBuilder.
diff --git a/include/exec/helper-head.h.inc b/include/exec/helper-head.h.inc
index 5ef467a..5b248fd 100644
--- a/include/exec/helper-head.h.inc
+++ b/include/exec/helper-head.h.inc
@@ -23,6 +23,7 @@
#define dh_alias_ptr ptr
#define dh_alias_cptr ptr
#define dh_alias_env ptr
+#define dh_alias_fpst ptr
#define dh_alias_void void
#define dh_alias_noreturn noreturn
#define dh_alias(t) glue(dh_alias_, t)
@@ -39,6 +40,7 @@
#define dh_ctype_ptr void *
#define dh_ctype_cptr const void *
#define dh_ctype_env CPUArchState *
+#define dh_ctype_fpst float_status *
#define dh_ctype_void void
#define dh_ctype_noreturn G_NORETURN void
#define dh_ctype(t) dh_ctype_##t
@@ -56,6 +58,17 @@
# define dh_ctype_tl target_ulong
#endif /* COMPILING_PER_TARGET */
+#if __SIZEOF_POINTER__ == 4
+# define dh_alias_vaddr i32
+# define dh_typecode_vaddr dh_typecode_i32
+#elif __SIZEOF_POINTER__ == 8
+# define dh_alias_vaddr i64
+# define dh_typecode_vaddr dh_typecode_i64
+#else
+# error "sizeof pointer is different from {4,8}"
+#endif /* __SIZEOF_POINTER__ */
+# define dh_ctype_vaddr uintptr_t
+
/* We can't use glue() here because it falls foul of C preprocessor
recursive expansion rules. */
#define dh_retvar_decl0_void void
@@ -96,6 +109,7 @@
#define dh_typecode_f64 dh_typecode_i64
#define dh_typecode_cptr dh_typecode_ptr
#define dh_typecode_env dh_typecode_ptr
+#define dh_typecode_fpst dh_typecode_ptr
#define dh_typecode(t) dh_typecode_##t
#define dh_callflag_i32 0
diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h
index 16782ef..76e6c25 100644
--- a/include/exec/helper-proto-common.h
+++ b/include/exec/helper-proto-common.h
@@ -13,4 +13,6 @@
#include "exec/helper-proto.h.inc"
#undef HELPER_H
+#include "accel/tcg/getpc.h"
+
#endif /* HELPER_PROTO_COMMON_H */
diff --git a/include/sysemu/cpu-timers.h b/include/exec/icount.h
index 7bfa960..7a26b40 100644
--- a/include/sysemu/cpu-timers.h
+++ b/include/exec/icount.h
@@ -1,21 +1,13 @@
/*
+ * icount - Instruction Counter API
* CPU timers state API
*
* Copyright 2020 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.
- *
+ * SPDX-License-Identifier: GPL-2.0-or-later
*/
-#ifndef SYSEMU_CPU_TIMERS_H
-#define SYSEMU_CPU_TIMERS_H
-
-#include "qemu/timer.h"
-/* init the whole cpu timers API, including icount, ticks, and cpu_throttle */
-void cpu_timers_init(void);
-
-/* icount - Instruction Counter API */
+#ifndef EXEC_ICOUNT_H
+#define EXEC_ICOUNT_H
/**
* ICountMode: icount enablement state:
@@ -30,13 +22,21 @@ typedef enum {
ICOUNT_ADAPTATIVE,
} ICountMode;
-#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
+#ifdef CONFIG_TCG
extern ICountMode use_icount;
#define icount_enabled() (use_icount)
#else
#define icount_enabled() ICOUNT_DISABLED
#endif
+/* Protect the CONFIG_USER_ONLY test vs poisoning. */
+#if defined(COMPILING_PER_TARGET) || defined(COMPILING_SYSTEM_VS_USER)
+# ifdef CONFIG_USER_ONLY
+# undef icount_enabled
+# define icount_enabled() ICOUNT_DISABLED
+# endif
+#endif
+
/*
* Update the icount with the executed instructions. Called by
* cpus-tcg vCPU thread so the main-loop can see time has moved forward.
@@ -73,32 +73,4 @@ void icount_start_warp_timer(void);
void icount_account_warp_timer(void);
void icount_notify_exit(void);
-/*
- * CPU Ticks and Clock
- */
-
-/* Caller must hold BQL */
-void cpu_enable_ticks(void);
-/* Caller must hold BQL */
-void cpu_disable_ticks(void);
-
-/*
- * return the time elapsed in VM between vm_start and vm_stop.
- * cpu_get_ticks() uses units of the host CPU cycle counter.
- */
-int64_t cpu_get_ticks(void);
-
-/*
- * Returns the monotonic time elapsed in VM, i.e.,
- * the time between vm_start and vm_stop
- */
-int64_t cpu_get_clock(void);
-
-void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
-
-/* get/set VIRTUAL clock and VM elapsed ticks via the cpus accel interface */
-int64_t cpus_get_virtual_clock(void);
-void cpus_set_virtual_clock(int64_t new_time);
-int64_t cpus_get_elapsed_ticks(void);
-
-#endif /* SYSEMU_CPU_TIMERS_H */
+#endif /* EXEC_ICOUNT_H */
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index 14cdd8d..8db1d30 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -23,12 +23,6 @@
* different semantics.
*/
typedef struct MemTxAttrs {
- /* Bus masters which don't specify any attributes will get this
- * (via the MEMTXATTRS_UNSPECIFIED constant), so that we can
- * distinguish "all attributes deliberately clear" from
- * "didn't specify" if necessary.
- */
- unsigned int unspecified:1;
/*
* ARM/AMBA: TrustZone Secure access
* x86: System Management Mode access
@@ -50,16 +44,37 @@ typedef struct MemTxAttrs {
* (see MEMTX_ACCESS_ERROR).
*/
unsigned int memory:1;
+ /* Debug access that can even write to ROM. */
+ unsigned int debug:1;
/* Requester ID (for MSI for example) */
unsigned int requester_id:16;
+
+ /*
+ * PID (PCI PASID) support: Limited to 8 bits process identifier.
+ */
+ unsigned int pid:8;
+
+ /*
+ * Bus masters which don't specify any attributes will get this
+ * (via the MEMTXATTRS_UNSPECIFIED constant), so that we can
+ * distinguish "all attributes deliberately clear" from
+ * "didn't specify" if necessary. "debug" can be set alongside
+ * "unspecified".
+ */
+ bool unspecified;
+
+ uint8_t _reserved1;
+ uint16_t _reserved2;
} MemTxAttrs;
+QEMU_BUILD_BUG_ON(sizeof(MemTxAttrs) > 8);
+
/* Bus masters which don't specify any attributes will get this,
* which has all attribute bits clear except the topmost one
* (so that we can distinguish "all attributes deliberately clear"
* from "didn't specify" if necessary).
*/
-#define MEMTXATTRS_UNSPECIFIED ((MemTxAttrs) { .unspecified = 1 })
+#define MEMTXATTRS_UNSPECIFIED ((MemTxAttrs) { .unspecified = true })
/* New-style MMIO accessors can indicate that the transaction failed.
* A zero (MEMTX_OK) response means success; anything else is a failure
diff --git a/include/exec/memop.h b/include/exec/memop.h
index f881fe7..cf7da33 100644
--- a/include/exec/memop.h
+++ b/include/exec/memop.h
@@ -91,8 +91,12 @@ typedef enum MemOp {
* Depending on alignment, one or both will be single-copy atomic.
* This is the atomicity e.g. of Arm FEAT_LSE2 LDP.
* MO_ATOM_SUBALIGN: the operation is single-copy atomic by parts
- * by the alignment. E.g. if the address is 0 mod 4, then each
- * 4-byte subobject is single-copy atomic.
+ * by the alignment. E.g. if an 8-byte value is accessed at an
+ * address which is 0 mod 8, then the whole 8-byte access is
+ * single-copy atomic; otherwise, if it is accessed at 0 mod 4
+ * then each 4-byte subobject is single-copy atomic; otherwise
+ * if it is accessed at 0 mod 2 then the four 2-byte subobjects
+ * are single-copy atomic.
* This is the atomicity e.g. of IBM Power.
* MO_ATOM_NONE: the operation has no atomicity requirements.
*
@@ -158,16 +162,57 @@ static inline unsigned memop_size(MemOp op)
static inline MemOp size_memop(unsigned size)
{
#ifdef CONFIG_DEBUG_TCG
- /* Power of 2 up to 8. */
- assert((size & (size - 1)) == 0 && size >= 1 && size <= 8);
+ /* Power of 2 up to 1024 */
+ assert(is_power_of_2(size) && size >= 1 && size <= (1 << MO_SIZE));
#endif
return (MemOp)ctz32(size);
}
-/* Big endianness from MemOp. */
-static inline bool memop_big_endian(MemOp op)
+/**
+ * memop_alignment_bits:
+ * @memop: MemOp value
+ *
+ * Extract the alignment size from the memop.
+ */
+static inline unsigned memop_alignment_bits(MemOp memop)
+{
+ unsigned a = memop & MO_AMASK;
+
+ if (a == MO_UNALN) {
+ /* No alignment required. */
+ a = 0;
+ } else if (a == MO_ALIGN) {
+ /* A natural alignment requirement. */
+ a = memop & MO_SIZE;
+ } else {
+ /* A specific alignment requirement. */
+ a = a >> MO_ASHIFT;
+ }
+ return a;
+}
+
+/*
+ * memop_atomicity_bits:
+ * @memop: MemOp value
+ *
+ * Extract the atomicity size from the memop.
+ */
+static inline unsigned memop_atomicity_bits(MemOp memop)
{
- return (op & MO_BSWAP) == MO_BE;
+ unsigned size = memop & MO_SIZE;
+
+ switch (memop & MO_ATOM_MASK) {
+ case MO_ATOM_NONE:
+ size = MO_8;
+ break;
+ case MO_ATOM_IFALIGN_PAIR:
+ case MO_ATOM_WITHIN16_PAIR:
+ size = size ? size - 1 : 0;
+ break;
+ default:
+ break;
+ }
+ return size;
}
#endif
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
deleted file mode 100644
index 100c123..0000000
--- a/include/exec/memory-internal.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Declarations for functions which are internal to the memory subsystem.
- *
- * Copyright 2011 Red Hat, Inc. and/or its affiliates
- *
- * Authors:
- * Avi Kivity <avi@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or
- * later. See the COPYING file in the top-level directory.
- *
- */
-
-/*
- * This header is for use by exec.c, memory.c and accel/tcg/cputlb.c ONLY,
- * for declarations which are shared between the memory subsystem's
- * internals and the TCG TLB code. Do not include it from elsewhere.
- */
-
-#ifndef MEMORY_INTERNAL_H
-#define MEMORY_INTERNAL_H
-
-#include "cpu.h"
-
-#ifndef CONFIG_USER_ONLY
-static inline AddressSpaceDispatch *flatview_to_dispatch(FlatView *fv)
-{
- return fv->dispatch;
-}
-
-static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
-{
- return flatview_to_dispatch(address_space_to_flatview(as));
-}
-
-FlatView *address_space_get_flatview(AddressSpace *as);
-void flatview_unref(FlatView *view);
-
-extern const MemoryRegionOps unassigned_mem_ops;
-
-void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
-AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
-void address_space_dispatch_compact(AddressSpaceDispatch *d);
-void address_space_dispatch_free(AddressSpaceDispatch *d);
-
-void mtree_print_dispatch(struct AddressSpaceDispatch *d,
- MemoryRegion *root);
-#endif
-#endif
diff --git a/include/exec/memory_ldst.h.inc b/include/exec/memory_ldst.h.inc
index 92ad74e..7270235 100644
--- a/include/exec/memory_ldst.h.inc
+++ b/include/exec/memory_ldst.h.inc
@@ -19,7 +19,6 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#ifdef TARGET_ENDIANNESS
uint16_t glue(address_space_lduw, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL,
@@ -34,7 +33,6 @@ void glue(address_space_stl, SUFFIX)(ARG1_DECL,
hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result);
void glue(address_space_stq, SUFFIX)(ARG1_DECL,
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
-#else
uint8_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
hwaddr addr, MemTxAttrs attrs, MemTxResult *result);
uint16_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL,
@@ -63,9 +61,7 @@ void glue(address_space_stq_le, SUFFIX)(ARG1_DECL,
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result);
-#endif
#undef ARG1_DECL
#undef ARG1
#undef SUFFIX
-#undef TARGET_ENDIANNESS
diff --git a/include/exec/memory_ldst_phys.h.inc b/include/exec/memory_ldst_phys.h.inc
index ecd6786..db67de7 100644
--- a/include/exec/memory_ldst_phys.h.inc
+++ b/include/exec/memory_ldst_phys.h.inc
@@ -19,7 +19,6 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#ifdef TARGET_ENDIANNESS
static inline uint16_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_lduw, SUFFIX)(ARG1, addr,
@@ -55,7 +54,7 @@ static inline void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
glue(address_space_stq, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
-#else
+
static inline uint8_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
{
return glue(address_space_ldub, SUFFIX)(ARG1, addr,
@@ -139,9 +138,7 @@ static inline void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t va
glue(address_space_stq_be, SUFFIX)(ARG1, addr, val,
MEMTXATTRS_UNSPECIFIED, NULL);
}
-#endif
#undef ARG1_DECL
#undef ARG1
#undef SUFFIX
-#undef TARGET_ENDIANNESS
diff --git a/include/exec/mmap-lock.h b/include/exec/mmap-lock.h
new file mode 100644
index 0000000..50ffdab
--- /dev/null
+++ b/include/exec/mmap-lock.h
@@ -0,0 +1,33 @@
+/*
+ * QEMU user-only mmap lock, with stubs for system mode
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+#ifndef EXEC_MMAP_LOCK_H
+#define EXEC_MMAP_LOCK_H
+
+#ifdef CONFIG_USER_ONLY
+
+void TSA_NO_TSA mmap_lock(void);
+void TSA_NO_TSA mmap_unlock(void);
+bool have_mmap_lock(void);
+
+static inline void mmap_unlock_guard(void *unused)
+{
+ mmap_unlock();
+}
+
+#define WITH_MMAP_LOCK_GUARD() \
+ for (int _mmap_lock_iter __attribute__((cleanup(mmap_unlock_guard))) \
+ = (mmap_lock(), 0); _mmap_lock_iter == 0; _mmap_lock_iter = 1)
+
+#else
+
+static inline void mmap_lock(void) {}
+static inline void mmap_unlock(void) {}
+#define WITH_MMAP_LOCK_GUARD()
+
+#endif /* CONFIG_USER_ONLY */
+#endif /* EXEC_MMAP_LOCK_H */
diff --git a/include/exec/page-vary.h b/include/exec/page-vary.h
index 54ddde3..101c259 100644
--- a/include/exec/page-vary.h
+++ b/include/exec/page-vary.h
@@ -49,4 +49,13 @@ bool set_preferred_target_page_bits(int bits);
*/
void finalize_target_page_bits(void);
+/**
+ * migration_legacy_page_bits
+ *
+ * For migration compatibility with qemu v2.9, prior to the introduction
+ * of the configuration/target-page-bits section, return the value of
+ * TARGET_PAGE_BITS that the target had then.
+ */
+int migration_legacy_page_bits(void);
+
#endif /* EXEC_PAGE_VARY_H */
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 792a83f..a779adb 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -11,7 +11,6 @@
#pragma GCC poison TARGET_AARCH64
#pragma GCC poison TARGET_ALPHA
#pragma GCC poison TARGET_ARM
-#pragma GCC poison TARGET_CRIS
#pragma GCC poison TARGET_HEXAGON
#pragma GCC poison TARGET_HPPA
#pragma GCC poison TARGET_LOONGARCH64
@@ -36,35 +35,17 @@
#pragma GCC poison TARGET_HAS_BFLT
#pragma GCC poison TARGET_NAME
-#pragma GCC poison TARGET_SUPPORTS_MTTCG
#pragma GCC poison TARGET_BIG_ENDIAN
-#pragma GCC poison BSWAP_NEEDED
+#pragma GCC poison TCG_GUEST_DEFAULT_MO
#pragma GCC poison TARGET_LONG_BITS
#pragma GCC poison TARGET_FMT_lx
#pragma GCC poison TARGET_FMT_ld
#pragma GCC poison TARGET_FMT_lu
-#pragma GCC poison TARGET_PAGE_SIZE
-#pragma GCC poison TARGET_PAGE_MASK
-#pragma GCC poison TARGET_PAGE_BITS
-#pragma GCC poison TARGET_PAGE_ALIGN
-
-#pragma GCC poison CPU_INTERRUPT_HARD
-#pragma GCC poison CPU_INTERRUPT_EXITTB
-#pragma GCC poison CPU_INTERRUPT_HALT
-#pragma GCC poison CPU_INTERRUPT_DEBUG
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_0
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_1
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_2
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_3
-#pragma GCC poison CPU_INTERRUPT_TGT_EXT_4
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_0
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_1
-#pragma GCC poison CPU_INTERRUPT_TGT_INT_2
+#pragma GCC poison TARGET_PHYS_ADDR_SPACE_BITS
#pragma GCC poison CONFIG_ALPHA_DIS
-#pragma GCC poison CONFIG_CRIS_DIS
#pragma GCC poison CONFIG_HPPA_DIS
#pragma GCC poison CONFIG_I386_DIS
#pragma GCC poison CONFIG_HEXAGON_DIS
@@ -85,4 +66,11 @@
#pragma GCC poison CONFIG_WHPX
#pragma GCC poison CONFIG_XEN
+#ifndef COMPILING_SYSTEM_VS_USER
+#pragma GCC poison CONFIG_USER_ONLY
+#pragma GCC poison CONFIG_SOFTMMU
+#endif
+
+#pragma GCC poison KVM_HAVE_MCE_INJECTION
+
#endif
diff --git a/include/exec/ramlist.h b/include/exec/ramlist.h
index 2ad2a81..d9cfe53 100644
--- a/include/exec/ramlist.h
+++ b/include/exec/ramlist.h
@@ -50,6 +50,7 @@ typedef struct RAMList {
/* RCU-enabled, writes protected by the ramlist lock. */
QLIST_HEAD(, RAMBlock) blocks;
DirtyMemoryBlocks *dirty_memory[DIRTY_MEMORY_NUM];
+ unsigned int num_dirty_blocks;
uint32_t version;
QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers;
} RAMList;
diff --git a/include/exec/target_page.h b/include/exec/target_page.h
index 98ffbb5..ca0ebbc 100644
--- a/include/exec/target_page.h
+++ b/include/exec/target_page.h
@@ -14,10 +14,54 @@
#ifndef EXEC_TARGET_PAGE_H
#define EXEC_TARGET_PAGE_H
-size_t qemu_target_page_size(void);
-int qemu_target_page_mask(void);
-int qemu_target_page_bits(void);
-int qemu_target_page_bits_min(void);
+/*
+ * If compiling per-target, get the real values.
+ * For generic code, reuse the mechanism for variable page size.
+ */
+#ifdef COMPILING_PER_TARGET
+#include "cpu-param.h"
+#include "exec/target_long.h"
+#define TARGET_PAGE_TYPE target_long
+#else
+#define TARGET_PAGE_BITS_VARY
+#define TARGET_PAGE_TYPE int
+#endif
+
+#ifdef TARGET_PAGE_BITS_VARY
+# include "exec/page-vary.h"
+extern const TargetPageBits target_page;
+# ifdef CONFIG_DEBUG_TCG
+# define TARGET_PAGE_BITS ({ assert(target_page.decided); \
+ target_page.bits; })
+# define TARGET_PAGE_MASK ({ assert(target_page.decided); \
+ (TARGET_PAGE_TYPE)target_page.mask; })
+# else
+# define TARGET_PAGE_BITS target_page.bits
+# define TARGET_PAGE_MASK ((TARGET_PAGE_TYPE)target_page.mask)
+# endif
+# define TARGET_PAGE_SIZE (-(int)TARGET_PAGE_MASK)
+#else
+# define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
+# define TARGET_PAGE_MASK ((TARGET_PAGE_TYPE)-1 << TARGET_PAGE_BITS)
+#endif
+
+#define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE)
+
+static inline size_t qemu_target_page_size(void)
+{
+ return TARGET_PAGE_SIZE;
+}
+
+static inline int qemu_target_page_mask(void)
+{
+ return TARGET_PAGE_MASK;
+}
+
+static inline int qemu_target_page_bits(void)
+{
+ return TARGET_PAGE_BITS;
+}
size_t qemu_target_pages_to_MiB(size_t pages);
+
#endif
diff --git a/include/exec/tlb-common.h b/include/exec/tlb-common.h
index dc5a5fa..03b5a8f 100644
--- a/include/exec/tlb-common.h
+++ b/include/exec/tlb-common.h
@@ -19,14 +19,14 @@
#ifndef EXEC_TLB_COMMON_H
#define EXEC_TLB_COMMON_H 1
-#define CPU_TLB_ENTRY_BITS 5
+#define CPU_TLB_ENTRY_BITS (HOST_LONG_BITS == 32 ? 4 : 5)
/* Minimalized TLB entry for use by TCG fast path. */
typedef union CPUTLBEntry {
struct {
- uint64_t addr_read;
- uint64_t addr_write;
- uint64_t addr_code;
+ uintptr_t addr_read;
+ uintptr_t addr_write;
+ uintptr_t addr_code;
/*
* Addend to virtual address to get host address. IO accesses
* use the corresponding iotlb value.
@@ -37,7 +37,7 @@ typedef union CPUTLBEntry {
* Padding to get a power of two size, as well as index
* access to addr_{read,write,code}.
*/
- uint64_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uint64_t)];
+ uintptr_t addr_idx[(1 << CPU_TLB_ENTRY_BITS) / sizeof(uintptr_t)];
} CPUTLBEntry;
QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
diff --git a/include/exec/tlb-flags.h b/include/exec/tlb-flags.h
new file mode 100644
index 0000000..357e790
--- /dev/null
+++ b/include/exec/tlb-flags.h
@@ -0,0 +1,86 @@
+/*
+ * TLB flags definition
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef TLB_FLAGS_H
+#define TLB_FLAGS_H
+
+/*
+ * Flags returned for lookup of a TLB virtual address.
+ */
+
+#ifdef CONFIG_USER_ONLY
+
+/*
+ * Allow some level of source compatibility with softmmu.
+ * Invalid is set when the page does not have requested permissions.
+ * MMIO is set when we want the target helper to use the functional
+ * interface for load/store so that plugins see the access.
+ */
+#define TLB_INVALID_MASK (1 << 0)
+#define TLB_MMIO (1 << 1)
+#define TLB_WATCHPOINT 0
+
+#else
+
+/*
+ * Flags stored in CPUTLBEntryFull.slow_flags[x].
+ * TLB_FORCE_SLOW must be set in CPUTLBEntry.addr_idx[x].
+ */
+
+/* Set if TLB entry requires byte swap. */
+#define TLB_BSWAP (1 << 0)
+/* Set if TLB entry contains a watchpoint. */
+#define TLB_WATCHPOINT (1 << 1)
+/* Set if TLB entry requires aligned accesses. */
+#define TLB_CHECK_ALIGNED (1 << 2)
+/* Set if TLB entry writes ignored. */
+#define TLB_DISCARD_WRITE (1 << 3)
+/* Set if TLB entry is an IO callback. */
+#define TLB_MMIO (1 << 4)
+
+#define TLB_SLOW_FLAGS_MASK \
+ (TLB_BSWAP | TLB_WATCHPOINT | TLB_CHECK_ALIGNED | \
+ TLB_DISCARD_WRITE | TLB_MMIO)
+
+/*
+ * Flags stored in CPUTLBEntry.addr_idx[x].
+ * These must be above the largest alignment (64 bytes),
+ * and below the smallest page size (1024 bytes).
+ * This leaves bits [9:6] available for use.
+ */
+
+/* Zero if TLB entry is valid. */
+#define TLB_INVALID_MASK (1 << 6)
+/* Set if TLB entry references a clean RAM page. */
+#define TLB_NOTDIRTY (1 << 7)
+/* Set if the slow path must be used; more flags in CPUTLBEntryFull. */
+#define TLB_FORCE_SLOW (1 << 8)
+
+/*
+ * Use this mask to check interception with an alignment mask
+ * in a TCG backend.
+ */
+#define TLB_FLAGS_MASK \
+ (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_FORCE_SLOW)
+
+/* The two sets of flags must not overlap. */
+QEMU_BUILD_BUG_ON(TLB_FLAGS_MASK & TLB_SLOW_FLAGS_MASK);
+
+#endif /* !CONFIG_USER_ONLY */
+
+#endif /* TLB_FLAGS_H */
diff --git a/include/exec/translate-all.h b/include/exec/translate-all.h
deleted file mode 100644
index 85c9460..0000000
--- a/include/exec/translate-all.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Translated block handling
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef TRANSLATE_ALL_H
-#define TRANSLATE_ALL_H
-
-#include "exec/exec-all.h"
-
-
-/* translate-all.c */
-void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr);
-
-#ifdef CONFIG_USER_ONLY
-void page_protect(tb_page_addr_t page_addr);
-int page_unprotect(target_ulong address, uintptr_t pc);
-#endif
-
-#endif /* TRANSLATE_ALL_H */
diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
index a6d1af6..cdce399 100644
--- a/include/exec/translation-block.h
+++ b/include/exec/translation-block.h
@@ -7,10 +7,13 @@
#ifndef EXEC_TRANSLATION_BLOCK_H
#define EXEC_TRANSLATION_BLOCK_H
+#include "qemu/atomic.h"
#include "qemu/thread.h"
#include "exec/cpu-common.h"
+#include "exec/vaddr.h"
#ifdef CONFIG_USER_ONLY
#include "qemu/interval-tree.h"
+#include "exec/target_page.h"
#endif
/*
@@ -152,4 +155,60 @@ static inline uint32_t tb_cflags(const TranslationBlock *tb)
return qatomic_read(&tb->cflags);
}
+bool tcg_cflags_has(CPUState *cpu, uint32_t flags);
+void tcg_cflags_set(CPUState *cpu, uint32_t flags);
+
+static inline tb_page_addr_t tb_page_addr0(const TranslationBlock *tb)
+{
+#ifdef CONFIG_USER_ONLY
+ return tb->itree.start;
+#else
+ return tb->page_addr[0];
+#endif
+}
+
+static inline tb_page_addr_t tb_page_addr1(const TranslationBlock *tb)
+{
+#ifdef CONFIG_USER_ONLY
+ tb_page_addr_t next = tb->itree.last & TARGET_PAGE_MASK;
+ return next == (tb->itree.start & TARGET_PAGE_MASK) ? -1 : next;
+#else
+ return tb->page_addr[1];
+#endif
+}
+
+static inline void tb_set_page_addr0(TranslationBlock *tb,
+ tb_page_addr_t addr)
+{
+#ifdef CONFIG_USER_ONLY
+ tb->itree.start = addr;
+ /*
+ * To begin, we record an interval of one byte. When the translation
+ * loop encounters a second page, the interval will be extended to
+ * include the first byte of the second page, which is sufficient to
+ * allow tb_page_addr1() above to work properly. The final corrected
+ * interval will be set by tb_page_add() from tb->size before the
+ * node is added to the interval tree.
+ */
+ tb->itree.last = addr;
+#else
+ tb->page_addr[0] = addr;
+#endif
+}
+
+static inline void tb_set_page_addr1(TranslationBlock *tb,
+ tb_page_addr_t addr)
+{
+#ifdef CONFIG_USER_ONLY
+ /* Extend the interval to the first byte of the second page. See above. */
+ tb->itree.last = addr;
+#else
+ tb->page_addr[1] = addr;
+#endif
+}
+
+/* TranslationBlock invalidate API */
+void tb_invalidate_phys_range(CPUState *cpu, tb_page_addr_t start,
+ tb_page_addr_t last);
+
#endif /* EXEC_TRANSLATION_BLOCK_H */
diff --git a/include/exec/translator.h b/include/exec/translator.h
index 25004df..3c32655 100644
--- a/include/exec/translator.h
+++ b/include/exec/translator.h
@@ -18,24 +18,10 @@
* member in your target-specific DisasContext.
*/
-#include "qemu/bswap.h"
+#include "exec/memop.h"
#include "exec/vaddr.h"
/**
- * gen_intermediate_code
- * @cpu: cpu context
- * @tb: translation block
- * @max_insns: max number of instructions to translate
- * @pc: guest virtual program counter address
- * @host_pc: host physical program counter address
- *
- * This function must be provided by the target, which should create
- * the target-specific DisasContext, and then invoke translator_loop.
- */
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
- vaddr pc, void *host_pc);
-
-/**
* DisasJumpType:
* @DISAS_NEXT: Next instruction in program order.
* @DISAS_TOO_MANY: Too many instructions translated.
@@ -71,7 +57,6 @@ typedef enum DisasJumpType {
* @is_jmp: What instruction to disassemble next.
* @num_insns: Number of translated instructions (including current).
* @max_insns: Maximum number of instructions to be translated in this TB.
- * @singlestep_enabled: "Hardware" single stepping enabled.
* @plugin_enabled: TCG plugin enabled in this TB.
* @fake_insn: True if translator_fake_ldb used.
* @insn_start: The last op emitted by the insn_start hook,
@@ -86,9 +71,9 @@ struct DisasContextBase {
DisasJumpType is_jmp;
int num_insns;
int max_insns;
- bool singlestep_enabled;
bool plugin_enabled;
bool fake_insn;
+ uint8_t code_mmuidx;
struct TCGOp *insn_start;
void *host_addr[2];
@@ -196,42 +181,53 @@ bool translator_io_start(DisasContextBase *db);
*/
uint8_t translator_ldub(CPUArchState *env, DisasContextBase *db, vaddr pc);
-uint16_t translator_lduw(CPUArchState *env, DisasContextBase *db, vaddr pc);
-uint32_t translator_ldl(CPUArchState *env, DisasContextBase *db, vaddr pc);
-uint64_t translator_ldq(CPUArchState *env, DisasContextBase *db, vaddr pc);
+uint16_t translator_lduw_end(CPUArchState *env, DisasContextBase *db,
+ vaddr pc, MemOp endian);
+uint32_t translator_ldl_end(CPUArchState *env, DisasContextBase *db,
+ vaddr pc, MemOp endian);
+uint64_t translator_ldq_end(CPUArchState *env, DisasContextBase *db,
+ vaddr pc, MemOp endian);
+
+#ifdef COMPILING_PER_TARGET
+static inline uint16_t
+translator_lduw(CPUArchState *env, DisasContextBase *db, vaddr pc)
+{
+ return translator_lduw_end(env, db, pc, MO_TE);
+}
+
+static inline uint32_t
+translator_ldl(CPUArchState *env, DisasContextBase *db, vaddr pc)
+{
+ return translator_ldl_end(env, db, pc, MO_TE);
+}
+
+static inline uint64_t
+translator_ldq(CPUArchState *env, DisasContextBase *db, vaddr pc)
+{
+ return translator_ldq_end(env, db, pc, MO_TE);
+}
static inline uint16_t
translator_lduw_swap(CPUArchState *env, DisasContextBase *db,
vaddr pc, bool do_swap)
{
- uint16_t ret = translator_lduw(env, db, pc);
- if (do_swap) {
- ret = bswap16(ret);
- }
- return ret;
+ return translator_lduw_end(env, db, pc, MO_TE ^ (do_swap * MO_BSWAP));
}
static inline uint32_t
translator_ldl_swap(CPUArchState *env, DisasContextBase *db,
vaddr pc, bool do_swap)
{
- uint32_t ret = translator_ldl(env, db, pc);
- if (do_swap) {
- ret = bswap32(ret);
- }
- return ret;
+ return translator_ldl_end(env, db, pc, MO_TE ^ (do_swap * MO_BSWAP));
}
static inline uint64_t
translator_ldq_swap(CPUArchState *env, DisasContextBase *db,
vaddr pc, bool do_swap)
{
- uint64_t ret = translator_ldq(env, db, pc);
- if (do_swap) {
- ret = bswap64(ret);
- }
- return ret;
+ return translator_ldq_end(env, db, pc, MO_TE ^ (do_swap * MO_BSWAP));
}
+#endif /* COMPILING_PER_TARGET */
/**
* translator_fake_ld - fake instruction load
@@ -269,16 +265,15 @@ bool translator_st(const DisasContextBase *db, void *dest,
*/
size_t translator_st_len(const DisasContextBase *db);
-#ifdef COMPILING_PER_TARGET
-/*
- * Return whether addr is on the same page as where disassembly started.
+/**
+ * translator_is_same_page
+ * @db: disassembly context
+ * @addr: virtual address within TB
+ *
+ * Return whether @addr is on the same page as where disassembly started.
* Translators can use this to enforce the rule that only single-insn
* translation blocks are allowed to cross page boundaries.
*/
-static inline bool is_same_page(const DisasContextBase *db, vaddr addr)
-{
- return ((addr ^ db->pc_first) & TARGET_PAGE_MASK) == 0;
-}
-#endif
+bool translator_is_same_page(const DisasContextBase *db, vaddr addr);
#endif /* EXEC__TRANSLATOR_H */
diff --git a/include/exec/tswap.h b/include/exec/tswap.h
index b7a4191..49511f2 100644
--- a/include/exec/tswap.h
+++ b/include/exec/tswap.h
@@ -11,15 +11,16 @@
#include "qemu/bswap.h"
/**
- * target_words_bigendian:
+ * target_big_endian:
* Returns true if the (default) endianness of the target is big endian,
- * false otherwise. Note that in target-specific code, you can use
- * TARGET_BIG_ENDIAN directly instead. On the other hand, common
- * code should normally never need to know about the endianness of the
- * target, so please do *not* use this function unless you know very well
- * what you are doing!
+ * false otherwise. Common code should normally never need to know about the
+ * endianness of the target, so please do *not* use this function unless you
+ * know very well what you are doing!
*/
-bool target_words_bigendian(void);
+bool target_big_endian(void);
+#ifdef COMPILING_PER_TARGET
+#define target_big_endian() TARGET_BIG_ENDIAN
+#endif
/*
* If we're in target-specific code, we can hard-code the swapping
@@ -28,7 +29,7 @@ bool target_words_bigendian(void);
#ifdef COMPILING_PER_TARGET
#define target_needs_bswap() (HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN)
#else
-#define target_needs_bswap() (target_words_bigendian() != HOST_BIG_ENDIAN)
+#define target_needs_bswap() (HOST_BIG_ENDIAN != target_big_endian())
#endif /* COMPILING_PER_TARGET */
static inline uint16_t tswap16(uint16_t s)
@@ -79,4 +80,74 @@ static inline void tswap64s(uint64_t *s)
}
}
+/* Return ld{word}_{le,be}_p following target endianness. */
+#define LOAD_IMPL(word, args...) \
+do { \
+ if (target_big_endian()) { \
+ return glue(glue(ld, word), _be_p)(args); \
+ } else { \
+ return glue(glue(ld, word), _le_p)(args); \
+ } \
+} while (0)
+
+static inline int lduw_p(const void *ptr)
+{
+ LOAD_IMPL(uw, ptr);
+}
+
+static inline int ldsw_p(const void *ptr)
+{
+ LOAD_IMPL(sw, ptr);
+}
+
+static inline int ldl_p(const void *ptr)
+{
+ LOAD_IMPL(l, ptr);
+}
+
+static inline uint64_t ldq_p(const void *ptr)
+{
+ LOAD_IMPL(q, ptr);
+}
+
+static inline uint64_t ldn_p(const void *ptr, int sz)
+{
+ LOAD_IMPL(n, ptr, sz);
+}
+
+#undef LOAD_IMPL
+
+/* Call st{word}_{le,be}_p following target endianness. */
+#define STORE_IMPL(word, args...) \
+do { \
+ if (target_big_endian()) { \
+ glue(glue(st, word), _be_p)(args); \
+ } else { \
+ glue(glue(st, word), _le_p)(args); \
+ } \
+} while (0)
+
+
+static inline void stw_p(void *ptr, uint16_t v)
+{
+ STORE_IMPL(w, ptr, v);
+}
+
+static inline void stl_p(void *ptr, uint32_t v)
+{
+ STORE_IMPL(l, ptr, v);
+}
+
+static inline void stq_p(void *ptr, uint64_t v)
+{
+ STORE_IMPL(q, ptr, v);
+}
+
+static inline void stn_p(void *ptr, int sz, uint64_t v)
+{
+ STORE_IMPL(n, ptr, sz, v);
+}
+
+#undef STORE_IMPL
+
#endif /* TSWAP_H */
diff --git a/include/exec/vaddr.h b/include/exec/vaddr.h
index b9844af..28bec63 100644
--- a/include/exec/vaddr.h
+++ b/include/exec/vaddr.h
@@ -6,13 +6,15 @@
/**
* vaddr:
* Type wide enough to contain any #target_ulong virtual address.
+ * We do not support 64-bit guest on 32-host and detect at configure time.
+ * Therefore, a host pointer width will always fit a guest pointer.
*/
-typedef uint64_t vaddr;
-#define VADDR_PRId PRId64
-#define VADDR_PRIu PRIu64
-#define VADDR_PRIo PRIo64
-#define VADDR_PRIx PRIx64
-#define VADDR_PRIX PRIX64
-#define VADDR_MAX UINT64_MAX
+typedef uintptr_t vaddr;
+#define VADDR_PRId PRIdPTR
+#define VADDR_PRIu PRIuPTR
+#define VADDR_PRIo PRIoPTR
+#define VADDR_PRIx PRIxPTR
+#define VADDR_PRIX PRIXPTR
+#define VADDR_MAX UINTPTR_MAX
#endif
diff --git a/include/exec/watchpoint.h b/include/exec/watchpoint.h
new file mode 100644
index 0000000..4b66688
--- /dev/null
+++ b/include/exec/watchpoint.h
@@ -0,0 +1,41 @@
+/*
+ * CPU watchpoints
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef EXEC_WATCHPOINT_H
+#define EXEC_WATCHPOINT_H
+
+#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
+
+#endif /* EXEC_WATCHPOINT_H */
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
index 94cbe07..90862f5 100644
--- a/include/fpu/softfloat-helpers.h
+++ b/include/fpu/softfloat-helpers.h
@@ -75,6 +75,36 @@ static inline void set_floatx80_rounding_precision(FloatX80RoundPrec val,
status->floatx80_rounding_precision = val;
}
+static inline void set_floatx80_behaviour(FloatX80Behaviour b,
+ float_status *status)
+{
+ status->floatx80_behaviour = b;
+}
+
+static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
+ float_status *status)
+{
+ status->float_2nan_prop_rule = rule;
+}
+
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
+ float_status *status)
+{
+ status->float_3nan_prop_rule = rule;
+}
+
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
+ float_status *status)
+{
+ status->float_infzeronan_rule = rule;
+}
+
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
+ float_status *status)
+{
+ status->default_nan_pattern = dnan_pattern;
+}
+
static inline void set_flush_to_zero(bool val, float_status *status)
{
status->flush_to_zero = val;
@@ -85,6 +115,12 @@ static inline void set_flush_inputs_to_zero(bool val, float_status *status)
status->flush_inputs_to_zero = val;
}
+static inline void set_float_ftz_detection(FloatFTZDetection d,
+ float_status *status)
+{
+ status->ftz_detection = d;
+}
+
static inline void set_default_nan_mode(bool val, float_status *status)
{
status->default_nan_mode = val;
@@ -95,50 +131,79 @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
status->snan_bit_is_one = val;
}
-static inline void set_use_first_nan(bool val, float_status *status)
-{
- status->use_first_nan = val;
-}
-
static inline void set_no_signaling_nans(bool val, float_status *status)
{
status->no_signaling_nans = val;
}
-static inline bool get_float_detect_tininess(float_status *status)
+static inline bool get_float_detect_tininess(const float_status *status)
{
return status->tininess_before_rounding;
}
-static inline FloatRoundMode get_float_rounding_mode(float_status *status)
+static inline FloatRoundMode get_float_rounding_mode(const float_status *status)
{
return status->float_rounding_mode;
}
-static inline int get_float_exception_flags(float_status *status)
+static inline int get_float_exception_flags(const float_status *status)
{
return status->float_exception_flags;
}
static inline FloatX80RoundPrec
-get_floatx80_rounding_precision(float_status *status)
+get_floatx80_rounding_precision(const float_status *status)
{
return status->floatx80_rounding_precision;
}
-static inline bool get_flush_to_zero(float_status *status)
+static inline FloatX80Behaviour
+get_floatx80_behaviour(const float_status *status)
+{
+ return status->floatx80_behaviour;
+}
+
+static inline Float2NaNPropRule
+get_float_2nan_prop_rule(const float_status *status)
+{
+ return status->float_2nan_prop_rule;
+}
+
+static inline Float3NaNPropRule
+get_float_3nan_prop_rule(const float_status *status)
+{
+ return status->float_3nan_prop_rule;
+}
+
+static inline FloatInfZeroNaNRule
+get_float_infzeronan_rule(const float_status *status)
+{
+ return status->float_infzeronan_rule;
+}
+
+static inline uint8_t get_float_default_nan_pattern(const float_status *status)
+{
+ return status->default_nan_pattern;
+}
+
+static inline bool get_flush_to_zero(const float_status *status)
{
return status->flush_to_zero;
}
-static inline bool get_flush_inputs_to_zero(float_status *status)
+static inline bool get_flush_inputs_to_zero(const float_status *status)
{
return status->flush_inputs_to_zero;
}
-static inline bool get_default_nan_mode(float_status *status)
+static inline bool get_default_nan_mode(const float_status *status)
{
return status->default_nan_mode;
}
+static inline FloatFTZDetection get_float_ftz_detection(const float_status *status)
+{
+ return status->ftz_detection;
+}
+
#endif /* SOFTFLOAT_HELPERS_H */
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 0884ec4..1af2a0c 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -80,6 +80,8 @@ this code that are retained.
#ifndef SOFTFLOAT_TYPES_H
#define SOFTFLOAT_TYPES_H
+#include "hw/registerfields.h"
+
/*
* Software IEC/IEEE floating-point types.
*/
@@ -138,6 +140,8 @@ typedef enum __attribute__((__packed__)) {
float_round_to_odd = 5,
/* Not an IEEE rounding mode: round to closest odd, overflow to inf */
float_round_to_odd_inf = 6,
+ /* Not an IEEE rounding mode: round to nearest even, overflow to max */
+ float_round_nearest_even_max = 7,
} FloatRoundMode;
/*
@@ -150,8 +154,10 @@ enum {
float_flag_overflow = 0x0004,
float_flag_underflow = 0x0008,
float_flag_inexact = 0x0010,
- float_flag_input_denormal = 0x0020,
- float_flag_output_denormal = 0x0040,
+ /* We flushed an input denormal to 0 (because of flush_inputs_to_zero) */
+ float_flag_input_denormal_flushed = 0x0020,
+ /* We flushed an output denormal to 0 (because of flush_to_zero) */
+ float_flag_output_denormal_flushed = 0x0040,
float_flag_invalid_isi = 0x0080, /* inf - inf */
float_flag_invalid_imz = 0x0100, /* inf * 0 */
float_flag_invalid_idi = 0x0200, /* inf / inf */
@@ -159,6 +165,13 @@ enum {
float_flag_invalid_sqrt = 0x0800, /* sqrt(-x) */
float_flag_invalid_cvti = 0x1000, /* non-nan to integer */
float_flag_invalid_snan = 0x2000, /* any operand was snan */
+ /*
+ * An input was denormal and we used it (without flushing it to zero).
+ * Not set if we do not actually use the denormal input (e.g.
+ * because some other input was a NaN, or because the operation
+ * wasn't actually carried out (divide-by-zero; invalid))
+ */
+ float_flag_input_denormal_used = 0x4000,
};
/*
@@ -171,6 +184,193 @@ typedef enum __attribute__((__packed__)) {
} FloatX80RoundPrec;
/*
+ * 2-input NaN propagation rule. Individual architectures have
+ * different rules for which input NaN is propagated to the output
+ * when there is more than one NaN on the input.
+ *
+ * If default_nan_mode is enabled then it is valid not to set a
+ * NaN propagation rule, because the softfloat code guarantees
+ * not to try to pick a NaN to propagate in default NaN mode.
+ * When not in default-NaN mode, it is an error for the target
+ * not to set the rule in float_status, and we will assert if
+ * we need to handle an input NaN and no rule was selected.
+ */
+typedef enum __attribute__((__packed__)) {
+ /* No propagation rule specified */
+ float_2nan_prop_none = 0,
+ /* Prefer SNaN over QNaN, then operand A over B */
+ float_2nan_prop_s_ab,
+ /* Prefer SNaN over QNaN, then operand B over A */
+ float_2nan_prop_s_ba,
+ /* Prefer A over B regardless of SNaN vs QNaN */
+ float_2nan_prop_ab,
+ /* Prefer B over A regardless of SNaN vs QNaN */
+ float_2nan_prop_ba,
+ /*
+ * This implements x87 NaN propagation rules:
+ * SNaN + QNaN => return the QNaN
+ * two SNaNs => return the one with the larger significand, silenced
+ * two QNaNs => return the one with the larger significand
+ * SNaN and a non-NaN => return the SNaN, silenced
+ * QNaN and a non-NaN => return the QNaN
+ *
+ * If we get down to comparing significands and they are the same,
+ * return the NaN with the positive sign bit (if any).
+ */
+ float_2nan_prop_x87,
+} Float2NaNPropRule;
+
+/*
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
+ * architectures have different rules for which input NaN is
+ * propagated to the output when there is more than one NaN on the
+ * input.
+ *
+ * If default_nan_mode is enabled then it is valid not to set a NaN
+ * propagation rule, because the softfloat code guarantees not to try
+ * to pick a NaN to propagate in default NaN mode. When not in
+ * default-NaN mode, it is an error for the target not to set the rule
+ * in float_status if it uses a muladd, and we will assert if we need
+ * to handle an input NaN and no rule was selected.
+ *
+ * The naming scheme for Float3NaNPropRule values is:
+ * float_3nan_prop_s_abc:
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
+ * float_3nan_prop_abc:
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
+ *
+ * For QEMU, the multiply-add operation is A * B + C.
+ */
+
+/*
+ * We set the Float3NaNPropRule enum values up so we can select the
+ * right value in pickNaNMulAdd in a data driven way.
+ */
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
+
+#define PROPRULE(X, Y, Z) \
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
+
+typedef enum __attribute__((__packed__)) {
+ float_3nan_prop_none = 0, /* No propagation rule specified */
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
+} Float3NaNPropRule;
+
+#undef PROPRULE
+
+/*
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
+ * This must be a NaN, but implementations differ on whether this
+ * is the input NaN or the default NaN.
+ *
+ * You don't need to set this if default_nan_mode is enabled.
+ * When not in default-NaN mode, it is an error for the target
+ * not to set the rule in float_status if it uses muladd, and we
+ * will assert if we need to handle an input NaN and no rule was
+ * selected.
+ */
+typedef enum __attribute__((__packed__)) {
+ /* No propagation rule specified */
+ float_infzeronan_none = 0,
+ /* Result is never the default NaN (so always the input NaN) */
+ float_infzeronan_dnan_never = 1,
+ /* Result is always the default NaN */
+ float_infzeronan_dnan_always = 2,
+ /* Result is the default NaN if the input NaN is quiet */
+ float_infzeronan_dnan_if_qnan = 3,
+ /*
+ * Don't raise Invalid for 0 * Inf + NaN. Default is to raise.
+ * IEEE 754-2008 section 7.2 makes it implementation defined whether
+ * 0 * Inf + QNaN raises Invalid or not. Note that 0 * Inf + SNaN will
+ * raise the Invalid flag for the SNaN anyway.
+ *
+ * This is a flag which can be ORed in with any of the above
+ * DNaN behaviour options.
+ */
+ float_infzeronan_suppress_invalid = (1 << 7),
+} FloatInfZeroNaNRule;
+
+/*
+ * When flush_to_zero is set, should we detect denormal results to
+ * be flushed before or after rounding? For most architectures this
+ * should be set to match the tininess_before_rounding setting,
+ * but a few architectures, e.g. MIPS MSA, detect FTZ before
+ * rounding but tininess after rounding.
+ *
+ * This enum is arranged so that the default if the target doesn't
+ * configure it matches the default for tininess_before_rounding
+ * (i.e. "after rounding").
+ */
+typedef enum __attribute__((__packed__)) {
+ float_ftz_after_rounding = 0,
+ float_ftz_before_rounding = 1,
+} FloatFTZDetection;
+
+/*
+ * floatx80 is primarily used by x86 and m68k, and there are
+ * differences in the handling, largely related to the explicit
+ * Integer bit which floatx80 has and the other float formats do not.
+ * These flag values allow specification of the target's requirements
+ * and can be ORed together to set floatx80_behaviour.
+ */
+typedef enum __attribute__((__packed__)) {
+ /* In the default Infinity value, is the Integer bit 0 ? */
+ floatx80_default_inf_int_bit_is_zero = 1,
+ /*
+ * Are Pseudo-infinities (Inf with the Integer bit zero) valid?
+ * If so, floatx80_is_infinity() will return true for them.
+ * If not, floatx80_invalid_encoding will return false for them,
+ * and using them as inputs to a float op will raise Invalid.
+ */
+ floatx80_pseudo_inf_valid = 2,
+ /*
+ * Are Pseudo-NaNs (NaNs where the Integer bit is zero) valid?
+ * If not, floatx80_invalid_encoding() will return false for them,
+ * and using them as inputs to a float op will raise Invalid.
+ */
+ floatx80_pseudo_nan_valid = 4,
+ /*
+ * Are Unnormals (0 < exp < 0x7fff, Integer bit zero) valid?
+ * If not, floatx80_invalid_encoding() will return false for them,
+ * and using them as inputs to a float op will raise Invalid.
+ */
+ floatx80_unnormal_valid = 8,
+
+ /*
+ * If the exponent is 0 and the Integer bit is set, Intel call
+ * this a "pseudo-denormal"; x86 supports that only on input
+ * (treating them as denormals by ignoring the Integer bit).
+ * For m68k, the integer bit is considered validly part of the
+ * input value when the exponent is 0, and may be 0 or 1,
+ * giving extra range. They may also be generated as outputs.
+ * (The m68k manual actually calls these values part of the
+ * normalized number range, not the denormalized number range.)
+ *
+ * By default you get the Intel behaviour where the Integer
+ * bit is ignored; if this is set then the Integer bit value
+ * is honoured, m68k-style.
+ *
+ * Either way, floatx80_invalid_encoding() will always accept
+ * pseudo-denormals.
+ */
+ floatx80_pseudo_denormal_valid = 16,
+} FloatX80Behaviour;
+
+/*
* Floating Point Status. Individual architectures may maintain
* several versions of float_status for different functions. The
* correct status for the operation is then passed by reference to
@@ -181,19 +381,34 @@ typedef struct float_status {
uint16_t float_exception_flags;
FloatRoundMode float_rounding_mode;
FloatX80RoundPrec floatx80_rounding_precision;
+ FloatX80Behaviour floatx80_behaviour;
+ Float2NaNPropRule float_2nan_prop_rule;
+ Float3NaNPropRule float_3nan_prop_rule;
+ FloatInfZeroNaNRule float_infzeronan_rule;
bool tininess_before_rounding;
- /* should denormalised results go to zero and set the inexact flag? */
+ /* should denormalised results go to zero and set output_denormal_flushed? */
bool flush_to_zero;
- /* should denormalised inputs go to zero and set the input_denormal flag? */
+ /* do we detect and flush denormal results before or after rounding? */
+ FloatFTZDetection ftz_detection;
+ /* should denormalised inputs go to zero and set input_denormal_flushed? */
bool flush_inputs_to_zero;
bool default_nan_mode;
/*
+ * The pattern to use for the default NaN. Here the high bit specifies
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
+ * fractional part. The low bits of the fractional part are copies of bit 0.
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
+ * Note that a value of 0 here is not a valid NaN. The target must set
+ * this to the correct non-zero value, or we will assert when trying to
+ * create a default NaN.
+ */
+ uint8_t default_nan_pattern;
+ /*
* The flags below are not used on all specializations and may
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
* softfloat-specialize.inc.c)
*/
bool snan_bit_is_one;
- bool use_first_nan;
bool no_signaling_nans;
/* should overflowed results subtract re_bias to its exponent? */
bool rebias_overflow;
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index eb64075..c18ab2c 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -120,14 +120,16 @@ bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status);
| Using these differs from negating an input or output before calling
| the muladd function in that this means that a NaN doesn't have its
| sign bit inverted before it is propagated.
-| We also support halving the result before rounding, as a special
-| case to support the ARM fused-sqrt-step instruction FRSQRTS.
+|
+| With float_muladd_suppress_add_product_zero, if A or B is zero
+| such that the product is a true zero, then return C without addition.
+| This preserves the sign of C when C is +/- 0. Used for Hexagon.
*----------------------------------------------------------------------------*/
enum {
float_muladd_negate_c = 1,
float_muladd_negate_product = 2,
float_muladd_negate_result = 4,
- float_muladd_halve_result = 8,
+ float_muladd_suppress_add_product_zero = 8,
};
/*----------------------------------------------------------------------------
@@ -238,6 +240,8 @@ float16 float16_add(float16, float16, float_status *status);
float16 float16_sub(float16, float16, float_status *status);
float16 float16_mul(float16, float16, float_status *status);
float16 float16_muladd(float16, float16, float16, int, float_status *status);
+float16 float16_muladd_scalbn(float16, float16, float16,
+ int, int, float_status *status);
float16 float16_div(float16, float16, float_status *status);
float16 float16_scalbn(float16, int, float_status *status);
float16 float16_min(float16, float16, float_status *status);
@@ -597,6 +601,8 @@ float32 float32_mul(float32, float32, float_status *status);
float32 float32_div(float32, float32, float_status *status);
float32 float32_rem(float32, float32, float_status *status);
float32 float32_muladd(float32, float32, float32, int, float_status *status);
+float32 float32_muladd_scalbn(float32, float32, float32,
+ int, int, float_status *status);
float32 float32_sqrt(float32, float_status *status);
float32 float32_exp2(float32, float_status *status);
float32 float32_log2(float32, float_status *status);
@@ -792,6 +798,8 @@ float64 float64_mul(float64, float64, float_status *status);
float64 float64_div(float64, float64, float_status *status);
float64 float64_rem(float64, float64, float_status *status);
float64 float64_muladd(float64, float64, float64, int, float_status *status);
+float64 float64_muladd_scalbn(float64, float64, float64,
+ int, int, float_status *status);
float64 float64_sqrt(float64, float_status *status);
float64 float64_log2(float64, float_status *status);
FloatRelation float64_compare(float64, float64, float_status *status);
@@ -952,7 +960,7 @@ float128 floatx80_to_float128(floatx80, float_status *status);
/*----------------------------------------------------------------------------
| The pattern for an extended double-precision inf.
*----------------------------------------------------------------------------*/
-extern const floatx80 floatx80_infinity;
+floatx80 floatx80_default_inf(bool zSign, float_status *status);
/*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision operations.
@@ -987,14 +995,19 @@ static inline floatx80 floatx80_chs(floatx80 a)
return a;
}
-static inline bool floatx80_is_infinity(floatx80 a)
+static inline bool floatx80_is_infinity(floatx80 a, float_status *status)
{
-#if defined(TARGET_M68K)
- return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);
-#else
- return (a.high & 0x7fff) == floatx80_infinity.high &&
- a.low == floatx80_infinity.low;
-#endif
+ /*
+ * It's target-specific whether the Integer bit is permitted
+ * to be 0 in a valid Infinity value. (x86 says no, m68k says yes).
+ */
+ bool intbit = a.low >> 63;
+
+ if (!intbit &&
+ !(status->floatx80_behaviour & floatx80_pseudo_inf_valid)) {
+ return false;
+ }
+ return (a.high & 0x7fff) == 0x7fff && !(a.low << 1);
}
static inline bool floatx80_is_neg(floatx80 a)
@@ -1060,41 +1073,45 @@ static inline bool floatx80_unordered_quiet(floatx80 a, floatx80 b,
/*----------------------------------------------------------------------------
| Return whether the given value is an invalid floatx80 encoding.
-| Invalid floatx80 encodings arise when the integer bit is not set, but
-| the exponent is not zero. The only times the integer bit is permitted to
-| be zero is in subnormal numbers and the value zero.
-| This includes what the Intel software developer's manual calls pseudo-NaNs,
-| pseudo-infinities and un-normal numbers. It does not include
-| pseudo-denormals, which must still be correctly handled as inputs even
-| if they are never generated as outputs.
+| Invalid floatx80 encodings may arise when the integer bit is not set
+| correctly; this is target-specific. In Intel terminology the
+| categories are:
+| exp == 0, int = 0, mantissa == 0 : zeroes
+| exp == 0, int = 0, mantissa != 0 : denormals
+| exp == 0, int = 1 : pseudo-denormals
+| 0 < exp < 0x7fff, int = 0 : unnormals
+| 0 < exp < 0x7fff, int = 1 : normals
+| exp == 0x7fff, int = 0, mantissa == 0 : pseudo-infinities
+| exp == 0x7fff, int = 1, mantissa == 0 : infinities
+| exp == 0x7fff, int = 0, mantissa != 0 : pseudo-NaNs
+| exp == 0x7fff, int = 1, mantissa == 0 : NaNs
+|
+| The usual IEEE cases of zero, denormal, normal, inf and NaN are always valid.
+| x87 permits as input also pseudo-denormals.
+| m68k permits all those and also pseudo-infinities, pseudo-NaNs and unnormals.
+|
+| Since we don't have a target that handles floatx80 but prohibits
+| pseudo-denormals in input, we don't currently have a floatx80_behaviour
+| flag for that case, but instead always accept it. Conveniently this
+| means that all cases with either exponent 0 or the integer bit set are
+| valid for all targets.
*----------------------------------------------------------------------------*/
-static inline bool floatx80_invalid_encoding(floatx80 a)
-{
-#if defined(TARGET_M68K)
- /*-------------------------------------------------------------------------
- | With m68k, the explicit integer bit can be zero in the case of:
- | - zeros (exp == 0, mantissa == 0)
- | - denormalized numbers (exp == 0, mantissa != 0)
- | - unnormalized numbers (exp != 0, exp < 0x7FFF)
- | - infinities (exp == 0x7FFF, mantissa == 0)
- | - not-a-numbers (exp == 0x7FFF, mantissa != 0)
- |
- | For infinities and NaNs, the explicit integer bit can be either one or
- | zero.
- |
- | The IEEE 754 standard does not define a zero integer bit. Such a number
- | is an unnormalized number. Hardware does not directly support
- | denormalized and unnormalized numbers, but implicitly supports them by
- | trapping them as unimplemented data types, allowing efficient conversion
- | in software.
- |
- | See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL",
- | "1.6 FLOATING-POINT DATA TYPES"
- *------------------------------------------------------------------------*/
- return false;
-#else
- return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0;
-#endif
+static inline bool floatx80_invalid_encoding(floatx80 a, float_status *s)
+{
+ if ((a.low >> 63) || (a.high & 0x7fff) == 0) {
+ /* Anything with the Integer bit set or the exponent 0 is valid */
+ return false;
+ }
+
+ if ((a.high & 0x7fff) == 0x7fff) {
+ if (a.low) {
+ return !(s->floatx80_behaviour & floatx80_pseudo_nan_valid);
+ } else {
+ return !(s->floatx80_behaviour & floatx80_pseudo_inf_valid);
+ }
+ } else {
+ return !(s->floatx80_behaviour & floatx80_unnormal_valid);
+ }
}
#define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL)
diff --git a/include/gdbstub/commands.h b/include/gdbstub/commands.h
new file mode 100644
index 0000000..bff3674
--- /dev/null
+++ b/include/gdbstub/commands.h
@@ -0,0 +1,108 @@
+#ifndef GDBSTUB_COMMANDS_H
+#define GDBSTUB_COMMANDS_H
+
+typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx);
+
+typedef enum GDBThreadIdKind {
+ GDB_ONE_THREAD = 0,
+ GDB_ALL_THREADS, /* One process, all threads */
+ GDB_ALL_PROCESSES,
+ GDB_READ_THREAD_ERR
+} GDBThreadIdKind;
+
+typedef union GdbCmdVariant {
+ const char *data;
+ uint8_t opcode;
+ unsigned long val_ul;
+ unsigned long long val_ull;
+ struct {
+ GDBThreadIdKind kind;
+ uint32_t pid;
+ uint32_t tid;
+ } thread_id;
+} GdbCmdVariant;
+
+#define gdb_get_cmd_param(p, i) (&g_array_index(p, GdbCmdVariant, i))
+
+/**
+ * typedef GdbCmdParseEntry - gdb command parser
+ *
+ * This structure keeps the information necessary to match a gdb command,
+ * parse it (extract its parameters), and select the correct handler for it.
+ *
+ * @cmd: The command to be matched
+ * @cmd_startswith: If true, @cmd is compared using startswith
+ * @schema: Each schema for the command parameter entry consists of 2 chars,
+ * the first char represents the parameter type handling the second char
+ * represents the delimiter for the next parameter.
+ *
+ * Currently supported schema types:
+ * 'l' -> unsigned long (stored in .val_ul)
+ * 'L' -> unsigned long long (stored in .val_ull)
+ * 's' -> string (stored in .data)
+ * 'o' -> single char (stored in .opcode)
+ * 't' -> thread id (stored in .thread_id)
+ * '?' -> skip according to delimiter
+ *
+ * Currently supported delimiters:
+ * '?' -> Stop at any delimiter (",;:=\0")
+ * '0' -> Stop at "\0"
+ * '.' -> Skip 1 char unless reached "\0"
+ * Any other value is treated as the delimiter value itself
+ *
+ * @allow_stop_reply: True iff the gdbstub can respond to this command with a
+ * "stop reply" packet. The list of commands that accept such response is
+ * defined at the GDB Remote Serial Protocol documentation. See:
+ * https://sourceware.org/gdb/onlinedocs/gdb/Stop-Reply-Packets.html#Stop-Reply-Packets.
+ *
+ * @need_cpu_context: Pass current CPU context to command handler via user_ctx.
+ */
+typedef struct GdbCmdParseEntry {
+ GdbCmdHandler handler;
+ const char *cmd;
+ bool cmd_startswith;
+ const char *schema;
+ bool allow_stop_reply;
+ bool need_cpu_context;
+} GdbCmdParseEntry;
+
+/**
+ * gdb_put_packet() - put string into gdb server's buffer so it is sent
+ * to the client
+ */
+int gdb_put_packet(const char *buf);
+
+/**
+ * gdb_extend_query_table() - Extend query table.
+ * @table: GPtrArray of GdbCmdParseEntry entries.
+ *
+ * The caller should free @table afterwards
+ */
+void gdb_extend_query_table(GPtrArray *table);
+
+/**
+ * gdb_extend_set_table() - Extend set table.
+ * @table: GPtrArray of GdbCmdParseEntry entries.
+ *
+ * The caller should free @table afterwards
+ */
+void gdb_extend_set_table(GPtrArray *table);
+
+/**
+ * gdb_extend_qsupported_features() - Extend the qSupported features string.
+ * @qsupported_features: The additional qSupported feature(s) string. The string
+ * should start with a semicolon and, if there are more than one feature, the
+ * features should be separate by a semicolon.
+ *
+ * The caller should free @qsupported_features afterwards if
+ * dynamically allocated.
+ */
+void gdb_extend_qsupported_features(char *qsupported_features);
+
+/**
+ * Convert a hex string to bytes. Conversion is done per byte, so 2 hex digits
+ * are converted to 1 byte. Invalid hex digits are treated as 0 digits.
+ */
+void gdb_hextomem(GByteArray *mem, const char *buf, int len);
+
+#endif /* GDBSTUB_COMMANDS_H */
diff --git a/include/gdbstub/helpers.h b/include/gdbstub/helpers.h
index 26140ef..6f7cc48 100644
--- a/include/gdbstub/helpers.h
+++ b/include/gdbstub/helpers.h
@@ -95,9 +95,13 @@ static inline uint8_t *gdb_get_reg_ptr(GByteArray *buf, int len)
#if TARGET_LONG_BITS == 64
#define gdb_get_regl(buf, val) gdb_get_reg64(buf, val)
#define ldtul_p(addr) ldq_p(addr)
+#define ldtul_le_p(addr) ldq_le_p(addr)
+#define ldtul_be_p(addr) ldq_be_p(addr)
#else
#define gdb_get_regl(buf, val) gdb_get_reg32(buf, val)
#define ldtul_p(addr) ldl_p(addr)
+#define ldtul_le_p(addr) ldl_le_p(addr)
+#define ldtul_be_p(addr) ldl_be_p(addr)
#endif
#endif /* _GDBSTUB_HELPERS_H_ */
diff --git a/include/gdbstub/syscalls.h b/include/gdbstub/syscalls.h
index 54ff724..d63228e 100644
--- a/include/gdbstub/syscalls.h
+++ b/include/gdbstub/syscalls.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2023 Linaro Ltd
*
- * SPDX-License-Identifier: LGPL-2.0+
+ * SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef _SYSCALLS_H_
diff --git a/include/gdbstub/user.h b/include/gdbstub/user.h
index 3b8358e..654986d 100644
--- a/include/gdbstub/user.h
+++ b/include/gdbstub/user.h
@@ -3,7 +3,7 @@
*
* Copyright (c) 2022 Linaro Ltd
*
- * SPDX-License-Identifier: LGPL-2.0+
+ * SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef GDBSTUB_USER_H
diff --git a/include/glib-compat.h b/include/glib-compat.h
index 86be439..2e32b90 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -37,6 +37,13 @@
#endif
/*
+ * These functions perform function pointer casts which can cause function call
+ * failure on Emscripten. Use g_slist_sort_with_data and g_list_sort_with_data
+ * instead of these functions.
+ */
+#pragma GCC poison g_slist_sort g_list_sort
+
+/*
* Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing
* use of functions from newer GLib via this compat header needs a little
* trickery to prevent warnings being emitted.
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/cpu.h b/include/hw/acpi/cpu.h
index e6e1a9e..32654dc 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -19,6 +19,8 @@
#include "hw/boards.h"
#include "hw/hotplug.h"
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
+
typedef struct AcpiCpuStatus {
CPUState *cpu;
uint64_t arch_id;
@@ -61,9 +63,10 @@ typedef void (*build_madt_cpu_fn)(int uid, const CPUArchIdList *apic_ids,
GArray *entry, bool force_enabled);
void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
- build_madt_cpu_fn build_madt_cpu, hwaddr io_base,
+ build_madt_cpu_fn build_madt_cpu, hwaddr base_addr,
const char *res_root,
- const char *event_handler_method);
+ const char *event_handler_method,
+ AmlRegionSpace rs);
void acpi_cpu_ospm_status(CPUHotplugState *cpu_st, ACPIOSTInfoList ***list);
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
index ba84ce0..d2dac87 100644
--- a/include/hw/acpi/generic_event_device.h
+++ b/include/hw/acpi/generic_event_device.h
@@ -62,6 +62,7 @@
#include "hw/sysbus.h"
#include "hw/acpi/memory_hotplug.h"
#include "hw/acpi/ghes.h"
+#include "hw/acpi/cpu.h"
#include "qom/object.h"
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
@@ -80,12 +81,16 @@ 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"
#define AML_GED_EVT_SEL "ESEL"
+#define AML_GED_EVT_CPU_SCAN_METHOD "\\_SB.GED.CSCN"
/*
* Platforms need to specify the GED event bitmap
@@ -95,6 +100,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED)
#define ACPI_GED_MEM_HOTPLUG_EVT 0x1
#define ACPI_GED_PWR_DOWN_EVT 0x2
#define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4
+#define ACPI_GED_CPU_HOTPLUG_EVT 0x8
typedef struct GEDState {
MemoryRegion evt;
@@ -106,6 +112,8 @@ struct AcpiGedState {
SysBusDevice parent_obj;
MemHotplugState memhp_state;
MemoryRegion container_memhp;
+ CPUHotplugState cpuhp_state;
+ MemoryRegion container_cpuhp;
GEDState ged_state;
uint32_t ged_event_bitmap;
qemu_irq irq;
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..a97904b 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -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/aspeed_adc.h b/include/hw/adc/aspeed_adc.h
index ff1d06e..f502f19 100644
--- a/include/hw/adc/aspeed_adc.h
+++ b/include/hw/adc/aspeed_adc.h
@@ -18,6 +18,7 @@
#define TYPE_ASPEED_2500_ADC TYPE_ASPEED_ADC "-ast2500"
#define TYPE_ASPEED_2600_ADC TYPE_ASPEED_ADC "-ast2600"
#define TYPE_ASPEED_1030_ADC TYPE_ASPEED_ADC "-ast1030"
+#define TYPE_ASPEED_2700_ADC TYPE_ASPEED_ADC "-ast2700"
OBJECT_DECLARE_TYPE(AspeedADCState, AspeedADCClass, ASPEED_ADC)
#define TYPE_ASPEED_ADC_ENGINE "aspeed.adc.engine"
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 849ba37..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;
@@ -164,13 +191,18 @@ struct AspeedSoCClass {
const hwaddr *memmap;
uint32_t num_cpus;
qemu_irq (*get_irq)(AspeedSoCState *s, int dev);
+ bool (*boot_from_emmc)(AspeedSoCState *s);
};
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,
@@ -192,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,
@@ -248,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/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
index 636203b..1eeaeec 100644
--- a/include/hw/arm/bcm2835_peripherals.h
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -33,6 +33,7 @@
#include "hw/usb/hcd-dwc2.h"
#include "hw/ssi/bcm2835_spi.h"
#include "hw/i2c/bcm2835_i2c.h"
+#include "hw/nvram/bcm2835_otp.h"
#include "hw/misc/unimp.h"
#include "qom/object.h"
@@ -71,7 +72,7 @@ struct BCMSocPeripheralBaseState {
BCM2835SPIState spi[1];
BCM2835I2CState i2c[3];
OrIRQState orgated_i2c_irq;
- UnimplementedDeviceState otp;
+ BCM2835OTPState otp;
UnimplementedDeviceState dbus;
UnimplementedDeviceState ave0;
UnimplementedDeviceState v3d;
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/raspberrypi-fw-defs.h b/include/hw/arm/raspberrypi-fw-defs.h
index 8b404e0..60b8e5b 100644
--- a/include/hw/arm/raspberrypi-fw-defs.h
+++ b/include/hw/arm/raspberrypi-fw-defs.h
@@ -56,6 +56,7 @@ enum rpi_firmware_property_tag {
RPI_FWREQ_GET_THROTTLED = 0x00030046,
RPI_FWREQ_GET_CLOCK_MEASURED = 0x00030047,
RPI_FWREQ_NOTIFY_REBOOT = 0x00030048,
+ RPI_FWREQ_GET_PRIVATE_KEY = 0x00030081,
RPI_FWREQ_SET_CLOCK_STATE = 0x00038001,
RPI_FWREQ_SET_CLOCK_RATE = 0x00038002,
RPI_FWREQ_SET_VOLTAGE = 0x00038003,
@@ -73,6 +74,7 @@ enum rpi_firmware_property_tag {
RPI_FWREQ_SET_PERIPH_REG = 0x00038045,
RPI_FWREQ_GET_POE_HAT_VAL = 0x00030049,
RPI_FWREQ_SET_POE_HAT_VAL = 0x00038049,
+ RPI_FWREQ_SET_PRIVATE_KEY = 0x00038081,
RPI_FWREQ_SET_POE_HAT_VAL_OLD = 0x00030050,
RPI_FWREQ_NOTIFY_XHCI_RESET = 0x00030058,
RPI_FWREQ_GET_REBOOT_FLAGS = 0x00030064,
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 5ec2e6c..e5e2d09 100644
--- a/include/hw/arm/smmu-common.h
+++ b/include/hw/arm/smmu-common.h
@@ -37,6 +37,9 @@
#define VMSA_IDXMSK(isz, strd, lvl) ((1ULL << \
VMSA_BIT_LVL(isz, strd, lvl)) - 1)
+#define CACHED_ENTRY_TO_ADDR(ent, addr) ((ent)->entry.translated_addr + \
+ ((addr) & (ent)->entry.addr_mask))
+
/*
* Page table walk error types
*/
@@ -49,10 +52,18 @@ typedef enum {
SMMU_PTW_ERR_PERMISSION, /* Permission fault */
} SMMUPTWEventType;
+/* SMMU Stage */
+typedef enum {
+ SMMU_STAGE_1 = 1,
+ SMMU_STAGE_2,
+ SMMU_NESTED,
+} SMMUStage;
+
typedef struct SMMUPTWEventInfo {
- int stage;
+ SMMUStage stage;
SMMUPTWEventType type;
dma_addr_t addr; /* fetched address that induced an abort, if any */
+ bool is_ipa_descriptor; /* src for fault in nested translation. */
} SMMUPTWEventInfo;
typedef struct SMMUTransTableInfo {
@@ -67,6 +78,7 @@ typedef struct SMMUTLBEntry {
IOMMUTLBEntry entry;
uint8_t level;
uint8_t granule;
+ IOMMUAccessFlags parent_perm;
} SMMUTLBEntry;
/* Stage-2 configuration. */
@@ -77,7 +89,7 @@ typedef struct SMMUS2Cfg {
bool record_faults; /* Record fault events (S2R) */
uint8_t granule_sz; /* Granule page shift (based on S2TG) */
uint8_t eff_ps; /* Effective PA output range (based on S2PS) */
- uint16_t vmid; /* Virtual Machine ID (S2VMID) */
+ int vmid; /* Virtual Machine ID (S2VMID) */
uint64_t vttb; /* Address of translation table base (S2TTB) */
} SMMUS2Cfg;
@@ -88,7 +100,7 @@ typedef struct SMMUS2Cfg {
*/
typedef struct SMMUTransCfg {
/* Shared fields between stage-1 and stage-2. */
- int stage; /* translation stage */
+ SMMUStage stage; /* translation stage */
bool disabled; /* smmu is disabled */
bool bypassed; /* translation is bypassed */
bool aborted; /* translation is aborted */
@@ -98,10 +110,9 @@ 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 */
- uint16_t asid;
+ int asid;
SMMUTransTableInfo tt[2];
/* Used by stage-2 only. */
struct SMMUS2Cfg s2cfg;
@@ -125,12 +136,17 @@ typedef struct SMMUPciBus {
typedef struct SMMUIOTLBKey {
uint64_t iova;
- uint16_t asid;
- uint16_t vmid;
+ int asid;
+ int vmid;
uint8_t tg;
uint8_t level;
} SMMUIOTLBKey;
+typedef struct SMMUSIDRange {
+ uint32_t start;
+ uint32_t end;
+} SMMUSIDRange;
+
struct SMMUState {
/* <private> */
SysBusDevice dev;
@@ -173,8 +189,16 @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
* smmu_ptw - Perform the page table walk for a given iova / access flags
* pair, according to @cfg translation config
*/
-int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
- SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info);
+int smmu_ptw(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t iova,
+ IOMMUAccessFlags perm, SMMUTLBEntry *tlbe,
+ SMMUPTWEventInfo *info);
+
+/*
+ * smmu_translate - Look for a translation in TLB, if not, do a PTW.
+ * Returns NULL on PTW error or incase of TLB permission errors.
+ */
+SMMUTLBEntry *smmu_translate(SMMUState *bs, SMMUTransCfg *cfg, dma_addr_t addr,
+ IOMMUAccessFlags flag, SMMUPTWEventInfo *info);
/**
* select_tt - compute which translation table shall be used according to
@@ -182,22 +206,25 @@ int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
*/
SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
-/* Return the iommu mr associated to @sid, or NULL if none */
-IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
+/* Return the SMMUDevice associated to @sid, or NULL if none */
+SMMUDevice *smmu_find_sdev(SMMUState *s, uint32_t sid);
#define SMMU_IOTLB_MAX_SIZE 256
SMMUTLBEntry *smmu_iotlb_lookup(SMMUState *bs, SMMUTransCfg *cfg,
SMMUTransTableInfo *tt, hwaddr iova);
void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *entry);
-SMMUIOTLBKey smmu_get_iotlb_key(uint16_t asid, uint16_t vmid, uint64_t iova,
+SMMUIOTLBKey smmu_get_iotlb_key(int asid, int vmid, uint64_t iova,
uint8_t tg, uint8_t level);
void smmu_iotlb_inv_all(SMMUState *s);
-void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
-void smmu_iotlb_inv_vmid(SMMUState *s, uint16_t vmid);
+void smmu_iotlb_inv_asid_vmid(SMMUState *s, int asid, int vmid);
+void smmu_iotlb_inv_vmid(SMMUState *s, int vmid);
+void smmu_iotlb_inv_vmid_s1(SMMUState *s, int vmid);
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 73ad319..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:
@@ -237,6 +256,9 @@ typedef struct {
* purposes only.
* Applies only to default memory backend, i.e., explicit memory backend
* wasn't used.
+ * @smbios_memory_device_size:
+ * Default size of memory device,
+ * SMBIOS 3.1.0 "7.18 Memory Device (Type 17)"
*/
struct MachineClass {
/*< private >*/
@@ -250,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;
@@ -263,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;
@@ -304,6 +326,9 @@ struct MachineClass {
const CPUArchIdList *(*possible_cpu_arch_ids)(MachineState *machine);
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);
};
/**
@@ -359,6 +384,10 @@ typedef struct CpuTopology {
unsigned int max_cpus;
} CpuTopology;
+typedef struct SmpCache {
+ SmpCacheProperties props[CACHE_LEVEL_AND_TYPE__MAX];
+} SmpCache;
+
/**
* MachineState:
*/
@@ -383,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
@@ -404,17 +434,335 @@ 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;
};
+/*
+ * The macros which follow are intended to facilitate the
+ * definition of versioned machine types, using a somewhat
+ * similar pattern across targets.
+ *
+ * For example, a macro that can be used to define versioned
+ * 'virt' machine types would look like:
+ *
+ * #define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \
+ * static void MACHINE_VER_SYM(class_init, virt, __VA_ARGS__)( \
+ * ObjectClass *oc, \
+ * void *data) \
+ * { \
+ * MachineClass *mc = MACHINE_CLASS(oc); \
+ * MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \
+ * mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " Virtual Machine"; \
+ * MACHINE_VER_DEPRECATION(__VA_ARGS__); \
+ * if (latest) { \
+ * mc->alias = "virt"; \
+ * } \
+ * } \
+ * static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = { \
+ * .name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
+ * .parent = TYPE_VIRT_MACHINE, \
+ * .class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
+ * }; \
+ * static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \
+ * { \
+ * MACHINE_VER_DELETION(__VA_ARGS__); \
+ * type_register_static(&MACHINE_VER_SYM(info, virt, __VA_ARGS__)); \
+ * } \
+ * type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__));
+ *
+ * Following this, one (or more) helpers can be added for
+ * whichever scenarios need to be catered for with a machine:
+ *
+ * // Normal 2 digit, marked as latest e.g. 'virt-9.0'
+ * #define DEFINE_VIRT_MACHINE_LATEST(major, minor) \
+ * DEFINE_VIRT_MACHINE_IMPL(true, major, minor)
+ *
+ * // Normal 2 digit e.g. 'virt-9.0'
+ * #define DEFINE_VIRT_MACHINE(major, minor) \
+ * DEFINE_VIRT_MACHINE_IMPL(false, major, minor)
+ *
+ * // Bugfix 3 digit e.g. 'virt-9.0.1'
+ * #define DEFINE_VIRT_MACHINE_BUGFIX(major, minor, micro) \
+ * DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro)
+ *
+ * // Tagged 2 digit e.g. 'virt-9.0-extra'
+ * #define DEFINE_VIRT_MACHINE_TAGGED(major, minor, tag) \
+ * DEFINE_VIRT_MACHINE_IMPL(false, major, minor, _, tag)
+ *
+ * // Tagged bugfix 2 digit e.g. 'virt-9.0.1-extra'
+ * #define DEFINE_VIRT_MACHINE_TAGGED(major, minor, micro, tag) \
+ * DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro, _, tag)
+ */
+
+/*
+ * Helper for dispatching different macros based on how
+ * many __VA_ARGS__ are passed. Supports 1 to 5 variadic
+ * arguments, with the called target able to be prefixed
+ * with 0 or more fixed arguments too. To be called thus:
+ *
+ * _MACHINE_VER_PICK(__VA_ARGS,
+ * MACRO_MATCHING_5_ARGS,
+ * MACRO_MATCHING_4_ARGS,
+ * MACRO_MATCHING_3_ARGS,
+ * MACRO_MATCHING_2_ARGS,
+ * MACRO_MATCHING_1_ARG) (FIXED-ARG-1,
+ * ...,
+ * FIXED-ARG-N,
+ * __VA_ARGS__)
+ */
+#define _MACHINE_VER_PICK(x1, x2, x3, x4, x5, x6, ...) x6
+
+/*
+ * Construct a human targeted machine version string.
+ *
+ * Can be invoked with various signatures
+ *
+ * MACHINE_VER_STR(sym, prefix, major, minor)
+ * MACHINE_VER_STR(sym, prefix, major, minor, micro)
+ * MACHINE_VER_STR(sym, prefix, major, minor, _, tag)
+ * MACHINE_VER_STR(sym, prefix, major, minor, micro, _, tag)
+ *
+ * Respectively emitting symbols with the format
+ *
+ * "{major}.{minor}"
+ * "{major}.{minor}-{tag}"
+ * "{major}.{minor}.{micro}"
+ * "{major}.{minor}.{micro}-{tag}"
+ */
+#define _MACHINE_VER_STR2(major, minor) \
+ #major "." #minor
+
+#define _MACHINE_VER_STR3(major, minor, micro) \
+ #major "." #minor "." #micro
+
+#define _MACHINE_VER_STR4(major, minor, _unused_, tag) \
+ #major "." #minor "-" #tag
+
+#define _MACHINE_VER_STR5(major, minor, micro, _unused_, tag) \
+ #major "." #minor "." #micro "-" #tag
+
+#define MACHINE_VER_STR(...) \
+ _MACHINE_VER_PICK(__VA_ARGS__, \
+ _MACHINE_VER_STR5, \
+ _MACHINE_VER_STR4, \
+ _MACHINE_VER_STR3, \
+ _MACHINE_VER_STR2) (__VA_ARGS__)
+
+
+/*
+ * Construct a QAPI type name for a versioned machine
+ * type
+ *
+ * Can be invoked with various signatures
+ *
+ * MACHINE_VER_TYPE_NAME(prefix, major, minor)
+ * MACHINE_VER_TYPE_NAME(prefix, major, minor, micro)
+ * MACHINE_VER_TYPE_NAME(prefix, major, minor, _, tag)
+ * MACHINE_VER_TYPE_NAME(prefix, major, minor, micro, _, tag)
+ *
+ * Respectively emitting symbols with the format
+ *
+ * "{prefix}-{major}.{minor}"
+ * "{prefix}-{major}.{minor}.{micro}"
+ * "{prefix}-{major}.{minor}-{tag}"
+ * "{prefix}-{major}.{minor}.{micro}-{tag}"
+ */
+#define _MACHINE_VER_TYPE_NAME2(prefix, major, minor) \
+ prefix "-" #major "." #minor TYPE_MACHINE_SUFFIX
+
+#define _MACHINE_VER_TYPE_NAME3(prefix, major, minor, micro) \
+ prefix "-" #major "." #minor "." #micro TYPE_MACHINE_SUFFIX
+
+#define _MACHINE_VER_TYPE_NAME4(prefix, major, minor, _unused_, tag) \
+ prefix "-" #major "." #minor "-" #tag TYPE_MACHINE_SUFFIX
+
+#define _MACHINE_VER_TYPE_NAME5(prefix, major, minor, micro, _unused_, tag) \
+ prefix "-" #major "." #minor "." #micro "-" #tag TYPE_MACHINE_SUFFIX
+
+#define MACHINE_VER_TYPE_NAME(prefix, ...) \
+ _MACHINE_VER_PICK(__VA_ARGS__, \
+ _MACHINE_VER_TYPE_NAME5, \
+ _MACHINE_VER_TYPE_NAME4, \
+ _MACHINE_VER_TYPE_NAME3, \
+ _MACHINE_VER_TYPE_NAME2) (prefix, __VA_ARGS__)
+
+/*
+ * Construct a name for a versioned machine type that is
+ * suitable for use as a C symbol (function/variable/etc).
+ *
+ * Can be invoked with various signatures
+ *
+ * MACHINE_VER_SYM(sym, prefix, major, minor)
+ * MACHINE_VER_SYM(sym, prefix, major, minor, micro)
+ * MACHINE_VER_SYM(sym, prefix, major, minor, _, tag)
+ * MACHINE_VER_SYM(sym, prefix, major, minor, micro, _, tag)
+ *
+ * Respectively emitting symbols with the format
+ *
+ * {prefix}_machine_{major}_{minor}_{sym}
+ * {prefix}_machine_{major}_{minor}_{micro}_{sym}
+ * {prefix}_machine_{major}_{minor}_{tag}_{sym}
+ * {prefix}_machine_{major}_{minor}_{micro}_{tag}_{sym}
+ */
+#define _MACHINE_VER_SYM2(sym, prefix, major, minor) \
+ prefix ## _machine_ ## major ## _ ## minor ## _ ## sym
+
+#define _MACHINE_VER_SYM3(sym, prefix, major, minor, micro) \
+ prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## sym
+
+#define _MACHINE_VER_SYM4(sym, prefix, major, minor, _unused_, tag) \
+ prefix ## _machine_ ## major ## _ ## minor ## _ ## tag ## _ ## sym
+
+#define _MACHINE_VER_SYM5(sym, prefix, major, minor, micro, _unused_, tag) \
+ prefix ## _machine_ ## major ## _ ## minor ## _ ## micro ## _ ## tag ## _ ## sym
+
+#define MACHINE_VER_SYM(sym, prefix, ...) \
+ _MACHINE_VER_PICK(__VA_ARGS__, \
+ _MACHINE_VER_SYM5, \
+ _MACHINE_VER_SYM4, \
+ _MACHINE_VER_SYM3, \
+ _MACHINE_VER_SYM2) (sym, prefix, __VA_ARGS__)
+
+
+/*
+ * How many years/major releases for each phase
+ * of the life cycle. Assumes use of versioning
+ * 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
+
+/*
+ * Expands to a static string containing a deprecation
+ * message for a versioned machine type
+ */
+#define MACHINE_VER_DEPRECATION_MSG \
+ "machines more than " stringify(MACHINE_VER_DEPRECATION_MAJOR) \
+ " years old are subject to deletion after " \
+ stringify(MACHINE_VER_DELETION_MAJOR) " years"
+
+#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) \
+ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
+#define _MACHINE_VER_IS_EXPIRED4(cutoff, major, minor, _unused, tag) \
+ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
+#define _MACHINE_VER_IS_EXPIRED5(cutoff, major, minor, micro, _unused, tag) \
+ _MACHINE_VER_IS_EXPIRED_IMPL(cutoff, major, minor)
+
+#define _MACHINE_IS_EXPIRED(cutoff, ...) \
+ _MACHINE_VER_PICK(__VA_ARGS__, \
+ _MACHINE_VER_IS_EXPIRED5, \
+ _MACHINE_VER_IS_EXPIRED4, \
+ _MACHINE_VER_IS_EXPIRED3, \
+ _MACHINE_VER_IS_EXPIRED2) (cutoff, __VA_ARGS__)
+
+/*
+ * Evaluates true when a machine type with (major, minor)
+ * or (major, minor, micro) version should be considered
+ * deprecated based on the current versioned machine type
+ * lifecycle rules
+ */
+#define MACHINE_VER_IS_DEPRECATED(...) \
+ _MACHINE_IS_EXPIRED(MACHINE_VER_DEPRECATION_MAJOR, __VA_ARGS__)
+
+/*
+ * Evaluates true when a machine type with (major, minor)
+ * or (major, minor, micro) version should be considered
+ * for deletion based on the current versioned machine type
+ * lifecycle rules
+ */
+#define MACHINE_VER_SHOULD_DELETE(...) \
+ _MACHINE_IS_EXPIRED(MACHINE_VER_DELETION_MAJOR, __VA_ARGS__)
+
+/*
+ * Sets the deprecation reason for a versioned machine based
+ * on its age
+ *
+ * This must be unconditionally used in the _class_init
+ * function for all machine types which support versioning.
+ *
+ * Initially it will effectively be a no-op, but after a
+ * suitable period of time has passed, it will set the
+ * 'deprecation_reason' field on the machine, to warn users
+ * about forthcoming removal.
+ */
+#define MACHINE_VER_DEPRECATION(...) \
+ do { \
+ if (MACHINE_VER_IS_DEPRECATED(__VA_ARGS__)) { \
+ mc->deprecation_reason = MACHINE_VER_DEPRECATION_MSG; \
+ } \
+ } while (0)
+
+/*
+ * Prevents registration of a versioned machined based on
+ * its age
+ *
+ * This must be unconditionally used in the register
+ * method for all machine types which support versioning.
+ *
+ * Inijtially it will effectively be a no-op, but after a
+ * suitable period of time has passed, it will cause
+ * execution of the method to return, avoiding registration
+ * of the machine
+ */
+#define MACHINE_VER_DELETION(...) \
+ do { \
+ if (MACHINE_VER_SHOULD_DELETE(__VA_ARGS__)) { \
+ 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); \
@@ -430,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;
@@ -505,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/cpu.h b/include/hw/core/cpu.h
index a2c8536..33296a1 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,8 @@ 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;
#endif
IcountDecr icount_decr;
bool can_do_io;
@@ -402,7 +412,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 +470,6 @@ struct CPUState {
CPUClass *cc;
/*< public >*/
- int nr_cores;
int nr_threads;
struct QemuThread *thread;
@@ -496,6 +504,7 @@ struct CPUState {
QSIMPLEQ_HEAD(, qemu_work_item) work_list;
struct CPUAddressSpace *cpu_ases;
+ int cpu_ases_count;
int num_ases;
AddressSpace *as;
MemoryRegion *memory;
@@ -578,7 +587,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);
}
@@ -594,15 +603,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.
*
@@ -621,8 +621,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
@@ -672,8 +670,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:
@@ -697,7 +693,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.
@@ -744,7 +739,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:
@@ -811,22 +814,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.
*
@@ -962,9 +949,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);
}
/**
@@ -985,6 +970,14 @@ void cpu_reset_interrupt(CPUState *cpu, int mask);
void cpu_exit(CPUState *cpu);
/**
+ * cpu_pause:
+ * @cpu: The CPU to pause.
+ *
+ * Pauses CPU, i.e. puts CPU into stopped state.
+ */
+void cpu_pause(CPUState *cpu);
+
+/**
* cpu_resume:
* @cpu: The CPU to resume.
*
@@ -1001,6 +994,12 @@ void cpu_resume(CPUState *cpu);
void cpu_remove_sync(CPUState *cpu);
/**
+ * free_queued_cpu_work() - free all items on CPU work queue
+ * @cpu: The CPU which work queue to free.
+ */
+void free_queued_cpu_work(CPUState *cpu);
+
+/**
* process_queued_cpu_work() - process all items on CPU work queue
* @cpu: The CPU which work queue to process.
*/
@@ -1099,36 +1098,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
@@ -1144,31 +1113,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/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 279b276..ed6cd50 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -164,7 +164,7 @@ typedef struct CXLEventLog {
} CXLEventLog;
typedef struct CXLCCI {
- const struct cxl_cmd (*cxl_cmd_set)[256];
+ struct cxl_cmd cxl_cmd_set[256][256];
struct cel_log {
uint16_t opcode;
uint16_t effect;
@@ -176,16 +176,34 @@ 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 */
+ struct {
+ uint8_t active_slot;
+ uint8_t staged_slot;
+ bool slot[4];
+ uint8_t curr_action;
+ uint8_t curr_slot;
+ /* handle partial transfers */
+ bool transferring;
+ size_t prev_offset;
+ size_t prev_len;
+ time_t last_partxfer;
+ } fw;
+
size_t payload_max;
/* Pointer to device hosting the CCI */
DeviceState *d;
/* Pointer to the device hosting the protocol conversion */
DeviceState *intf;
+ bool initialized;
} CXLCCI;
typedef struct cxl_device_state {
@@ -234,7 +252,7 @@ typedef struct cxl_device_state {
} timestamp;
/* memory region size, HDM */
- uint64_t mem_size;
+ uint64_t static_mem_size;
uint64_t pmem_size;
uint64_t vmem_size;
@@ -249,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
@@ -301,6 +319,9 @@ 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,
size_t len_in, uint8_t *pl_in,
size_t *len_out, uint8_t *pl_out,
@@ -395,9 +416,14 @@ static inline void __toggle_media(CXLDeviceState *cxl_dstate, int val)
#define cxl_dev_enable_media(cxlds) \
do { __toggle_media((cxlds), 0x1); } while (0)
-static inline bool sanitize_running(CXLCCI *cci)
+static inline bool cxl_dev_media_disabled(CXLDeviceState *cxl_dstate)
+{
+ uint64_t dev_status_reg = cxl_dstate->mbox_reg_state64[R_CXL_MEM_DEV_STS];
+ return FIELD_EX64(dev_status_reg, CXL_MEM_DEV_STS, MEDIA_STATUS) == 0x3;
+}
+static inline bool scan_media_running(CXLCCI *cci)
{
- return !!cci->bg.runtime && cci->bg.opcode == 0x4400;
+ return !!cci->bg.runtime && cci->bg.opcode == 0x4304;
}
typedef struct CXLError {
@@ -420,6 +446,115 @@ typedef struct CXLPoison {
typedef QLIST_HEAD(, CXLPoison) CXLPoisonList;
#define CXL_POISON_LIST_LIMIT 256
+/* CXL memory device patrol scrub control attributes */
+typedef struct CXLMemPatrolScrubReadAttrs {
+ uint8_t scrub_cycle_cap;
+ uint16_t scrub_cycle;
+ uint8_t scrub_flags;
+} QEMU_PACKED CXLMemPatrolScrubReadAttrs;
+
+typedef struct CXLMemPatrolScrubWriteAttrs {
+ uint8_t scrub_cycle_hr;
+ uint8_t scrub_flags;
+} QEMU_PACKED CXLMemPatrolScrubWriteAttrs;
+
+#define CXL_MEMDEV_PS_GET_FEATURE_VERSION 0x01
+#define CXL_MEMDEV_PS_SET_FEATURE_VERSION 0x01
+#define CXL_MEMDEV_PS_SCRUB_CYCLE_CHANGE_CAP_DEFAULT BIT(0)
+#define CXL_MEMDEV_PS_SCRUB_REALTIME_REPORT_CAP_DEFAULT BIT(1)
+#define CXL_MEMDEV_PS_CUR_SCRUB_CYCLE_DEFAULT 12
+#define CXL_MEMDEV_PS_MIN_SCRUB_CYCLE_DEFAULT 1
+#define CXL_MEMDEV_PS_ENABLE_DEFAULT 0
+
+/* CXL memory device DDR5 ECS control attributes */
+#define CXL_ECS_GET_FEATURE_VERSION 0x01
+#define CXL_ECS_SET_FEATURE_VERSION 0x01
+#define CXL_ECS_LOG_ENTRY_TYPE_DEFAULT 0x01
+#define CXL_ECS_REALTIME_REPORT_CAP_DEFAULT 1
+#define CXL_ECS_THRESHOLD_COUNT_DEFAULT 3 /* 3: 256, 4: 1024, 5: 4096 */
+#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 {
+ uint64_t start_dpa;
+ uint64_t len;
+ uint8_t tag[0x10];
+ uint16_t shared_seq;
+ uint8_t rsvd[0x6];
+} QEMU_PACKED CXLDCExtentRaw;
+
+typedef struct CXLDCExtent {
+ uint64_t start_dpa;
+ uint64_t len;
+ uint8_t tag[0x10];
+ uint16_t shared_seq;
+ uint8_t rsvd[0x6];
+
+ QTAILQ_ENTRY(CXLDCExtent) node;
+} CXLDCExtent;
+typedef QTAILQ_HEAD(, CXLDCExtent) CXLDCExtentList;
+
+typedef struct CXLDCExtentGroup {
+ CXLDCExtentList list;
+ QTAILQ_ENTRY(CXLDCExtentGroup) node;
+} CXLDCExtentGroup;
+typedef QTAILQ_HEAD(, CXLDCExtentGroup) CXLDCExtentGroupList;
+
+typedef struct CXLDCRegion {
+ uint64_t base; /* aligned to 256*MiB */
+ uint64_t decode_len; /* aligned to 256*MiB */
+ uint64_t len;
+ uint64_t block_size;
+ uint32_t dsmadhandle;
+ uint8_t flags;
+ unsigned long *blk_bitmap;
+} CXLDCRegion;
+
+typedef struct CXLSetFeatureInfo {
+ QemuUUID uuid;
+ uint8_t data_transfer_flag;
+ bool data_saved_across_reset;
+ uint16_t data_offset;
+ 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;
@@ -441,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;
@@ -452,6 +593,38 @@ struct CXLType3Dev {
unsigned int poison_list_cnt;
bool poison_list_overflowed;
uint64_t poison_list_overflow_ts;
+ /* Poison Injection - backup */
+ CXLPoisonList poison_list_bkp;
+ CXLPoisonList scan_media_results;
+ bool scan_media_hasrun;
+
+ CXLSetFeatureInfo set_feat_info;
+
+ /* Patrol scrub control attributes */
+ CXLMemPatrolScrubReadAttrs patrol_scrub_attrs;
+ CXLMemPatrolScrubWriteAttrs patrol_scrub_wr_attrs;
+ /* ECS control attributes */
+ CXLMemECSReadAttrs ecs_attrs;
+ CXLMemECSWriteAttrs ecs_wr_attrs;
+
+ struct dynamic_capacity {
+ HostMemoryBackend *host_dc;
+ AddressSpace host_dc_as;
+ /*
+ * total_capacity is equivalent to the dynamic capability
+ * memory region size.
+ */
+ uint64_t total_capacity; /* 256M aligned */
+ CXLDCExtentList extents;
+ CXLDCExtentGroupList extents_pending;
+ uint32_t total_extent_count;
+ uint32_t ext_list_gen_seq;
+
+ 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"
@@ -498,9 +671,36 @@ CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl,
size_t *len);
CXLRetCode cxl_event_clear_records(CXLDeviceState *cxlds,
CXLClearEventPayload *pl);
+void cxl_discard_all_event_records(CXLDeviceState *cxlds);
void cxl_event_irq_assert(CXLType3Dev *ct3d);
void cxl_set_poison_list_overflowed(CXLType3Dev *ct3d);
-
+void cxl_clear_poison_list_overflowed(CXLType3Dev *ct3d);
+
+CXLDCRegion *cxl_find_dc_region(CXLType3Dev *ct3d, uint64_t dpa, uint64_t len);
+
+void cxl_remove_extent_from_extent_list(CXLDCExtentList *list,
+ CXLDCExtent *extent);
+void cxl_insert_extent_to_extent_list(CXLDCExtentList *list, uint64_t dpa,
+ uint64_t len, uint8_t *tag,
+ uint16_t shared_seq);
+bool test_any_bits_set(const unsigned long *addr, unsigned long nr,
+ unsigned long size);
+bool cxl_extents_contains_dpa_range(CXLDCExtentList *list,
+ uint64_t dpa, uint64_t len);
+CXLDCExtentGroup *cxl_insert_extent_to_extent_group(CXLDCExtentGroup *group,
+ uint64_t dpa,
+ uint64_t len,
+ uint8_t *tag,
+ uint16_t shared_seq);
+void cxl_extent_group_list_insert_tail(CXLDCExtentGroupList *list,
+ CXLDCExtentGroup *group);
+void cxl_extent_group_list_delete_front(CXLDCExtentGroupList *list);
+void ct3_set_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
+ uint64_t len);
+void ct3_clear_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
+ uint64_t len);
+bool ct3_test_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
+ uint64_t len);
#endif
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 5170b8d..38cadaa 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -166,4 +166,22 @@ typedef struct CXLEventMemoryModule {
uint8_t reserved[0x3d];
} QEMU_PACKED CXLEventMemoryModule;
+/*
+ * CXL r3.1 section Table 8-50: Dynamic Capacity Event Record
+ * All fields little endian.
+ */
+typedef struct CXLEventDynamicCapacity {
+ CXLEventRecordHdr hdr;
+ uint8_t type;
+ uint8_t validity_flags;
+ uint16_t host_id;
+ uint8_t updated_region_id;
+ uint8_t flags;
+ uint8_t reserved2[2];
+ uint8_t dynamic_capacity_extent[0x28]; /* defined in cxl_device.h */
+ uint8_t reserved[0x18];
+ uint32_t extents_avail;
+ uint32_t tags_avail;
+} QEMU_PACKED CXLEventDynamicCapacity;
+
#endif /* CXL_EVENTS_H */
diff --git a/include/hw/cxl/cxl_mailbox.h b/include/hw/cxl/cxl_mailbox.h
new file mode 100644
index 0000000..9008402
--- /dev/null
+++ b/include/hw/cxl/cxl_mailbox.h
@@ -0,0 +1,19 @@
+/*
+ * QEMU CXL Mailbox
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See the
+ * COPYING file in the top-level directory.
+ */
+
+#ifndef CXL_MAILBOX_H
+#define CXL_MAILBOX_H
+
+#define CXL_MBOX_IMMEDIATE_CONFIG_CHANGE (1 << 1)
+#define CXL_MBOX_IMMEDIATE_DATA_CHANGE (1 << 2)
+#define CXL_MBOX_IMMEDIATE_POLICY_CHANGE (1 << 3)
+#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 904eecf..e6b2fe7 100644
--- a/include/hw/gpio/aspeed_gpio.h
+++ b/include/hw/gpio/aspeed_gpio.h
@@ -70,11 +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 {
@@ -87,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 a064479..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_MAX_POOL_SIZE 0x800
+#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 {
@@ -257,7 +270,7 @@ struct AspeedI2CState {
uint32_t ctrl_global;
uint32_t new_clk_divider;
MemoryRegion pool_iomem;
- uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
+ uint8_t share_pool[ASPEED_I2C_SHARE_POOL_SIZE];
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
MemoryRegion *dram_mr;
@@ -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 7fa0a69..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 */
@@ -292,6 +295,8 @@ struct IntelIOMMUState {
/* list of registered notifiers */
QLIST_HEAD(, VTDAddressSpace) vtd_as_with_notifiers;
+ GHashTable *vtd_host_iommu_dev; /* HostIOMMUDevice */
+
/* interrupt remapping */
bool intr_enabled; /* Whether guest enabled IR */
dma_addr_t intr_root; /* Interrupt remapping table pointer */
@@ -303,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 46bc411..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,8 +313,38 @@ 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, isdefault, malias, ...) \
+ static void MACHINE_VER_SYM(init, namesym, __VA_ARGS__)( \
+ MachineState *machine) \
+ { \
+ initfn(machine); \
+ } \
+ static void MACHINE_VER_SYM(class_init, namesym, __VA_ARGS__)( \
+ ObjectClass *oc, \
+ 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__) = \
+ { \
+ .name = MACHINE_VER_TYPE_NAME(namestr, __VA_ARGS__), \
+ .parent = TYPE_PC_MACHINE, \
+ .class_init = MACHINE_VER_SYM(class_init, namesym, __VA_ARGS__), \
+ }; \
+ static void MACHINE_VER_SYM(register, namesym, __VA_ARGS__)(void) \
+ { \
+ MACHINE_VER_DELETION(__VA_ARGS__); \
+ type_register_static(&MACHINE_VER_SYM(info, namesym, __VA_ARGS__)); \
+ } \
+ type_init(MACHINE_VER_SYM(register, namesym, __VA_ARGS__));
+
#endif
diff --git a/include/hw/i386/sgx-epc.h b/include/hw/i386/sgx-epc.h
index 3e00efd..41d55da 100644
--- a/include/hw/i386/sgx-epc.h
+++ b/include/hw/i386/sgx-epc.h
@@ -58,6 +58,7 @@ typedef struct SGXEPCState {
int nr_sections;
} SGXEPCState;
+bool check_sgx_support(void);
bool sgx_epc_get_section(int section_nr, uint64_t *addr, uint64_t *size);
void sgx_epc_build_srat(GArray *table_data);
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/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 eccc2e0..9be1d73 100644
--- a/include/hw/intc/loongarch_extioi.h
+++ b/include/hw/intc/loongarch_extioi.h
@@ -5,86 +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_INT_ENCODE) \
- | 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 8685e27..c96b5e1 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -77,15 +77,13 @@ ssize_t load_image_targphys(const char *filename, hwaddr,
ssize_t load_image_mr(const char *filename, MemoryRegion *mr);
/* This is the limit on the maximum uncompressed image size that
- * load_image_gzipped_buffer() and load_image_gzipped() will read. It prevents
+ * load_image_gzipped_buffer() will read. It prevents
* g_malloc() in those functions from allocating a huge amount of memory.
*/
#define LOAD_IMAGE_MAX_GUNZIP_BYTES (256 << 20)
ssize_t load_image_gzipped_buffer(const char *filename, uint64_t max_sz,
uint8_t **buffer);
-ssize_t load_image_gzipped(const char *filename, hwaddr addr, uint64_t max_sz);
-
/**
* unpack_efi_zboot_image:
* @buffer: pointer to a variable holding the address of a buffer containing the
@@ -103,7 +101,7 @@ ssize_t load_image_gzipped(const char *filename, hwaddr addr, 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
@@ -122,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)
@@ -153,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);
@@ -188,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:
@@ -204,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)
@@ -284,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:
@@ -338,7 +322,6 @@ void *rom_ptr(hwaddr addr, size_t size);
* rom_ptr().
*/
void *rom_ptr_for_as(AddressSpace *as, hwaddr addr, size_t size);
-void hmp_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \
rom_add_file(_f, NULL, _a, _i, false, NULL, NULL)
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 8fdfacf..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"
@@ -20,7 +18,7 @@
#define VIRT_FWCFG_BASE 0x1e020000UL
#define VIRT_BIOS_BASE 0x1c000000UL
#define VIRT_BIOS_SIZE (16 * MiB)
-#define VIRT_FLASH_SECTOR_SIZE (128 * KiB)
+#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
#define VIRT_FLASH0_BASE VIRT_BIOS_BASE
#define VIRT_FLASH0_SIZE VIRT_BIOS_SIZE
#define VIRT_FLASH1_BASE 0x1d000000UL
@@ -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 58db28d..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)
@@ -349,6 +351,10 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
#define SCU_AST2600_H_PLL_BYPASS_EN (0x1 << 24)
#define SCU_AST2600_H_PLL_OFF (0x1 << 23)
+/* STRAP1 SCU500 */
+#define SCU_AST2600_HW_STRAP_BOOT_SRC_EMMC (0x1 << 2)
+#define SCU_AST2600_HW_STRAP_BOOT_SRC_SPI (0x0 << 2)
+
/*
* SCU310 Clock Selection Register Set 4 (for Aspeed AST1030 SOC)
*
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/bcm2835_property.h b/include/hw/misc/bcm2835_property.h
index ba88966..2f93fd0 100644
--- a/include/hw/misc/bcm2835_property.h
+++ b/include/hw/misc/bcm2835_property.h
@@ -11,6 +11,7 @@
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/display/bcm2835_fb.h"
+#include "hw/nvram/bcm2835_otp.h"
#include "qom/object.h"
#define TYPE_BCM2835_PROPERTY "bcm2835-property"
@@ -26,6 +27,7 @@ struct BCM2835PropertyState {
MemoryRegion iomem;
qemu_irq mbox_irq;
BCM2835FBState *fbdev;
+ BCM2835OTPState *otp;
MACAddr macaddr;
uint32_t board_rev;
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..09bc3ab
--- /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.txt 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/macio/macio.h b/include/hw/misc/macio/macio.h
index 2b54da6..16aa95b 100644
--- a/include/hw/misc/macio/macio.h
+++ b/include/hw/misc/macio/macio.h
@@ -80,8 +80,6 @@ struct MACIOIDEState {
uint32_t channel;
qemu_irq real_ide_irq;
qemu_irq real_dma_irq;
- qemu_irq ide_irq;
- qemu_irq dma_irq;
MemoryRegion mem;
IDEBus bus;
@@ -92,6 +90,11 @@ struct MACIOIDEState {
uint32_t irq_reg;
};
+#define MACIO_IDE_PMAC_NIRQS 2
+
+#define MACIO_IDE_PMAC_DMA_IRQ 0
+#define MACIO_IDE_PMAC_IDE_IRQ 1
+
void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table);
void macio_ide_register_dma(MACIOIDEState *ide);
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 fab9416..5098693 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -15,11 +15,18 @@
#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"
+
+#define PVPANIC_EVENTS (PVPANIC_PANICKED | \
+ PVPANIC_CRASH_LOADED | \
+ PVPANIC_SHUTDOWN)
+
#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_exti.h b/include/hw/misc/stm32l4x5_exti.h
index be961d2..62f7936 100644
--- a/include/hw/misc/stm32l4x5_exti.h
+++ b/include/hw/misc/stm32l4x5_exti.h
@@ -30,7 +30,7 @@
#define TYPE_STM32L4X5_EXTI "stm32l4x5-exti"
OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5ExtiState, STM32L4X5_EXTI)
-#define EXTI_NUM_INTERRUPT_OUT_LINES 40
+#define EXTI_NUM_LINES 40
#define EXTI_NUM_REGISTER 2
struct Stm32l4x5ExtiState {
@@ -45,7 +45,9 @@ struct Stm32l4x5ExtiState {
uint32_t swier[EXTI_NUM_REGISTER];
uint32_t pr[EXTI_NUM_REGISTER];
- qemu_irq irq[EXTI_NUM_INTERRUPT_OUT_LINES];
+ /* used for edge detection */
+ uint32_t irq_levels[EXTI_NUM_REGISTER];
+ qemu_irq irq[EXTI_NUM_LINES];
};
#endif
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-cfi-if.h b/include/hw/misc/xlnx-cfi-if.h
index f9bd122..5010401 100644
--- a/include/hw/misc/xlnx-cfi-if.h
+++ b/include/hw/misc/xlnx-cfi-if.h
@@ -11,7 +11,6 @@
#define XLNX_CFI_IF_H 1
#include "qemu/help-texts.h"
-#include "hw/hw.h"
#include "qom/object.h"
#define TYPE_XLNX_CFI_IF "xlnx-cfi-if"
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/ftgmac100.h b/include/hw/net/ftgmac100.h
index 765d153..24ccdf0 100644
--- a/include/hw/net/ftgmac100.h
+++ b/include/hw/net/ftgmac100.h
@@ -14,6 +14,11 @@
#define TYPE_FTGMAC100 "ftgmac100"
OBJECT_DECLARE_SIMPLE_TYPE(FTGMAC100State, FTGMAC100)
+#define FTGMAC100_MEM_SIZE 0x1000
+#define FTGMAC100_REG_MEM_SIZE 0x100
+#define FTGMAC100_REG_HIGH_MEM_SIZE 0x100
+#define FTGMAC100_REG_HIGH_OFFSET 0x100
+
#include "hw/sysbus.h"
#include "net/net.h"
@@ -30,7 +35,9 @@ struct FTGMAC100State {
NICState *nic;
NICConf conf;
qemu_irq irq;
+ MemoryRegion iomem_container;
MemoryRegion iomem;
+ MemoryRegion iomem_high;
uint8_t frame[FTGMAC100_MAX_FRAME_SIZE];
@@ -38,10 +45,6 @@ struct FTGMAC100State {
uint32_t isr;
uint32_t ier;
uint32_t rx_enabled;
- uint32_t rx_ring;
- uint32_t rx_descriptor;
- uint32_t tx_ring;
- uint32_t tx_descriptor;
uint32_t math[2];
uint32_t rbsr;
uint32_t itc;
@@ -54,7 +57,10 @@ struct FTGMAC100State {
uint32_t phycr;
uint32_t phydata;
uint32_t fcr;
-
+ uint64_t rx_ring;
+ uint64_t rx_descriptor;
+ uint64_t tx_ring;
+ uint64_t tx_descriptor;
uint32_t phy_status;
uint32_t phy_control;
@@ -65,6 +71,7 @@ struct FTGMAC100State {
bool aspeed;
uint32_t txdes0_edotr;
uint32_t rxdes0_edorr;
+ bool dma64;
};
#define TYPE_ASPEED_MII "aspeed-mmi"
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/bcm2835_otp.h b/include/hw/nvram/bcm2835_otp.h
new file mode 100644
index 0000000..1df3370
--- /dev/null
+++ b/include/hw/nvram/bcm2835_otp.h
@@ -0,0 +1,68 @@
+/*
+ * BCM2835 One-Time Programmable (OTP) Memory
+ *
+ * Copyright (c) 2024 Rayhan Faizel <rayhan.faizel@gmail.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef BCM2835_OTP_H
+#define BCM2835_OTP_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_BCM2835_OTP "bcm2835-otp"
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835OTPState, BCM2835_OTP)
+
+#define BCM2835_OTP_ROW_COUNT 66
+
+/* https://elinux.org/BCM2835_registers#OTP */
+#define BCM2835_OTP_BOOTMODE_REG 0x00
+#define BCM2835_OTP_CONFIG_REG 0x04
+#define BCM2835_OTP_CTRL_LO_REG 0x08
+#define BCM2835_OTP_CTRL_HI_REG 0x0c
+#define BCM2835_OTP_STATUS_REG 0x10
+#define BCM2835_OTP_BITSEL_REG 0x14
+#define BCM2835_OTP_DATA_REG 0x18
+#define BCM2835_OTP_ADDR_REG 0x1c
+#define BCM2835_OTP_WRITE_DATA_READ_REG 0x20
+#define BCM2835_OTP_INIT_STATUS_REG 0x24
+
+
+/* -- Row 32: Undocumented -- */
+
+#define BCM2835_OTP_ROW_32 32
+
+/* Lock OTP Programming (Customer OTP and private key) */
+#define BCM2835_OTP_ROW_32_LOCK BIT(6)
+
+/* -- Row 36-43: Customer OTP -- */
+
+#define BCM2835_OTP_CUSTOMER_OTP 36
+#define BCM2835_OTP_CUSTOMER_OTP_LEN 8
+
+/* Magic numbers to lock programming of customer OTP and private key */
+#define BCM2835_OTP_LOCK_NUM1 0xffffffff
+#define BCM2835_OTP_LOCK_NUM2 0xaffe0000
+
+/* -- Row 56-63: Device-specific private key -- */
+
+#define BCM2835_OTP_PRIVATE_KEY 56
+#define BCM2835_OTP_PRIVATE_KEY_LEN 8
+
+
+struct BCM2835OTPState {
+ /* <private> */
+ SysBusDevice parent_obj;
+
+ /* <public> */
+ MemoryRegion iomem;
+ uint32_t otp_rows[BCM2835_OTP_ROW_COUNT];
+};
+
+
+uint32_t bcm2835_otp_get_row(BCM2835OTPState *s, unsigned int row);
+void bcm2835_otp_set_row(BCM2835OTPState *s, unsigned int row, uint32_t value);
+
+#endif
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 eaa3fc9..df3cc7b 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -1,8 +1,9 @@
#ifndef QEMU_PCI_H
#define QEMU_PCI_H
-#include "exec/memory.h"
-#include "sysemu/dma.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"
@@ -15,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"
@@ -115,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
@@ -212,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 {
@@ -293,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)
{
@@ -362,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
@@ -383,10 +420,338 @@ typedef struct PCIIOMMUOps {
*
* @devfn: device and function number
*/
- AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int devfn);
+ AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int devfn);
+ /**
+ * @set_iommu_device: attach a HostIOMMUDevice to a vIOMMU
+ *
+ * Optional callback, if not implemented in vIOMMU, then vIOMMU can't
+ * retrieve host information from the associated HostIOMMUDevice.
+ *
+ * @bus: the #PCIBus of the PCI device.
+ *
+ * @opaque: the data passed to pci_setup_iommu().
+ *
+ * @devfn: device and function number of the PCI device.
+ *
+ * @dev: the #HostIOMMUDevice to attach.
+ *
+ * @errp: pass an Error out only when return false
+ *
+ * Returns: true if HostIOMMUDevice is attached or else false with errp set.
+ */
+ bool (*set_iommu_device)(PCIBus *bus, void *opaque, int devfn,
+ HostIOMMUDevice *dev, Error **errp);
+ /**
+ * @unset_iommu_device: detach a HostIOMMUDevice from a vIOMMU
+ *
+ * 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.
+ */
+ 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);
+bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod,
+ Error **errp);
+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
@@ -620,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)
{
@@ -631,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 d3dd0f6..eee0338 100644
--- a/include/hw/pci/pci_device.h
+++ b/include/hw/pci/pci_device.h
@@ -3,6 +3,7 @@
#include "hw/pci/pci.h"
#include "hw/pci/pcie.h"
+#include "hw/pci/pcie_doe.h"
#define TYPE_PCI_DEVICE "pci-device"
typedef struct PCIDeviceClass PCIDeviceClass;
@@ -37,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 {
@@ -56,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;
@@ -87,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;
@@ -104,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;
@@ -147,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;
@@ -157,9 +164,24 @@ struct PCIDevice {
MSIVectorReleaseNotifier msix_vector_release_notifier;
MSIVectorPollNotifier msix_vector_poll_notifier;
+ /* SPDM */
+ uint16_t spdm_port;
+
+ /* DOE */
+ DOECap doe_spdm;
+
/* 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)
@@ -192,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_doe.h b/include/hw/pci/pcie_doe.h
index 87dc17d..9e1275d 100644
--- a/include/hw/pci/pcie_doe.h
+++ b/include/hw/pci/pcie_doe.h
@@ -46,6 +46,8 @@ REG32(PCI_DOE_CAP_STATUS, 0)
/* PCI-SIG defined Data Object Types - r6.0 Table 6-32 */
#define PCI_SIG_DOE_DISCOVERY 0x00
+#define PCI_SIG_DOE_CMA 0x01
+#define PCI_SIG_DOE_SECURED_CMA 0x02
#define PCI_DOE_DW_SIZE_MAX (1 << 18)
#define PCI_DOE_PROTOCOL_NUM_MAX 256
@@ -106,6 +108,9 @@ struct DOECap {
/* Protocols and its callback response */
DOEProtocol *protocols;
uint16_t protocol_num;
+
+ /* Used for spdm-socket */
+ int spdm_socket;
};
void pcie_doe_init(PCIDevice *pdev, DOECap *doe_cap, uint16_t offset,
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 476b136..d8fca07 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -76,6 +76,9 @@ struct PnvMachineClass {
/*< public >*/
const char *compat;
int compat_size;
+ int max_smt_threads;
+ bool has_lpar_per_thread;
+ bool quirk_tb_big_core;
void (*dt_power_mgt)(PnvMachineState *pnv, void *fdt);
void (*i2c_init)(PnvMachineState *pnv);
@@ -100,6 +103,9 @@ struct PnvMachineState {
PnvPnor *pnor;
hwaddr fw_load_addr;
+
+ bool big_core;
+ bool lpar_per_core;
};
PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id);
@@ -108,6 +114,8 @@ PnvChip *pnv_chip_add_phb(PnvChip *chip, PnvPHB *phb);
#define PNV_FDT_ADDR 0x01000000
#define PNV_TIMEBASE_FREQ 512000000ULL
+void pnv_cpu_do_nmi_resume(CPUState *cs);
+
/*
* BMC helpers
*/
@@ -197,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
@@ -242,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_adu.h b/include/hw/ppc/pnv_adu.h
new file mode 100644
index 0000000..f9dbd8c
--- /dev/null
+++ b/include/hw/ppc/pnv_adu.h
@@ -0,0 +1,32 @@
+/*
+ * QEMU PowerPC PowerNV Emulation of some ADU behaviour
+ *
+ * Copyright (c) 2024, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef PPC_PNV_ADU_H
+#define PPC_PNV_ADU_H
+
+#include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_lpc.h"
+#include "hw/qdev-core.h"
+
+#define TYPE_PNV_ADU "pnv-adu"
+
+OBJECT_DECLARE_TYPE(PnvADU, PnvADUClass, PNV_ADU)
+
+struct PnvADU {
+ DeviceState xd;
+
+ /* LPCMC (LPC Master Controller) access engine */
+ PnvLpcController *lpc;
+ uint64_t lpc_base_reg;
+ uint64_t lpc_cmd_reg;
+ uint64_t lpc_data_reg;
+
+ MemoryRegion xscom_regs;
+};
+
+#endif /* PPC_PNV_ADU_H */
diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index a4ed17a..24ce37a 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -2,10 +2,12 @@
#define PPC_PNV_CHIP_H
#include "hw/pci-host/pnv_phb4.h"
+#include "hw/ppc/pnv_adu.h"
#include "hw/ppc/pnv_chiptod.h"
#include "hw/ppc/pnv_core.h"
#include "hw/ppc/pnv_homer.h"
#include "hw/ppc/pnv_n1_chiplet.h"
+#include "hw/ssi/pnv_spi.h"
#include "hw/ppc/pnv_lpc.h"
#include "hw/ppc/pnv_occ.h"
#include "hw/ppc/pnv_psi.h"
@@ -26,6 +28,8 @@ struct PnvChip {
uint64_t ram_start;
uint64_t ram_size;
+ bool big_core;
+ bool lpar_per_core;
uint32_t nr_cores;
uint32_t nr_threads;
uint64_t cores_mask;
@@ -77,6 +81,7 @@ struct Pnv9Chip {
PnvChip parent_obj;
/*< public >*/
+ PnvADU adu;
PnvXive xive;
Pnv9Psi psi;
PnvLpcController lpc;
@@ -110,6 +115,7 @@ struct Pnv10Chip {
PnvChip parent_obj;
/*< public >*/
+ PnvADU adu;
PnvXive2 xive;
Pnv9Psi psi;
PnvLpcController lpc;
@@ -118,6 +124,8 @@ struct Pnv10Chip {
PnvSBE sbe;
PnvHomer homer;
PnvN1Chiplet n1_chiplet;
+#define PNV10_CHIP_MAX_PIB_SPIC 6
+ PnvSpi pib_spic[PNV10_CHIP_MAX_PIB_SPIC];
uint32_t nr_quads;
PnvQuad *quads;
@@ -131,6 +139,7 @@ struct Pnv10Chip {
#define PNV10_PIR2FUSEDCORE(pir) (((pir) >> 3) & 0xf)
#define PNV10_PIR2CHIP(pir) (((pir) >> 8) & 0x7f)
+#define PNV10_PIR2THREAD(pir) (((pir) & 0x7f))
struct PnvChipClass {
/*< private >*/
@@ -147,7 +156,9 @@ struct PnvChipClass {
DeviceRealize parent_realize;
- uint32_t (*chip_pir)(PnvChip *chip, uint32_t core_id, uint32_t thread_id);
+ /* Get PIR and TIR values for a CPU thread identified by core/thread id */
+ void (*get_pir_tir)(PnvChip *chip, uint32_t core_id, uint32_t thread_id,
+ uint32_t *pir, uint32_t *tir);
void (*intc_create)(PnvChip *chip, PowerPCCPU *cpu, Error **errp);
void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu);
void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu);
diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h
index c6d62fd..d8afb4f 100644
--- a/include/hw/ppc/pnv_core.h
+++ b/include/hw/ppc/pnv_core.h
@@ -25,6 +25,27 @@
#include "hw/ppc/pnv.h"
#include "qom/object.h"
+/* Per-core ChipTOD / TimeBase state */
+typedef struct PnvCoreTODState {
+ /*
+ * POWER10 DD2.0 - big core TFMR drives the state machine on the even
+ * small core. Skiboot has a workaround that targets the even small core
+ * for CHIPTOD_TO_TB ops.
+ */
+ bool big_core_quirk;
+
+ int tb_ready_for_tod; /* core TB ready to receive TOD from chiptod */
+ int tod_sent_to_tb; /* chiptod sent TOD to the core TB */
+
+ /*
+ * "Timers" for async TBST events are simulated by mfTFAC because TFAC
+ * is polled for such events. These are just used to ensure firmware
+ * performs the polling at least a few times.
+ */
+ int tb_state_timer;
+ int tb_sync_pulse_timer;
+} PnvCoreTODState;
+
#define TYPE_PNV_CORE "powernv-cpu-core"
OBJECT_DECLARE_TYPE(PnvCore, PnvCoreClass,
PNV_CORE)
@@ -35,9 +56,15 @@ struct PnvCore {
/*< public >*/
PowerPCCPU **threads;
+ bool big_core;
+ bool lpar_per_core;
uint32_t pir;
uint32_t hwid;
uint64_t hrmor;
+
+ target_ulong scratch[8]; /* SPRC/SPRD indirect SCRATCH registers */
+ PnvCoreTODState tod_state;
+
PnvChip *chip;
MemoryRegion xscom_regs;
@@ -54,6 +81,7 @@ struct PnvCoreClass {
#define PNV_CORE_TYPE_NAME(cpu_model) cpu_model PNV_CORE_TYPE_SUFFIX
typedef struct PnvCPUState {
+ PnvCore *pnv_core;
Object *intc;
} PnvCPUState;
@@ -82,6 +110,9 @@ OBJECT_DECLARE_TYPE(PnvQuad, PnvQuadClass, PNV_QUAD)
struct PnvQuad {
DeviceState parent_obj;
+ bool special_wakeup_done;
+ bool special_wakeup[4];
+
uint32_t quad_id;
MemoryRegion xscom_regs;
MemoryRegion xscom_qme_regs;
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 5d22c45..266d562 100644
--- a/include/hw/ppc/pnv_lpc.h
+++ b/include/hw/ppc/pnv_lpc.h
@@ -20,9 +20,10 @@
#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 */
#define TYPE_PNV_LPC "pnv-lpc"
typedef struct PnvLpcClass PnvLpcClass;
@@ -73,6 +74,9 @@ struct PnvLpcController {
uint32_t opb_irq_pol;
uint32_t opb_irq_input;
+ /* LPC device IRQ state */
+ uint32_t lpc_hc_irq_inputs;
+
/* LPC HC registers */
uint32_t lpc_hc_fw_seg_idsel;
uint32_t lpc_hc_fw_rd_acc_size;
@@ -84,8 +88,19 @@ struct PnvLpcController {
/* XSCOM registers */
MemoryRegion xscom_regs;
+ /*
+ * In P8, ISA irqs are combined with internal sources to drive the
+ * LPCHC interrupt output. P9 ISA irqs raise one of 4 lines that
+ * drive PSI SERIRQ irqs, routing according to OPB routing registers.
+ */
+ bool psi_has_serirq;
+
/* PSI to generate interrupts */
- qemu_irq psi_irq;
+ qemu_irq psi_irq_lpchc;
+
+ /* P9 serirq lines and irq routing table */
+ qemu_irq psi_irq_serirq[4];
+ int irq_to_serirq_route[ISA_NUM_IRQS];
};
struct PnvLpcClass {
@@ -94,6 +109,11 @@ struct PnvLpcClass {
DeviceRealize parent_realize;
};
+bool pnv_lpc_opb_read(PnvLpcController *lpc, uint32_t addr,
+ uint8_t *data, int sz);
+bool pnv_lpc_opb_write(PnvLpcController *lpc, uint32_t addr,
+ uint8_t *data, int sz);
+
ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp);
int pnv_dt_lpc(PnvChip *chip, void *fdt, int root_offset,
uint64_t lpcm_addr, uint64_t lpcm_size);
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 6209e18..b14549d 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -20,10 +20,10 @@
#ifndef PPC_PNV_XSCOM_H
#define PPC_PNV_XSCOM_H
-#include "exec/memory.h"
-#include "hw/ppc/pnv.h"
+#include "system/memory.h"
typedef struct PnvXScomInterface PnvXScomInterface;
+typedef struct PnvChip PnvChip;
#define TYPE_PNV_XSCOM_INTERFACE "pnv-xscom-interface"
#define PNV_XSCOM_INTERFACE(obj) \
@@ -82,6 +82,9 @@ struct PnvXScomInterfaceClass {
#define PNV_XSCOM_PBCQ_SPCI_BASE 0x9013c00
#define PNV_XSCOM_PBCQ_SPCI_SIZE 0x5
+#define PNV9_XSCOM_ADU_BASE 0x0090000
+#define PNV9_XSCOM_ADU_SIZE 0x55
+
/*
* Layout of the XSCOM PCB addresses (POWER 9)
*/
@@ -123,11 +126,16 @@ 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
#define PNV9_XSCOM_PEC_PCI_STK2 0x180
+#define PNV10_XSCOM_ADU_BASE 0x0090000
+#define PNV10_XSCOM_ADU_SIZE 0x55
+
/*
* Layout of the XSCOM PCB addresses (POWER 10)
*/
@@ -191,9 +199,14 @@ 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
+#define PNV10_XSCOM_PIB_SPIC_BASE 0xc0000
+#define PNV10_XSCOM_PIB_SPIC_SIZE 0x20
+
void pnv_xscom_init(PnvChip *chip, uint64_t size, hwaddr addr);
int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
uint64_t xscom_base, uint64_t xscom_size,
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 4aaf23d..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
@@ -1004,7 +1005,9 @@ extern const VMStateDescription vmstate_spapr_cap_large_decr;
extern const VMStateDescription vmstate_spapr_cap_ccf_assist;
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 4e5e17c..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)
@@ -97,6 +98,7 @@ typedef struct Xive2End {
uint32_t w6;
#define END2_W6_FORMAT_BIT PPC_BIT32(0)
#define END2_W6_IGNORE PPC_BIT32(1)
+#define END2_W6_CROWD PPC_BIT32(2)
#define END2_W6_VP_BLOCK PPC_BITMASK32(4, 7)
#define END2_W6_VP_OFFSET PPC_BITMASK32(8, 31)
#define END2_W6_VP_OFFSET_GEN1 PPC_BITMASK32(13, 31)
@@ -111,6 +113,8 @@ typedef struct Xive2End {
#define xive2_end_is_notify(end) \
(be32_to_cpu((end)->w0) & END2_W0_UCOND_NOTIFY)
#define xive2_end_is_backlog(end) (be32_to_cpu((end)->w0) & END2_W0_BACKLOG)
+#define xive2_end_is_precluded_escalation(end) \
+ (be32_to_cpu((end)->w0) & END2_W0_PRECL_ESC_CTL)
#define xive2_end_is_escalate(end) \
(be32_to_cpu((end)->w0) & END2_W0_ESCALATE_CTL)
#define xive2_end_is_uncond_escalation(end) \
@@ -123,6 +127,10 @@ typedef struct Xive2End {
(be32_to_cpu((end)->w0) & END2_W0_FIRMWARE1)
#define xive2_end_is_firmware2(end) \
(be32_to_cpu((end)->w0) & END2_W0_FIRMWARE2)
+#define xive2_end_is_ignore(end) \
+ (be32_to_cpu((end)->w6) & END2_W6_IGNORE)
+#define xive2_end_is_crowd(end) \
+ (be32_to_cpu((end)->w6) & END2_W6_CROWD)
static inline uint64_t xive2_end_qaddr(Xive2End *end)
{
@@ -143,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)
@@ -153,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 */
@@ -164,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)
@@ -194,12 +210,15 @@ static inline uint32_t xive2_nvp_blk(uint32_t cam_line)
return (cam_line >> XIVE2_NVP_SHIFT) & 0xf;
}
+void xive2_nvp_pic_print_info(Xive2Nvp *nvp, uint32_t nvp_idx, GString *buf);
+
/*
* Notification Virtual Group or Crowd (NVG/NVC)
*/
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;
@@ -209,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 5336728..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);
@@ -624,8 +633,9 @@ qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
* @name: Name of the input GPIO array
* @n: Number of the GPIO line in that array (which must be in range)
*
- * Returns the qemu_irq corresponding to a named input GPIO line
- * (which the device has set up with qdev_init_gpio_in_named()).
+ * Returns the qemu_irq corresponding to a single input GPIO line
+ * in a named array of input GPIO lines on a device (which the device
+ * has set up with qdev_init_gpio_in_named()).
* The @name string must correspond to an input GPIO array which exists on
* the device, and the index @n of the GPIO line must be valid (i.e.
* be at least 0 and less than the total number of input GPIOs in that
@@ -673,15 +683,15 @@ void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
* GPIO lines
* @dev: Device whose GPIO to connect
* @name: Name of the output GPIO array
- * @n: Number of the anonymous output GPIO line (which must be in range)
+ * @n: Number of the output GPIO line within that array (which must be in range)
* @input_pin: qemu_irq to connect the output line to
*
- * This function connects an anonymous output GPIO line on a device
- * up to an arbitrary qemu_irq, so that when the device asserts that
- * output GPIO line, the qemu_irq's callback is invoked.
+ * This function connects a single GPIO output in a named array of output
+ * GPIO lines on a device up to an arbitrary qemu_irq, so that when the
+ * device asserts that output GPIO line, the qemu_irq's callback is invoked.
* The @name string must correspond to an output GPIO array which exists on
* the device, and the index @n of the GPIO line must be valid (i.e.
- * be at least 0 and less than the total number of input GPIOs in that
+ * be at least 0 and less than the total number of output GPIOs in that
* array); this function will assert() if passed an invalid name or index.
*
* Outbound GPIO lines can be connected to any qemu_irq, but the common
@@ -796,7 +806,7 @@ void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
* @dev: Device to create output GPIOs for
* @pins: Pointer to qemu_irq or qemu_irq array for the GPIO lines
* @name: Name to give this array of GPIO lines
- * @n: Number of GPIO lines to create
+ * @n: Number of GPIO lines to create in this array
*
* Like qdev_init_gpio_out(), but creates an array of GPIO output lines
* with a name. Code using the device can then connect these GPIO lines
@@ -928,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
@@ -968,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
@@ -993,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 3db8391..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 */
};
@@ -118,6 +122,7 @@ enum {
#define FDT_PLIC_ADDR_CELLS 0
#define FDT_PLIC_INT_CELLS 1
#define FDT_APLIC_INT_CELLS 2
+#define FDT_APLIC_ADDR_CELLS 0
#define FDT_IMSIC_INT_CELLS 0
#define FDT_MAX_INT_CELLS 2
#define FDT_MAX_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + \
@@ -128,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 382d983..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;
};
@@ -116,6 +113,7 @@ struct QEMUS390FLICState {
uint8_t simm;
uint8_t nimm;
QLIST_HEAD(, QEMUS390FlicIO) io[8];
+ bool migrate_all_state;
};
uint32_t qemu_s390_flic_dequeue_service(QEMUS390FLICState *flic);
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 2c8748f..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_none = -1,
- sd_bc = 0, /* 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;
@@ -96,6 +88,9 @@ OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
#define TYPE_SD_CARD_SPI "sd-card-spi"
DECLARE_INSTANCE_CHECKER(SDState, SD_CARD_SPI, TYPE_SD_CARD_SPI)
+#define TYPE_EMMC "emmc"
+DECLARE_INSTANCE_CHECKER(SDState, EMMC, TYPE_EMMC)
+
struct SDCardClass {
/*< private >*/
DeviceClass parent_class;
@@ -124,9 +119,10 @@ 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);
+ void (*set_csd)(SDState *sd, uint64_t size);
const struct SDProto *proto;
};
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
new file mode 100644
index 0000000..c591a06
--- /dev/null
+++ b/include/hw/ssi/pnv_spi.h
@@ -0,0 +1,72 @@
+/*
+ * QEMU PowerPC SPI model
+ *
+ * Copyright (c) 2024, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This model Supports a connection to a single SPI responder.
+ * Introduced for P10 to provide access to SPI seeproms, TPM, flash device
+ * and an ADC controller.
+ *
+ * All SPI function control is mapped into the SPI register space to enable
+ * full control by firmware.
+ *
+ * SPI Controller has sequencer and shift engine. The SPI shift engine
+ * performs serialization and de-serialization according to the control by
+ * the sequencer and according to the setup defined in the configuration
+ * registers and the SPI sequencer implements the main control logic.
+ */
+
+#ifndef PPC_PNV_SPI_H
+#define PPC_PNV_SPI_H
+
+#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)
+
+#define PNV_SPI_REG_SIZE 8
+#define PNV_SPI_REGS 7
+
+#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 */
+ bool shift_n1_done;
+ /* Loop counter for branch operation opcode Ex/Fx */
+ uint8_t loop_counter_1;
+ uint8_t loop_counter_2;
+ /* N1/N2_bits specifies the size of the N1/N2 segment of a frame in bits.*/
+ uint8_t N1_bits;
+ uint8_t N2_bits;
+ /* Number of bytes in a payload for the N1/N2 frame segment.*/
+ uint8_t N1_bytes;
+ uint8_t N2_bytes;
+ /* Number of N1/N2 bytes marked for transmit */
+ uint8_t N1_tx;
+ uint8_t N2_tx;
+ /* Number of N1/N2 bytes marked for receive */
+ uint8_t N1_rx;
+ uint8_t N2_rx;
+
+ /* SPI registers */
+ uint64_t regs[PNV_SPI_REGS];
+ uint8_t seq_op[PNV_SPI_REG_SIZE];
+ uint64_t status;
+} PnvSpi;
+#endif /* PPC_PNV_SPI_H */
diff --git a/include/hw/ssi/pnv_spi_regs.h b/include/hw/ssi/pnv_spi_regs.h
new file mode 100644
index 0000000..596e2c1
--- /dev/null
+++ b/include/hw/ssi/pnv_spi_regs.h
@@ -0,0 +1,133 @@
+/*
+ * QEMU PowerPC SPI model
+ *
+ * Copyright (c) 2024, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef PNV_SPI_CONTROLLER_REGS_H
+#define PNV_SPI_CONTROLLER_REGS_H
+
+/*
+ * Macros from target/ppc/cpu.h
+ * These macros are copied from ppc target specific file target/ppc/cpu.h
+ * as target/ppc/cpu.h cannot be included here.
+ */
+#define PPC_BIT(bit) (0x8000000000000000ULL >> (bit))
+#define PPC_BIT8(bit) (0x80 >> (bit))
+#define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
+#define PPC_BITMASK8(bs, be) ((PPC_BIT8(bs) - PPC_BIT8(be)) | PPC_BIT8(bs))
+#define MASK_TO_LSH(m) (__builtin_ffsll(m) - 1)
+#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m))
+#define SETFIELD(m, v, val) \
+ (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m)))
+
+/* Error Register */
+#define ERROR_REG 0x00
+
+/* counter_config_reg */
+#define SPI_CTR_CFG_REG 0x01
+#define SPI_CTR_CFG_N1 PPC_BITMASK(0, 7)
+#define SPI_CTR_CFG_N2 PPC_BITMASK(8, 15)
+#define SPI_CTR_CFG_CMP1 PPC_BITMASK(24, 31)
+#define SPI_CTR_CFG_CMP2 PPC_BITMASK(32, 39)
+#define SPI_CTR_CFG_N1_CTRL_B1 PPC_BIT(49)
+#define SPI_CTR_CFG_N1_CTRL_B2 PPC_BIT(50)
+#define SPI_CTR_CFG_N1_CTRL_B3 PPC_BIT(51)
+#define SPI_CTR_CFG_N2_CTRL_B0 PPC_BIT(52)
+#define SPI_CTR_CFG_N2_CTRL_B1 PPC_BIT(53)
+#define SPI_CTR_CFG_N2_CTRL_B2 PPC_BIT(54)
+#define SPI_CTR_CFG_N2_CTRL_B3 PPC_BIT(55)
+
+/* config_reg */
+#define CONFIG_REG1 0x02
+
+/* clock_config_reset_control_ecc_enable_reg */
+#define SPI_CLK_CFG_REG 0x03
+#define SPI_CLK_CFG_HARD_RST 0x0084000000000000;
+#define SPI_CLK_CFG_RST_CTRL PPC_BITMASK(24, 27)
+#define SPI_CLK_CFG_ECC_EN PPC_BIT(28)
+#define SPI_CLK_CFG_ECC_CTRL PPC_BITMASK(29, 30)
+
+/* memory_mapping_reg */
+#define SPI_MM_REG 0x04
+#define SPI_MM_RDR_MATCH_VAL PPC_BITMASK(32, 47)
+#define SPI_MM_RDR_MATCH_MASK PPC_BITMASK(48, 63)
+
+/* transmit_data_reg */
+#define SPI_XMIT_DATA_REG 0x05
+
+/* receive_data_reg */
+#define SPI_RCV_DATA_REG 0x06
+
+/* sequencer_operation_reg */
+#define SPI_SEQ_OP_REG 0x07
+
+/* status_reg */
+#define SPI_STS_REG 0x08
+#define SPI_STS_RDR_FULL PPC_BIT(0)
+#define SPI_STS_RDR_OVERRUN PPC_BIT(1)
+#define SPI_STS_RDR_UNDERRUN PPC_BIT(2)
+#define SPI_STS_TDR_FULL PPC_BIT(4)
+#define SPI_STS_TDR_OVERRUN PPC_BIT(5)
+#define SPI_STS_TDR_UNDERRUN PPC_BIT(6)
+#define SPI_STS_SEQ_FSM PPC_BITMASK(8, 15)
+#define SPI_STS_SHIFTER_FSM PPC_BITMASK(16, 27)
+#define SPI_STS_SEQ_INDEX PPC_BITMASK(28, 31)
+#define SPI_STS_GEN_STATUS_B3 PPC_BIT(35)
+#define SPI_STS_RDR PPC_BITMASK(1, 3)
+#define SPI_STS_TDR PPC_BITMASK(5, 7)
+
+/*
+ * Shifter states
+ *
+ * These are the same values defined for the Shifter FSM field of the
+ * status register. It's a 12 bit field so we will represent it as three
+ * nibbles in the constants.
+ *
+ * These are shifter_fsm values
+ *
+ * Status reg bits 16-27 -> field bits 0-11
+ * bits 0,1,2,5 unused/reserved
+ * bit 4 crc shift in (unused)
+ * bit 8 crc shift out (unused)
+ */
+
+#define FSM_DONE 0x100 /* bit 3 */
+#define FSM_SHIFT_N2 0x020 /* bit 6 */
+#define FSM_WAIT 0x010 /* bit 7 */
+#define FSM_SHIFT_N1 0x004 /* bit 9 */
+#define FSM_START 0x002 /* bit 10 */
+#define FSM_IDLE 0x001 /* bit 11 */
+
+/*
+ * Sequencer states
+ *
+ * These are sequencer_fsm values
+ *
+ * Status reg bits 8-15 -> field bits 0-7
+ * bits 0-3 unused/reserved
+ *
+ */
+#define SEQ_STATE_INDEX_INCREMENT 0x08 /* bit 4 */
+#define SEQ_STATE_EXECUTE 0x04 /* bit 5 */
+#define SEQ_STATE_DECODE 0x02 /* bit 6 */
+#define SEQ_STATE_IDLE 0x01 /* bit 7 */
+
+/*
+ * These are the supported sequencer operations.
+ * Only the upper nibble is significant because for many operations
+ * the lower nibble is a variable specific to the operation.
+ */
+#define SEQ_OP_STOP 0x00
+#define SEQ_OP_SELECT_SLAVE 0x10
+#define SEQ_OP_SHIFT_N1 0x30
+#define SEQ_OP_SHIFT_N2 0x40
+#define SEQ_OP_BRANCH_IFNEQ_RDR 0x60
+#define SEQ_OP_TRANSFER_TDR 0xC0
+#define SEQ_OP_BRANCH_IFNEQ_INC_1 0xE0
+#define SEQ_OP_BRANCH_IFNEQ_INC_2 0xF0
+#define NUM_SEQ_OPS 8
+
+#endif
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 4cb1ab8..0000000
--- a/include/hw/vfio/vfio-common.h
+++ /dev/null
@@ -1,286 +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"
-
-#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;
-
-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 VFIOIOMMUFDContainer {
- VFIOContainerBase bcontainer;
- IOMMUFDBackend *be;
- uint32_t ioas_id;
-} VFIOIOMMUFDContainer;
-
-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 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;
- bool dirty_pages_supported;
- bool dirty_tracking;
- int devid;
- IOMMUFDBackend *iommufd;
-} 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;
-
-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);
-
-/* SPAPR specific */
-int vfio_spapr_container_init(VFIOContainer *container, Error **errp);
-void vfio_spapr_container_deinit(VFIOContainer *container);
-
-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_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);
-#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 2776481..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;
@@ -34,7 +34,7 @@ typedef struct VFIOAddressSpace {
* This is the base object for vfio container backends
*/
typedef struct VFIOContainerBase {
- const VFIOIOMMUClass *ops;
+ Object parent;
VFIOAddressSpace *space;
MemoryListener listener;
Error *error;
@@ -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,42 +89,126 @@ 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);
-void vfio_container_init(VFIOContainerBase *bcontainer,
- VFIOAddressSpace *space,
- const VFIOIOMMUClass *ops);
-void vfio_container_destroy(VFIOContainerBase *bcontainer);
+GList *vfio_container_get_iova_ranges(const VFIOContainerBase *bcontainer);
+static inline uint64_t
+vfio_container_get_page_size_mask(const VFIOContainerBase *bcontainer)
+{
+ assert(bcontainer);
+ return bcontainer->pgsizes;
+}
#define TYPE_VFIO_IOMMU "vfio-iommu"
#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"
-/*
- * VFIOContainerBase is not an abstract QOM object because it felt
- * unnecessary to expose all the IOMMU backends to the QEMU machine
- * and human interface. However, we can still abstract the IOMMU
- * backend handlers using a QOM interface class. This provides more
- * flexibility when referencing the various implementations.
- */
-DECLARE_CLASS_CHECKERS(VFIOIOMMUClass, VFIO_IOMMU, TYPE_VFIO_IOMMU)
+OBJECT_DECLARE_TYPE(VFIOContainerBase, VFIOIOMMUClass, VFIO_IOMMU)
struct VFIOIOMMUClass {
- InterfaceClass parent_class;
+ ObjectClass parent_class;
- /* 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 */
@@ -133,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);
@@ -148,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);
@@ -163,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 d7c09ff..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;
/**
@@ -108,7 +109,6 @@ typedef void (*vu_async_close_fn)(DeviceState *cb);
void vhost_user_async_close(DeviceState *d,
CharBackend *chardev, struct vhost_dev *vhost,
- vu_async_close_fn cb,
- IOEventHandler *event_cb);
+ vu_async_close_fn cb);
#endif
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 0247778..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
@@ -129,6 +129,7 @@ struct vhost_dev {
void *opaque;
struct vhost_log *log;
QLIST_ENTRY(vhost_dev) entry;
+ QLIST_ENTRY(vhost_dev) logdev_entry;
QLIST_HEAD(, vhost_iommu) iommu_list;
IOMMUNotifier n;
const VhostDevConfigOps *config_ops;
@@ -170,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
@@ -227,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
@@ -328,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);
@@ -362,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
@@ -445,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
@@ -462,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 83a52cc..3b86050 100644
--- a/include/hw/virtio/virtio-iommu.h
+++ b/include/hw/virtio/virtio-iommu.h
@@ -25,6 +25,7 @@
#include "hw/pci/pci.h"
#include "qom/object.h"
#include "qapi/qapi-types-virtio.h"
+#include "system/host_iommu_device.h"
#define TYPE_VIRTIO_IOMMU "virtio-iommu-device"
#define TYPE_VIRTIO_IOMMU_PCI "virtio-iommu-pci"
@@ -42,7 +43,6 @@ typedef struct IOMMUDevice {
MemoryRegion bypass_mr; /* The alias of shared memory MR */
GList *resv_regions;
GList *host_resv_ranges;
- bool probe_done;
} IOMMUDevice;
typedef struct IOMMUPciBus {
@@ -57,6 +57,7 @@ struct VirtIOIOMMU {
struct virtio_iommu_config config;
uint64_t features;
GHashTable *as_by_busptr;
+ GHashTable *host_iommu_devices;
IOMMUPciBus *iommu_pcibus_by_bus_num[PCI_BUS_MAX];
PCIBus *primary_bus;
ReservedRegion *prop_resv_regions;
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 59d8801..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,
@@ -43,6 +41,7 @@ enum {
VIRTIO_PCI_FLAG_INIT_FLR_BIT,
VIRTIO_PCI_FLAG_AER_BIT,
VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT,
+ VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT,
};
/* Need to activate work-arounds for buggy guests at vmstate load. */
@@ -53,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)
@@ -79,6 +72,10 @@ enum {
/* Init Power Management */
#define VIRTIO_PCI_FLAG_INIT_PM (1 << VIRTIO_PCI_FLAG_INIT_PM_BIT)
+/* Init The No_Soft_Reset bit of Power Management */
+#define VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET \
+ (1 << VIRTIO_PCI_FLAG_PM_NO_SOFT_RESET_BIT)
+
/* Init Function Level Reset capability */
#define VIRTIO_PCI_FLAG_INIT_FLR (1 << VIRTIO_PCI_FLAG_INIT_FLR_BIT)
@@ -142,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;
@@ -247,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 7d5ffdc..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"
@@ -69,6 +69,8 @@ typedef struct VirtQueueElement
unsigned int ndescs;
unsigned int out_num;
unsigned int in_num;
+ /* Element has been processed (VIRTIO_F_IN_ORDER) */
+ bool in_order_filled;
hwaddr *in_addr;
hwaddr *out_addr;
struct iovec *in_sg;
@@ -184,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. */
@@ -208,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.
*/
@@ -221,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);
};
@@ -271,9 +276,13 @@ void qemu_put_virtqueue_element(VirtIODevice *vdev, QEMUFile *f,
VirtQueueElement *elem);
int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes,
unsigned int out_bytes);
-void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
- unsigned int *out_bytes,
- unsigned max_in_bytes, unsigned max_out_bytes);
+/**
+ * Return <0 on error or an opaque >=0 to pass to
+ * virtio_queue_enable_notification_and_check on success.
+ */
+int virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
+ unsigned int *out_bytes, unsigned max_in_bytes,
+ unsigned max_out_bytes);
void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue *vq);
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq);
@@ -307,6 +316,17 @@ int virtio_queue_ready(VirtQueue *vq);
int virtio_queue_empty(VirtQueue *vq);
+/**
+ * Enable notification and check whether guest has added some
+ * buffers since last call to virtqueue_get_avail_bytes.
+ *
+ * @opaque: value returned from virtqueue_get_avail_bytes
+ */
+bool virtio_queue_enable_notification_and_check(VirtQueue *vq,
+ int opaque);
+
+void virtio_queue_set_shadow_avail_idx(VirtQueue *vq, uint16_t idx);
+
/* Host binding interface. */
uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
@@ -369,7 +389,9 @@ typedef struct VirtIORNGConf VirtIORNGConf;
DEFINE_PROP_BIT64("packed", _state, _field, \
VIRTIO_F_RING_PACKED, false), \
DEFINE_PROP_BIT64("queue_reset", _state, _field, \
- VIRTIO_F_RING_RESET, true)
+ VIRTIO_F_RING_RESET, true), \
+ DEFINE_PROP_BIT64("in_order", _state, _field, \
+ VIRTIO_F_IN_ORDER, false)
hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
bool virtio_queue_enabled_legacy(VirtIODevice *vdev, int n);
@@ -470,9 +492,9 @@ static inline bool virtio_device_started(VirtIODevice *vdev, uint8_t status)
* @vdev - the VirtIO device
* @status - the devices status bits
*
- * This is similar to virtio_device_started() but also encapsulates a
- * check on the VM status which would prevent a device starting
- * anyway.
+ * This is similar to virtio_device_started() but ignores vdev->started
+ * and also encapsulates a check on the VM status which would prevent a
+ * device from starting anyway.
*/
static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status)
{
@@ -480,7 +502,7 @@ static inline bool virtio_device_should_start(VirtIODevice *vdev, uint8_t status
return false;
}
- return virtio_device_started(vdev, status);
+ return status & VIRTIO_CONFIG_S_DRIVER_OK;
}
static inline void virtio_set_started(VirtIODevice *vdev, bool started)
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 37ecc91..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) */
@@ -36,6 +34,7 @@ enum xen_mode {
extern uint32_t xen_domid;
extern enum xen_mode xen_mode;
extern bool xen_domid_restrict;
+extern bool xen_is_stubdomain;
int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
int xen_set_pci_link_route(uint8_t link, uint8_t irq);
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;
diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
index ab15577..a88cf8b 100644
--- a/include/io/channel-socket.h
+++ b/include/io/channel-socket.h
@@ -261,5 +261,18 @@ QIOChannelSocket *
qio_channel_socket_accept(QIOChannelSocket *ioc,
Error **errp);
+/**
+ * qio_channel_socket_set_send_buffer:
+ * @ioc: the socket channel object
+ * @size: buffer size
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Set the underlying socket send buffer size.
+ *
+ * Retruns: 0 on success, or -1 on error.
+ */
+int qio_channel_socket_set_send_buffer(QIOChannelSocket *ioc,
+ size_t size,
+ Error **errp);
#endif /* QIO_CHANNEL_SOCKET_H */
diff --git a/include/io/channel-tls.h b/include/io/channel-tls.h
index 26c67f1..7e90235 100644
--- a/include/io/channel-tls.h
+++ b/include/io/channel-tls.h
@@ -49,9 +49,21 @@ struct QIOChannelTLS {
QCryptoTLSSession *session;
QIOChannelShutdown shutdown;
guint hs_ioc_tag;
+ guint bye_ioc_tag;
};
/**
+ * qio_channel_tls_bye:
+ * @ioc: the TLS channel object
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Perform the TLS session termination. This method will return
+ * immediately and the termination will continue in the background,
+ * provided the main loop is running.
+ */
+void qio_channel_tls_bye(QIOChannelTLS *ioc, Error **errp);
+
+/**
* qio_channel_tls_new_server:
* @master: the underlying channel object
* @creds: the credentials to use for TLS handshake
diff --git a/include/io/channel.h b/include/io/channel.h
index 7986c49..62b6571 100644
--- a/include/io/channel.h
+++ b/include/io/channel.h
@@ -35,6 +35,7 @@ OBJECT_DECLARE_TYPE(QIOChannel, QIOChannelClass,
#define QIO_CHANNEL_WRITE_FLAG_ZERO_COPY 0x1
#define QIO_CHANNEL_READ_FLAG_MSG_PEEK 0x1
+#define QIO_CHANNEL_READ_FLAG_RELAXED_EOF 0x2
typedef enum QIOChannelFeature QIOChannelFeature;
@@ -160,6 +161,9 @@ struct QIOChannelClass {
void *opaque);
int (*io_flush)(QIOChannel *ioc,
Error **errp);
+ int (*io_peerpid)(QIOChannel *ioc,
+ unsigned int *pid,
+ Error **errp);
};
/* General I/O handling functions */
@@ -882,6 +886,7 @@ void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
* @niov: the length of the @iov array
* @fds: an array of file handles to read
* @nfds: number of file handles in @fds
+ * @flags: read flags (QIO_CHANNEL_READ_FLAG_*)
* @errp: pointer to a NULL-initialized error object
*
*
@@ -900,6 +905,7 @@ int coroutine_mixed_fn qio_channel_readv_full_all_eof(QIOChannel *ioc,
const struct iovec *iov,
size_t niov,
int **fds, size_t *nfds,
+ int flags,
Error **errp);
/**
@@ -981,4 +987,22 @@ int coroutine_mixed_fn qio_channel_writev_full_all(QIOChannel *ioc,
int qio_channel_flush(QIOChannel *ioc,
Error **errp);
+/**
+ * qio_channel_get_peercred:
+ * @ioc: the channel object
+ * @pid: pointer to pid
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Returns the pid of the peer process connected to this socket.
+ *
+ * The use of this function is possible only for connected
+ * AF_UNIX stream sockets and for AF_UNIX stream and datagram
+ * socket pairs on Linux.
+ * Return -1 on error with pid -1 for the non-Linux OS.
+ *
+ */
+int qio_channel_get_peerpid(QIOChannel *ioc,
+ unsigned int *pid,
+ Error **errp);
+
#endif /* QIO_CHANNEL_H */
diff --git a/include/libdecnumber/dconfig.h b/include/libdecnumber/dconfig.h
index 2bc0ba7f..e67ecc1 100644
--- a/include/libdecnumber/dconfig.h
+++ b/include/libdecnumber/dconfig.h
@@ -23,9 +23,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
#if HOST_BIG_ENDIAN
diff --git a/include/libdecnumber/decContext.h b/include/libdecnumber/decContext.h
index cea6e42..5bb64e1 100644
--- a/include/libdecnumber/decContext.h
+++ b/include/libdecnumber/decContext.h
@@ -24,9 +24,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------ */
/* Decimal Context module header */
diff --git a/include/libdecnumber/decDPD.h b/include/libdecnumber/decDPD.h
index 26a21ec..8eb4552 100644
--- a/include/libdecnumber/decDPD.h
+++ b/include/libdecnumber/decDPD.h
@@ -24,9 +24,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------------ */
/* Binary Coded Decimal and Densely Packed Decimal conversion lookup tables */
diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index 41bc2a0..bf37af8 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -24,9 +24,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------ */
/* Decimal Number arithmetic module header */
diff --git a/include/libdecnumber/decNumberLocal.h b/include/libdecnumber/decNumberLocal.h
index 6198ca8..0959f66 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -24,9 +24,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------ */
/* decNumber package local type, tuning, and macro definitions */
diff --git a/include/libdecnumber/dpd/decimal128.h b/include/libdecnumber/dpd/decimal128.h
index aff261e..c57180b 100644
--- a/include/libdecnumber/dpd/decimal128.h
+++ b/include/libdecnumber/dpd/decimal128.h
@@ -24,9 +24,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------ */
/* Decimal 128-bit format module header */
diff --git a/include/libdecnumber/dpd/decimal128Local.h b/include/libdecnumber/dpd/decimal128Local.h
index 9765427..2948ab2 100644
--- a/include/libdecnumber/dpd/decimal128Local.h
+++ b/include/libdecnumber/dpd/decimal128Local.h
@@ -23,9 +23,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
#if !defined(DECIMAL128LOCAL)
diff --git a/include/libdecnumber/dpd/decimal32.h b/include/libdecnumber/dpd/decimal32.h
index 6cb9e43..9a17933 100644
--- a/include/libdecnumber/dpd/decimal32.h
+++ b/include/libdecnumber/dpd/decimal32.h
@@ -24,9 +24,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------ */
/* Decimal 32-bit format module header */
diff --git a/include/libdecnumber/dpd/decimal64.h b/include/libdecnumber/dpd/decimal64.h
index f29e570..5c3d0bb 100644
--- a/include/libdecnumber/dpd/decimal64.h
+++ b/include/libdecnumber/dpd/decimal64.h
@@ -24,9 +24,8 @@
for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA. */
+ along with GCC; see the file COPYING. If not, see
+ <https://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------ */
/* Decimal 64-bit format module header */
diff --git a/include/migration/client-options.h b/include/migration/client-options.h
index 59f4b55..289c9d7 100644
--- a/include/migration/client-options.h
+++ b/include/migration/client-options.h
@@ -10,6 +10,10 @@
#ifndef QEMU_MIGRATION_CLIENT_OPTIONS_H
#define QEMU_MIGRATION_CLIENT_OPTIONS_H
+
+/* properties */
+bool migrate_send_switchover_start(void);
+
/* capabilities */
bool migrate_background_snapshot(void);
diff --git a/include/migration/cpr.h b/include/migration/cpr.h
new file mode 100644
index 0000000..07858e9
--- /dev/null
+++ b/include/migration/cpr.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021, 2024 Oracle and/or its affiliates.
+ *
+ * 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 MIGRATION_CPR_H
+#define MIGRATION_CPR_H
+
+#include "qapi/qapi-types-migration.h"
+
+#define MIG_MODE_NONE -1
+
+#define QEMU_CPR_FILE_MAGIC 0x51435052
+#define QEMU_CPR_FILE_VERSION 0x00000001
+
+void cpr_save_fd(const char *name, int id, int fd);
+void cpr_delete_fd(const char *name, int id);
+int cpr_find_fd(const char *name, int id);
+void cpr_resave_fd(const char *name, int id, int fd);
+int cpr_open_fd(const char *path, int flags, const char *name, int id,
+ Error **errp);
+
+MigMode cpr_get_incoming_mode(void);
+void cpr_set_incoming_mode(MigMode mode);
+bool cpr_is_incoming(void);
+
+int cpr_state_save(MigrationChannel *channel, Error **errp);
+int cpr_state_load(MigrationChannel *channel, Error **errp);
+void cpr_state_close(void);
+struct QIOChannel *cpr_state_ioc(void);
+
+bool cpr_incoming_needed(void *opaque);
+
+QEMUFile *cpr_transfer_output(MigrationChannel *channel, Error **errp);
+QEMUFile *cpr_transfer_input(MigrationChannel *channel, Error **errp);
+
+#endif
diff --git a/include/migration/misc.h b/include/migration/misc.h
index bfadc56..8fd36eb 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -39,25 +39,25 @@ void precopy_add_notifier(NotifierWithReturn *n);
void precopy_remove_notifier(NotifierWithReturn *n);
int precopy_notify(PrecopyNotifyReason reason, Error **errp);
-void ram_mig_init(void);
void qemu_guest_free_page_hint(void *addr, size_t len);
bool migrate_ram_is_ignored(RAMBlock *block);
/* migration/block.c */
AnnounceParameters *migrate_announce_params(void);
+
/* migration/savevm.c */
void dump_vmstate_json_to_file(FILE *out_fp);
+void qemu_loadvm_start_load_thread(MigrationLoadThread function,
+ void *opaque);
/* migration/migration.c */
void migration_object_init(void);
void migration_shutdown(void);
-bool migration_is_idle(void);
-bool migration_is_active(void);
-bool migration_is_device(void);
+
+bool migration_is_running(void);
bool migration_thread_is_self(void);
-bool migration_is_setup_or_active(void);
typedef enum MigrationEventType {
MIG_EVENT_PRECOPY_SETUP,
@@ -96,7 +96,6 @@ void migration_add_notifier_mode(NotifierWithReturn *notify,
MigrationNotifyFunc func, MigMode mode);
void migration_remove_notifier(NotifierWithReturn *notify);
-bool migration_is_running(void);
void migration_file_set_error(int ret, Error *err);
/* True if incoming migration entered POSTCOPY_INCOMING_DISCARD */
@@ -108,7 +107,37 @@ bool migration_incoming_postcopy_advised(void);
/* True if background snapshot is active */
bool migration_in_bg_snapshot(void);
-/* migration/block-dirty-bitmap.c */
-void dirty_bitmap_mig_init(void);
+/* Wrapper for block active/inactive operations */
+bool migration_block_activate(Error **errp);
+bool migration_block_inactivate(void);
+
+/* True if @uri starts with a syntactically valid URI prefix */
+bool migrate_is_uri(const char *uri);
+
+/* Parse @uri and return @channel, returning true on success */
+bool migrate_uri_parse(const char *uri, MigrationChannel **channel,
+ Error **errp);
+
+/* migration/multifd-device-state.c */
+typedef struct SaveLiveCompletePrecopyThreadData {
+ SaveLiveCompletePrecopyThreadHandler hdlr;
+ char *idstr;
+ uint32_t instance_id;
+ void *handler_opaque;
+} SaveLiveCompletePrecopyThreadData;
+
+bool multifd_queue_device_state(char *idstr, uint32_t instance_id,
+ char *data, size_t len);
+bool multifd_device_state_supported(void);
+
+void
+multifd_spawn_device_state_save_thread(SaveLiveCompletePrecopyThreadHandler hdlr,
+ char *idstr, uint32_t instance_id,
+ void *opaque);
+
+bool multifd_device_state_save_thread_should_exit(void);
+
+void multifd_abort_device_state_save_threads(void);
+bool multifd_join_device_state_save_threads(void);
#endif
diff --git a/include/migration/register.h b/include/migration/register.h
index f60e797..b79dc81 100644
--- a/include/migration/register.h
+++ b/include/migration/register.h
@@ -69,7 +69,9 @@ typedef struct SaveVMHandlers {
/**
* @save_cleanup
*
- * Uninitializes the data structures on the source
+ * Uninitializes the data structures on the source.
+ * Note that this handler can be called even if save_setup
+ * wasn't called earlier.
*
* @opaque: data pointer passed to register_savevm_live()
*/
@@ -103,6 +105,25 @@ typedef struct SaveVMHandlers {
*/
int (*save_live_complete_precopy)(QEMUFile *f, void *opaque);
+ /**
+ * @save_live_complete_precopy_thread (invoked in a separate thread)
+ *
+ * Called at the end of a precopy phase from a separate worker thread
+ * in configurations where multifd device state transfer is supported
+ * in order to perform asynchronous transmission of the remaining data in
+ * parallel with @save_live_complete_precopy handlers.
+ * When postcopy is enabled, devices that support postcopy will skip this
+ * step.
+ *
+ * @d: a #SaveLiveCompletePrecopyThreadData containing parameters that the
+ * handler may need, including this device section idstr and instance_id,
+ * and opaque data pointer passed to register_savevm_live().
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns true to indicate success and false for errors.
+ */
+ SaveLiveCompletePrecopyThreadHandler save_live_complete_precopy_thread;
+
/* This runs both outside and inside the BQL. */
/**
@@ -169,6 +190,21 @@ typedef struct SaveVMHandlers {
/* This runs outside the BQL! */
/**
+ * @save_postcopy_prepare
+ *
+ * This hook will be invoked on the source side right before switching
+ * to postcopy (before VM stopped).
+ *
+ * @f: QEMUFile where to send the data
+ * @opaque: Data pointer passed to register_savevm_live()
+ * @errp: Error** used to report error message
+ *
+ * Returns: true if succeeded, false if error occured. When false is
+ * returned, @errp must be set.
+ */
+ bool (*save_postcopy_prepare)(QEMUFile *f, void *opaque, Error **errp);
+
+ /**
* @state_pending_estimate
*
* This estimates the remaining data to transfer
@@ -228,6 +264,21 @@ typedef struct SaveVMHandlers {
int (*load_state)(QEMUFile *f, void *opaque, int version_id);
/**
+ * @load_state_buffer (invoked outside the BQL)
+ *
+ * Load device state buffer provided to qemu_loadvm_load_state_buffer().
+ *
+ * @opaque: data pointer passed to register_savevm_live()
+ * @buf: the data buffer to load
+ * @len: the data length in buffer
+ * @errp: pointer to Error*, to store an error if it happens.
+ *
+ * Returns true to indicate success and false for errors.
+ */
+ bool (*load_state_buffer)(void *opaque, char *buf, size_t len,
+ Error **errp);
+
+ /**
* @load_setup
*
* Initializes the data structures on the destination.
@@ -244,6 +295,8 @@ typedef struct SaveVMHandlers {
* @load_cleanup
*
* Uninitializes the data structures on the destination.
+ * Note that this handler can be called even if load_setup
+ * wasn't called earlier.
*
* @opaque: data pointer passed to register_savevm_live()
*
@@ -275,6 +328,18 @@ typedef struct SaveVMHandlers {
* otherwise
*/
bool (*switchover_ack_needed)(void *opaque);
+
+ /**
+ * @switchover_start
+ *
+ * Notifies that the switchover has started. Called only on
+ * the destination.
+ *
+ * @opaque: data pointer passed to register_savevm_live()
+ *
+ * Returns zero to indicate success and negative for error
+ */
+ int (*switchover_start)(void *opaque);
} SaveVMHandlers;
/**
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index f313f2f..1ff7bd9 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -155,7 +155,11 @@ enum VMStateFlags {
};
typedef enum {
- MIG_PRI_DEFAULT = 0,
+ MIG_PRI_UNINITIALIZED = 0, /* An uninitialized priority field maps to */
+ /* MIG_PRI_DEFAULT in save_state_priority */
+
+ MIG_PRI_LOW, /* Must happen after default */
+ MIG_PRI_DEFAULT,
MIG_PRI_IOMMU, /* Must happen before PCI devices */
MIG_PRI_PCI_BUS, /* Must happen before IOMMU */
MIG_PRI_VIRTIO_MEM, /* Must happen before IOMMU */
@@ -230,6 +234,7 @@ extern const VMStateInfo vmstate_info_uint8;
extern const VMStateInfo vmstate_info_uint16;
extern const VMStateInfo vmstate_info_uint32;
extern const VMStateInfo vmstate_info_uint64;
+extern const VMStateInfo vmstate_info_fd;
/** Put this in the stream when migrating a null pointer.*/
#define VMS_NULLPTR_MARKER (0x30U) /* '0' */
@@ -902,6 +907,9 @@ extern const VMStateInfo vmstate_info_qlist;
#define VMSTATE_UINT64_V(_f, _s, _v) \
VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t)
+#define VMSTATE_FD_V(_f, _s, _v) \
+ VMSTATE_SINGLE(_f, _s, _v, vmstate_info_fd, int32_t)
+
#ifdef CONFIG_LINUX
#define VMSTATE_U8_V(_f, _s, _v) \
@@ -936,6 +944,9 @@ extern const VMStateInfo vmstate_info_qlist;
#define VMSTATE_UINT64(_f, _s) \
VMSTATE_UINT64_V(_f, _s, 0)
+#define VMSTATE_FD(_f, _s) \
+ VMSTATE_FD_V(_f, _s, 0)
+
#ifdef CONFIG_LINUX
#define VMSTATE_U8(_f, _s) \
@@ -1009,6 +1020,8 @@ extern const VMStateInfo vmstate_info_qlist;
#define VMSTATE_UINT64_TEST(_f, _s, _t) \
VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint64, uint64_t)
+#define VMSTATE_FD_TEST(_f, _s, _t) \
+ VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_fd, int32_t)
#define VMSTATE_TIMER_PTR_TEST(_f, _s, _test) \
VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *)
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 954f3c8..ae116d9 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -35,7 +35,6 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict);
void hmp_info_vnc(Monitor *mon, const QDict *qdict);
void hmp_info_spice(Monitor *mon, const QDict *qdict);
void hmp_info_balloon(Monitor *mon, const QDict *qdict);
-void hmp_info_irq(Monitor *mon, const QDict *qdict);
void hmp_info_pic(Monitor *mon, const QDict *qdict);
void hmp_info_pci(Monitor *mon, const QDict *qdict);
void hmp_info_tpm(Monitor *mon, const QDict *qdict);
@@ -102,7 +101,6 @@ void hmp_chardev_send_break(Monitor *mon, const QDict *qdict);
void hmp_object_add(Monitor *mon, const QDict *qdict);
void hmp_object_del(Monitor *mon, const QDict *qdict);
void hmp_info_memdev(Monitor *mon, const QDict *qdict);
-void hmp_info_numa(Monitor *mon, const QDict *qdict);
void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
void hmp_qom_list(Monitor *mon, const QDict *qdict);
void hmp_qom_get(Monitor *mon, const QDict *qdict);
@@ -141,7 +139,6 @@ void hmp_rocker_ports(Monitor *mon, const QDict *qdict);
void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict);
void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
void hmp_info_dump(Monitor *mon, const QDict *qdict);
-void hmp_info_ramblock(Monitor *mon, const QDict *qdict);
void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
void hmp_info_memory_size_summary(Monitor *mon, const QDict *qdict);
diff --git a/include/net/checksum.h b/include/net/checksum.h
index 7dec37e..188e4cc 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -30,7 +30,7 @@ uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq);
uint16_t net_checksum_finish(uint32_t sum);
uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
uint8_t *addrs, uint8_t *buf);
-void net_checksum_calculate(uint8_t *data, int length, int csum_flag);
+void net_checksum_calculate(void *data, int length, int csum_flag);
static inline uint32_t
net_checksum_add(int len, uint8_t *buf)
diff --git a/include/net/eth.h b/include/net/eth.h
index 3b80b6e..14c34f5 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -56,7 +56,7 @@ struct ip_header {
uint8_t ip_p; /* protocol */
uint16_t ip_sum; /* checksum */
uint32_t ip_src, ip_dst; /* source and destination address */
-};
+} QEMU_PACKED;
typedef struct tcp_header {
uint16_t th_sport; /* source port */
diff --git a/include/net/net.h b/include/net/net.h
index c8f6797..cdd5b10 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -172,9 +172,6 @@ ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov,
int iovcnt, NetPacketSent *sent_cb);
ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size);
ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size);
-ssize_t qemu_receive_packet_iov(NetClientState *nc,
- const struct iovec *iov,
- int iovcnt);
ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size);
ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf,
int size, NetPacketSent *sent_cb);
@@ -307,7 +304,6 @@ void hmp_host_net_remove(Monitor *mon, const QDict *qdict);
void netdev_add(QemuOpts *opts, Error **errp);
int net_hub_id_for_client(NetClientState *nc, int *id);
-NetClientState *net_hub_port_find(int hub_id);
#define DEFAULT_NETWORK_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifup"
#define DEFAULT_NETWORK_DOWN_SCRIPT CONFIG_SYSCONFDIR "/qemu-ifdown"
diff --git a/include/net/queue.h b/include/net/queue.h
index 9f2f289..2e686b1 100644
--- a/include/net/queue.h
+++ b/include/net/queue.h
@@ -59,10 +59,6 @@ ssize_t qemu_net_queue_receive(NetQueue *queue,
const uint8_t *data,
size_t size);
-ssize_t qemu_net_queue_receive_iov(NetQueue *queue,
- const struct iovec *iov,
- int iovcnt);
-
ssize_t qemu_net_queue_send(NetQueue *queue,
NetClientState *sender,
unsigned flags,
diff --git a/include/qapi/compat-policy.h b/include/qapi/compat-policy.h
index 8b7b25c..ea65e10 100644
--- a/include/qapi/compat-policy.h
+++ b/include/qapi/compat-policy.h
@@ -18,7 +18,7 @@
extern CompatPolicy compat_policy;
-bool compat_policy_input_ok(unsigned special_features,
+bool compat_policy_input_ok(uint64_t features,
const CompatPolicy *policy,
ErrorClass error_class,
const char *kind, const char *name,
diff --git a/include/qapi/error-internal.h b/include/qapi/error-internal.h
new file mode 100644
index 0000000..ff18a20
--- /dev/null
+++ b/include/qapi/error-internal.h
@@ -0,0 +1,35 @@
+/*
+ * QEMU Error Objects - struct definition
+ *
+ * Copyright IBM, Corp. 2011
+ * Copyright (C) 2011-2015 Red Hat, Inc.
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2. See
+ * the COPYING.LIB file in the top-level directory.
+ */
+
+#ifndef QAPI_ERROR_INTERNAL_H
+
+struct Error
+{
+ char *msg;
+ ErrorClass err_class;
+
+ /* Used for error_abort only, may be NULL. */
+ const char *func;
+
+ /*
+ * src might be NUL-terminated or not. If it is, src_len is negative.
+ * If it is not, src_len is the length.
+ */
+ const char *src;
+ int src_len;
+ int line;
+ GString *hint;
+};
+
+#endif
diff --git a/include/qapi/error.h b/include/qapi/error.h
index 71f8fb2..41e3816 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -437,6 +437,8 @@ Error *error_copy(const Error *err);
*/
void error_free(Error *err);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(Error, error_free)
+
/*
* Convenience function to assert that *@errp is set, then silently free it.
*/
@@ -467,6 +469,18 @@ void error_reportf_err(Error *err, const char *fmt, ...)
G_GNUC_PRINTF(2, 3);
/*
+ * Similar to warn_report_err(), except it prints the message just once.
+ * Return true when it prints, false otherwise.
+ */
+bool warn_report_err_once_cond(bool *printed, Error *err);
+
+#define warn_report_err_once(err) \
+ ({ \
+ static bool print_once_; \
+ warn_report_err_once_cond(&print_once_, err); \
+ })
+
+/*
* Just like error_setg(), except you get to specify the error class.
* Note: use of error classes other than ERROR_CLASS_GENERIC_ERROR is
* strongly discouraged.
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp-registry.h
index f2e9568..e0ee1ad 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp-registry.h
@@ -33,7 +33,7 @@ typedef struct QmpCommand
/* Runs in coroutine context if QCO_COROUTINE is set */
QmpCommandFunc *fn;
QmpCommandOptions options;
- unsigned special_features;
+ uint64_t features;
QTAILQ_ENTRY(QmpCommand) node;
bool enabled;
const char *disable_reason;
@@ -43,7 +43,7 @@ typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
void qmp_register_command(QmpCommandList *cmds, const char *name,
QmpCommandFunc *fn, QmpCommandOptions options,
- unsigned special_features);
+ uint64_t features);
const QmpCommand *qmp_find_command(const QmpCommandList *cmds,
const char *name);
void qmp_disable_command(QmpCommandList *cmds, const char *name,
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 38e8976..d1db6f1 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -23,10 +23,4 @@
#define QERR_MISSING_PARAMETER \
"Parameter '%s' is missing"
-#define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
- "Property %s.%s doesn't take value %" PRId64 " (minimum: %" PRId64 ", maximum: %" PRId64 ")"
-
-#define QERR_UNSUPPORTED \
- "this feature or command is not currently supported"
-
#endif /* QERROR_H */
diff --git a/include/qapi/util.h b/include/qapi/util.h
index 20dfea8..29bc4eb 100644
--- a/include/qapi/util.h
+++ b/include/qapi/util.h
@@ -18,7 +18,7 @@ typedef enum {
typedef struct QEnumLookup {
const char *const *array;
- const unsigned char *const special_features;
+ const uint64_t *const features;
const int size;
} QEnumLookup;
@@ -62,7 +62,7 @@ int parse_qapi_name(const char *name, bool complete);
#define QAPI_LIST_LENGTH(list) \
({ \
size_t _len = 0; \
- typeof(list) _tail; \
+ typeof_strip_qual(list) _tail; \
for (_tail = list; _tail != NULL; _tail = _tail->next) { \
_len++; \
} \
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 2badec5..7beb0db 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -115,11 +115,11 @@ struct Visitor
/* Optional */
bool (*policy_reject)(Visitor *v, const char *name,
- unsigned special_features, Error **errp);
+ uint64_t features, Error **errp);
/* Optional */
bool (*policy_skip)(Visitor *v, const char *name,
- unsigned special_features);
+ uint64_t features);
/* Must be set */
VisitorType type;
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 27b85d4..f6a9b07 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -463,29 +463,29 @@ bool visit_optional(Visitor *v, const char *name, bool *present);
/*
* Should we reject member @name due to policy?
*
- * @special_features is the member's special features encoded as a
- * bitset of QapiSpecialFeature.
+ * @features is the member's special features encoded as a
+ * bitset of QapiFeature.
*
* @name must not be NULL. This function is only useful between
* visit_start_struct() and visit_end_struct(), since only objects
* have deprecated members.
*/
bool visit_policy_reject(Visitor *v, const char *name,
- unsigned special_features, Error **errp);
+ uint64_t features, Error **errp);
/*
*
* Should we skip member @name due to policy?
*
- * @special_features is the member's special features encoded as a
- * bitset of QapiSpecialFeature.
+ * @features is the member's special features encoded as a
+ * bitset of QapiFeature.
*
* @name must not be NULL. This function is only useful between
* visit_start_struct() and visit_end_struct(), since only objects
* have deprecated members.
*/
bool visit_policy_skip(Visitor *v, const char *name,
- unsigned special_features);
+ uint64_t features);
/*
* Set policy for handling deprecated management interfaces.
diff --git a/include/qemu-main.h b/include/qemu-main.h
index 940960a..2ee83be 100644
--- a/include/qemu-main.h
+++ b/include/qemu-main.h
@@ -5,7 +5,19 @@
#ifndef QEMU_MAIN_H
#define QEMU_MAIN_H
-int qemu_default_main(void);
+/*
+ * The function to run on the main (initial) thread of the process.
+ * NULL means QEMU's main event loop.
+ * When non-NULL, QEMU's main event loop will run on a purposely created
+ * thread, after which the provided function pointer will be invoked on
+ * the initial thread.
+ * This is useful on platforms which treat the main thread as special
+ * (macOS/Darwin) and/or require all UI API calls to occur from the main
+ * thread. Those platforms can initialise it to a specific function,
+ * while UI implementations may reset it to NULL during their init if they
+ * will handle system and UI events on the main thread via QEMU's own main
+ * event loop.
+ */
extern int (*qemu_main)(void);
#endif /* QEMU_MAIN_H */
diff --git a/include/qemu/accel.h b/include/qemu/accel.h
index 972a849..fbd3d89 100644
--- a/include/qemu/accel.h
+++ b/include/qemu/accel.h
@@ -38,13 +38,13 @@ typedef struct AccelClass {
const char *name;
int (*init_machine)(MachineState *ms);
-#ifndef CONFIG_USER_ONLY
+ bool (*cpu_common_realize)(CPUState *cpu, Error **errp);
+ void (*cpu_common_unrealize)(CPUState *cpu);
+
+ /* system related hooks */
void (*setup_post)(MachineState *ms, AccelState *accel);
bool (*has_memory)(MachineState *ms, AddressSpace *as,
hwaddr start_addr, hwaddr size);
-#endif
- bool (*cpu_common_realize)(CPUState *cpu, Error **errp);
- void (*cpu_common_unrealize)(CPUState *cpu);
/* gdbstub related hooks */
int (*gdbstub_supported_sstep_flags)(void);
@@ -78,12 +78,10 @@ const char *current_accel_name(void);
void accel_init_interfaces(AccelClass *ac);
-#ifndef CONFIG_USER_ONLY
int accel_init_machine(AccelState *accel, MachineState *ms);
/* Called just before os_setup_post (ie just before drop OS privs) */
void accel_setup_post(MachineState *ms);
-#endif /* !CONFIG_USER_ONLY */
/**
* accel_cpu_instance_init:
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 99110ab..f80cba2 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -20,48 +20,6 @@
/* Compiler barrier */
#define barrier() ({ asm volatile("" ::: "memory"); (void)0; })
-/* The variable that receives the old value of an atomically-accessed
- * variable must be non-qualified, because atomic builtins return values
- * through a pointer-type argument as in __atomic_load(&var, &old, MODEL).
- *
- * This macro has to handle types smaller than int manually, because of
- * implicit promotion. int and larger types, as well as pointers, can be
- * converted to a non-qualified type just by applying a binary operator.
- */
-#define typeof_strip_qual(expr) \
- typeof( \
- __builtin_choose_expr( \
- __builtin_types_compatible_p(typeof(expr), bool) || \
- __builtin_types_compatible_p(typeof(expr), const bool) || \
- __builtin_types_compatible_p(typeof(expr), volatile bool) || \
- __builtin_types_compatible_p(typeof(expr), const volatile bool), \
- (bool)1, \
- __builtin_choose_expr( \
- __builtin_types_compatible_p(typeof(expr), signed char) || \
- __builtin_types_compatible_p(typeof(expr), const signed char) || \
- __builtin_types_compatible_p(typeof(expr), volatile signed char) || \
- __builtin_types_compatible_p(typeof(expr), const volatile signed char), \
- (signed char)1, \
- __builtin_choose_expr( \
- __builtin_types_compatible_p(typeof(expr), unsigned char) || \
- __builtin_types_compatible_p(typeof(expr), const unsigned char) || \
- __builtin_types_compatible_p(typeof(expr), volatile unsigned char) || \
- __builtin_types_compatible_p(typeof(expr), const volatile unsigned char), \
- (unsigned char)1, \
- __builtin_choose_expr( \
- __builtin_types_compatible_p(typeof(expr), signed short) || \
- __builtin_types_compatible_p(typeof(expr), const signed short) || \
- __builtin_types_compatible_p(typeof(expr), volatile signed short) || \
- __builtin_types_compatible_p(typeof(expr), const volatile signed short), \
- (signed short)1, \
- __builtin_choose_expr( \
- __builtin_types_compatible_p(typeof(expr), unsigned short) || \
- __builtin_types_compatible_p(typeof(expr), const unsigned short) || \
- __builtin_types_compatible_p(typeof(expr), volatile unsigned short) || \
- __builtin_types_compatible_p(typeof(expr), const volatile unsigned short), \
- (unsigned short)1, \
- (expr)+0))))))
-
#ifndef __ATOMIC_RELAXED
#error "Expecting C11 atomic ops"
#endif
@@ -98,25 +56,13 @@
*/
#define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
-/* Sanity check that the size of an atomic operation isn't "overly large".
+/*
+ * Sanity check that the size of an atomic operation isn't "overly large".
* Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
* want to use them because we ought not need them, and this lets us do a
* bit of sanity checking that other 32-bit hosts might build.
- *
- * That said, we have a problem on 64-bit ILP32 hosts in that in order to
- * sync with TCG_OVERSIZED_GUEST, this must match TCG_TARGET_REG_BITS.
- * We'd prefer not want to pull in everything else TCG related, so handle
- * those few cases by hand.
- *
- * Note that x32 is fully detected with __x86_64__ + _ILP32, and that for
- * Sparc we always force the use of sparcv9 in configure. MIPS n32 (ILP32) &
- * n64 (LP64) ABIs are both detected using __mips64.
*/
-#if defined(__x86_64__) || defined(__sparc__) || defined(__mips64)
-# define ATOMIC_REG_SIZE 8
-#else
-# define ATOMIC_REG_SIZE sizeof(void *)
-#endif
+#define ATOMIC_REG_SIZE sizeof(void *)
/* Weak atomic operations prevent the compiler moving other
* loads/stores past the atomic operation load/store. However there is
@@ -170,7 +116,7 @@
_val; \
})
#define qatomic_rcu_read(ptr) \
- qatomic_rcu_read_internal((ptr), MAKE_IDENTFIER(_val))
+ qatomic_rcu_read_internal((ptr), MAKE_IDENTIFIER(_val))
#define qatomic_rcu_set(ptr, i) do { \
qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
diff --git a/include/qemu/atomic128.h b/include/qemu/atomic128.h
index 88af6d4..31e5c48 100644
--- a/include/qemu/atomic128.h
+++ b/include/qemu/atomic128.h
@@ -13,6 +13,7 @@
#ifndef QEMU_ATOMIC128_H
#define QEMU_ATOMIC128_H
+#include "qemu/atomic.h"
#include "qemu/int128.h"
/*
@@ -58,7 +59,7 @@
* Therefore, special case each platform.
*/
-#include "host/atomic128-cas.h"
-#include "host/atomic128-ldst.h"
+#include "host/atomic128-cas.h.inc"
+#include "host/atomic128-ldst.h.inc"
#endif /* QEMU_ATOMIC128_H */
diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
index 1cf2884..0044333 100644
--- a/include/qemu/bitmap.h
+++ b/include/qemu/bitmap.h
@@ -69,6 +69,14 @@
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
+/*
+ * This is for use with the bit32 versions of set_bit() etc;
+ * we don't currently support the full range of bitmap operations
+ * on bitmaps backed by an array of uint32_t.
+ */
+#define DECLARE_BITMAP32(name, bits) \
+ uint32_t name[BITS_TO_U32S(bits)]
+
#define small_nbits(nbits) \
((nbits) <= BITS_PER_LONG)
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 2c0a2fe..c7b838a 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -18,17 +18,48 @@
#define BITS_PER_BYTE CHAR_BIT
#define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE)
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
+#define BITS_TO_U32S(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(uint32_t))
#define BIT(nr) (1UL << (nr))
#define BIT_ULL(nr) (1ULL << (nr))
-#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
-#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
-#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define MAKE_64BIT_MASK(shift, length) \
(((~0ULL) >> (64 - (length))) << (shift))
/**
+ * DOC: Functions operating on arrays of bits
+ *
+ * We provide a set of functions which work on arbitrary-length arrays of
+ * bits. These come in several flavours which vary in what the type of the
+ * underlying storage for the bits is:
+ *
+ * - Bits stored in an array of 'unsigned long': set_bit(), clear_bit(), etc
+ * - Bits stored in an array of 'uint32_t': set_bit32(), clear_bit32(), etc
+ *
+ * Because the 'unsigned long' type has a size which varies between
+ * host systems, the versions using 'uint32_t' are often preferable.
+ * This is particularly the case in a device model where there may
+ * be some guest-visible register view of the bit array.
+ *
+ * We do not currently implement uint32_t versions of find_last_bit(),
+ * find_next_bit(), find_next_zero_bit(), find_first_bit() or
+ * find_first_zero_bit(), because we haven't yet needed them. If you
+ * need them you should implement them similarly to the 'unsigned long'
+ * versions.
+ *
+ * You can declare a bitmap to be used with these functions via the
+ * DECLARE_BITMAP and DECLARE_BITMAP32 macros in bitmap.h.
+ */
+
+/**
+ * DOC: 'unsigned long' bit array APIs
+ */
+
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+
+/**
* set_bit - Set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
@@ -225,6 +256,141 @@ static inline unsigned long find_first_zero_bit(const unsigned long *addr,
}
/**
+ * DOC: 'uint32_t' bit array APIs
+ */
+
+#define BIT32_MASK(nr) (1UL << ((nr) % 32))
+#define BIT32_WORD(nr) ((nr) / 32)
+
+/**
+ * set_bit32 - Set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ */
+static inline void set_bit32(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+
+ *p |= mask;
+}
+
+/**
+ * set_bit32_atomic - Set a bit in memory atomically
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ */
+static inline void set_bit32_atomic(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+
+ qatomic_or(p, mask);
+}
+
+/**
+ * clear_bit32 - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ */
+static inline void clear_bit32(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+
+ *p &= ~mask;
+}
+
+/**
+ * clear_bit32_atomic - Clears a bit in memory atomically
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ */
+static inline void clear_bit32_atomic(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+
+ return qatomic_and(p, ~mask);
+}
+
+/**
+ * change_bit32 - Toggle a bit in memory
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ */
+static inline void change_bit32(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+
+ *p ^= mask;
+}
+
+/**
+ * test_and_set_bit32 - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ */
+static inline int test_and_set_bit32(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+ uint32_t old = *p;
+
+ *p = old | mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * test_and_clear_bit32 - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ */
+static inline int test_and_clear_bit32(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+ uint32_t old = *p;
+
+ *p = old & ~mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * test_and_change_bit32 - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ */
+static inline int test_and_change_bit32(long nr, uint32_t *addr)
+{
+ uint32_t mask = BIT32_MASK(nr);
+ uint32_t *p = addr + BIT32_WORD(nr);
+ uint32_t old = *p;
+
+ *p = old ^ mask;
+ return (old & mask) != 0;
+}
+
+/**
+ * test_bit32 - Determine whether a bit is set
+ * @nr: bit number to test
+ * @addr: Address to start counting from
+ */
+static inline int test_bit32(long nr, const uint32_t *addr)
+{
+ return 1U & (addr[BIT32_WORD(nr)] >> (nr & 31));
+}
+
+/**
+ * DOC: Miscellaneous bit operations on single values
+ *
+ * These functions are a collection of useful operations
+ * (rotations, bit extract, bit deposit, etc) on single
+ * integer values.
+ */
+
+/**
* rol8 - rotate an 8-bit value left
* @word: value to rotate
* @shift: bits to roll
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index bd67468..9a11764 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -38,12 +38,14 @@ static inline void bswap64s(uint64_t *s)
#if HOST_BIG_ENDIAN
#define be_bswap(v, size) (v)
#define le_bswap(v, size) glue(__builtin_bswap, size)(v)
+#define be_bswap24(v) (v)
#define le_bswap24(v) bswap24(v)
#define be_bswaps(v, size)
#define le_bswaps(p, size) \
do { *p = glue(__builtin_bswap, size)(*p); } while (0)
#else
#define le_bswap(v, size) (v)
+#define be_bswap24(v) bswap24(v)
#define le_bswap24(v) (v)
#define be_bswap(v, size) glue(__builtin_bswap, size)(v)
#define le_bswaps(v, size)
@@ -138,6 +140,8 @@ CPU_CONVERT(le, 16, uint16_t)
CPU_CONVERT(le, 32, uint32_t)
CPU_CONVERT(le, 64, uint64_t)
+#undef CPU_CONVERT
+
/*
* Same as cpu_to_le{16,32,64}, except that gcc will figure the result is
* a compile-time constant if you pass in a constant. So this can be
@@ -201,9 +205,6 @@ CPU_CONVERT(le, 64, uint64_t)
* te : target endian
* (except for byte accesses, which have no endian infix).
*
- * The target endian accessors are obviously only available to source
- * files which are built per-target; they are defined in cpu-all.h.
- *
* In all cases these functions take a host pointer.
* For accessors that take a guest address rather than a
* host address, see the cpu_{ld,st}_* accessors defined in
@@ -357,6 +358,11 @@ static inline void stw_be_p(void *ptr, uint16_t v)
stw_he_p(ptr, be_bswap(v, 16));
}
+static inline void st24_be_p(void *ptr, uint32_t v)
+{
+ st24_he_p(ptr, be_bswap24(v));
+}
+
static inline void stl_be_p(void *ptr, uint32_t v)
{
stl_he_p(ptr, be_bswap(v, 32));
diff --git a/include/qemu/cacheflush.h b/include/qemu/cacheflush.h
index ae20bcd..76eb55d 100644
--- a/include/qemu/cacheflush.h
+++ b/include/qemu/cacheflush.h
@@ -26,6 +26,13 @@ static inline void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
/* icache is coherent and does not require flushing. */
}
+#elif defined(EMSCRIPTEN)
+
+static inline void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
+{
+ /* Wasm doesn't have executable region of memory. */
+}
+
#else
void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len);
diff --git a/include/qemu/clang-tsa.h b/include/qemu/clang-tsa.h
deleted file mode 100644
index ba06fb8..0000000
--- a/include/qemu/clang-tsa.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef CLANG_TSA_H
-#define CLANG_TSA_H
-
-/*
- * Copyright 2018 Jarkko Hietaniemi <jhi@iki.fi>
- *
- * 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.
- */
-
-/* http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
- *
- * TSA is available since clang 3.6-ish.
- */
-#ifdef __clang__
-# define TSA(x) __attribute__((x))
-#else
-# define TSA(x) /* No TSA, make TSA attributes no-ops. */
-#endif
-
-/* TSA_CAPABILITY() is used to annotate typedefs:
- *
- * typedef pthread_mutex_t TSA_CAPABILITY("mutex") tsa_mutex;
- */
-#define TSA_CAPABILITY(x) TSA(capability(x))
-
-/* TSA_GUARDED_BY() is used to annotate global variables,
- * the data is guarded:
- *
- * Foo foo TSA_GUARDED_BY(mutex);
- */
-#define TSA_GUARDED_BY(x) TSA(guarded_by(x))
-
-/* TSA_PT_GUARDED_BY() is used to annotate global pointers, the data
- * behind the pointer is guarded.
- *
- * Foo* ptr TSA_PT_GUARDED_BY(mutex);
- */
-#define TSA_PT_GUARDED_BY(x) TSA(pt_guarded_by(x))
-
-/* The TSA_REQUIRES() is used to annotate functions: the caller of the
- * function MUST hold the resource, the function will NOT release it.
- *
- * More than one mutex may be specified, comma-separated.
- *
- * void Foo(void) TSA_REQUIRES(mutex);
- */
-#define TSA_REQUIRES(...) TSA(requires_capability(__VA_ARGS__))
-#define TSA_REQUIRES_SHARED(...) TSA(requires_shared_capability(__VA_ARGS__))
-
-/* TSA_EXCLUDES() is used to annotate functions: the caller of the
- * function MUST NOT hold resource, the function first acquires the
- * resource, and then releases it.
- *
- * More than one mutex may be specified, comma-separated.
- *
- * void Foo(void) TSA_EXCLUDES(mutex);
- */
-#define TSA_EXCLUDES(...) TSA(locks_excluded(__VA_ARGS__))
-
-/* TSA_ACQUIRE() is used to annotate functions: the caller of the
- * function MUST NOT hold the resource, the function will acquire the
- * resource, but NOT release it.
- *
- * More than one mutex may be specified, comma-separated.
- *
- * void Foo(void) TSA_ACQUIRE(mutex);
- */
-#define TSA_ACQUIRE(...) TSA(acquire_capability(__VA_ARGS__))
-#define TSA_ACQUIRE_SHARED(...) TSA(acquire_shared_capability(__VA_ARGS__))
-
-/* TSA_RELEASE() is used to annotate functions: the caller of the
- * function MUST hold the resource, but the function will then release it.
- *
- * More than one mutex may be specified, comma-separated.
- *
- * void Foo(void) TSA_RELEASE(mutex);
- */
-#define TSA_RELEASE(...) TSA(release_capability(__VA_ARGS__))
-#define TSA_RELEASE_SHARED(...) TSA(release_shared_capability(__VA_ARGS__))
-
-/* TSA_NO_TSA is used to annotate functions. Use only when you need to.
- *
- * void Foo(void) TSA_NO_TSA;
- */
-#define TSA_NO_TSA TSA(no_thread_safety_analysis)
-
-/*
- * TSA_ASSERT() is used to annotate functions: This function will assert that
- * the lock is held. When it returns, the caller of the function is assumed to
- * already hold the resource.
- *
- * More than one mutex may be specified, comma-separated.
- */
-#define TSA_ASSERT(...) TSA(assert_capability(__VA_ARGS__))
-#define TSA_ASSERT_SHARED(...) TSA(assert_shared_capability(__VA_ARGS__))
-
-#endif /* #ifndef CLANG_TSA_H */
diff --git a/include/qemu/co-shared-resource.h b/include/qemu/co-shared-resource.h
index 78ca585..41be1a8 100644
--- a/include/qemu/co-shared-resource.h
+++ b/include/qemu/co-shared-resource.h
@@ -45,13 +45,6 @@ SharedResource *shres_create(uint64_t total);
void shres_destroy(SharedResource *s);
/*
- * Try to allocate an amount of @n. Return true on success, and false
- * if there is too little left of the collective resource to fulfill
- * the request.
- */
-bool co_try_get_from_shres(SharedResource *s, uint64_t n);
-
-/*
* Allocate an amount of @n, and, if necessary, yield until
* that becomes possible.
*/
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index c797f0d..65b8995 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -22,12 +22,7 @@
#define QEMU_EXTERN_C extern
#endif
-#if defined(_WIN32) && (defined(__x86_64__) || defined(__i386__))
-# define QEMU_PACKED __attribute__((gcc_struct, packed))
-#else
-# define QEMU_PACKED __attribute__((packed))
-#endif
-
+#define QEMU_PACKED __attribute__((packed))
#define QEMU_ALIGNED(X) __attribute__((aligned(X)))
#ifndef glue
@@ -38,7 +33,7 @@
#endif
/* Expands into an identifier stemN, where N is another number each time */
-#define MAKE_IDENTFIER(stem) glue(stem, __COUNTER__)
+#define MAKE_IDENTIFIER(stem) glue(stem, __COUNTER__)
#ifndef likely
#define likely(x) __builtin_expect(!!(x), 1)
@@ -213,6 +208,122 @@
#endif
/*
+ * Disable -ftrivial-auto-var-init on a local variable.
+ *
+ * Use this in cases where there a method in the device I/O path (or other
+ * important hot paths), that has large variables on the stack. A rule of
+ * thumb is that "large" means a method with 4kb data in the local stack
+ * frame. Any variables which are KB in size, should be annotated with this
+ * attribute, to pre-emptively eliminate any potential overhead from the
+ * compiler's implicit zero'ing of memory.
+ *
+ * Given that this turns off a security hardening feature, when using this
+ * to flag variables, it is important that the code is double-checked to
+ * ensure there is no possible use of uninitialized data in the method.
+ */
+#if __has_attribute(uninitialized)
+# define QEMU_UNINITIALIZED __attribute__((uninitialized))
+#else
+# define QEMU_UNINITIALIZED
+#endif
+
+/*
+ * http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
+ *
+ * TSA is available since clang 3.6-ish.
+ */
+#ifdef __clang__
+# define TSA(x) __attribute__((x))
+#else
+# define TSA(x) /* No TSA, make TSA attributes no-ops. */
+#endif
+
+/*
+ * TSA_CAPABILITY() is used to annotate typedefs:
+ *
+ * typedef pthread_mutex_t TSA_CAPABILITY("mutex") tsa_mutex;
+ */
+#define TSA_CAPABILITY(x) TSA(capability(x))
+
+/*
+ * TSA_GUARDED_BY() is used to annotate global variables,
+ * the data is guarded:
+ *
+ * Foo foo TSA_GUARDED_BY(mutex);
+ */
+#define TSA_GUARDED_BY(x) TSA(guarded_by(x))
+
+/*
+ * TSA_PT_GUARDED_BY() is used to annotate global pointers, the data
+ * behind the pointer is guarded.
+ *
+ * Foo* ptr TSA_PT_GUARDED_BY(mutex);
+ */
+#define TSA_PT_GUARDED_BY(x) TSA(pt_guarded_by(x))
+
+/*
+ * The TSA_REQUIRES() is used to annotate functions: the caller of the
+ * function MUST hold the resource, the function will NOT release it.
+ *
+ * More than one mutex may be specified, comma-separated.
+ *
+ * void Foo(void) TSA_REQUIRES(mutex);
+ */
+#define TSA_REQUIRES(...) TSA(requires_capability(__VA_ARGS__))
+#define TSA_REQUIRES_SHARED(...) TSA(requires_shared_capability(__VA_ARGS__))
+
+/*
+ * TSA_EXCLUDES() is used to annotate functions: the caller of the
+ * function MUST NOT hold resource, the function first acquires the
+ * resource, and then releases it.
+ *
+ * More than one mutex may be specified, comma-separated.
+ *
+ * void Foo(void) TSA_EXCLUDES(mutex);
+ */
+#define TSA_EXCLUDES(...) TSA(locks_excluded(__VA_ARGS__))
+
+/*
+ * TSA_ACQUIRE() is used to annotate functions: the caller of the
+ * function MUST NOT hold the resource, the function will acquire the
+ * resource, but NOT release it.
+ *
+ * More than one mutex may be specified, comma-separated.
+ *
+ * void Foo(void) TSA_ACQUIRE(mutex);
+ */
+#define TSA_ACQUIRE(...) TSA(acquire_capability(__VA_ARGS__))
+#define TSA_ACQUIRE_SHARED(...) TSA(acquire_shared_capability(__VA_ARGS__))
+
+/*
+ * TSA_RELEASE() is used to annotate functions: the caller of the
+ * function MUST hold the resource, but the function will then release it.
+ *
+ * More than one mutex may be specified, comma-separated.
+ *
+ * void Foo(void) TSA_RELEASE(mutex);
+ */
+#define TSA_RELEASE(...) TSA(release_capability(__VA_ARGS__))
+#define TSA_RELEASE_SHARED(...) TSA(release_shared_capability(__VA_ARGS__))
+
+/*
+ * TSA_NO_TSA is used to annotate functions. Use only when you need to.
+ *
+ * void Foo(void) TSA_NO_TSA;
+ */
+#define TSA_NO_TSA TSA(no_thread_safety_analysis)
+
+/*
+ * TSA_ASSERT() is used to annotate functions: This function will assert that
+ * the lock is held. When it returns, the caller of the function is assumed to
+ * already hold the resource.
+ *
+ * More than one mutex may be specified, comma-separated.
+ */
+#define TSA_ASSERT(...) TSA(assert_capability(__VA_ARGS__))
+#define TSA_ASSERT_SHARED(...) TSA(assert_shared_capability(__VA_ARGS__))
+
+/*
* Ugly CPP trick that is like "defined FOO", but also works in C
* code. Useful to replace #ifdef with "if" statements; assumes
* the symbol was defined with Meson's "config.set()", so it is empty
@@ -227,4 +338,50 @@
#define SECOND_ARG(first, second, ...) second
#define IS_EMPTY_(junk_maybecomma) SECOND_ARG(junk_maybecomma 1, 0)
+#ifndef __cplusplus
+/*
+ * Useful in macros that need to declare temporary variables. For example,
+ * the variable that receives the old value of an atomically-accessed
+ * variable must be non-qualified, because atomic builtins return values
+ * through a pointer-type argument as in __atomic_load(&var, &old, MODEL).
+ *
+ * This macro has to handle types smaller than int manually, because of
+ * implicit promotion. int and larger types, as well as pointers, can be
+ * converted to a non-qualified type just by applying a binary operator.
+ */
+#define typeof_strip_qual(expr) \
+ typeof( \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(expr), bool) || \
+ __builtin_types_compatible_p(typeof(expr), const bool) || \
+ __builtin_types_compatible_p(typeof(expr), volatile bool) || \
+ __builtin_types_compatible_p(typeof(expr), const volatile bool), \
+ (bool)1, \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(expr), signed char) || \
+ __builtin_types_compatible_p(typeof(expr), const signed char) || \
+ __builtin_types_compatible_p(typeof(expr), volatile signed char) || \
+ __builtin_types_compatible_p(typeof(expr), const volatile signed char), \
+ (signed char)1, \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(expr), unsigned char) || \
+ __builtin_types_compatible_p(typeof(expr), const unsigned char) || \
+ __builtin_types_compatible_p(typeof(expr), volatile unsigned char) || \
+ __builtin_types_compatible_p(typeof(expr), const volatile unsigned char), \
+ (unsigned char)1, \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(expr), signed short) || \
+ __builtin_types_compatible_p(typeof(expr), const signed short) || \
+ __builtin_types_compatible_p(typeof(expr), volatile signed short) || \
+ __builtin_types_compatible_p(typeof(expr), const volatile signed short), \
+ (signed short)1, \
+ __builtin_choose_expr( \
+ __builtin_types_compatible_p(typeof(expr), unsigned short) || \
+ __builtin_types_compatible_p(typeof(expr), const unsigned short) || \
+ __builtin_types_compatible_p(typeof(expr), volatile unsigned short) || \
+ __builtin_types_compatible_p(typeof(expr), const volatile unsigned short), \
+ (unsigned short)1, \
+ (expr)+0))))))
+#endif
+
#endif /* COMPILER_H */
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index ff30845..e545bbf 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -16,6 +16,7 @@
#define QEMU_COROUTINE_H
#include "qemu/coroutine-core.h"
+#include "qemu/atomic.h"
#include "qemu/queue.h"
#include "qemu/timer.h"
diff --git a/include/qemu/crc-ccitt.h b/include/qemu/crc-ccitt.h
index 8918daf..ce28e29 100644
--- a/include/qemu/crc-ccitt.h
+++ b/include/qemu/crc-ccitt.h
@@ -8,7 +8,7 @@
*
* From Linux kernel v5.10 include/linux/crc-ccitt.h
*
- * SPDX-License-Identifier: GPL-2.0
+ * SPDX-License-Identifier: GPL-2.0-only
*/
#ifndef CRC_CCITT_H
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index da15547..36c68ce 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -241,13 +241,10 @@ int uleb128_decode_small(const uint8_t *in, uint32_t *n);
int qemu_pstrcmp0(const char **str1, const char **str2);
/* Find program directory, and save it for later usage with
- * qemu_get_exec_dir().
+ * get_relocated_path().
* Try OS specific API first, if not working, parse from argv0. */
void qemu_init_exec_dir(const char *argv0);
-/* Get the saved exec dir. */
-const char *qemu_get_exec_dir(void);
-
/**
* get_relocated_path:
* @dir: the directory (typically a `CONFIG_*DIR` variable) to be relocated.
@@ -305,4 +302,19 @@ GString *qemu_hexdump_line(GString *str, const void *buf, size_t len,
void qemu_hexdump(FILE *fp, const char *prefix,
const void *bufptr, size_t size);
+/**
+ * qemu_hexdump_to_buffer:
+ * @buffer: output string buffer
+ * @buffer_size: amount of available space in buffer. Must be at least
+ * data_size*2+1.
+ * @data: input bytes
+ * @data_size: number of bytes in data
+ *
+ * Converts the @data_size bytes in @data into hex digit pairs, writing them to
+ * @buffer. Finally, a nul terminating character is written; @buffer therefore
+ * needs space for (data_size*2+1) chars.
+ */
+void qemu_hexdump_to_buffer(char *restrict buffer, size_t buffer_size,
+ const uint8_t *restrict data, size_t data_size);
+
#endif
diff --git a/include/qemu/datadir.h b/include/qemu/datadir.h
index 21f9097..cca32af 100644
--- a/include/qemu/datadir.h
+++ b/include/qemu/datadir.h
@@ -1,11 +1,16 @@
#ifndef QEMU_DATADIR_H
#define QEMU_DATADIR_H
-#define QEMU_FILE_TYPE_BIOS 0
-#define QEMU_FILE_TYPE_KEYMAP 1
+typedef enum {
+ QEMU_FILE_TYPE_BIOS,
+ QEMU_FILE_TYPE_DTB,
+ QEMU_FILE_TYPE_KEYMAP,
+} QemuFileType;
+
/**
* qemu_find_file:
* @type: QEMU_FILE_TYPE_BIOS (for BIOS, VGA BIOS)
+ * QEMU_FILE_TYPE_DTB (for device tree blobs)
* or QEMU_FILE_TYPE_KEYMAP (for keymaps).
* @name: Relative or absolute file name
*
@@ -20,7 +25,7 @@
*
* Returns: a path that can access @name, or NULL if no matching file exists.
*/
-char *qemu_find_file(int type, const char *name);
+char *qemu_find_file(QemuFileType type, const char *name);
void qemu_add_default_firmwarepath(void);
void qemu_add_data_dir(char *path);
void qemu_list_data_dirs(void);
diff --git a/include/qemu/envlist.h b/include/qemu/envlist.h
index 6006dfa..b2883f6 100644
--- a/include/qemu/envlist.h
+++ b/include/qemu/envlist.h
@@ -7,8 +7,6 @@ envlist_t *envlist_create(void);
void envlist_free(envlist_t *);
int envlist_setenv(envlist_t *, const char *);
int envlist_unsetenv(envlist_t *, const char *);
-int envlist_parse_set(envlist_t *, const char *);
-int envlist_parse_unset(envlist_t *, const char *);
char **envlist_to_environ(const envlist_t *, size_t *);
#endif /* ENVLIST_H */
diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h
index c6295c6..4f768d4 100644
--- a/include/qemu/fifo8.h
+++ b/include/qemu/fifo8.h
@@ -15,10 +15,9 @@ typedef struct {
* @fifo: struct Fifo8 to initialise with new FIFO
* @capacity: capacity of the newly created FIFO
*
- * Create a FIFO of the specified size. Clients should call fifo8_destroy()
+ * Create a FIFO of the specified capacity. Clients should call fifo8_destroy()
* when finished using the fifo. The FIFO is initially empty.
*/
-
void fifo8_create(Fifo8 *fifo, uint32_t capacity);
/**
@@ -26,9 +25,8 @@ void fifo8_create(Fifo8 *fifo, uint32_t capacity);
* @fifo: FIFO to cleanup
*
* Cleanup a FIFO created with fifo8_create(). Frees memory created for FIFO
- *storage. The FIFO is no longer usable after this has been called.
+ * storage. The FIFO is no longer usable after this has been called.
*/
-
void fifo8_destroy(Fifo8 *fifo);
/**
@@ -39,7 +37,6 @@ void fifo8_destroy(Fifo8 *fifo);
* Push a data byte to the FIFO. Behaviour is undefined if the FIFO is full.
* Clients are responsible for checking for fullness using fifo8_is_full().
*/
-
void fifo8_push(Fifo8 *fifo, uint8_t data);
/**
@@ -52,7 +49,6 @@ void fifo8_push(Fifo8 *fifo, uint8_t data);
* Clients are responsible for checking the space left in the FIFO using
* fifo8_num_free().
*/
-
void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num);
/**
@@ -64,25 +60,65 @@ void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num);
*
* Returns: The popped data byte.
*/
-
uint8_t fifo8_pop(Fifo8 *fifo);
/**
+ * fifo8_peek:
+ * @fifo: fifo to peek from
+ *
+ * Peek the data byte at the current head of the FIFO. Clients are responsible
+ * for checking for emptyness using fifo8_is_empty().
+ *
+ * Returns: The peeked data byte.
+ */
+uint8_t fifo8_peek(Fifo8 *fifo);
+
+/**
* fifo8_pop_buf:
* @fifo: FIFO to pop from
+ * @dest: the buffer to write the data into (can be NULL)
+ * @destlen: size of @dest and maximum number of bytes to pop
+ *
+ * Pop a number of elements from the FIFO up to a maximum of @destlen.
+ * The popped data is copied into the @dest buffer.
+ * Care is taken when the data wraps around in the ring buffer.
+ *
+ * Returns: number of bytes popped.
+ */
+uint32_t fifo8_pop_buf(Fifo8 *fifo, uint8_t *dest, uint32_t destlen);
+
+/**
+ * fifo8_peek_buf:
+ * @fifo: FIFO to read from
+ * @dest: the buffer to write the data into (can be NULL)
+ * @destlen: size of @dest and maximum number of bytes to peek
+ *
+ * Peek a number of elements from the FIFO up to a maximum of @destlen.
+ * The peeked data is copied into the @dest buffer.
+ * Care is taken when the data wraps around in the ring buffer.
+ *
+ * Returns: number of bytes peeked.
+ */
+uint32_t fifo8_peek_buf(Fifo8 *fifo, uint8_t *dest, uint32_t destlen);
+
+/**
+ * fifo8_pop_bufptr:
+ * @fifo: FIFO to pop from
* @max: maximum number of bytes to pop
* @numptr: pointer filled with number of bytes returned (can be NULL)
*
- * Pop a number of elements from the FIFO up to a maximum of max. The buffer
+ * New code should prefer to use fifo8_pop_buf() instead of fifo8_pop_bufptr().
+ *
+ * Pop a number of elements from the FIFO up to a maximum of @max. The buffer
* containing the popped data is returned. This buffer points directly into
- * the FIFO backing store and data is invalidated once any of the fifo8_* APIs
- * are called on the FIFO.
+ * the internal FIFO backing store and data (without checking for overflow!)
+ * and is invalidated once any of the fifo8_* APIs are called on the FIFO.
*
* The function may return fewer bytes than requested when the data wraps
* around in the ring buffer; in this case only a contiguous part of the data
* is returned.
*
- * The number of valid bytes returned is populated in *numptr; will always
+ * The number of valid bytes returned is populated in *@numptr; will always
* return at least 1 byte. max must not be 0 or greater than the number of
* bytes in the FIFO.
*
@@ -91,15 +127,15 @@ uint8_t fifo8_pop(Fifo8 *fifo);
*
* Returns: A pointer to popped data.
*/
-const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
+const uint8_t *fifo8_pop_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
/**
- * fifo8_peek_buf: read upto max bytes from the fifo
+ * fifo8_peek_bufptr: read upto max bytes from the fifo
* @fifo: FIFO to read from
* @max: maximum number of bytes to peek
* @numptr: pointer filled with number of bytes returned (can be NULL)
*
- * Peek into a number of elements from the FIFO up to a maximum of max.
+ * Peek into a number of elements from the FIFO up to a maximum of @max.
* The buffer containing the data peeked into is returned. This buffer points
* directly into the FIFO backing store. Since data is invalidated once any
* of the fifo8_* APIs are called on the FIFO, it is the caller responsibility
@@ -109,7 +145,7 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
* around in the ring buffer; in this case only a contiguous part of the data
* is returned.
*
- * The number of valid bytes returned is populated in *numptr; will always
+ * The number of valid bytes returned is populated in *@numptr; will always
* return at least 1 byte. max must not be 0 or greater than the number of
* bytes in the FIFO.
*
@@ -118,7 +154,16 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
*
* Returns: A pointer to peekable data.
*/
-const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
+const uint8_t *fifo8_peek_bufptr(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
+
+/**
+ * fifo8_drop:
+ * @fifo: FIFO to drop bytes
+ * @len: number of bytes to drop
+ *
+ * Drop (consume) bytes from a FIFO.
+ */
+void fifo8_drop(Fifo8 *fifo, uint32_t len);
/**
* fifo8_reset:
@@ -126,7 +171,6 @@ const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr);
*
* Reset a FIFO. All data is discarded and the FIFO is emptied.
*/
-
void fifo8_reset(Fifo8 *fifo);
/**
@@ -137,7 +181,6 @@ void fifo8_reset(Fifo8 *fifo);
*
* Returns: True if the fifo is empty, false otherwise.
*/
-
bool fifo8_is_empty(Fifo8 *fifo);
/**
@@ -148,7 +191,6 @@ bool fifo8_is_empty(Fifo8 *fifo);
*
* Returns: True if the fifo is full, false otherwise.
*/
-
bool fifo8_is_full(Fifo8 *fifo);
/**
@@ -159,7 +201,6 @@ bool fifo8_is_full(Fifo8 *fifo);
*
* Returns: Number of free bytes.
*/
-
uint32_t fifo8_num_free(Fifo8 *fifo);
/**
@@ -170,7 +211,6 @@ uint32_t fifo8_num_free(Fifo8 *fifo);
*
* Returns: Number of used bytes.
*/
-
uint32_t fifo8_num_used(Fifo8 *fifo);
extern const VMStateDescription vmstate_fifo8;
diff --git a/include/qemu/futex.h b/include/qemu/futex.h
index 91ae889..607613e 100644
--- a/include/qemu/futex.h
+++ b/include/qemu/futex.h
@@ -1,5 +1,5 @@
/*
- * Wrappers around Linux futex syscall
+ * Wrappers around Linux futex syscall and similar
*
* Copyright Red Hat, Inc. 2017
*
@@ -11,17 +11,35 @@
*
*/
+/*
+ * Note that a wake-up can also be caused by common futex usage patterns in
+ * unrelated code that happened to have previously used the futex word's
+ * memory location (e.g., typical futex-based implementations of Pthreads
+ * mutexes can cause this under some conditions). Therefore, qemu_futex_wait()
+ * callers should always conservatively assume that it is a spurious wake-up,
+ * and use the futex word's value (i.e., the user-space synchronization scheme)
+ * to decide whether to continue to block or not.
+ */
+
#ifndef QEMU_FUTEX_H
#define QEMU_FUTEX_H
+#define HAVE_FUTEX
+
+#ifdef CONFIG_LINUX
#include <sys/syscall.h>
#include <linux/futex.h>
#define qemu_futex(...) syscall(__NR_futex, __VA_ARGS__)
-static inline void qemu_futex_wake(void *f, int n)
+static inline void qemu_futex_wake_all(void *f)
{
- qemu_futex(f, FUTEX_WAKE, n, NULL, NULL, 0);
+ qemu_futex(f, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
+}
+
+static inline void qemu_futex_wake_single(void *f)
+{
+ qemu_futex(f, FUTEX_WAKE, 1, NULL, NULL, 0);
}
static inline void qemu_futex_wait(void *f, unsigned val)
@@ -37,5 +55,25 @@ static inline void qemu_futex_wait(void *f, unsigned val)
}
}
}
+#elif defined(CONFIG_WIN32)
+#include <synchapi.h>
+
+static inline void qemu_futex_wake_all(void *f)
+{
+ WakeByAddressAll(f);
+}
+
+static inline void qemu_futex_wake_single(void *f)
+{
+ WakeByAddressSingle(f);
+}
+
+static inline void qemu_futex_wait(void *f, unsigned val)
+{
+ WaitOnAddress(f, &val, sizeof(val), INFINITE);
+}
+#else
+#undef HAVE_FUTEX
+#endif
#endif /* QEMU_FUTEX_H */
diff --git a/include/qemu/help-texts.h b/include/qemu/help-texts.h
index 353ab2a..bc8fab9 100644
--- a/include/qemu/help-texts.h
+++ b/include/qemu/help-texts.h
@@ -2,7 +2,7 @@
#define QEMU_HELP_TEXTS_H
/* Copyright string for -version arguments, About dialogs, etc */
-#define QEMU_COPYRIGHT "Copyright (c) 2003-2024 " \
+#define QEMU_COPYRIGHT "Copyright (c) 2003-2025 " \
"Fabrice Bellard and the QEMU Project developers"
/* Bug reporting information for --help arguments, About dialogs, etc */
diff --git a/include/qemu/host-pci-mmio.h b/include/qemu/host-pci-mmio.h
new file mode 100644
index 0000000..a8ed993
--- /dev/null
+++ b/include/qemu/host-pci-mmio.h
@@ -0,0 +1,136 @@
+/*
+ * API for host PCI MMIO accesses (e.g. Linux VFIO BARs)
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Farhan Ali <alifm@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HOST_PCI_MMIO_H
+#define HOST_PCI_MMIO_H
+
+#include "qemu/bswap.h"
+#include "qemu/s390x_pci_mmio.h"
+
+static inline uint8_t host_pci_ldub_p(const void *ioaddr)
+{
+ uint8_t ret = 0;
+#ifdef __s390x__
+ ret = s390x_pci_mmio_read_8(ioaddr);
+#else
+ ret = ldub_p(ioaddr);
+#endif
+
+ return ret;
+}
+
+static inline uint16_t host_pci_lduw_le_p(const void *ioaddr)
+{
+ uint16_t ret = 0;
+#ifdef __s390x__
+ ret = le16_to_cpu(s390x_pci_mmio_read_16(ioaddr));
+#else
+ ret = lduw_le_p(ioaddr);
+#endif
+
+ return ret;
+}
+
+static inline uint32_t host_pci_ldl_le_p(const void *ioaddr)
+{
+ uint32_t ret = 0;
+#ifdef __s390x__
+ ret = le32_to_cpu(s390x_pci_mmio_read_32(ioaddr));
+#else
+ ret = ldl_le_p(ioaddr);
+#endif
+
+ return ret;
+}
+
+static inline uint64_t host_pci_ldq_le_p(const void *ioaddr)
+{
+ uint64_t ret = 0;
+#ifdef __s390x__
+ ret = le64_to_cpu(s390x_pci_mmio_read_64(ioaddr));
+#else
+ ret = ldq_le_p(ioaddr);
+#endif
+
+ return ret;
+}
+
+static inline void host_pci_stb_p(void *ioaddr, uint8_t val)
+{
+#ifdef __s390x__
+ s390x_pci_mmio_write_8(ioaddr, val);
+#else
+ stb_p(ioaddr, val);
+#endif
+}
+
+static inline void host_pci_stw_le_p(void *ioaddr, uint16_t val)
+{
+#ifdef __s390x__
+ s390x_pci_mmio_write_16(ioaddr, cpu_to_le16(val));
+#else
+ stw_le_p(ioaddr, val);
+#endif
+}
+
+static inline void host_pci_stl_le_p(void *ioaddr, uint32_t val)
+{
+#ifdef __s390x__
+ s390x_pci_mmio_write_32(ioaddr, cpu_to_le32(val));
+#else
+ stl_le_p(ioaddr, val);
+#endif
+}
+
+static inline void host_pci_stq_le_p(void *ioaddr, uint64_t val)
+{
+#ifdef __s390x__
+ s390x_pci_mmio_write_64(ioaddr, cpu_to_le64(val));
+#else
+ stq_le_p(ioaddr, val);
+#endif
+}
+
+static inline uint64_t host_pci_ldn_le_p(const void *ioaddr, int sz)
+{
+ switch (sz) {
+ case 1:
+ return host_pci_ldub_p(ioaddr);
+ case 2:
+ return host_pci_lduw_le_p(ioaddr);
+ case 4:
+ return host_pci_ldl_le_p(ioaddr);
+ case 8:
+ return host_pci_ldq_le_p(ioaddr);
+ default:
+ g_assert_not_reached();
+ }
+}
+
+static inline void host_pci_stn_le_p(void *ioaddr, int sz, uint64_t v)
+{
+ switch (sz) {
+ case 1:
+ host_pci_stb_p(ioaddr, v);
+ break;
+ case 2:
+ host_pci_stw_le_p(ioaddr, v);
+ break;
+ case 4:
+ host_pci_stl_le_p(ioaddr, v);
+ break;
+ case 8:
+ host_pci_stq_le_p(ioaddr, v);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
+#endif
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index ead97d3..4d28fa2 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -313,6 +313,15 @@ static inline int ctpop8(uint8_t val)
return __builtin_popcount(val);
}
+/*
+ * parity8 - return the parity (1 = odd) of an 8-bit value.
+ * @val: The value to search
+ */
+static inline int parity8(uint8_t val)
+{
+ return __builtin_parity(val);
+}
+
/**
* ctpop16 - count the population of one bits in a 16-bit value.
* @val: The value to search
diff --git a/include/qemu/iov.h b/include/qemu/iov.h
index 63a1c01..9535673 100644
--- a/include/qemu/iov.h
+++ b/include/qemu/iov.h
@@ -1,6 +1,7 @@
/*
* Helpers for using (partial) iovecs.
*
+ * Copyright (c) 2024 Seagate Technology LLC and/or its Affiliates
* Copyright (C) 2010 Red Hat, Inc.
*
* Author(s):
@@ -30,7 +31,7 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
* only part of data will be copied, up to the end of the iovec.
* Number of bytes actually copied will be returned, which is
* min(bytes, iov_size(iov)-offset)
- * `Offset' must point to the inside of iovec.
+ * Returns 0 when `offset' points to the outside of iovec.
*/
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
size_t offset, const void *buf, size_t bytes);
@@ -66,16 +67,43 @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
/**
* Set data bytes pointed out by iovec `iov' of size `iov_cnt' elements,
* starting at byte offset `start', to value `fillc', repeating it
- * `bytes' number of times. `Offset' must point to the inside of iovec.
+ * `bytes' number of times.
* If `bytes' is large enough, only last bytes portion of iovec,
* up to the end of it, will be filled with the specified value.
* Function return actual number of bytes processed, which is
* min(size, iov_size(iov) - offset).
+ * Returns 0 when `offset' points to the outside of iovec.
*/
size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
size_t offset, int fillc, size_t bytes);
/*
+ * Send/recv data from/to iovec buffers directly, with the provided
+ * socket flags.
+ *
+ * `offset' bytes in the beginning of iovec buffer are skipped and
+ * next `bytes' bytes are used, which must be within data of iovec.
+ *
+ * r = iov_send_recv_with_flags(sockfd, sockflags, iov, iovcnt,
+ * offset, bytes, true);
+ *
+ * is logically equivalent to
+ *
+ * char *buf = malloc(bytes);
+ * iov_to_buf(iov, iovcnt, offset, buf, bytes);
+ * r = send(sockfd, buf, bytes, sockflags);
+ * free(buf);
+ *
+ * For iov_send_recv_with_flags() _whole_ area being sent or received
+ * should be within the iovec, not only beginning of it.
+ */
+ssize_t iov_send_recv_with_flags(int sockfd, int sockflags,
+ const struct iovec *iov,
+ unsigned iov_cnt, size_t offset,
+ size_t bytes,
+ bool do_send);
+
+/*
* Send/recv data from/to iovec buffers directly
*
* `offset' bytes in the beginning of iovec buffer are skipped and
diff --git a/include/qemu/iova-tree.h b/include/qemu/iova-tree.h
index 2a10a70..14e82a2 100644
--- a/include/qemu/iova-tree.h
+++ b/include/qemu/iova-tree.h
@@ -23,7 +23,7 @@
* for the thread safety issue.
*/
-#include "exec/memory.h"
+#include "system/memory.h"
#include "exec/hwaddr.h"
#define IOVA_OK (0)
@@ -41,6 +41,28 @@ typedef struct DMAMap {
typedef gboolean (*iova_tree_iterator)(DMAMap *map);
/**
+ * gpa_tree_new:
+ *
+ * Create a new GPA->IOVA tree.
+ *
+ * Returns: the tree point on success, or NULL otherwise.
+ */
+IOVATree *gpa_tree_new(void);
+
+/**
+ * gpa_tree_insert:
+ *
+ * @tree: The GPA->IOVA tree we're inserting the mapping to
+ * @map: The GPA->IOVA mapping to insert
+ *
+ * Inserts a GPA range to the GPA->IOVA tree. If there are overlapped
+ * ranges, IOVA_ERR_OVERLAP will be returned.
+ *
+ * Return: 0 if successful, < 0 otherwise.
+ */
+int gpa_tree_insert(IOVATree *tree, const DMAMap *map);
+
+/**
* iova_tree_new:
*
* Create a new iova tree.
@@ -112,31 +134,6 @@ const DMAMap *iova_tree_find(const IOVATree *tree, const DMAMap *map);
const DMAMap *iova_tree_find_iova(const IOVATree *tree, const DMAMap *map);
/**
- * iova_tree_find_address:
- *
- * @tree: the iova tree to search from
- * @iova: the iova address to find
- *
- * Similar to iova_tree_find(), but it tries to find mapping with
- * range iova=iova & size=0.
- *
- * Return: same as iova_tree_find().
- */
-const DMAMap *iova_tree_find_address(const IOVATree *tree, hwaddr iova);
-
-/**
- * iova_tree_foreach:
- *
- * @tree: the iova tree to iterate on
- * @iterator: the iterator for the mappings, return true to stop
- *
- * Iterate over the iova tree.
- *
- * Return: 1 if found any overlap, 0 if not, <0 if error.
- */
-void iova_tree_foreach(IOVATree *tree, iova_tree_iterator iterator);
-
-/**
* iova_tree_alloc_map:
*
* @tree: the iova tree to allocate from
diff --git a/include/qemu/job.h b/include/qemu/job.h
index 2b873f2..a5a0415 100644
--- a/include/qemu/job.h
+++ b/include/qemu/job.h
@@ -545,6 +545,9 @@ bool job_is_ready(Job *job);
/* Same as job_is_ready(), but called with job lock held. */
bool job_is_ready_locked(Job *job);
+/** Returns whether the job is paused. Called with job_mutex *not* held. */
+bool job_is_paused(Job *job);
+
/**
* Request @job to pause at the next pause point. Must be paired with
* job_resume(). If the job is supposed to be resumed by user action, call
diff --git a/include/qemu/lockcnt.h b/include/qemu/lockcnt.h
new file mode 100644
index 0000000..5a2800e
--- /dev/null
+++ b/include/qemu/lockcnt.h
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QemuLockCnt implementation
+ *
+ * Copyright Red Hat, Inc. 2017
+ *
+ * Author:
+ * Paolo Bonzini <pbonzini@redhat.com>
+ *
+ */
+
+#ifndef QEMU_LOCKCNT_H
+#define QEMU_LOCKCNT_H
+
+#include "qemu/thread.h"
+
+typedef struct QemuLockCnt QemuLockCnt;
+
+struct QemuLockCnt {
+#ifndef HAVE_FUTEX
+ QemuMutex mutex;
+#endif
+ unsigned count;
+};
+
+/**
+ * qemu_lockcnt_init: initialize a QemuLockcnt
+ * @lockcnt: the lockcnt to initialize
+ *
+ * Initialize lockcnt's counter to zero and prepare its mutex
+ * for usage.
+ */
+void qemu_lockcnt_init(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_destroy: destroy a QemuLockcnt
+ * @lockcnt: the lockcnt to destruct
+ *
+ * Destroy lockcnt's mutex.
+ */
+void qemu_lockcnt_destroy(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_inc: increment a QemuLockCnt's counter
+ * @lockcnt: the lockcnt to operate on
+ *
+ * If the lockcnt's count is zero, wait for critical sections
+ * to finish and increment lockcnt's count to 1. If the count
+ * is not zero, just increment it.
+ *
+ * Because this function can wait on the mutex, it must not be
+ * called while the lockcnt's mutex is held by the current thread.
+ * For the same reason, qemu_lockcnt_inc can also contribute to
+ * AB-BA deadlocks. This is a sample deadlock scenario::
+ *
+ * thread 1 thread 2
+ * -------------------------------------------------------
+ * qemu_lockcnt_lock(&lc1);
+ * qemu_lockcnt_lock(&lc2);
+ * qemu_lockcnt_inc(&lc2);
+ * qemu_lockcnt_inc(&lc1);
+ */
+void qemu_lockcnt_inc(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_dec: decrement a QemuLockCnt's counter
+ * @lockcnt: the lockcnt to operate on
+ */
+void qemu_lockcnt_dec(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and
+ * possibly lock it.
+ * @lockcnt: the lockcnt to operate on
+ *
+ * Decrement lockcnt's count. If the new count is zero, lock
+ * the mutex and return true. Otherwise, return false.
+ */
+bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and
+ * lock it.
+ * @lockcnt: the lockcnt to operate on
+ *
+ * If the count is 1, decrement the count to zero, lock
+ * the mutex and return true. Otherwise, return false.
+ */
+bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_lock: lock a QemuLockCnt's mutex.
+ * @lockcnt: the lockcnt to operate on
+ *
+ * Remember that concurrent visits are not blocked unless the count is
+ * also zero. You can use qemu_lockcnt_count to check for this inside a
+ * critical section.
+ */
+void qemu_lockcnt_lock(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_unlock: release a QemuLockCnt's mutex.
+ * @lockcnt: the lockcnt to operate on.
+ */
+void qemu_lockcnt_unlock(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt.
+ * @lockcnt: the lockcnt to operate on.
+ *
+ * This is the same as
+ *
+ * qemu_lockcnt_unlock(lockcnt);
+ * qemu_lockcnt_inc(lockcnt);
+ *
+ * but more efficient.
+ */
+void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt);
+
+/**
+ * qemu_lockcnt_count: query a LockCnt's count.
+ * @lockcnt: the lockcnt to query.
+ *
+ * Note that the count can change at any time. Still, while the
+ * lockcnt is locked, one can usefully check whether the count
+ * is non-zero.
+ */
+unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt);
+
+#endif
diff --git a/include/qemu/log.h b/include/qemu/log.h
index e10e24c..60da703 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -37,6 +37,7 @@ bool qemu_log_separate(void);
#define LOG_PER_THREAD (1 << 20)
#define CPU_LOG_TB_VPU (1 << 21)
#define LOG_TB_OP_PLUGIN (1 << 22)
+#define LOG_INVALID_MEM (1 << 23)
/* Lock/unlock output. */
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 5764db1..4e2436b 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -27,7 +27,7 @@
#include "block/aio.h"
#include "qom/object.h"
-#include "sysemu/event-loop-base.h"
+#include "system/event-loop-base.h"
#define SIG_IPI SIGUSR1
@@ -248,6 +248,14 @@ GSource *iohandler_get_g_source(void);
AioContext *iohandler_get_aio_context(void);
/**
+ * rust_bql_mock_lock:
+ *
+ * Called from Rust doctests to make bql_lock() return true.
+ * Do not touch.
+ */
+void rust_bql_mock_lock(void);
+
+/**
* bql_locked: Return lock status of the Big QEMU Lock (BQL)
*
* The Big QEMU Lock (BQL) is the coarsest lock in QEMU, and as such it
@@ -263,6 +271,21 @@ AioContext *iohandler_get_aio_context(void);
bool bql_locked(void);
/**
+ * bql_block: Allow/deny releasing the BQL
+ *
+ * The Big QEMU Lock (BQL) is used to provide interior mutability to
+ * Rust code, but this only works if other threads cannot run while
+ * the Rust code has an active borrow. This is because C code in
+ * other threads could come in and mutate data under the Rust code's
+ * feet.
+ *
+ * @increase: Whether to increase or decrease the blocking counter.
+ * Releasing the BQL while the counter is nonzero triggers
+ * an assertion failure.
+ */
+void bql_block_unlock(bool increase);
+
+/**
* qemu_in_main_thread: return whether it's possible to safely access
* the global state of the block layer.
*
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 191916f..96fe51b 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -8,7 +8,7 @@
* To avoid getting into possible circular include dependencies, this
* file should not include any other QEMU headers, with the exceptions
* of config-host.h, config-target.h, qemu/compiler.h,
- * sysemu/os-posix.h, sysemu/os-win32.h, glib-compat.h and
+ * system/os-posix.h, system/os-win32.h, system/os-wasm.h, glib-compat.h and
* qemu/typedefs.h, all of which are doing a similar job to this file
* and are under similar constraints.
*
@@ -128,7 +128,7 @@ QEMU_EXTERN_C int daemon(int, int);
#include <sys/stat.h>
#include <sys/time.h>
#include <assert.h>
-/* setjmp must be declared before sysemu/os-win32.h
+/* setjmp must be declared before system/os-win32.h
* because it is redefined there. */
#include <setjmp.h>
#include <signal.h>
@@ -161,11 +161,15 @@ QEMU_EXTERN_C int daemon(int, int);
#include "glib-compat.h"
#ifdef _WIN32
-#include "sysemu/os-win32.h"
+#include "system/os-win32.h"
#endif
-#ifdef CONFIG_POSIX
-#include "sysemu/os-posix.h"
+#if defined(CONFIG_POSIX) && !defined(EMSCRIPTEN)
+#include "system/os-posix.h"
+#endif
+
+#if defined(EMSCRIPTEN)
+#include "system/os-wasm.h"
#endif
#ifdef __cplusplus
@@ -297,6 +301,10 @@ void QEMU_ERROR("code path is reachable")
#error building with G_DISABLE_ASSERT is not supported
#endif
+#ifndef OFF_MAX
+#define OFF_MAX (sizeof (off_t) == 8 ? INT64_MAX : INT32_MAX)
+#endif
+
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
@@ -399,7 +407,7 @@ void QEMU_ERROR("code path is reachable")
})
#undef MIN
#define MIN(a, b) \
- MIN_INTERNAL((a), (b), MAKE_IDENTFIER(_a), MAKE_IDENTFIER(_b))
+ MIN_INTERNAL((a), (b), MAKE_IDENTIFIER(_a), MAKE_IDENTIFIER(_b))
#define MAX_INTERNAL(a, b, _a, _b) \
({ \
@@ -408,7 +416,7 @@ void QEMU_ERROR("code path is reachable")
})
#undef MAX
#define MAX(a, b) \
- MAX_INTERNAL((a), (b), MAKE_IDENTFIER(_a), MAKE_IDENTFIER(_b))
+ MAX_INTERNAL((a), (b), MAKE_IDENTIFIER(_a), MAKE_IDENTIFIER(_b))
#ifdef __COVERITY__
# define MIN_CONST(a, b) ((a) < (b) ? (a) : (b))
@@ -440,7 +448,7 @@ void QEMU_ERROR("code path is reachable")
_a == 0 ? _b : (_b == 0 || _b > _a) ? _a : _b; \
})
#define MIN_NON_ZERO(a, b) \
- MIN_NON_ZERO_INTERNAL((a), (b), MAKE_IDENTFIER(_a), MAKE_IDENTFIER(_b))
+ MIN_NON_ZERO_INTERNAL((a), (b), MAKE_IDENTIFIER(_a), MAKE_IDENTIFIER(_b))
/*
* Round number down to multiple. Safe when m is not a power of 2 (see
@@ -505,6 +513,7 @@ int qemu_daemon(int nochdir, int noclose);
void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
bool noreserve);
void qemu_anon_ram_free(void *ptr, size_t size);
+int qemu_shm_alloc(size_t size, Error **errp);
#ifdef _WIN32
#define HAVE_CHARDEV_SERIAL 1
@@ -626,6 +635,15 @@ bool qemu_write_pidfile(const char *pidfile, Error **errp);
int qemu_get_thread_id(void);
+/**
+ * qemu_kill_thread:
+ * @tid: thread id.
+ * @sig: host signal.
+ *
+ * Send @sig to one of QEMU's own threads with identifier @tid.
+ */
+int qemu_kill_thread(int tid, int sig);
+
#ifndef CONFIG_IOVEC
struct iovec {
void *iov_base;
@@ -758,6 +776,17 @@ static inline void qemu_reset_optind(void)
int qemu_fdatasync(int fd);
/**
+ * qemu_close_all_open_fd:
+ *
+ * Close all open file descriptors except the ones supplied in the @skip array
+ *
+ * @skip: ordered array of distinct file descriptors that should not be closed
+ * if any, or NULL.
+ * @nskip: number of entries in the @skip array or 0 if @skip is NULL.
+ */
+void qemu_close_all_open_fd(const int *skip, unsigned int nskip);
+
+/**
* Sync changes made to the memory mapped file back to the backing
* storage. For POSIX compliant systems this will fallback
* to regular msync call. Otherwise it will trigger whole file sync
@@ -786,8 +815,7 @@ size_t qemu_get_host_physmem(void);
* Toggle write/execute on the pages marked MAP_JIT
* for the current thread.
*/
-#if defined(MAC_OS_VERSION_11_0) && \
- MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
+#ifdef __APPLE__
static inline void qemu_thread_jit_execute(void)
{
pthread_jit_write_protect_np(true);
diff --git a/include/qemu/plugin-memory.h b/include/qemu/plugin-memory.h
index 71c1123..6065ec7 100644
--- a/include/qemu/plugin-memory.h
+++ b/include/qemu/plugin-memory.h
@@ -9,7 +9,6 @@
#ifndef PLUGIN_MEMORY_H
#define PLUGIN_MEMORY_H
-#include "exec/cpu-defs.h"
#include "exec/hwaddr.h"
struct qemu_plugin_hwaddr {
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index bc5aef9..9726a9e 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -149,6 +149,9 @@ struct CPUPluginState {
/**
* qemu_plugin_create_vcpu_state: allocate plugin state
+ *
+ * The returned data must be released with g_free()
+ * when no longer required.
*/
CPUPluginState *qemu_plugin_create_vcpu_state(void);
@@ -164,6 +167,8 @@ qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1,
void qemu_plugin_vcpu_syscall_ret(CPUState *cpu, int64_t num, int64_t ret);
void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
+ uint64_t value_low,
+ uint64_t value_high,
MemOpIdx oi, enum qemu_plugin_mem_rw rw);
void qemu_plugin_flush_cb(void);
@@ -248,6 +253,8 @@ void qemu_plugin_vcpu_syscall_ret(CPUState *cpu, int64_t num, int64_t ret)
{ }
static inline void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
+ uint64_t value_low,
+ uint64_t value_high,
MemOpIdx oi,
enum qemu_plugin_mem_rw rw)
{ }
diff --git a/include/qemu/pmem.h b/include/qemu/pmem.h
index d2d7ad0..e12a67b 100644
--- a/include/qemu/pmem.h
+++ b/include/qemu/pmem.h
@@ -22,7 +22,6 @@ pmem_memcpy_persist(void *pmemdest, const void *src, size_t len)
/* If 'pmem' option is 'on', we should always have libpmem support,
or qemu will report a error and exit, never come here. */
g_assert_not_reached();
- return NULL;
}
static inline void
diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h
index c71c705..3a850aa 100644
--- a/include/qemu/qemu-plugin.h
+++ b/include/qemu/qemu-plugin.h
@@ -57,11 +57,19 @@ typedef uint64_t qemu_plugin_id_t;
* - Remove qemu_plugin_register_vcpu_{tb, insn, mem}_exec_inline.
* Those functions are replaced by *_per_vcpu variants, which guarantee
* thread-safety for operations.
+ *
+ * version 3:
+ * - modified arguments and return value of qemu_plugin_insn_data to copy
+ * the data into a user-provided buffer instead of returning a pointer
+ * to the data.
+ *
+ * version 4:
+ * - added qemu_plugin_read_memory_vaddr
*/
extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
-#define QEMU_PLUGIN_VERSION 3
+#define QEMU_PLUGIN_VERSION 4
/**
* struct qemu_info_t - system information for plugins
@@ -262,6 +270,29 @@ enum qemu_plugin_mem_rw {
QEMU_PLUGIN_MEM_RW,
};
+enum qemu_plugin_mem_value_type {
+ QEMU_PLUGIN_MEM_VALUE_U8,
+ QEMU_PLUGIN_MEM_VALUE_U16,
+ QEMU_PLUGIN_MEM_VALUE_U32,
+ QEMU_PLUGIN_MEM_VALUE_U64,
+ QEMU_PLUGIN_MEM_VALUE_U128,
+};
+
+/* typedef qemu_plugin_mem_value - value accessed during a load/store */
+typedef struct {
+ enum qemu_plugin_mem_value_type type;
+ union {
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ struct {
+ uint64_t low;
+ uint64_t high;
+ } u128;
+ } data;
+} qemu_plugin_mem_value;
+
/**
* enum qemu_plugin_cond - condition to enable callback
*
@@ -552,6 +583,15 @@ QEMU_PLUGIN_API
bool qemu_plugin_mem_is_store(qemu_plugin_meminfo_t info);
/**
+ * qemu_plugin_mem_get_value() - return last value loaded/stored
+ * @info: opaque memory transaction handle
+ *
+ * Returns: memory value
+ */
+QEMU_PLUGIN_API
+qemu_plugin_mem_value qemu_plugin_mem_get_value(qemu_plugin_meminfo_t info);
+
+/**
* qemu_plugin_get_hwaddr() - return handle for memory operation
* @info: opaque memory info structure
* @vaddr: the virtual address of the memory operation
@@ -763,6 +803,7 @@ void qemu_plugin_register_atexit_cb(qemu_plugin_id_t id,
qemu_plugin_udata_cb_t cb, void *userdata);
/* returns how many vcpus were started at this point */
+QEMU_PLUGIN_API
int qemu_plugin_num_vcpus(void);
/**
@@ -853,6 +894,28 @@ QEMU_PLUGIN_API
GArray *qemu_plugin_get_registers(void);
/**
+ * qemu_plugin_read_memory_vaddr() - read from memory using a virtual address
+ *
+ * @addr: A virtual address to read from
+ * @data: A byte array to store data into
+ * @len: The number of bytes to read, starting from @addr
+ *
+ * @len bytes of data is read starting at @addr and stored into @data. If @data
+ * is not large enough to hold @len bytes, it will be expanded to the necessary
+ * size, reallocating if necessary. @len must be greater than 0.
+ *
+ * This function does not ensure writes are flushed prior to reading, so
+ * callers should take care when calling this function in plugin callbacks to
+ * avoid attempting to read data which may not yet be written and should use
+ * the memory callback API instead.
+ *
+ * Returns true on success and false on failure.
+ */
+QEMU_PLUGIN_API
+bool qemu_plugin_read_memory_vaddr(uint64_t addr,
+ GByteArray *data, size_t len);
+
+/**
* qemu_plugin_read_register() - read register for current vCPU
*
* @handle: a @qemu_plugin_reg_handle handle
diff --git a/include/qemu/range.h b/include/qemu/range.h
index 205e1da..d446ad8 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -20,6 +20,8 @@
#ifndef QEMU_RANGE_H
#define QEMU_RANGE_H
+#include "qemu/bitops.h"
+
/*
* Operations on 64 bit address ranges.
* Notes:
@@ -208,8 +210,8 @@ static inline int range_covers_byte(uint64_t offset, uint64_t len,
/* Check whether 2 given ranges overlap.
* Undefined if ranges that wrap around 0. */
-static inline int ranges_overlap(uint64_t first1, uint64_t len1,
- uint64_t first2, uint64_t len2)
+static inline bool ranges_overlap(uint64_t first1, uint64_t len1,
+ uint64_t first2, uint64_t len2)
{
uint64_t last1 = range_get_last(first1, len1);
uint64_t last2 = range_get_last(first2, len2);
@@ -217,6 +219,15 @@ static inline int ranges_overlap(uint64_t first1, uint64_t len1,
return !(last2 < first1 || last1 < first2);
}
+/* Get highest non-zero bit position of a range */
+static inline int range_get_last_bit(Range *range)
+{
+ if (range_is_empty(range)) {
+ return -1;
+ }
+ return 63 - clz64(range->upb);
+}
+
/*
* Return -1 if @a < @b, 1 @a > @b, and 0 if they touch or overlap.
* Both @a and @b must not be empty.
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index fea058a..020dbe4 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -17,8 +17,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * License along with this library; if not, see
+ * <https://www.gnu.org/licenses/>.
*
* IBM's contributions to this file may be relicensed under LGPLv2 or later.
*/
diff --git a/include/qemu/rcu_queue.h b/include/qemu/rcu_queue.h
index 4e6298d..bfd5900 100644
--- a/include/qemu/rcu_queue.h
+++ b/include/qemu/rcu_queue.h
@@ -17,8 +17,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * License along with this library; if not, see
+ * <https://www.gnu.org/licenses/>.
*
* Copyright (c) 2013 Mike D. Day, IBM Corporation.
*
diff --git a/include/qemu/reserved-region.h b/include/qemu/reserved-region.h
index 8e6f0a9..9026cf0 100644
--- a/include/qemu/reserved-region.h
+++ b/include/qemu/reserved-region.h
@@ -20,7 +20,7 @@
#ifndef QEMU_RESERVED_REGION_H
#define QEMU_RESERVED_REGION_H
-#include "exec/memory.h"
+#include "system/memory.h"
/*
* Insert a new region into a sorted list of reserved regions. In case
diff --git a/include/qemu/s390x_pci_mmio.h b/include/qemu/s390x_pci_mmio.h
new file mode 100644
index 0000000..c5f63ec
--- /dev/null
+++ b/include/qemu/s390x_pci_mmio.h
@@ -0,0 +1,24 @@
+/*
+ * s390x PCI MMIO definitions
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Farhan Ali <alifm@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef S390X_PCI_MMIO_H
+#define S390X_PCI_MMIO_H
+
+#ifdef __s390x__
+uint8_t s390x_pci_mmio_read_8(const void *ioaddr);
+uint16_t s390x_pci_mmio_read_16(const void *ioaddr);
+uint32_t s390x_pci_mmio_read_32(const void *ioaddr);
+uint64_t s390x_pci_mmio_read_64(const void *ioaddr);
+
+void s390x_pci_mmio_write_8(void *ioaddr, uint8_t val);
+void s390x_pci_mmio_write_16(void *ioaddr, uint16_t val);
+void s390x_pci_mmio_write_32(void *ioaddr, uint32_t val);
+void s390x_pci_mmio_write_64(void *ioaddr, uint64_t val);
+#endif /* __s390x__ */
+
+#endif /* S390X_PCI_MMIO_H */
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index d935fd8..c562690 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -61,7 +61,6 @@ int socket_set_fast_reuse(int fd);
int inet_ai_family_from_address(InetSocketAddress *addr,
Error **errp);
int inet_parse(InetSocketAddress *addr, const char *str, Error **errp);
-int inet_connect(const char *str, Error **errp);
int inet_connect_saddr(InetSocketAddress *saddr, Error **errp);
NetworkAddressFamily inet_netfamily(int family);
@@ -118,21 +117,6 @@ socket_sockaddr_to_address(struct sockaddr_storage *sa,
SocketAddress *socket_local_address(int fd, Error **errp);
/**
- * socket_remote_address:
- * @fd: the socket file handle
- * @errp: pointer to uninitialized error object
- *
- * Get the string representation of the remote socket
- * address. A pointer to the allocated address information
- * struct will be returned, which the caller is required to
- * release with a call qapi_free_SocketAddress() when no
- * longer required.
- *
- * Returns: the socket address struct, or NULL on error
- */
-SocketAddress *socket_remote_address(int fd, Error **errp);
-
-/**
* socket_address_flatten:
* @addr: the socket address to flatten
*
diff --git a/include/qemu/target-info-impl.h b/include/qemu/target-info-impl.h
new file mode 100644
index 0000000..1b51cbc
--- /dev/null
+++ b/include/qemu/target-info-impl.h
@@ -0,0 +1,32 @@
+/*
+ * QEMU TargetInfo structure definition
+ *
+ * Copyright (c) Linaro
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_TARGET_INFO_IMPL_H
+#define QEMU_TARGET_INFO_IMPL_H
+
+#include "qemu/target-info.h"
+
+typedef struct TargetInfo {
+ /* runtime equivalent of TARGET_NAME definition */
+ const char *target_name;
+ /* runtime equivalent of TARGET_LONG_BITS definition */
+ unsigned long_bits;
+ /* runtime equivalent of CPU_RESOLVING_TYPE definition */
+ const char *cpu_type;
+ /* QOM typename machines for this binary must implement */
+ const char *machine_typename;
+} TargetInfo;
+
+/**
+ * target_info:
+ *
+ * Returns: The TargetInfo structure definition for this target binary.
+ */
+const TargetInfo *target_info(void);
+
+#endif
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h
new file mode 100644
index 0000000..850a295
--- /dev/null
+++ b/include/qemu/target-info.h
@@ -0,0 +1,41 @@
+/*
+ * QEMU target info API
+ *
+ * Copyright (c) Linaro
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QEMU_TARGET_INFO_H
+#define QEMU_TARGET_INFO_H
+
+/**
+ * target_name:
+ *
+ * Returns: Canonical target name (i.e. "i386").
+ */
+const char *target_name(void);
+
+/**
+ * target_long_bits:
+ *
+ * Returns: number of bits in a long type for this target (i.e. 64).
+ */
+unsigned target_long_bits(void);
+
+/**
+ * target_machine_typename:
+ *
+ * Returns: Name of the QOM interface implemented by machines
+ * usable on this target binary.
+ */
+const char *target_machine_typename(void);
+
+/**
+ * target_cpu_type:
+ *
+ * Returns: target CPU base QOM type name (i.e. TYPE_X86_CPU).
+ */
+const char *target_cpu_type(void);
+
+#endif
diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
index 5f2f3d1..758808b 100644
--- a/include/qemu/thread-posix.h
+++ b/include/qemu/thread-posix.h
@@ -32,15 +32,6 @@ struct QemuSemaphore {
unsigned int count;
};
-struct QemuEvent {
-#ifndef __linux__
- pthread_mutex_t lock;
- pthread_cond_t cond;
-#endif
- unsigned value;
- bool initialized;
-};
-
struct QemuThread {
pthread_t thread;
};
diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h
index d95af44..da9e732 100644
--- a/include/qemu/thread-win32.h
+++ b/include/qemu/thread-win32.h
@@ -28,12 +28,6 @@ struct QemuSemaphore {
bool initialized;
};
-struct QemuEvent {
- int value;
- HANDLE event;
- bool initialized;
-};
-
typedef struct QemuThreadData QemuThreadData;
struct QemuThread {
QemuThreadData *data;
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index fb74e21..f0302ed 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -3,14 +3,32 @@
#include "qemu/processor.h"
#include "qemu/atomic.h"
-#include "qemu/clang-tsa.h"
+#include "qemu/futex.h"
typedef struct QemuCond QemuCond;
typedef struct QemuSemaphore QemuSemaphore;
-typedef struct QemuEvent QemuEvent;
typedef struct QemuLockCnt QemuLockCnt;
typedef struct QemuThread QemuThread;
+/*
+ * QemuEvent
+ * =========
+ *
+ * QemuEvent is an implementation of Win32 manual-reset event object.
+ * For details, refer to:
+ * https://learn.microsoft.com/en-us/windows/win32/sync/using-event-objects
+ *
+ * QemuEvent is more lightweight than QemuSemaphore when HAVE_FUTEX is defined.
+ */
+typedef struct QemuEvent {
+#ifndef HAVE_FUTEX
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+#endif
+ unsigned value;
+ bool initialized;
+} QemuEvent;
+
#ifdef _WIN32
#include "qemu/thread-win32.h"
#else
@@ -293,115 +311,4 @@ static inline void qemu_spin_unlock(QemuSpin *spin)
#endif
}
-struct QemuLockCnt {
-#ifndef CONFIG_LINUX
- QemuMutex mutex;
-#endif
- unsigned count;
-};
-
-/**
- * qemu_lockcnt_init: initialize a QemuLockcnt
- * @lockcnt: the lockcnt to initialize
- *
- * Initialize lockcnt's counter to zero and prepare its mutex
- * for usage.
- */
-void qemu_lockcnt_init(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_destroy: destroy a QemuLockcnt
- * @lockcnt: the lockcnt to destruct
- *
- * Destroy lockcnt's mutex.
- */
-void qemu_lockcnt_destroy(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_inc: increment a QemuLockCnt's counter
- * @lockcnt: the lockcnt to operate on
- *
- * If the lockcnt's count is zero, wait for critical sections
- * to finish and increment lockcnt's count to 1. If the count
- * is not zero, just increment it.
- *
- * Because this function can wait on the mutex, it must not be
- * called while the lockcnt's mutex is held by the current thread.
- * For the same reason, qemu_lockcnt_inc can also contribute to
- * AB-BA deadlocks. This is a sample deadlock scenario:
- *
- * thread 1 thread 2
- * -------------------------------------------------------
- * qemu_lockcnt_lock(&lc1);
- * qemu_lockcnt_lock(&lc2);
- * qemu_lockcnt_inc(&lc2);
- * qemu_lockcnt_inc(&lc1);
- */
-void qemu_lockcnt_inc(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_dec: decrement a QemuLockCnt's counter
- * @lockcnt: the lockcnt to operate on
- */
-void qemu_lockcnt_dec(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and
- * possibly lock it.
- * @lockcnt: the lockcnt to operate on
- *
- * Decrement lockcnt's count. If the new count is zero, lock
- * the mutex and return true. Otherwise, return false.
- */
-bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and
- * lock it.
- * @lockcnt: the lockcnt to operate on
- *
- * If the count is 1, decrement the count to zero, lock
- * the mutex and return true. Otherwise, return false.
- */
-bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_lock: lock a QemuLockCnt's mutex.
- * @lockcnt: the lockcnt to operate on
- *
- * Remember that concurrent visits are not blocked unless the count is
- * also zero. You can use qemu_lockcnt_count to check for this inside a
- * critical section.
- */
-void qemu_lockcnt_lock(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_unlock: release a QemuLockCnt's mutex.
- * @lockcnt: the lockcnt to operate on.
- */
-void qemu_lockcnt_unlock(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt.
- * @lockcnt: the lockcnt to operate on.
- *
- * This is the same as
- *
- * qemu_lockcnt_unlock(lockcnt);
- * qemu_lockcnt_inc(lockcnt);
- *
- * but more efficient.
- */
-void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt);
-
-/**
- * qemu_lockcnt_count: query a LockCnt's count.
- * @lockcnt: the lockcnt to query.
- *
- * Note that the count can change at any time. Still, while the
- * lockcnt is locked, one can usefully check whether the count
- * is non-zero.
- */
-unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt);
-
#endif
diff --git a/include/qemu/timed-average.h b/include/qemu/timed-average.h
index 08245e7..dfd8d65 100644
--- a/include/qemu/timed-average.h
+++ b/include/qemu/timed-average.h
@@ -8,10 +8,12 @@
* Benoît Canet <benoit.canet@nodalink.com>
* Alberto Garcia <berto@igalia.com>
*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
* 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) version 3 or any later version.
+ * (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
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 5ce83c7..abd2204 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -191,16 +191,6 @@ bool qemu_clock_use_for_deadline(QEMUClockType type);
int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask);
/**
- * qemu_clock_get_main_loop_timerlist:
- * @type: the clock type
- *
- * Return the default timer list associated with a clock.
- *
- * Returns: the default timer list
- */
-QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type);
-
-/**
* qemu_clock_nofify:
* @type: the clock type
*
@@ -327,17 +317,6 @@ bool timerlist_expired(QEMUTimerList *timer_list);
int64_t timerlist_deadline_ns(QEMUTimerList *timer_list);
/**
- * timerlist_get_clock:
- * @timer_list: the timer list to operate on
- *
- * Determine the clock type associated with a timer list.
- *
- * Returns: the clock type associated with the
- * timer list.
- */
-QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list);
-
-/**
* timerlist_run_timers:
* @timer_list: the timer list to use
*
@@ -528,6 +507,8 @@ static inline void timer_init_ms(QEMUTimer *ts, QEMUClockType type,
* with an AioContext---each of them runs its timer callbacks in its own
* AioContext thread.
*
+ * The timer returned must be freed using timer_free().
+ *
* Returns: a pointer to the timer
*/
static inline QEMUTimer *timer_new_full(QEMUTimerListGroup *timer_list_group,
@@ -551,6 +532,8 @@ static inline QEMUTimer *timer_new_full(QEMUTimerListGroup *timer_list_group,
* and associate it with the default timer list for the clock type @type.
* See timer_new_full for details.
*
+ * The timer returned must be freed using timer_free().
+ *
* Returns: a pointer to the timer
*/
static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
@@ -569,6 +552,8 @@ static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
* associated with the clock.
* See timer_new_full for details.
*
+ * The timer returned must be freed using timer_free().
+ *
* Returns: a pointer to the newly created timer
*/
static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
@@ -587,6 +572,8 @@ static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
* associated with the clock.
* See timer_new_full for details.
*
+ * The timer returned must be freed using timer_free().
+ *
* Returns: a pointer to the newly created timer
*/
static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
@@ -605,6 +592,8 @@ static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
* associated with the clock.
* See timer_new_full for details.
*
+ * The timer returned must be freed using timer_free().
+ *
* Returns: a pointer to the newly created timer
*/
static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
@@ -1016,6 +1005,15 @@ static inline int64_t cpu_get_host_ticks(void)
return val;
}
+#elif defined(__loongarch64)
+static inline int64_t cpu_get_host_ticks(void)
+{
+ uint64_t val;
+
+ asm volatile("rdtime.d %0, $zero" : "=r"(val));
+ return val;
+}
+
#else
/* The host CPU doesn't have an easily accessible cycle counter.
Just return a monotonically increasing value. This will be
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 9d222dc..507f081 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -22,6 +22,7 @@
* Please keep this list in case-insensitive alphabetical order.
*/
typedef struct AccelCPUState AccelCPUState;
+typedef struct AccelOpsClass AccelOpsClass;
typedef struct AccelState AccelState;
typedef struct AddressSpace AddressSpace;
typedef struct AioContext AioContext;
@@ -40,6 +41,7 @@ typedef struct ConfidentialGuestSupport ConfidentialGuestSupport;
typedef struct CPUArchState CPUArchState;
typedef struct CPUPluginState CPUPluginState;
typedef struct CPUState CPUState;
+typedef struct CPUTLBEntryFull CPUTLBEntryFull;
typedef struct DeviceState DeviceState;
typedef struct DirtyBitmapSnapshot DirtyBitmapSnapshot;
typedef struct DisasContextBase DisasContextBase;
@@ -107,6 +109,7 @@ typedef struct QString QString;
typedef struct RAMBlock RAMBlock;
typedef struct Range Range;
typedef struct ReservedRegion ReservedRegion;
+typedef struct SaveLiveCompletePrecopyThreadData SaveLiveCompletePrecopyThreadData;
typedef struct SHPCDevice SHPCDevice;
typedef struct SSIBus SSIBus;
typedef struct TCGCPUOps TCGCPUOps;
@@ -130,5 +133,9 @@ typedef struct IRQState *qemu_irq;
* Function types
*/
typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
+typedef bool (*MigrationLoadThread)(void *opaque, bool *should_quit,
+ Error **errp);
+typedef bool (*SaveLiveCompletePrecopyThreadHandler)(SaveLiveCompletePrecopyThreadData *d,
+ Error **errp);
#endif /* QEMU_TYPEDEFS_H */
diff --git a/include/qemu/userfaultfd.h b/include/qemu/userfaultfd.h
index 18a4314..a197930 100644
--- a/include/qemu/userfaultfd.h
+++ b/include/qemu/userfaultfd.h
@@ -39,7 +39,6 @@ int uffd_copy_page(int uffd_fd, void *dst_addr, void *src_addr,
int uffd_zero_page(int uffd_fd, void *addr, uint64_t length, bool dont_wake);
int uffd_wakeup(int uffd_fd, void *addr, uint64_t length);
int uffd_read_events(int uffd_fd, struct uffd_msg *msgs, int count);
-bool uffd_poll_events(int uffd_fd, int tmo);
#endif /* CONFIG_LINUX */
diff --git a/include/qapi/qmp/json-parser.h b/include/qobject/json-parser.h
index 7345a9b..7345a9b 100644
--- a/include/qapi/qmp/json-parser.h
+++ b/include/qobject/json-parser.h
diff --git a/include/qapi/qmp/json-writer.h b/include/qobject/json-writer.h
index b70ba64..b70ba64 100644
--- a/include/qapi/qmp/json-writer.h
+++ b/include/qobject/json-writer.h
diff --git a/include/qapi/qmp/qbool.h b/include/qobject/qbool.h
index 0d09726..b348e17 100644
--- a/include/qapi/qmp/qbool.h
+++ b/include/qobject/qbool.h
@@ -14,7 +14,7 @@
#ifndef QBOOL_H
#define QBOOL_H
-#include "qapi/qmp/qobject.h"
+#include "qobject/qobject.h"
struct QBool {
struct QObjectBase_ base;
diff --git a/include/qapi/qmp/qdict.h b/include/qobject/qdict.h
index 82e90fc..903e6e5 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qobject/qdict.h
@@ -13,7 +13,7 @@
#ifndef QDICT_H
#define QDICT_H
-#include "qapi/qmp/qobject.h"
+#include "qobject/qobject.h"
#include "qemu/queue.h"
#define QDICT_BUCKET_MAX 512
diff --git a/include/qapi/qmp/qjson.h b/include/qobject/qjson.h
index 7bd8d2d..7bd8d2d 100644
--- a/include/qapi/qmp/qjson.h
+++ b/include/qobject/qjson.h
diff --git a/include/qapi/qmp/qlist.h b/include/qobject/qlist.h
index e4e985d..0377bf8 100644
--- a/include/qapi/qmp/qlist.h
+++ b/include/qobject/qlist.h
@@ -13,7 +13,7 @@
#ifndef QLIST_H
#define QLIST_H
-#include "qapi/qmp/qobject.h"
+#include "qobject/qobject.h"
#include "qemu/queue.h"
typedef struct QListEntry {
diff --git a/include/qapi/qmp/qlit.h b/include/qobject/qlit.h
index c0676d5..c0676d5 100644
--- a/include/qapi/qmp/qlit.h
+++ b/include/qobject/qlit.h
diff --git a/include/qapi/qmp/qnull.h b/include/qobject/qnull.h
index 7feb7c7..4423836 100644
--- a/include/qapi/qmp/qnull.h
+++ b/include/qobject/qnull.h
@@ -13,7 +13,7 @@
#ifndef QNULL_H
#define QNULL_H
-#include "qapi/qmp/qobject.h"
+#include "qobject/qobject.h"
struct QNull {
struct QObjectBase_ base;
diff --git a/include/qapi/qmp/qnum.h b/include/qobject/qnum.h
index e86788d..1ce24b3 100644
--- a/include/qapi/qmp/qnum.h
+++ b/include/qobject/qnum.h
@@ -15,7 +15,7 @@
#ifndef QNUM_H
#define QNUM_H
-#include "qapi/qmp/qobject.h"
+#include "qobject/qobject.h"
typedef enum {
QNUM_I64,
diff --git a/include/qapi/qmp/qobject.h b/include/qobject/qobject.h
index 89b97d8..a6244d0 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qobject/qobject.h
@@ -34,7 +34,7 @@
#include "qapi/qapi-builtin-types.h"
-/* Not for use outside include/qapi/qmp/ */
+/* Not for use outside include/qobject/ */
struct QObjectBase_ {
QType type;
size_t refcnt;
@@ -54,7 +54,7 @@ struct QObject {
typeof(obj) _obj = (obj); \
_obj ? container_of(&_obj->base, QObject, base) : NULL; \
})
-#define QOBJECT(obj) QOBJECT_INTERNAL((obj), MAKE_IDENTFIER(_obj))
+#define QOBJECT(obj) QOBJECT_INTERNAL((obj), MAKE_IDENTIFIER(_obj))
/* Required for qobject_to() */
#define QTYPE_CAST_TO_QNull QTYPE_QNULL
diff --git a/include/qapi/qmp/qstring.h b/include/qobject/qstring.h
index 318d815..1e2abe4 100644
--- a/include/qapi/qmp/qstring.h
+++ b/include/qobject/qstring.h
@@ -13,7 +13,7 @@
#ifndef QSTRING_H
#define QSTRING_H
-#include "qapi/qmp/qobject.h"
+#include "qobject/qobject.h"
struct QString {
struct QObjectBase_ base;
diff --git a/include/qom/object.h b/include/qom/object.h
index 13d3a65..26df613 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -26,6 +26,7 @@ typedef struct InterfaceClass InterfaceClass;
typedef struct InterfaceInfo InterfaceInfo;
#define TYPE_OBJECT "object"
+#define TYPE_CONTAINER "container"
typedef struct ObjectProperty ObjectProperty;
@@ -279,7 +280,7 @@ struct Object
static void \
module_obj_name##_finalize(Object *obj); \
static void \
- module_obj_name##_class_init(ObjectClass *oc, void *data); \
+ module_obj_name##_class_init(ObjectClass *oc, const void *data); \
static void \
module_obj_name##_init(Object *obj); \
\
@@ -293,7 +294,7 @@ struct Object
.class_size = CLASS_SIZE, \
.class_init = module_obj_name##_class_init, \
.abstract = ABSTRACT, \
- .interfaces = (InterfaceInfo[]) { __VA_ARGS__ } , \
+ .interfaces = (const InterfaceInfo[]) { __VA_ARGS__ } , \
}; \
\
static void \
@@ -444,7 +445,8 @@ struct Object
* class will have already been initialized so the type is only responsible
* for initializing its own members.
* @instance_post_init: This function is called to finish initialization of
- * an object, after all @instance_init functions were called.
+ * an object, after all @instance_init functions were called, as well as
+ * @instance_post_init functions for the parent classes.
* @instance_finalize: This function is called during object destruction. This
* is called before the parent @instance_finalize function has been called.
* An object should only free the members that are unique to its type in this
@@ -485,11 +487,11 @@ struct TypeInfo
bool abstract;
size_t class_size;
- void (*class_init)(ObjectClass *klass, void *data);
- void (*class_base_init)(ObjectClass *klass, void *data);
- void *class_data;
+ void (*class_init)(ObjectClass *klass, const void *data);
+ void (*class_base_init)(ObjectClass *klass, const void *data);
+ const void *class_data;
- InterfaceInfo *interfaces;
+ const InterfaceInfo *interfaces;
};
/**
@@ -572,12 +574,15 @@ struct InterfaceInfo {
*
* The class for all interfaces. Subclasses of this class should only add
* virtual methods.
+ *
+ * Note that most of the fields of ObjectClass are unused (all except
+ * "type", in fact). They are only present in InterfaceClass to allow
+ * @object_class_dynamic_cast to work with both regular classes and interfaces.
*/
struct InterfaceClass
{
ObjectClass parent_class;
/* private: */
- ObjectClass *concrete_class;
Type interface_type;
};
@@ -880,25 +885,11 @@ const char *object_get_typename(const Object *obj);
* type_register_static:
* @info: The #TypeInfo of the new type.
*
- * @info and all of the strings it points to should exist for the life time
- * that the type is registered.
- *
* Returns: the new #Type.
*/
Type type_register_static(const TypeInfo *info);
/**
- * type_register:
- * @info: The #TypeInfo of the new type
- *
- * Unlike type_register_static(), this call does not require @info or its
- * string members to continue to exist after the call returns.
- *
- * Returns: the new #Type.
- */
-Type type_register(const TypeInfo *info);
-
-/**
* type_register_static_array:
* @infos: The array of the new type #TypeInfo structures.
* @nr_infos: number of entries in @infos
@@ -1523,6 +1514,16 @@ const char *object_property_get_type(Object *obj, const char *name,
*/
Object *object_get_root(void);
+/**
+ * object_get_container:
+ * @name: the name of container to lookup
+ *
+ * Lookup a root level container.
+ *
+ * Returns: the container with @name.
+ */
+Object *object_get_container(const char *name);
+
/**
* object_get_objects_root:
@@ -1569,8 +1570,8 @@ char *object_get_canonical_path(const Object *obj);
/**
* object_resolve_path:
* @path: the path to resolve
- * @ambiguous: returns true if the path resolution failed because of an
- * ambiguous match
+ * @ambiguous: (out) (optional): location to store whether the lookup failed
+ * because it was ambiguous, or %NULL. Set to %false on success.
*
* There are two types of supported paths--absolute paths and partial paths.
*
@@ -1587,7 +1588,7 @@ char *object_get_canonical_path(const Object *obj);
* only one match is found. If more than one match is found, a flag is
* returned to indicate that the match was ambiguous.
*
- * Returns: The matched object or NULL on path lookup failure.
+ * Returns: The matched object or %NULL on path lookup failure.
*/
Object *object_resolve_path(const char *path, bool *ambiguous);
@@ -1595,10 +1596,10 @@ Object *object_resolve_path(const char *path, bool *ambiguous);
* object_resolve_path_type:
* @path: the path to resolve
* @typename: the type to look for.
- * @ambiguous: returns true if the path resolution failed because of an
- * ambiguous match
+ * @ambiguous: (out) (optional): location to store whether the lookup failed
+ * because it was ambiguous, or %NULL. Set to %false on success.
*
- * This is similar to object_resolve_path. However, when looking for a
+ * This is similar to object_resolve_path(). However, when looking for a
* partial path only matches that implement the given type are considered.
* This restricts the search and avoids spuriously flagging matches as
* ambiguous.
@@ -2020,25 +2021,18 @@ int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque),
int object_child_foreach_recursive(Object *obj,
int (*fn)(Object *child, void *opaque),
void *opaque);
-/**
- * container_get:
- * @root: root of the #path, e.g., object_get_root()
- * @path: path to the container
- *
- * Return a container object whose path is @path. Create more containers
- * along the path if necessary.
- *
- * Returns: the container object.
- */
-Object *container_get(Object *root, const char *path);
/**
- * object_type_get_instance_size:
- * @typename: Name of the Type whose instance_size is required
+ * object_property_add_new_container:
+ * @obj: the parent object
+ * @name: the name of the parent object's property to add
+ *
+ * Add a newly created container object to a parent object.
*
- * Returns the instance_size of the given @typename.
+ * Returns: the newly created container object. Its reference count is 1,
+ * and the reference is owned by the parent object.
*/
-size_t object_type_get_instance_size(const char *typename);
+Object *object_property_add_new_container(Object *obj, const char *name);
/**
* object_property_help:
diff --git a/include/semihosting/console.h b/include/semihosting/console.h
index bd78e5f..1c12e17 100644
--- a/include/semihosting/console.h
+++ b/include/semihosting/console.h
@@ -9,8 +9,6 @@
#ifndef SEMIHOST_CONSOLE_H
#define SEMIHOST_CONSOLE_H
-#include "cpu.h"
-
/**
* qemu_semihosting_console_read:
* @cs: CPUState
diff --git a/include/semihosting/semihost.h b/include/semihosting/semihost.h
index 97d2a2b..b03e637 100644
--- a/include/semihosting/semihost.h
+++ b/include/semihosting/semihost.h
@@ -26,32 +26,6 @@ typedef enum SemihostingTarget {
SEMIHOSTING_TARGET_GDB
} SemihostingTarget;
-#ifdef CONFIG_USER_ONLY
-static inline bool semihosting_enabled(bool is_user)
-{
- return true;
-}
-
-static inline SemihostingTarget semihosting_get_target(void)
-{
- return SEMIHOSTING_TARGET_AUTO;
-}
-
-static inline const char *semihosting_get_arg(int i)
-{
- return NULL;
-}
-
-static inline int semihosting_get_argc(void)
-{
- return 0;
-}
-
-static inline const char *semihosting_get_cmdline(void)
-{
- return NULL;
-}
-#else /* !CONFIG_USER_ONLY */
/**
* semihosting_enabled:
* @is_user: true if guest code is in usermode (i.e. not privileged)
@@ -59,17 +33,18 @@ static inline const char *semihosting_get_cmdline(void)
* Return true if guest code is allowed to make semihosting calls.
*/
bool semihosting_enabled(bool is_user);
+
SemihostingTarget semihosting_get_target(void);
const char *semihosting_get_arg(int i);
int semihosting_get_argc(void);
const char *semihosting_get_cmdline(void);
void semihosting_arg_fallback(const char *file, const char *cmd);
+
/* for vl.c hooks */
void qemu_semihosting_enable(void);
int qemu_semihosting_config_options(const char *optstr);
void qemu_semihosting_chardev_init(void);
void qemu_semihosting_console_init(Chardev *);
-#endif /* CONFIG_USER_ONLY */
void qemu_semihosting_guestfd_init(void);
#endif /* SEMIHOST_H */
diff --git a/include/semihosting/syscalls.h b/include/semihosting/syscalls.h
index 3a5ec22..6627c45 100644
--- a/include/semihosting/syscalls.h
+++ b/include/semihosting/syscalls.h
@@ -9,6 +9,9 @@
#ifndef SEMIHOSTING_SYSCALLS_H
#define SEMIHOSTING_SYSCALLS_H
+#include "exec/cpu-defs.h"
+#include "gdbstub/syscalls.h"
+
/*
* Argument loading from the guest is performed by the caller;
* results are returned via the 'complete' callback.
diff --git a/include/semihosting/uaccess.h b/include/semihosting/uaccess.h
index c2fa5a6..6bc90b1 100644
--- a/include/semihosting/uaccess.h
+++ b/include/semihosting/uaccess.h
@@ -19,41 +19,96 @@
#include "exec/tswap.h"
#include "exec/page-protection.h"
+/**
+ * get_user_u64:
+ *
+ * Returns: 0 on success, -1 on error.
+ */
#define get_user_u64(val, addr) \
({ uint64_t val_ = 0; \
int ret_ = cpu_memory_rw_debug(env_cpu(env), (addr), \
&val_, sizeof(val_), 0); \
(val) = tswap64(val_); ret_; })
+/**
+ * get_user_u32:
+ *
+ * Returns: 0 on success, -1 on error.
+ */
#define get_user_u32(val, addr) \
({ uint32_t val_ = 0; \
int ret_ = cpu_memory_rw_debug(env_cpu(env), (addr), \
&val_, sizeof(val_), 0); \
(val) = tswap32(val_); ret_; })
+/**
+ * get_user_u8:
+ *
+ * Returns: 0 on success, -1 on error.
+ */
#define get_user_u8(val, addr) \
({ uint8_t val_ = 0; \
int ret_ = cpu_memory_rw_debug(env_cpu(env), (addr), \
&val_, sizeof(val_), 0); \
(val) = val_; ret_; })
+/**
+ * get_user_ual:
+ *
+ * Returns: 0 on success, -1 on error.
+ */
#define get_user_ual(arg, p) get_user_u32(arg, p)
+/**
+ * put_user_u64:
+ *
+ * Returns: 0 on success, -1 on error.
+ */
#define put_user_u64(val, addr) \
({ uint64_t val_ = tswap64(val); \
cpu_memory_rw_debug(env_cpu(env), (addr), &val_, sizeof(val_), 1); })
+/**
+ * put_user_u32:
+ *
+ * Returns: 0 on success, -1 on error.
+ */
#define put_user_u32(val, addr) \
({ uint32_t val_ = tswap32(val); \
cpu_memory_rw_debug(env_cpu(env), (addr), &val_, sizeof(val_), 1); })
+/**
+ * put_user_ual:
+ *
+ * Returns: 0 on success, -1 on error.
+ */
#define put_user_ual(arg, p) put_user_u32(arg, p)
+/**
+ * uaccess_lock_user:
+ *
+ * The returned pointer should be freed using uaccess_unlock_user().
+ */
void *uaccess_lock_user(CPUArchState *env, target_ulong addr,
target_ulong len, bool copy);
+/**
+ * lock_user:
+ *
+ * The returned pointer should be freed using unlock_user().
+ */
#define lock_user(type, p, len, copy) uaccess_lock_user(env, p, len, copy)
+/**
+ * uaccess_lock_user_string:
+ *
+ * The returned string should be freed using uaccess_unlock_user().
+ */
char *uaccess_lock_user_string(CPUArchState *env, target_ulong addr);
+/**
+ * uaccess_lock_user_string:
+ *
+ * The returned string should be freed using unlock_user().
+ */
#define lock_user_string(p) uaccess_lock_user_string(env, p)
void uaccess_unlock_user(CPUArchState *env, void *p,
diff --git a/include/standard-headers/asm-x86/setup_data.h b/include/standard-headers/asm-x86/setup_data.h
index 09355f5..2e446c1d 100644
--- a/include/standard-headers/asm-x86/setup_data.h
+++ b/include/standard-headers/asm-x86/setup_data.h
@@ -13,12 +13,13 @@
#define SETUP_CC_BLOB 7
#define SETUP_IMA 8
#define SETUP_RNG_SEED 9
-#define SETUP_ENUM_MAX SETUP_RNG_SEED
+#define SETUP_KEXEC_KHO 10
+#define SETUP_ENUM_MAX SETUP_KEXEC_KHO
#define SETUP_INDIRECT (1<<31)
#define SETUP_TYPE_MAX (SETUP_ENUM_MAX | SETUP_INDIRECT)
-#ifndef __ASSEMBLY__
+#ifndef __ASSEMBLER__
#include "standard-headers/linux/types.h"
@@ -78,6 +79,16 @@ struct ima_setup_data {
uint64_t size;
} QEMU_PACKED;
-#endif /* __ASSEMBLY__ */
+/*
+ * Locations of kexec handover metadata
+ */
+struct kho_data {
+ uint64_t fdt_addr;
+ uint64_t fdt_size;
+ uint64_t scratch_addr;
+ uint64_t scratch_size;
+} QEMU_PACKED;
+
+#endif /* __ASSEMBLER__ */
#endif /* _ASM_X86_SETUP_DATA_H */
diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h
index b729170..c8309d3 100644
--- a/include/standard-headers/drm/drm_fourcc.h
+++ b/include/standard-headers/drm/drm_fourcc.h
@@ -420,6 +420,8 @@ extern "C" {
#define DRM_FORMAT_MOD_VENDOR_ARM 0x08
#define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09
#define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a
+#define DRM_FORMAT_MOD_VENDOR_MTK 0x0b
+#define DRM_FORMAT_MOD_VENDOR_APPLE 0x0c
/* add more to the end as needed */
@@ -702,6 +704,31 @@ extern "C" {
#define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15)
/*
+ * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression
+ * on integrated graphics
+ *
+ * The main surface is Tile 4 and at plane index 0. For semi-planar formats
+ * like NV12, the Y and UV planes are Tile 4 and are located at plane indices
+ * 0 and 1, respectively. The CCS for all planes are stored outside of the
+ * GEM object in a reserved memory area dedicated for the storage of the
+ * CCS data for all compressible GEM objects.
+ */
+#define I915_FORMAT_MOD_4_TILED_LNL_CCS fourcc_mod_code(INTEL, 16)
+
+/*
+ * Intel Color Control Surfaces (CCS) for graphics ver. 20 unified compression
+ * on discrete graphics
+ *
+ * The main surface is Tile 4 and at plane index 0. For semi-planar formats
+ * like NV12, the Y and UV planes are Tile 4 and are located at plane indices
+ * 0 and 1, respectively. The CCS for all planes are stored outside of the
+ * GEM object in a reserved memory area dedicated for the storage of the
+ * CCS data for all compressible GEM objects. The GEM object must be stored in
+ * contiguous memory with a size aligned to 64KB
+ */
+#define I915_FORMAT_MOD_4_TILED_BMG_CCS fourcc_mod_code(INTEL, 17)
+
+/*
* Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
*
* Macroblocks are laid in a Z-shape, and each pixel data is following the
@@ -1427,6 +1454,90 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier)
*/
#define AMLOGIC_FBC_OPTION_MEM_SAVING (1ULL << 0)
+/* MediaTek modifiers
+ * Bits Parameter Notes
+ * ----- ------------------------ ---------------------------------------------
+ * 7: 0 TILE LAYOUT Values are MTK_FMT_MOD_TILE_*
+ * 15: 8 COMPRESSION Values are MTK_FMT_MOD_COMPRESS_*
+ * 23:16 10 BIT LAYOUT Values are MTK_FMT_MOD_10BIT_LAYOUT_*
+ *
+ */
+
+#define DRM_FORMAT_MOD_MTK(__flags) fourcc_mod_code(MTK, __flags)
+
+/*
+ * MediaTek Tiled Modifier
+ * The lowest 8 bits of the modifier is used to specify the tiling
+ * layout. Only the 16L_32S tiling is used for now, but we define an
+ * "untiled" version and leave room for future expansion.
+ */
+#define MTK_FMT_MOD_TILE_MASK 0xf
+#define MTK_FMT_MOD_TILE_NONE 0x0
+#define MTK_FMT_MOD_TILE_16L32S 0x1
+
+/*
+ * Bits 8-15 specify compression options
+ */
+#define MTK_FMT_MOD_COMPRESS_MASK (0xf << 8)
+#define MTK_FMT_MOD_COMPRESS_NONE (0x0 << 8)
+#define MTK_FMT_MOD_COMPRESS_V1 (0x1 << 8)
+
+/*
+ * Bits 16-23 specify how the bits of 10 bit formats are
+ * stored out in memory
+ */
+#define MTK_FMT_MOD_10BIT_LAYOUT_MASK (0xf << 16)
+#define MTK_FMT_MOD_10BIT_LAYOUT_PACKED (0x0 << 16)
+#define MTK_FMT_MOD_10BIT_LAYOUT_LSBTILED (0x1 << 16)
+#define MTK_FMT_MOD_10BIT_LAYOUT_LSBRASTER (0x2 << 16)
+
+/* alias for the most common tiling format */
+#define DRM_FORMAT_MOD_MTK_16L_32S_TILE DRM_FORMAT_MOD_MTK(MTK_FMT_MOD_TILE_16L32S)
+
+/*
+ * Apple GPU-tiled layouts.
+ *
+ * Apple GPUs support nonlinear tilings with optional lossless compression.
+ *
+ * GPU-tiled images are divided into 16KiB tiles:
+ *
+ * Bytes per pixel Tile size
+ * --------------- ---------
+ * 1 128x128
+ * 2 128x64
+ * 4 64x64
+ * 8 64x32
+ * 16 32x32
+ *
+ * Tiles are raster-order. Pixels within a tile are interleaved (Morton order).
+ *
+ * Compressed images pad the body to 128-bytes and are immediately followed by a
+ * metadata section. The metadata section rounds the image dimensions to
+ * powers-of-two and contains 8 bytes for each 16x16 compression subtile.
+ * Subtiles are interleaved (Morton order).
+ *
+ * All images are 128-byte aligned.
+ *
+ * These layouts fundamentally do not have meaningful strides. No matter how we
+ * specify strides for these layouts, userspace unaware of Apple image layouts
+ * will be unable to use correctly the specified stride for any purpose.
+ * Userspace aware of the image layouts do not use strides. The most "correct"
+ * convention would be setting the image stride to 0. Unfortunately, some
+ * software assumes the stride is at least (width * bytes per pixel). We
+ * therefore require that stride equals (width * bytes per pixel). Since the
+ * stride is arbitrary here, we pick the simplest convention.
+ *
+ * Although containing two sections, compressed image layouts are treated in
+ * software as a single plane. This is modelled after AFBC, a similar
+ * scheme. Attempting to separate the sections to be "explicit" in DRM would
+ * only generate more confusion, as software does not treat the image this way.
+ *
+ * For detailed information on the hardware image layouts, see
+ * https://docs.mesa3d.org/drivers/asahi.html#image-layouts
+ */
+#define DRM_FORMAT_MOD_APPLE_GPU_TILED fourcc_mod_code(APPLE, 1)
+#define DRM_FORMAT_MOD_APPLE_GPU_TILED_COMPRESSED fourcc_mod_code(APPLE, 2)
+
/*
* AMD modifiers
*
@@ -1475,6 +1586,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier)
#define AMD_FMT_MOD_TILE_VER_GFX10 2
#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
#define AMD_FMT_MOD_TILE_VER_GFX11 4
+#define AMD_FMT_MOD_TILE_VER_GFX12 5
/*
* 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical
@@ -1485,13 +1597,31 @@ drm_fourcc_canonicalize_nvidia_format_mod(uint64_t modifier)
/*
* 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
* GFX9 as canonical version.
+ *
+ * 64K_D_2D on GFX12 is identical to 64K_D on GFX11.
*/
#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+#define AMD_FMT_MOD_TILE_GFX9_4K_D_X 22
#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
#define AMD_FMT_MOD_TILE_GFX11_256K_R_X 31
+/* Gfx12 swizzle modes:
+ * 0 - LINEAR
+ * 1 - 256B_2D - 2D block dimensions
+ * 2 - 4KB_2D
+ * 3 - 64KB_2D
+ * 4 - 256KB_2D
+ * 5 - 4KB_3D - 3D block dimensions
+ * 6 - 64KB_3D
+ * 7 - 256KB_3D
+ */
+#define AMD_FMT_MOD_TILE_GFX12_256B_2D 1
+#define AMD_FMT_MOD_TILE_GFX12_4K_2D 2
+#define AMD_FMT_MOD_TILE_GFX12_64K_2D 3
+#define AMD_FMT_MOD_TILE_GFX12_256K_2D 4
+
#define AMD_FMT_MOD_DCC_BLOCK_64B 0
#define AMD_FMT_MOD_DCC_BLOCK_128B 1
#define AMD_FMT_MOD_DCC_BLOCK_256B 2
diff --git a/include/standard-headers/linux/const.h b/include/standard-headers/linux/const.h
index 1eb84b5..95ede23 100644
--- a/include/standard-headers/linux/const.h
+++ b/include/standard-headers/linux/const.h
@@ -28,6 +28,23 @@
#define _BITUL(x) (_UL(1) << (x))
#define _BITULL(x) (_ULL(1) << (x))
+#if !defined(__ASSEMBLY__)
+/*
+ * Missing __asm__ support
+ *
+ * __BIT128() would not work in the __asm__ code, as it shifts an
+ * 'unsigned __int128' data type as direct representation of
+ * 128 bit constants is not supported in the gcc compiler, as
+ * they get silently truncated.
+ *
+ * TODO: Please revisit this implementation when gcc compiler
+ * starts representing 128 bit constants directly like long
+ * and unsigned long etc. Subsequently drop the comment for
+ * GENMASK_U128() which would then start supporting __asm__ code.
+ */
+#define _BIT128(x) ((unsigned __int128)(1) << (x))
+#endif
+
#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (__typeof__(x))(a) - 1)
#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask))
diff --git a/include/standard-headers/linux/ethtool.h b/include/standard-headers/linux/ethtool.h
index 0150378..cef0d20 100644
--- a/include/standard-headers/linux/ethtool.h
+++ b/include/standard-headers/linux/ethtool.h
@@ -681,6 +681,8 @@ enum ethtool_link_ext_substate_module {
* @ETH_SS_STATS_ETH_MAC: names of IEEE 802.3 MAC statistics
* @ETH_SS_STATS_ETH_CTRL: names of IEEE 802.3 MAC Control statistics
* @ETH_SS_STATS_RMON: names of RMON statistics
+ * @ETH_SS_STATS_PHY: names of PHY(dev) statistics
+ * @ETH_SS_TS_FLAGS: hardware timestamping flags
*
* @ETH_SS_COUNT: number of defined string sets
*/
@@ -706,6 +708,8 @@ enum ethtool_stringset {
ETH_SS_STATS_ETH_MAC,
ETH_SS_STATS_ETH_CTRL,
ETH_SS_STATS_RMON,
+ ETH_SS_STATS_PHY,
+ ETH_SS_TS_FLAGS,
/* add new constants above here */
ETH_SS_COUNT
@@ -753,6 +757,252 @@ enum ethtool_module_power_mode {
};
/**
+ * enum ethtool_c33_pse_ext_state - groups of PSE extended states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION: Group of error_condition states
+ * @ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID: Group of mr_mps_valid states
+ * @ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE: Group of mr_pse_enable states
+ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED: Group of option_detect_ted
+ * states
+ * @ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM: Group of option_vport_lim states
+ * @ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED: Group of ovld_detected states
+ * @ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE: Group of pd_dll_power_type
+ * states
+ * @ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE: Group of power_not_available
+ * states
+ * @ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED: Group of short_detected states
+ */
+enum ethtool_c33_pse_ext_state {
+ ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION = 1,
+ ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
+ ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE,
+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
+ ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
+ ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED,
+ ETHTOOL_C33_PSE_EXT_STATE_PD_DLL_POWER_TYPE,
+ ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
+ ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_mr_mps_valid - mr_mps_valid states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD: Underload
+ * state
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN: Port is not
+ * connected
+ *
+ * The PSE monitors either the DC or AC Maintain Power Signature
+ * (MPS, see 33.2.9.1). This variable indicates the presence or absence of
+ * a valid MPS.
+ */
+enum ethtool_c33_pse_ext_substate_mr_mps_valid {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_error_condition - error_condition states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT: Non-existing
+ * port number
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT: Undefined port
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT: Internal
+ * hardware fault
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON:
+ * Communication error after force on
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS: Unknown
+ * port status
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF: Host
+ * crash turn off
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN:
+ * Host crash force shutdown
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE: Configuration
+ * change
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP: Over
+ * temperature detected
+ *
+ * error_condition is a variable indicating the status of
+ * implementation-specific fault conditions or optionally other system faults
+ * that prevent the PSE from meeting the specifications in Table 33–11 and that
+ * require the PSE not to source power. These error conditions are different
+ * from those monitored by the state diagrams in Figure 33–10.
+ */
+enum ethtool_c33_pse_ext_substate_error_condition {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_COMM_ERROR_AFTER_FORCE_ON,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_TURN_OFF,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_HOST_CRASH_FORCE_SHUTDOWN,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_mr_pse_enable - mr_pse_enable states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE: Disable
+ * pin active
+ *
+ * mr_pse_enable is control variable that selects PSE operation and test
+ * functions.
+ */
+enum ethtool_c33_pse_ext_substate_mr_pse_enable {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE = 1,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_option_detect_ted - option_detect_ted
+ * states functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS: Detection
+ * in process
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR:
+ * Connection check error
+ *
+ * option_detect_ted is a variable indicating if detection can be performed
+ * by the PSE during the ted_timer interval.
+ */
+enum ethtool_c33_pse_ext_substate_option_detect_ted {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_option_vport_lim - option_vport_lim states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE: Main supply
+ * voltage is high
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE: Main supply
+ * voltage is low
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION: Voltage
+ * injection into the port
+ *
+ * option_vport_lim is an optional variable indicates if VPSE is out of the
+ * operating range during normal operating state.
+ */
+enum ethtool_c33_pse_ext_substate_option_vport_lim {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_ovld_detected - ovld_detected states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD: Overload state
+ *
+ * ovld_detected is a variable indicating if the PSE output current has been
+ * in an overload condition (see 33.2.7.6) for at least TCUT of a one-second
+ * sliding time.
+ */
+enum ethtool_c33_pse_ext_substate_ovld_detected {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD = 1,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_power_not_available - power_not_available
+ * states functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED: Power
+ * budget exceeded for the controller
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET:
+ * Configured port power limit exceeded controller power budget
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT:
+ * Power request from PD exceeds port limit
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT: Power
+ * denied due to Hardware power limit
+ *
+ * power_not_available is a variable that is asserted in an
+ * implementation-dependent manner when the PSE is no longer capable of
+ * sourcing sufficient power to support the attached PD. Sufficient power
+ * is defined by classification; see 33.2.6.
+ */
+enum ethtool_c33_pse_ext_substate_power_not_available {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED = 1,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT,
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT,
+};
+
+/**
+ * enum ethtool_c33_pse_ext_substate_short_detected - short_detected states
+ * functions. IEEE 802.3-2022 33.2.4.4 Variables
+ *
+ * @ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION: Short
+ * condition was detected
+ *
+ * short_detected is a variable indicating if the PSE output current has been
+ * in a short circuit condition for TLIM within a sliding window (see 33.2.7.7).
+ */
+enum ethtool_c33_pse_ext_substate_short_detected {
+ ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION = 1,
+};
+
+/**
+ * enum ethtool_pse_types - Types of PSE controller.
+ * @ETHTOOL_PSE_UNKNOWN: Type of PSE controller is unknown
+ * @ETHTOOL_PSE_PODL: PSE controller which support PoDL
+ * @ETHTOOL_PSE_C33: PSE controller which support Clause 33 (PoE)
+ */
+enum ethtool_pse_types {
+ ETHTOOL_PSE_UNKNOWN = 1 << 0,
+ ETHTOOL_PSE_PODL = 1 << 1,
+ ETHTOOL_PSE_C33 = 1 << 2,
+};
+
+/**
+ * enum ethtool_c33_pse_admin_state - operational state of the PoDL PSE
+ * functions. IEEE 802.3-2022 30.9.1.1.2 aPSEAdminState
+ * @ETHTOOL_C33_PSE_ADMIN_STATE_UNKNOWN: state of PSE functions is unknown
+ * @ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED: PSE functions are disabled
+ * @ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED: PSE functions are enabled
+ */
+enum ethtool_c33_pse_admin_state {
+ ETHTOOL_C33_PSE_ADMIN_STATE_UNKNOWN = 1,
+ ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED,
+ ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED,
+};
+
+/**
+ * enum ethtool_c33_pse_pw_d_status - power detection status of the PSE.
+ * IEEE 802.3-2022 30.9.1.1.3 aPoDLPSEPowerDetectionStatus:
+ * @ETHTOOL_C33_PSE_PW_D_STATUS_UNKNOWN: PSE status is unknown
+ * @ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED: The enumeration "disabled"
+ * indicates that the PSE State diagram is in the state DISABLED.
+ * @ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING: The enumeration "searching"
+ * indicates the PSE State diagram is in a state other than those
+ * listed.
+ * @ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING: The enumeration
+ * "deliveringPower" indicates that the PSE State diagram is in the
+ * state POWER_ON.
+ * @ETHTOOL_C33_PSE_PW_D_STATUS_TEST: The enumeration "test" indicates that
+ * the PSE State diagram is in the state TEST_MODE.
+ * @ETHTOOL_C33_PSE_PW_D_STATUS_FAULT: The enumeration "fault" indicates that
+ * the PSE State diagram is in the state TEST_ERROR.
+ * @ETHTOOL_C33_PSE_PW_D_STATUS_OTHERFAULT: The enumeration "otherFault"
+ * indicates that the PSE State diagram is in the state IDLE due to
+ * the variable error_condition = true.
+ */
+enum ethtool_c33_pse_pw_d_status {
+ ETHTOOL_C33_PSE_PW_D_STATUS_UNKNOWN = 1,
+ ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED,
+ ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING,
+ ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING,
+ ETHTOOL_C33_PSE_PW_D_STATUS_TEST,
+ ETHTOOL_C33_PSE_PW_D_STATUS_FAULT,
+ ETHTOOL_C33_PSE_PW_D_STATUS_OTHERFAULT,
+};
+
+/**
* enum ethtool_podl_pse_admin_state - operational state of the PoDL PSE
* functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
* @ETHTOOL_PODL_PSE_ADMIN_STATE_UNKNOWN: state of PoDL PSE functions are
@@ -823,6 +1073,24 @@ enum ethtool_mm_verify_status {
};
/**
+ * enum ethtool_module_fw_flash_status - plug-in module firmware flashing status
+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED: The firmware flashing process has
+ * started.
+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS: The firmware flashing process
+ * is in progress.
+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED: The firmware flashing process was
+ * completed successfully.
+ * @ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR: The firmware flashing process was
+ * stopped due to an error.
+ */
+enum ethtool_module_fw_flash_status {
+ ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED = 1,
+ ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS,
+ ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED,
+ ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR,
+};
+
+/**
* struct ethtool_gstrings - string set for data tagging
* @cmd: Command number = %ETHTOOL_GSTRINGS
* @string_set: String set ID; one of &enum ethtool_stringset
@@ -1790,6 +2058,25 @@ enum ethtool_link_mode_bit_indices {
ETHTOOL_LINK_MODE_10baseT1S_Full_BIT = 99,
ETHTOOL_LINK_MODE_10baseT1S_Half_BIT = 100,
ETHTOOL_LINK_MODE_10baseT1S_P2MP_Half_BIT = 101,
+ ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT = 102,
+ ETHTOOL_LINK_MODE_200000baseCR_Full_BIT = 103,
+ ETHTOOL_LINK_MODE_200000baseKR_Full_BIT = 104,
+ ETHTOOL_LINK_MODE_200000baseDR_Full_BIT = 105,
+ ETHTOOL_LINK_MODE_200000baseDR_2_Full_BIT = 106,
+ ETHTOOL_LINK_MODE_200000baseSR_Full_BIT = 107,
+ ETHTOOL_LINK_MODE_200000baseVR_Full_BIT = 108,
+ ETHTOOL_LINK_MODE_400000baseCR2_Full_BIT = 109,
+ ETHTOOL_LINK_MODE_400000baseKR2_Full_BIT = 110,
+ ETHTOOL_LINK_MODE_400000baseDR2_Full_BIT = 111,
+ ETHTOOL_LINK_MODE_400000baseDR2_2_Full_BIT = 112,
+ ETHTOOL_LINK_MODE_400000baseSR2_Full_BIT = 113,
+ ETHTOOL_LINK_MODE_400000baseVR2_Full_BIT = 114,
+ ETHTOOL_LINK_MODE_800000baseCR4_Full_BIT = 115,
+ ETHTOOL_LINK_MODE_800000baseKR4_Full_BIT = 116,
+ ETHTOOL_LINK_MODE_800000baseDR4_Full_BIT = 117,
+ ETHTOOL_LINK_MODE_800000baseDR4_2_Full_BIT = 118,
+ ETHTOOL_LINK_MODE_800000baseSR4_Full_BIT = 119,
+ ETHTOOL_LINK_MODE_800000baseVR4_Full_BIT = 120,
/* must be last entry */
__ETHTOOL_LINK_MODE_MASK_NBITS
@@ -2002,73 +2289,81 @@ static inline int ethtool_validate_duplex(uint8_t duplex)
* be exploited to reduce the RSS queue spread.
*/
#define RXH_XFRM_SYM_XOR (1 << 0)
+/* Similar to SYM_XOR, except that one copy of the XOR'ed fields is replaced by
+ * an OR of the same fields
+ */
+#define RXH_XFRM_SYM_OR_XOR (1 << 1)
#define RXH_XFRM_NO_CHANGE 0xff
-/* L2-L4 network traffic flow types */
-#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */
-#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */
-#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */
-#define AH_ESP_V4_FLOW 0x04 /* hash only */
-#define TCP_V6_FLOW 0x05 /* hash or spec (tcp_ip6_spec; nfc only) */
-#define UDP_V6_FLOW 0x06 /* hash or spec (udp_ip6_spec; nfc only) */
-#define SCTP_V6_FLOW 0x07 /* hash or spec (sctp_ip6_spec; nfc only) */
-#define AH_ESP_V6_FLOW 0x08 /* hash only */
-#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */
-#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */
-#define AH_V6_FLOW 0x0b /* hash or spec (ah_ip6_spec; nfc only) */
-#define ESP_V6_FLOW 0x0c /* hash or spec (esp_ip6_spec; nfc only) */
-#define IPV4_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */
-#define IP_USER_FLOW IPV4_USER_FLOW
-#define IPV6_USER_FLOW 0x0e /* spec only (usr_ip6_spec; nfc only) */
-#define IPV4_FLOW 0x10 /* hash only */
-#define IPV6_FLOW 0x11 /* hash only */
-#define ETHER_FLOW 0x12 /* spec only (ether_spec) */
-
-/* Used for GTP-U IPv4 and IPv6.
- * The format of GTP packets only includes
- * elements such as TEID and GTP version.
- * It is primarily intended for data communication of the UE.
- */
-#define GTPU_V4_FLOW 0x13 /* hash only */
-#define GTPU_V6_FLOW 0x14 /* hash only */
-
-/* Use for GTP-C IPv4 and v6.
- * The format of these GTP packets does not include TEID.
- * Primarily expected to be used for communication
- * to create sessions for UE data communication,
- * commonly referred to as CSR (Create Session Request).
- */
-#define GTPC_V4_FLOW 0x15 /* hash only */
-#define GTPC_V6_FLOW 0x16 /* hash only */
-
-/* Use for GTP-C IPv4 and v6.
- * Unlike GTPC_V4_FLOW, the format of these GTP packets includes TEID.
- * After session creation, it becomes this packet.
- * This is mainly used for requests to realize UE handover.
- */
-#define GTPC_TEID_V4_FLOW 0x17 /* hash only */
-#define GTPC_TEID_V6_FLOW 0x18 /* hash only */
-
-/* Use for GTP-U and extended headers for the PSC (PDU Session Container).
- * The format of these GTP packets includes TEID and QFI.
- * In 5G communication using UPF (User Plane Function),
- * data communication with this extended header is performed.
- */
-#define GTPU_EH_V4_FLOW 0x19 /* hash only */
-#define GTPU_EH_V6_FLOW 0x1a /* hash only */
-
-/* Use for GTP-U IPv4 and v6 PSC (PDU Session Container) extended headers.
- * This differs from GTPU_EH_V(4|6)_FLOW in that it is distinguished by
- * UL/DL included in the PSC.
- * There are differences in the data included based on Downlink/Uplink,
- * and can be used to distinguish packets.
- * The functions described so far are useful when you want to
- * handle communication from the mobile network in UPF, PGW, etc.
- */
-#define GTPU_UL_V4_FLOW 0x1b /* hash only */
-#define GTPU_UL_V6_FLOW 0x1c /* hash only */
-#define GTPU_DL_V4_FLOW 0x1d /* hash only */
-#define GTPU_DL_V6_FLOW 0x1e /* hash only */
+enum {
+ /* L2-L4 network traffic flow types */
+ TCP_V4_FLOW = 0x01, /* hash or spec (tcp_ip4_spec) */
+ UDP_V4_FLOW = 0x02, /* hash or spec (udp_ip4_spec) */
+ SCTP_V4_FLOW = 0x03, /* hash or spec (sctp_ip4_spec) */
+ AH_ESP_V4_FLOW = 0x04, /* hash only */
+ TCP_V6_FLOW = 0x05, /* hash or spec (tcp_ip6_spec; nfc only) */
+ UDP_V6_FLOW = 0x06, /* hash or spec (udp_ip6_spec; nfc only) */
+ SCTP_V6_FLOW = 0x07, /* hash or spec (sctp_ip6_spec; nfc only) */
+ AH_ESP_V6_FLOW = 0x08, /* hash only */
+ AH_V4_FLOW = 0x09, /* hash or spec (ah_ip4_spec) */
+ ESP_V4_FLOW = 0x0a, /* hash or spec (esp_ip4_spec) */
+ AH_V6_FLOW = 0x0b, /* hash or spec (ah_ip6_spec; nfc only) */
+ ESP_V6_FLOW = 0x0c, /* hash or spec (esp_ip6_spec; nfc only) */
+ IPV4_USER_FLOW = 0x0d, /* spec only (usr_ip4_spec) */
+ IP_USER_FLOW = IPV4_USER_FLOW,
+ IPV6_USER_FLOW = 0x0e, /* spec only (usr_ip6_spec; nfc only) */
+ IPV4_FLOW = 0x10, /* hash only */
+ IPV6_FLOW = 0x11, /* hash only */
+ ETHER_FLOW = 0x12, /* spec only (ether_spec) */
+
+ /* Used for GTP-U IPv4 and IPv6.
+ * The format of GTP packets only includes
+ * elements such as TEID and GTP version.
+ * It is primarily intended for data communication of the UE.
+ */
+ GTPU_V4_FLOW = 0x13, /* hash only */
+ GTPU_V6_FLOW = 0x14, /* hash only */
+
+ /* Use for GTP-C IPv4 and v6.
+ * The format of these GTP packets does not include TEID.
+ * Primarily expected to be used for communication
+ * to create sessions for UE data communication,
+ * commonly referred to as CSR (Create Session Request).
+ */
+ GTPC_V4_FLOW = 0x15, /* hash only */
+ GTPC_V6_FLOW = 0x16, /* hash only */
+
+ /* Use for GTP-C IPv4 and v6.
+ * Unlike GTPC_V4_FLOW, the format of these GTP packets includes TEID.
+ * After session creation, it becomes this packet.
+ * This is mainly used for requests to realize UE handover.
+ */
+ GTPC_TEID_V4_FLOW = 0x17, /* hash only */
+ GTPC_TEID_V6_FLOW = 0x18, /* hash only */
+
+ /* Use for GTP-U and extended headers for the PSC (PDU Session Container).
+ * The format of these GTP packets includes TEID and QFI.
+ * In 5G communication using UPF (User Plane Function),
+ * data communication with this extended header is performed.
+ */
+ GTPU_EH_V4_FLOW = 0x19, /* hash only */
+ GTPU_EH_V6_FLOW = 0x1a, /* hash only */
+
+ /* Use for GTP-U IPv4 and v6 PSC (PDU Session Container) extended headers.
+ * This differs from GTPU_EH_V(4|6)_FLOW in that it is distinguished by
+ * UL/DL included in the PSC.
+ * There are differences in the data included based on Downlink/Uplink,
+ * and can be used to distinguish packets.
+ * The functions described so far are useful when you want to
+ * handle communication from the mobile network in UPF, PGW, etc.
+ */
+ GTPU_UL_V4_FLOW = 0x1b, /* hash only */
+ GTPU_UL_V6_FLOW = 0x1c, /* hash only */
+ GTPU_DL_V4_FLOW = 0x1d, /* hash only */
+ GTPU_DL_V6_FLOW = 0x1e, /* hash only */
+
+ __FLOW_TYPE_COUNT,
+};
/* Flag to enable additional fields in struct ethtool_rx_flow_spec */
#define FLOW_EXT 0x80000000
@@ -2261,6 +2556,11 @@ struct ethtool_link_settings {
uint8_t master_slave_state;
uint8_t rate_matching;
uint32_t reserved[7];
+ /* Linux builds with -Wflex-array-member-not-at-end but does
+ * not use the "link_mode_masks" member. Leave it defined for
+ * userspace for now, and when userspace wants to start using
+ * -Wfamnae, we'll need a new solution.
+ */
uint32_t link_mode_masks[];
/* layout of link_mode_masks fields:
* uint32_t map_supported[link_mode_masks_nwords];
@@ -2268,4 +2568,20 @@ struct ethtool_link_settings {
* uint32_t map_lp_advertising[link_mode_masks_nwords];
*/
};
+
+/**
+ * enum phy_upstream - Represents the upstream component a given PHY device
+ * is connected to, as in what is on the other end of the MII bus. Most PHYs
+ * will be attached to an Ethernet MAC controller, but in some cases, there's
+ * an intermediate PHY used as a media-converter, which will driver another
+ * MII interface as its output.
+ * @PHY_UPSTREAM_MAC: Upstream component is a MAC (a switch port,
+ * or ethernet controller)
+ * @PHY_UPSTREAM_PHY: Upstream component is a PHY (likely a media converter)
+ */
+enum phy_upstream {
+ PHY_UPSTREAM_MAC,
+ PHY_UPSTREAM_PHY,
+};
+
#endif /* _LINUX_ETHTOOL_H */
diff --git a/include/standard-headers/linux/fuse.h b/include/standard-headers/linux/fuse.h
index bac9dbc..d8b2fd6 100644
--- a/include/standard-headers/linux/fuse.h
+++ b/include/standard-headers/linux/fuse.h
@@ -217,6 +217,24 @@
* - add backing_id to fuse_open_out, add FOPEN_PASSTHROUGH open flag
* - add FUSE_NO_EXPORT_SUPPORT init flag
* - add FUSE_NOTIFY_RESEND, add FUSE_HAS_RESEND init flag
+ *
+ * 7.41
+ * - add FUSE_ALLOW_IDMAP
+ * 7.42
+ * - Add FUSE_OVER_IO_URING and all other io-uring related flags and data
+ * structures:
+ * - struct fuse_uring_ent_in_out
+ * - struct fuse_uring_req_header
+ * - struct fuse_uring_cmd_req
+ * - FUSE_URING_IN_OUT_HEADER_SZ
+ * - FUSE_URING_OP_IN_OUT_SZ
+ * - enum fuse_uring_cmd
+ *
+ * 7.43
+ * - add FUSE_REQUEST_TIMEOUT
+ *
+ * 7.44
+ * - add FUSE_NOTIFY_INC_EPOCH
*/
#ifndef _LINUX_FUSE_H
@@ -248,7 +266,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 40
+#define FUSE_KERNEL_MINOR_VERSION 44
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -417,6 +435,10 @@ struct fuse_file_lock {
* FUSE_NO_EXPORT_SUPPORT: explicitly disable export support
* FUSE_HAS_RESEND: kernel supports resending pending requests, and the high bit
* of the request ID indicates resend requests
+ * FUSE_ALLOW_IDMAP: allow creation of idmapped mounts
+ * FUSE_OVER_IO_URING: Indicate that client supports io-uring
+ * FUSE_REQUEST_TIMEOUT: kernel supports timing out requests.
+ * init_out.request_timeout contains the timeout (in secs)
*/
#define FUSE_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1)
@@ -459,9 +481,11 @@ struct fuse_file_lock {
#define FUSE_PASSTHROUGH (1ULL << 37)
#define FUSE_NO_EXPORT_SUPPORT (1ULL << 38)
#define FUSE_HAS_RESEND (1ULL << 39)
-
/* Obsolete alias for FUSE_DIRECT_IO_ALLOW_MMAP */
#define FUSE_DIRECT_IO_RELAX FUSE_DIRECT_IO_ALLOW_MMAP
+#define FUSE_ALLOW_IDMAP (1ULL << 40)
+#define FUSE_OVER_IO_URING (1ULL << 41)
+#define FUSE_REQUEST_TIMEOUT (1ULL << 42)
/**
* CUSE INIT request/reply flags
@@ -646,6 +670,7 @@ enum fuse_notify_code {
FUSE_NOTIFY_RETRIEVE = 5,
FUSE_NOTIFY_DELETE = 6,
FUSE_NOTIFY_RESEND = 7,
+ FUSE_NOTIFY_INC_EPOCH = 8,
FUSE_NOTIFY_CODE_MAX,
};
@@ -889,7 +914,8 @@ struct fuse_init_out {
uint16_t map_alignment;
uint32_t flags2;
uint32_t max_stack_depth;
- uint32_t unused[6];
+ uint16_t request_timeout;
+ uint16_t unused[11];
};
#define CUSE_INIT_INFO_MAX 4096
@@ -980,6 +1006,21 @@ struct fuse_fallocate_in {
*/
#define FUSE_UNIQUE_RESEND (1ULL << 63)
+/**
+ * This value will be set by the kernel to
+ * (struct fuse_in_header).{uid,gid} fields in
+ * case when:
+ * - fuse daemon enabled FUSE_ALLOW_IDMAP
+ * - idmapping information is not available and uid/gid
+ * can not be mapped in accordance with an idmapping.
+ *
+ * Note: an idmapping information always available
+ * for inode creation operations like:
+ * FUSE_MKNOD, FUSE_SYMLINK, FUSE_MKDIR, FUSE_TMPFILE,
+ * FUSE_CREATE and FUSE_RENAME2 (with RENAME_WHITEOUT).
+ */
+#define FUSE_INVALID_UIDGID ((uint32_t)(-1))
+
struct fuse_in_header {
uint32_t len;
uint32_t opcode;
@@ -1182,4 +1223,67 @@ struct fuse_supp_groups {
uint32_t groups[];
};
+/**
+ * Size of the ring buffer header
+ */
+#define FUSE_URING_IN_OUT_HEADER_SZ 128
+#define FUSE_URING_OP_IN_OUT_SZ 128
+
+/* Used as part of the fuse_uring_req_header */
+struct fuse_uring_ent_in_out {
+ uint64_t flags;
+
+ /*
+ * commit ID to be used in a reply to a ring request (see also
+ * struct fuse_uring_cmd_req)
+ */
+ uint64_t commit_id;
+
+ /* size of user payload buffer */
+ uint32_t payload_sz;
+ uint32_t padding;
+
+ uint64_t reserved;
+};
+
+/**
+ * Header for all fuse-io-uring requests
+ */
+struct fuse_uring_req_header {
+ /* struct fuse_in_header / struct fuse_out_header */
+ char in_out[FUSE_URING_IN_OUT_HEADER_SZ];
+
+ /* per op code header */
+ char op_in[FUSE_URING_OP_IN_OUT_SZ];
+
+ struct fuse_uring_ent_in_out ring_ent_in_out;
+};
+
+/**
+ * sqe commands to the kernel
+ */
+enum fuse_uring_cmd {
+ FUSE_IO_URING_CMD_INVALID = 0,
+
+ /* register the request buffer and fetch a fuse request */
+ FUSE_IO_URING_CMD_REGISTER = 1,
+
+ /* commit fuse request result and fetch next request */
+ FUSE_IO_URING_CMD_COMMIT_AND_FETCH = 2,
+};
+
+/**
+ * In the 80B command area of the SQE.
+ */
+struct fuse_uring_cmd_req {
+ uint64_t flags;
+
+ /* entry identifier for commits */
+ uint64_t commit_id;
+
+ /* queue the command is for (queue index) */
+ uint16_t qid;
+ uint8_t padding[6];
+};
+
#endif /* _LINUX_FUSE_H */
diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h
index 2221b0c..a82ff79 100644
--- a/include/standard-headers/linux/input-event-codes.h
+++ b/include/standard-headers/linux/input-event-codes.h
@@ -519,6 +519,7 @@
#define KEY_NOTIFICATION_CENTER 0x1bc /* Show/hide the notification center */
#define KEY_PICKUP_PHONE 0x1bd /* Answer incoming call */
#define KEY_HANGUP_PHONE 0x1be /* Decline incoming call */
+#define KEY_LINK_PHONE 0x1bf /* AL Phone Syncing */
#define KEY_DEL_EOL 0x1c0
#define KEY_DEL_EOS 0x1c1
@@ -618,6 +619,8 @@
#define KEY_CAMERA_ACCESS_ENABLE 0x24b /* Enables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_DISABLE 0x24c /* Disables programmatic access to camera devices. (HUTRR72) */
#define KEY_CAMERA_ACCESS_TOGGLE 0x24d /* Toggles the current state of the camera access control. (HUTRR72) */
+#define KEY_ACCESSIBILITY 0x24e /* Toggles the system bound accessibility UI/command (HUTRR116) */
+#define KEY_DO_NOT_DISTURB 0x24f /* Toggles the system-wide "Do Not Disturb" control (HUTRR94)*/
#define KEY_BRIGHTNESS_MIN 0x250 /* Set Brightness to Minimum */
#define KEY_BRIGHTNESS_MAX 0x251 /* Set Brightness to Maximum */
@@ -922,7 +925,8 @@
#define SW_MUTE_DEVICE 0x0e /* set = device disabled */
#define SW_PEN_INSERTED 0x0f /* set = pen inserted */
#define SW_MACHINE_COVER 0x10 /* set = cover closed */
-#define SW_MAX_ 0x10
+#define SW_USB_INSERT 0x11 /* set = USB audio device connected */
+#define SW_MAX_ 0x11
#define SW_CNT (SW_MAX_+1)
/*
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
index a391932..a3a3e94 100644
--- a/include/standard-headers/linux/pci_regs.h
+++ b/include/standard-headers/linux/pci_regs.h
@@ -340,7 +340,8 @@
#define PCI_MSIX_ENTRY_UPPER_ADDR 0x4 /* Message Upper Address */
#define PCI_MSIX_ENTRY_DATA 0x8 /* Message Data */
#define PCI_MSIX_ENTRY_VECTOR_CTRL 0xc /* Vector Control */
-#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001
+#define PCI_MSIX_ENTRY_CTRL_MASKBIT 0x00000001 /* Mask Bit */
+#define PCI_MSIX_ENTRY_CTRL_ST 0xffff0000 /* Steering Tag */
/* CompactPCI Hotswap Register */
@@ -485,6 +486,7 @@
#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
+#define PCI_EXP_FLAGS_FLIT 0x8000 /* Flit Mode Supported */
#define PCI_EXP_DEVCAP 0x04 /* Device capabilities */
#define PCI_EXP_DEVCAP_PAYLOAD 0x00000007 /* Max_Payload_Size */
#define PCI_EXP_DEVCAP_PHANTOM 0x00000018 /* Phantom functions */
@@ -532,7 +534,7 @@
#define PCI_EXP_DEVSTA_TRPND 0x0020 /* Transactions Pending */
#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V1 12 /* v1 endpoints without link end here */
#define PCI_EXP_LNKCAP 0x0c /* Link Capabilities */
-#define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */
+#define PCI_EXP_LNKCAP_SLS 0x0000000f /* Max Link Speed (prior to PCIe r3.0: Supported Link Speeds) */
#define PCI_EXP_LNKCAP_SLS_2_5GB 0x00000001 /* LNKCAP2 SLS Vector bit 0 */
#define PCI_EXP_LNKCAP_SLS_5_0GB 0x00000002 /* LNKCAP2 SLS Vector bit 1 */
#define PCI_EXP_LNKCAP_SLS_8_0GB 0x00000003 /* LNKCAP2 SLS Vector bit 2 */
@@ -634,9 +636,11 @@
#define PCI_EXP_RTCTL_SENFEE 0x0002 /* System Error on Non-Fatal Error */
#define PCI_EXP_RTCTL_SEFEE 0x0004 /* System Error on Fatal Error */
#define PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */
-#define PCI_EXP_RTCTL_CRSSVE 0x0010 /* CRS Software Visibility Enable */
+#define PCI_EXP_RTCTL_RRS_SVE 0x0010 /* Config RRS Software Visibility Enable */
+#define PCI_EXP_RTCTL_CRSSVE PCI_EXP_RTCTL_RRS_SVE /* compatibility */
#define PCI_EXP_RTCAP 0x1e /* Root Capabilities */
-#define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */
+#define PCI_EXP_RTCAP_RRS_SV 0x0001 /* Config RRS Software Visibility */
+#define PCI_EXP_RTCAP_CRSVIS PCI_EXP_RTCAP_RRS_SV /* compatibility */
#define PCI_EXP_RTSTA 0x20 /* Root Status */
#define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff /* PME Requester ID */
#define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */
@@ -657,10 +661,12 @@
#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* 64b AtomicOp completion */
#define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200 /* 128b AtomicOp completion */
#define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */
+#define PCI_EXP_DEVCAP2_TPH_COMP_MASK 0x00003000 /* TPH completer support */
#define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */
#define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */
#define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */
#define PCI_EXP_DEVCAP2_EE_PREFIX 0x00200000 /* End-End TLP Prefix */
+#define PCI_EXP_DEVCAP2_EE_PREFIX_MAX 0x00c00000 /* Max End-End TLP Prefixes */
#define PCI_EXP_DEVCTL2 0x28 /* Device Control 2 */
#define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */
#define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010 /* Completion Timeout Disable */
@@ -676,6 +682,7 @@
#define PCI_EXP_DEVSTA2 0x2a /* Device Status 2 */
#define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c /* end of v2 EPs w/o link */
#define PCI_EXP_LNKCAP2 0x2c /* Link Capabilities 2 */
+#define PCI_EXP_LNKCAP2_SLS 0x000000fe /* Supported Link Speeds Vector */
#define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */
#define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */
#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */
@@ -740,9 +747,11 @@
#define PCI_EXT_CAP_ID_DVSEC 0x23 /* Designated Vendor-Specific */
#define PCI_EXT_CAP_ID_DLF 0x25 /* Data Link Feature */
#define PCI_EXT_CAP_ID_PL_16GT 0x26 /* Physical Layer 16.0 GT/s */
+#define PCI_EXT_CAP_ID_NPEM 0x29 /* Native PCIe Enclosure Management */
#define PCI_EXT_CAP_ID_PL_32GT 0x2A /* Physical Layer 32.0 GT/s */
#define PCI_EXT_CAP_ID_DOE 0x2E /* Data Object Exchange */
-#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DOE
+#define PCI_EXT_CAP_ID_PL_64GT 0x31 /* Physical Layer 64.0 GT/s */
+#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_64GT
#define PCI_EXT_CAP_DSN_SIZEOF 12
#define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40
@@ -783,10 +792,13 @@
/* Same bits as above */
#define PCI_ERR_CAP 0x18 /* Advanced Error Capabilities & Ctrl*/
#define PCI_ERR_CAP_FEP(x) ((x) & 0x1f) /* First Error Pointer */
-#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
-#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
-#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
-#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
+#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
+#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
+#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
+#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
+#define PCI_ERR_CAP_PREFIX_LOG_PRESENT 0x00000800 /* TLP Prefix Log Present */
+#define PCI_ERR_CAP_TLP_LOG_FLIT 0x00040000 /* TLP was logged in Flit Mode */
+#define PCI_ERR_CAP_TLP_LOG_SIZE 0x00f80000 /* Logged TLP Size (only in Flit mode) */
#define PCI_ERR_HEADER_LOG 0x1c /* Header Log Register (16 bytes) */
#define PCI_ERR_ROOT_COMMAND 0x2c /* Root Error Command */
#define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 /* Correctable Err Reporting Enable */
@@ -802,6 +814,7 @@
#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */
#define PCI_ERR_ROOT_AER_IRQ 0xf8000000 /* Advanced Error Interrupt Message Number */
#define PCI_ERR_ROOT_ERR_SRC 0x34 /* Error Source Identification */
+#define PCI_ERR_PREFIX_LOG 0x38 /* TLP Prefix LOG Register (up to 16 bytes) */
/* Virtual Channel */
#define PCI_VC_PORT_CAP1 0x04
@@ -995,9 +1008,6 @@
#define PCI_ACS_CTRL 0x06 /* ACS Control Register */
#define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */
-#define PCI_VSEC_HDR 4 /* extended cap - vendor-specific */
-#define PCI_VSEC_HDR_LEN_SHIFT 20 /* shift for length field */
-
/* SATA capability */
#define PCI_SATA_REGS 4 /* SATA REGs specifier */
#define PCI_SATA_REGS_MASK 0xF /* location - BAR#/inline */
@@ -1007,7 +1017,7 @@
/* Resizable BARs */
#define PCI_REBAR_CAP 4 /* capability register */
-#define PCI_REBAR_CAP_SIZES 0x00FFFFF0 /* supported BAR sizes */
+#define PCI_REBAR_CAP_SIZES 0xFFFFFFF0 /* supported BAR sizes */
#define PCI_REBAR_CTRL 8 /* control register */
#define PCI_REBAR_CTRL_BAR_IDX 0x00000007 /* BAR index */
#define PCI_REBAR_CTRL_NBAR_MASK 0x000000E0 /* # of resizable BARs */
@@ -1020,15 +1030,34 @@
#define PCI_DPA_CAP_SUBSTATE_MASK 0x1F /* # substates - 1 */
#define PCI_DPA_BASE_SIZEOF 16 /* size with 0 substates */
+/* TPH Completer Support */
+#define PCI_EXP_DEVCAP2_TPH_COMP_NONE 0x0 /* None */
+#define PCI_EXP_DEVCAP2_TPH_COMP_TPH_ONLY 0x1 /* TPH only */
+#define PCI_EXP_DEVCAP2_TPH_COMP_EXT_TPH 0x3 /* TPH and Extended TPH */
+
/* TPH Requester */
#define PCI_TPH_CAP 4 /* capability register */
-#define PCI_TPH_CAP_LOC_MASK 0x600 /* location mask */
-#define PCI_TPH_LOC_NONE 0x000 /* no location */
-#define PCI_TPH_LOC_CAP 0x200 /* in capability */
-#define PCI_TPH_LOC_MSIX 0x400 /* in MSI-X */
-#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST table mask */
-#define PCI_TPH_CAP_ST_SHIFT 16 /* ST table shift */
-#define PCI_TPH_BASE_SIZEOF 0xc /* size with no ST table */
+#define PCI_TPH_CAP_ST_NS 0x00000001 /* No ST Mode Supported */
+#define PCI_TPH_CAP_ST_IV 0x00000002 /* Interrupt Vector Mode Supported */
+#define PCI_TPH_CAP_ST_DS 0x00000004 /* Device Specific Mode Supported */
+#define PCI_TPH_CAP_EXT_TPH 0x00000100 /* Ext TPH Requester Supported */
+#define PCI_TPH_CAP_LOC_MASK 0x00000600 /* ST Table Location */
+#define PCI_TPH_LOC_NONE 0x00000000 /* Not present */
+#define PCI_TPH_LOC_CAP 0x00000200 /* In capability */
+#define PCI_TPH_LOC_MSIX 0x00000400 /* In MSI-X */
+#define PCI_TPH_CAP_ST_MASK 0x07FF0000 /* ST Table Size */
+#define PCI_TPH_CAP_ST_SHIFT 16 /* ST Table Size shift */
+#define PCI_TPH_BASE_SIZEOF 0xc /* Size with no ST table */
+
+#define PCI_TPH_CTRL 8 /* control register */
+#define PCI_TPH_CTRL_MODE_SEL_MASK 0x00000007 /* ST Mode Select */
+#define PCI_TPH_ST_NS_MODE 0x0 /* No ST Mode */
+#define PCI_TPH_ST_IV_MODE 0x1 /* Interrupt Vector Mode */
+#define PCI_TPH_ST_DS_MODE 0x2 /* Device Specific Mode */
+#define PCI_TPH_CTRL_REQ_EN_MASK 0x00000300 /* TPH Requester Enable */
+#define PCI_TPH_REQ_DISABLE 0x0 /* No TPH requests allowed */
+#define PCI_TPH_REQ_TPH_ONLY 0x1 /* TPH only requests allowed */
+#define PCI_TPH_REQ_EXT_TPH 0x3 /* Extended TPH requests allowed */
/* Downstream Port Containment */
#define PCI_EXP_DPC_CAP 0x04 /* DPC Capability */
@@ -1036,8 +1065,9 @@
#define PCI_EXP_DPC_CAP_RP_EXT 0x0020 /* Root Port Extensions */
#define PCI_EXP_DPC_CAP_POISONED_TLP 0x0040 /* Poisoned TLP Egress Blocking Supported */
#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x0080 /* Software Triggering Supported */
-#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00 /* RP PIO Log Size */
+#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00 /* RP PIO Log Size [3:0] */
#define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */
+#define PCI_EXP_DPC_RP_PIO_LOG_SIZE4 0x2000 /* RP PIO Log Size [4] */
#define PCI_EXP_DPC_CTL 0x06 /* DPC control */
#define PCI_EXP_DPC_CTL_EN_FATAL 0x0001 /* Enable trigger on ERR_FATAL message */
@@ -1115,12 +1145,55 @@
#define PCI_DLF_CAP 0x04 /* Capabilities Register */
#define PCI_DLF_EXCHANGE_ENABLE 0x80000000 /* Data Link Feature Exchange Enable */
+/* Secondary PCIe Capability 8.0 GT/s */
+#define PCI_SECPCI_LE_CTRL 0x0c /* Lane Equalization Control Register */
+
/* Physical Layer 16.0 GT/s */
#define PCI_PL_16GT_LE_CTRL 0x20 /* Lane Equalization Control Register */
#define PCI_PL_16GT_LE_CTRL_DSP_TX_PRESET_MASK 0x0000000F
#define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK 0x000000F0
#define PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT 4
+/* Physical Layer 32.0 GT/s */
+#define PCI_PL_32GT_LE_CTRL 0x20 /* Lane Equalization Control Register */
+
+/* Physical Layer 64.0 GT/s */
+#define PCI_PL_64GT_LE_CTRL 0x20 /* Lane Equalization Control Register */
+
+/* Native PCIe Enclosure Management */
+#define PCI_NPEM_CAP 0x04 /* NPEM capability register */
+#define PCI_NPEM_CAP_CAPABLE 0x00000001 /* NPEM Capable */
+
+#define PCI_NPEM_CTRL 0x08 /* NPEM control register */
+#define PCI_NPEM_CTRL_ENABLE 0x00000001 /* NPEM Enable */
+
+/*
+ * Native PCIe Enclosure Management indication bits and Reset command bit
+ * are corresponding for capability and control registers.
+ */
+#define PCI_NPEM_CMD_RESET 0x00000002 /* Reset Command */
+#define PCI_NPEM_IND_OK 0x00000004 /* OK */
+#define PCI_NPEM_IND_LOCATE 0x00000008 /* Locate */
+#define PCI_NPEM_IND_FAIL 0x00000010 /* Fail */
+#define PCI_NPEM_IND_REBUILD 0x00000020 /* Rebuild */
+#define PCI_NPEM_IND_PFA 0x00000040 /* Predicted Failure Analysis */
+#define PCI_NPEM_IND_HOTSPARE 0x00000080 /* Hot Spare */
+#define PCI_NPEM_IND_ICA 0x00000100 /* In Critical Array */
+#define PCI_NPEM_IND_IFA 0x00000200 /* In Failed Array */
+#define PCI_NPEM_IND_IDT 0x00000400 /* Device Type */
+#define PCI_NPEM_IND_DISABLED 0x00000800 /* Disabled */
+#define PCI_NPEM_IND_SPEC_0 0x01000000
+#define PCI_NPEM_IND_SPEC_1 0x02000000
+#define PCI_NPEM_IND_SPEC_2 0x04000000
+#define PCI_NPEM_IND_SPEC_3 0x08000000
+#define PCI_NPEM_IND_SPEC_4 0x10000000
+#define PCI_NPEM_IND_SPEC_5 0x20000000
+#define PCI_NPEM_IND_SPEC_6 0x40000000
+#define PCI_NPEM_IND_SPEC_7 0x80000000
+
+#define PCI_NPEM_STATUS 0x0c /* NPEM status register */
+#define PCI_NPEM_STATUS_CC 0x00000001 /* Command Completed */
+
/* Data Object Exchange */
#define PCI_DOE_CAP 0x04 /* DOE Capabilities Register */
#define PCI_DOE_CAP_INT_SUP 0x00000001 /* Interrupt Support */
@@ -1144,8 +1217,17 @@
#define PCI_DOE_DATA_OBJECT_HEADER_2_LENGTH 0x0003ffff
#define PCI_DOE_DATA_OBJECT_DISC_REQ_3_INDEX 0x000000ff
+#define PCI_DOE_DATA_OBJECT_DISC_REQ_3_VER 0x0000ff00
#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_VID 0x0000ffff
-#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL 0x00ff0000
+#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE 0x00ff0000
#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_NEXT_INDEX 0xff000000
+/* Deprecated old name, replaced with PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE */
+#define PCI_DOE_DATA_OBJECT_DISC_RSP_3_PROTOCOL PCI_DOE_DATA_OBJECT_DISC_RSP_3_TYPE
+
+/* Compute Express Link (CXL r3.1, sec 8.1.5) */
+#define PCI_DVSEC_CXL_PORT 3
+#define PCI_DVSEC_CXL_PORT_CTL 0x0c
+#define PCI_DVSEC_CXL_PORT_CTL_UNMASK_SBR 0x00000001
+
#endif /* LINUX_PCI_REGS_H */
diff --git a/include/standard-headers/linux/virtio_balloon.h b/include/standard-headers/linux/virtio_balloon.h
index f343bfe..3121cd2 100644
--- a/include/standard-headers/linux/virtio_balloon.h
+++ b/include/standard-headers/linux/virtio_balloon.h
@@ -71,7 +71,13 @@ struct virtio_balloon_config {
#define VIRTIO_BALLOON_S_CACHES 7 /* Disk caches */
#define VIRTIO_BALLOON_S_HTLB_PGALLOC 8 /* Hugetlb page allocations */
#define VIRTIO_BALLOON_S_HTLB_PGFAIL 9 /* Hugetlb page allocation failures */
-#define VIRTIO_BALLOON_S_NR 10
+#define VIRTIO_BALLOON_S_OOM_KILL 10 /* OOM killer invocations */
+#define VIRTIO_BALLOON_S_ALLOC_STALL 11 /* Stall count of memory allocatoin */
+#define VIRTIO_BALLOON_S_ASYNC_SCAN 12 /* Amount of memory scanned asynchronously */
+#define VIRTIO_BALLOON_S_DIRECT_SCAN 13 /* Amount of memory scanned directly */
+#define VIRTIO_BALLOON_S_ASYNC_RECLAIM 14 /* Amount of memory reclaimed asynchronously */
+#define VIRTIO_BALLOON_S_DIRECT_RECLAIM 15 /* Amount of memory reclaimed directly */
+#define VIRTIO_BALLOON_S_NR 16
#define VIRTIO_BALLOON_S_NAMES_WITH_PREFIX(VIRTIO_BALLOON_S_NAMES_prefix) { \
VIRTIO_BALLOON_S_NAMES_prefix "swap-in", \
@@ -83,7 +89,13 @@ struct virtio_balloon_config {
VIRTIO_BALLOON_S_NAMES_prefix "available-memory", \
VIRTIO_BALLOON_S_NAMES_prefix "disk-caches", \
VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-allocations", \
- VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures" \
+ VIRTIO_BALLOON_S_NAMES_prefix "hugetlb-failures", \
+ VIRTIO_BALLOON_S_NAMES_prefix "oom-kills", \
+ VIRTIO_BALLOON_S_NAMES_prefix "alloc-stalls", \
+ VIRTIO_BALLOON_S_NAMES_prefix "async-scans", \
+ VIRTIO_BALLOON_S_NAMES_prefix "direct-scans", \
+ VIRTIO_BALLOON_S_NAMES_prefix "async-reclaims", \
+ VIRTIO_BALLOON_S_NAMES_prefix "direct-reclaims" \
}
#define VIRTIO_BALLOON_S_NAMES VIRTIO_BALLOON_S_NAMES_WITH_PREFIX("")
diff --git a/include/standard-headers/linux/virtio_bt.h b/include/standard-headers/linux/virtio_bt.h
index a11ecc3..6f0dee7 100644
--- a/include/standard-headers/linux/virtio_bt.h
+++ b/include/standard-headers/linux/virtio_bt.h
@@ -13,7 +13,6 @@
enum virtio_bt_config_type {
VIRTIO_BT_CONFIG_TYPE_PRIMARY = 0,
- VIRTIO_BT_CONFIG_TYPE_AMP = 1,
};
enum virtio_bt_config_vendor {
diff --git a/include/standard-headers/linux/virtio_crypto.h b/include/standard-headers/linux/virtio_crypto.h
index 68066da..4d350ae 100644
--- a/include/standard-headers/linux/virtio_crypto.h
+++ b/include/standard-headers/linux/virtio_crypto.h
@@ -329,6 +329,7 @@ struct virtio_crypto_op_header {
VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x00)
#define VIRTIO_CRYPTO_AKCIPHER_DECRYPT \
VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x01)
+ /* akcipher sign/verify opcodes are deprecated */
#define VIRTIO_CRYPTO_AKCIPHER_SIGN \
VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AKCIPHER, 0x02)
#define VIRTIO_CRYPTO_AKCIPHER_VERIFY \
diff --git a/include/standard-headers/linux/virtio_gpu.h b/include/standard-headers/linux/virtio_gpu.h
index 2db643e..00cd3f0 100644
--- a/include/standard-headers/linux/virtio_gpu.h
+++ b/include/standard-headers/linux/virtio_gpu.h
@@ -309,8 +309,10 @@ struct virtio_gpu_cmd_submit {
#define VIRTIO_GPU_CAPSET_VIRGL 1
#define VIRTIO_GPU_CAPSET_VIRGL2 2
-/* 3 is reserved for gfxstream */
+#define VIRTIO_GPU_CAPSET_GFXSTREAM_VULKAN 3
#define VIRTIO_GPU_CAPSET_VENUS 4
+#define VIRTIO_GPU_CAPSET_CROSS_DOMAIN 5
+#define VIRTIO_GPU_CAPSET_DRM 6
/* VIRTIO_GPU_CMD_GET_CAPSET_INFO */
struct virtio_gpu_get_capset_info {
diff --git a/include/standard-headers/linux/virtio_mem.h b/include/standard-headers/linux/virtio_mem.h
index 18c74c5..6bfa41b 100644
--- a/include/standard-headers/linux/virtio_mem.h
+++ b/include/standard-headers/linux/virtio_mem.h
@@ -90,6 +90,8 @@
#define VIRTIO_MEM_F_ACPI_PXM 0
/* unplugged memory must not be accessed */
#define VIRTIO_MEM_F_UNPLUGGED_INACCESSIBLE 1
+/* plugged memory will remain plugged when suspending+resuming */
+#define VIRTIO_MEM_F_PERSISTENT_SUSPEND 2
/* --- virtio-mem: guest -> host requests --- */
diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h
index 0f88417..982e854 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -56,6 +56,7 @@
#define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow
* Steering */
#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */
+#define VIRTIO_NET_F_DEVICE_STATS 50 /* Device can provide device-level statistics. */
#define VIRTIO_NET_F_VQ_NOTF_COAL 52 /* Device supports virtqueue notification coalescing */
#define VIRTIO_NET_F_NOTF_COAL 53 /* Device supports notifications coalescing */
#define VIRTIO_NET_F_GUEST_USO4 54 /* Guest can handle USOv4 in. */
@@ -326,6 +327,19 @@ struct virtio_net_rss_config {
uint8_t hash_key_data[/* hash_key_length */];
};
+struct virtio_net_rss_config_hdr {
+ uint32_t hash_types;
+ uint16_t indirection_table_mask;
+ uint16_t unclassified_queue;
+ uint16_t indirection_table[/* 1 + indirection_table_mask */];
+};
+
+struct virtio_net_rss_config_trailer {
+ uint16_t max_tx_vq;
+ uint8_t hash_key_length;
+ uint8_t hash_key_data[/* hash_key_length */];
+};
+
#define VIRTIO_NET_CTRL_MQ_RSS_CONFIG 1
/*
@@ -406,4 +420,146 @@ struct virtio_net_ctrl_coal_vq {
struct virtio_net_ctrl_coal coal;
};
+/*
+ * Device Statistics
+ */
+#define VIRTIO_NET_CTRL_STATS 8
+#define VIRTIO_NET_CTRL_STATS_QUERY 0
+#define VIRTIO_NET_CTRL_STATS_GET 1
+
+struct virtio_net_stats_capabilities {
+
+#define VIRTIO_NET_STATS_TYPE_CVQ (1ULL << 32)
+
+#define VIRTIO_NET_STATS_TYPE_RX_BASIC (1ULL << 0)
+#define VIRTIO_NET_STATS_TYPE_RX_CSUM (1ULL << 1)
+#define VIRTIO_NET_STATS_TYPE_RX_GSO (1ULL << 2)
+#define VIRTIO_NET_STATS_TYPE_RX_SPEED (1ULL << 3)
+
+#define VIRTIO_NET_STATS_TYPE_TX_BASIC (1ULL << 16)
+#define VIRTIO_NET_STATS_TYPE_TX_CSUM (1ULL << 17)
+#define VIRTIO_NET_STATS_TYPE_TX_GSO (1ULL << 18)
+#define VIRTIO_NET_STATS_TYPE_TX_SPEED (1ULL << 19)
+
+ uint64_t supported_stats_types[1];
+};
+
+struct virtio_net_ctrl_queue_stats {
+ struct {
+ uint16_t vq_index;
+ uint16_t reserved[3];
+ uint64_t types_bitmap[1];
+ } stats[1];
+};
+
+struct virtio_net_stats_reply_hdr {
+#define VIRTIO_NET_STATS_TYPE_REPLY_CVQ 32
+
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_BASIC 0
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_CSUM 1
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_GSO 2
+#define VIRTIO_NET_STATS_TYPE_REPLY_RX_SPEED 3
+
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_BASIC 16
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_CSUM 17
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_GSO 18
+#define VIRTIO_NET_STATS_TYPE_REPLY_TX_SPEED 19
+ uint8_t type;
+ uint8_t reserved;
+ uint16_t vq_index;
+ uint16_t reserved1;
+ uint16_t size;
+};
+
+struct virtio_net_stats_cvq {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ uint64_t command_num;
+ uint64_t ok_num;
+};
+
+struct virtio_net_stats_rx_basic {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ uint64_t rx_notifications;
+
+ uint64_t rx_packets;
+ uint64_t rx_bytes;
+
+ uint64_t rx_interrupts;
+
+ uint64_t rx_drops;
+ uint64_t rx_drop_overruns;
+};
+
+struct virtio_net_stats_tx_basic {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ uint64_t tx_notifications;
+
+ uint64_t tx_packets;
+ uint64_t tx_bytes;
+
+ uint64_t tx_interrupts;
+
+ uint64_t tx_drops;
+ uint64_t tx_drop_malformed;
+};
+
+struct virtio_net_stats_rx_csum {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ uint64_t rx_csum_valid;
+ uint64_t rx_needs_csum;
+ uint64_t rx_csum_none;
+ uint64_t rx_csum_bad;
+};
+
+struct virtio_net_stats_tx_csum {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ uint64_t tx_csum_none;
+ uint64_t tx_needs_csum;
+};
+
+struct virtio_net_stats_rx_gso {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ uint64_t rx_gso_packets;
+ uint64_t rx_gso_bytes;
+ uint64_t rx_gso_packets_coalesced;
+ uint64_t rx_gso_bytes_coalesced;
+};
+
+struct virtio_net_stats_tx_gso {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ uint64_t tx_gso_packets;
+ uint64_t tx_gso_bytes;
+ uint64_t tx_gso_segments;
+ uint64_t tx_gso_segments_bytes;
+ uint64_t tx_gso_packets_noseg;
+ uint64_t tx_gso_bytes_noseg;
+};
+
+struct virtio_net_stats_rx_speed {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ /* rx_{packets,bytes}_allowance_exceeded are too long. So rename to
+ * short name.
+ */
+ uint64_t rx_ratelimit_packets;
+ uint64_t rx_ratelimit_bytes;
+};
+
+struct virtio_net_stats_tx_speed {
+ struct virtio_net_stats_reply_hdr hdr;
+
+ /* tx_{packets,bytes}_allowance_exceeded are too long. So rename to
+ * short name.
+ */
+ uint64_t tx_ratelimit_packets;
+ uint64_t tx_ratelimit_bytes;
+};
+
#endif /* _LINUX_VIRTIO_NET_H */
diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h
index 4010216..09e964e 100644
--- a/include/standard-headers/linux/virtio_pci.h
+++ b/include/standard-headers/linux/virtio_pci.h
@@ -40,6 +40,7 @@
#define _LINUX_VIRTIO_PCI_H
#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/kernel.h"
#ifndef VIRTIO_PCI_NO_LEGACY
@@ -115,6 +116,8 @@
#define VIRTIO_PCI_CAP_PCI_CFG 5
/* Additional shared memory capability */
#define VIRTIO_PCI_CAP_SHARED_MEMORY_CFG 8
+/* PCI vendor data configuration */
+#define VIRTIO_PCI_CAP_VENDOR_CFG 9
/* This is the PCI capability header: */
struct virtio_pci_cap {
@@ -129,6 +132,18 @@ struct virtio_pci_cap {
uint32_t length; /* Length of the structure, in bytes. */
};
+/* This is the PCI vendor data capability header: */
+struct virtio_pci_vndr_data {
+ uint8_t cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */
+ uint8_t cap_next; /* Generic PCI field: next ptr. */
+ uint8_t cap_len; /* Generic PCI field: capability length */
+ uint8_t cfg_type; /* Identifies the structure. */
+ uint16_t vendor_id; /* Identifies the vendor-specific format. */
+ /* For Vendor Definition */
+ /* Pads structure to a multiple of 4 bytes */
+ /* Reads must not have side effects */
+};
+
struct virtio_pci_cap64 {
struct virtio_pci_cap cap;
uint32_t offset_hi; /* Most sig 32 bits of offset */
@@ -231,6 +246,7 @@ struct virtio_pci_cfg_cap {
#define VIRTIO_ADMIN_CMD_LIST_USE 0x1
/* Admin command group type. */
+#define VIRTIO_ADMIN_GROUP_TYPE_SELF 0x0
#define VIRTIO_ADMIN_GROUP_TYPE_SRIOV 0x1
/* Transitional device admin command. */
@@ -240,6 +256,17 @@ struct virtio_pci_cfg_cap {
#define VIRTIO_ADMIN_CMD_LEGACY_DEV_CFG_READ 0x5
#define VIRTIO_ADMIN_CMD_LEGACY_NOTIFY_INFO 0x6
+/* Device parts access commands. */
+#define VIRTIO_ADMIN_CMD_CAP_ID_LIST_QUERY 0x7
+#define VIRTIO_ADMIN_CMD_DEVICE_CAP_GET 0x8
+#define VIRTIO_ADMIN_CMD_DRIVER_CAP_SET 0x9
+#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_CREATE 0xa
+#define VIRTIO_ADMIN_CMD_RESOURCE_OBJ_DESTROY 0xd
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_GET 0xe
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET 0xf
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_SET 0x10
+#define VIRTIO_ADMIN_CMD_DEV_MODE_SET 0x11
+
struct virtio_admin_cmd_hdr {
uint16_t opcode;
/*
@@ -286,4 +313,123 @@ struct virtio_admin_cmd_notify_info_result {
struct virtio_admin_cmd_notify_info_data entries[VIRTIO_ADMIN_CMD_MAX_NOTIFY_INFO];
};
+#define VIRTIO_DEV_PARTS_CAP 0x0000
+
+struct virtio_dev_parts_cap {
+ uint8_t get_parts_resource_objects_limit;
+ uint8_t set_parts_resource_objects_limit;
+};
+
+#define MAX_CAP_ID __KERNEL_DIV_ROUND_UP(VIRTIO_DEV_PARTS_CAP + 1, 64)
+
+struct virtio_admin_cmd_query_cap_id_result {
+ uint64_t supported_caps[MAX_CAP_ID];
+};
+
+struct virtio_admin_cmd_cap_get_data {
+ uint16_t id;
+ uint8_t reserved[6];
+};
+
+struct virtio_admin_cmd_cap_set_data {
+ uint16_t id;
+ uint8_t reserved[6];
+ uint8_t cap_specific_data[];
+};
+
+struct virtio_admin_cmd_resource_obj_cmd_hdr {
+ uint16_t type;
+ uint8_t reserved[2];
+ uint32_t id; /* Indicates unique resource object id per resource object type */
+};
+
+struct virtio_admin_cmd_resource_obj_create_data {
+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr;
+ uint64_t flags;
+ uint8_t resource_obj_specific_data[];
+};
+
+#define VIRTIO_RESOURCE_OBJ_DEV_PARTS 0
+
+#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_GET 0
+#define VIRTIO_RESOURCE_OBJ_DEV_PARTS_TYPE_SET 1
+
+struct virtio_resource_obj_dev_parts {
+ uint8_t type;
+ uint8_t reserved[7];
+};
+
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_SIZE 0
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_COUNT 1
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_METADATA_TYPE_LIST 2
+
+struct virtio_admin_cmd_dev_parts_metadata_data {
+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr;
+ uint8_t type;
+ uint8_t reserved[7];
+};
+
+#define VIRTIO_DEV_PART_F_OPTIONAL 0
+
+struct virtio_dev_part_hdr {
+ uint16_t part_type;
+ uint8_t flags;
+ uint8_t reserved;
+ union {
+ struct {
+ uint32_t offset;
+ uint32_t reserved;
+ } pci_common_cfg;
+ struct {
+ uint16_t index;
+ uint8_t reserved[6];
+ } vq_index;
+ } selector;
+ uint32_t length;
+};
+
+struct virtio_dev_part {
+ struct virtio_dev_part_hdr hdr;
+ uint8_t value[];
+};
+
+struct virtio_admin_cmd_dev_parts_metadata_result {
+ union {
+ struct {
+ uint32_t size;
+ uint32_t reserved;
+ } parts_size;
+ struct {
+ uint32_t count;
+ uint32_t reserved;
+ } hdr_list_count;
+ struct {
+ uint32_t count;
+ uint32_t reserved;
+ struct virtio_dev_part_hdr hdrs[];
+ } hdr_list;
+ };
+};
+
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_SELECTED 0
+#define VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_ALL 1
+
+struct virtio_admin_cmd_dev_parts_get_data {
+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr;
+ uint8_t type;
+ uint8_t reserved[7];
+ struct virtio_dev_part_hdr hdr_list[];
+};
+
+struct virtio_admin_cmd_dev_parts_set_data {
+ struct virtio_admin_cmd_resource_obj_cmd_hdr hdr;
+ struct virtio_dev_part parts[];
+};
+
+#define VIRTIO_ADMIN_CMD_DEV_MODE_F_STOPPED 0
+
+struct virtio_admin_cmd_dev_mode_set_data {
+ uint8_t flags;
+};
+
#endif
diff --git a/include/standard-headers/linux/virtio_snd.h b/include/standard-headers/linux/virtio_snd.h
index 860f12e..160d578 100644
--- a/include/standard-headers/linux/virtio_snd.h
+++ b/include/standard-headers/linux/virtio_snd.h
@@ -25,7 +25,7 @@ struct virtio_snd_config {
uint32_t streams;
/* # of available channel maps */
uint32_t chmaps;
- /* # of available control elements */
+ /* # of available control elements (if VIRTIO_SND_F_CTLS) */
uint32_t controls;
};
diff --git a/include/standard-headers/linux/vmclock-abi.h b/include/standard-headers/linux/vmclock-abi.h
new file mode 100644
index 0000000..15b0316
--- /dev/null
+++ b/include/standard-headers/linux/vmclock-abi.h
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) */
+
+/*
+ * This structure provides a vDSO-style clock to VM guests, exposing the
+ * relationship (or lack thereof) between the CPU clock (TSC, timebase, arch
+ * counter, etc.) and real time. It is designed to address the problem of
+ * live migration, which other clock enlightenments do not.
+ *
+ * When a guest is live migrated, this affects the clock in two ways.
+ *
+ * First, even between identical hosts the actual frequency of the underlying
+ * counter will change within the tolerances of its specification (typically
+ * ±50PPM, or 4 seconds a day). This frequency also varies over time on the
+ * same host, but can be tracked by NTP as it generally varies slowly. With
+ * live migration there is a step change in the frequency, with no warning.
+ *
+ * Second, there may be a step change in the value of the counter itself, as
+ * its accuracy is limited by the precision of the NTP synchronization on the
+ * source and destination hosts.
+ *
+ * So any calibration (NTP, PTP, etc.) which the guest has done on the source
+ * host before migration is invalid, and needs to be redone on the new host.
+ *
+ * In its most basic mode, this structure provides only an indication to the
+ * guest that live migration has occurred. This allows the guest to know that
+ * its clock is invalid and take remedial action. For applications that need
+ * reliable accurate timestamps (e.g. distributed databases), the structure
+ * can be mapped all the way to userspace. This allows the application to see
+ * directly for itself that the clock is disrupted and take appropriate
+ * action, even when using a vDSO-style method to get the time instead of a
+ * system call.
+ *
+ * In its more advanced mode. this structure can also be used to expose the
+ * precise relationship of the CPU counter to real time, as calibrated by the
+ * host. This means that userspace applications can have accurate time
+ * immediately after live migration, rather than having to pause operations
+ * and wait for NTP to recover. This mode does, of course, rely on the
+ * counter being reliable and consistent across CPUs.
+ *
+ * Note that this must be true UTC, never with smeared leap seconds. If a
+ * guest wishes to construct a smeared clock, it can do so. Presenting a
+ * smeared clock through this interface would be problematic because it
+ * actually messes with the apparent counter *period*. A linear smearing
+ * of 1 ms per second would effectively tweak the counter period by 1000PPM
+ * at the start/end of the smearing period, while a sinusoidal smear would
+ * basically be impossible to represent.
+ *
+ * This structure is offered with the intent that it be adopted into the
+ * nascent virtio-rtc standard, as a virtio-rtc that does not address the live
+ * migration problem seems a little less than fit for purpose. For that
+ * reason, certain fields use precisely the same numeric definitions as in
+ * the virtio-rtc proposal. The structure can also be exposed through an ACPI
+ * device with the CID "VMCLOCK", modelled on the "VMGENID" device except for
+ * the fact that it uses a real _CRS to convey the address of the structure
+ * (which should be a full page, to allow for mapping directly to userspace).
+ */
+
+#ifndef __VMCLOCK_ABI_H__
+#define __VMCLOCK_ABI_H__
+
+#include "standard-headers/linux/types.h"
+
+struct vmclock_abi {
+ /* CONSTANT FIELDS */
+ uint32_t magic;
+#define VMCLOCK_MAGIC 0x4b4c4356 /* "VCLK" */
+ uint32_t size; /* Size of region containing this structure */
+ uint16_t version; /* 1 */
+ uint8_t counter_id; /* Matches VIRTIO_RTC_COUNTER_xxx except INVALID */
+#define VMCLOCK_COUNTER_ARM_VCNT 0
+#define VMCLOCK_COUNTER_X86_TSC 1
+#define VMCLOCK_COUNTER_INVALID 0xff
+ uint8_t time_type; /* Matches VIRTIO_RTC_TYPE_xxx */
+#define VMCLOCK_TIME_UTC 0 /* Since 1970-01-01 00:00:00z */
+#define VMCLOCK_TIME_TAI 1 /* Since 1970-01-01 00:00:00z */
+#define VMCLOCK_TIME_MONOTONIC 2 /* Since undefined epoch */
+#define VMCLOCK_TIME_INVALID_SMEARED 3 /* Not supported */
+#define VMCLOCK_TIME_INVALID_MAYBE_SMEARED 4 /* Not supported */
+
+ /* NON-CONSTANT FIELDS PROTECTED BY SEQCOUNT LOCK */
+ uint32_t seq_count; /* Low bit means an update is in progress */
+ /*
+ * This field changes to another non-repeating value when the CPU
+ * counter is disrupted, for example on live migration. This lets
+ * the guest know that it should discard any calibration it has
+ * performed of the counter against external sources (NTP/PTP/etc.).
+ */
+ uint64_t disruption_marker;
+ uint64_t flags;
+ /* Indicates that the tai_offset_sec field is valid */
+#define VMCLOCK_FLAG_TAI_OFFSET_VALID (1 << 0)
+ /*
+ * Optionally used to notify guests of pending maintenance events.
+ * A guest which provides latency-sensitive services may wish to
+ * remove itself from service if an event is coming up. Two flags
+ * indicate the approximate imminence of the event.
+ */
+#define VMCLOCK_FLAG_DISRUPTION_SOON (1 << 1) /* About a day */
+#define VMCLOCK_FLAG_DISRUPTION_IMMINENT (1 << 2) /* About an hour */
+#define VMCLOCK_FLAG_PERIOD_ESTERROR_VALID (1 << 3)
+#define VMCLOCK_FLAG_PERIOD_MAXERROR_VALID (1 << 4)
+#define VMCLOCK_FLAG_TIME_ESTERROR_VALID (1 << 5)
+#define VMCLOCK_FLAG_TIME_MAXERROR_VALID (1 << 6)
+ /*
+ * If the MONOTONIC flag is set then (other than leap seconds) it is
+ * guaranteed that the time calculated according this structure at
+ * any given moment shall never appear to be later than the time
+ * calculated via the structure at any *later* moment.
+ *
+ * In particular, a timestamp based on a counter reading taken
+ * immediately after setting the low bit of seq_count (and the
+ * associated memory barrier), using the previously-valid time and
+ * period fields, shall never be later than a timestamp based on
+ * a counter reading taken immediately before *clearing* the low
+ * bit again after the update, using the about-to-be-valid fields.
+ */
+#define VMCLOCK_FLAG_TIME_MONOTONIC (1 << 7)
+
+ uint8_t pad[2];
+ uint8_t clock_status;
+#define VMCLOCK_STATUS_UNKNOWN 0
+#define VMCLOCK_STATUS_INITIALIZING 1
+#define VMCLOCK_STATUS_SYNCHRONIZED 2
+#define VMCLOCK_STATUS_FREERUNNING 3
+#define VMCLOCK_STATUS_UNRELIABLE 4
+
+ /*
+ * The time exposed through this device is never smeared. This field
+ * corresponds to the 'subtype' field in virtio-rtc, which indicates
+ * the smearing method. However in this case it provides a *hint* to
+ * the guest operating system, such that *if* the guest OS wants to
+ * provide its users with an alternative clock which does not follow
+ * UTC, it may do so in a fashion consistent with the other systems
+ * in the nearby environment.
+ */
+ uint8_t leap_second_smearing_hint; /* Matches VIRTIO_RTC_SUBTYPE_xxx */
+#define VMCLOCK_SMEARING_STRICT 0
+#define VMCLOCK_SMEARING_NOON_LINEAR 1
+#define VMCLOCK_SMEARING_UTC_SLS 2
+ uint16_t tai_offset_sec; /* Actually two's complement signed */
+ uint8_t leap_indicator;
+ /*
+ * This field is based on the VIRTIO_RTC_LEAP_xxx values as defined
+ * in the current draft of virtio-rtc, but since smearing cannot be
+ * used with the shared memory device, some values are not used.
+ *
+ * The _POST_POS and _POST_NEG values allow the guest to perform
+ * its own smearing during the day or so after a leap second when
+ * such smearing may need to continue being applied for a leap
+ * second which is now theoretically "historical".
+ */
+#define VMCLOCK_LEAP_NONE 0x00 /* No known nearby leap second */
+#define VMCLOCK_LEAP_PRE_POS 0x01 /* Positive leap second at EOM */
+#define VMCLOCK_LEAP_PRE_NEG 0x02 /* Negative leap second at EOM */
+#define VMCLOCK_LEAP_POS 0x03 /* Set during 23:59:60 second */
+#define VMCLOCK_LEAP_POST_POS 0x04
+#define VMCLOCK_LEAP_POST_NEG 0x05
+
+ /* Bit shift for counter_period_frac_sec and its error rate */
+ uint8_t counter_period_shift;
+ /*
+ * Paired values of counter and UTC at a given point in time.
+ */
+ uint64_t counter_value;
+ /*
+ * Counter period, and error margin of same. The unit of these
+ * fields is 1/2^(64 + counter_period_shift) of a second.
+ */
+ uint64_t counter_period_frac_sec;
+ uint64_t counter_period_esterror_rate_frac_sec;
+ uint64_t counter_period_maxerror_rate_frac_sec;
+
+ /*
+ * Time according to time_type field above.
+ */
+ uint64_t time_sec; /* Seconds since time_type epoch */
+ uint64_t time_frac_sec; /* Units of 1/2^64 of a second */
+ uint64_t time_esterror_nanosec;
+ uint64_t time_maxerror_nanosec;
+};
+
+#endif /* __VMCLOCK_ABI_H__ */
diff --git a/include/standard-headers/misc/pvpanic.h b/include/standard-headers/misc/pvpanic.h
index 54b7485..b115094 100644
--- a/include/standard-headers/misc/pvpanic.h
+++ b/include/standard-headers/misc/pvpanic.h
@@ -3,7 +3,10 @@
#ifndef __PVPANIC_H__
#define __PVPANIC_H__
-#define PVPANIC_PANICKED (1 << 0)
-#define PVPANIC_CRASH_LOADED (1 << 1)
+#include "standard-headers/linux/const.h"
+
+#define PVPANIC_PANICKED _BITUL(0)
+#define PVPANIC_CRASH_LOADED _BITUL(1)
+#define PVPANIC_SHUTDOWN _BITUL(2)
#endif /* __PVPANIC_H__ */
diff --git a/include/standard-headers/uefi/uefi.h b/include/standard-headers/uefi/uefi.h
new file mode 100644
index 0000000..5256349
--- /dev/null
+++ b/include/standard-headers/uefi/uefi.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2025 Intel Corporation
+ *
+ * Author: Isaku Yamahata <isaku.yamahata at gmail.com>
+ * <isaku.yamahata at intel.com>
+ * Xiaoyao Li <xiaoyao.li@intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_I386_UEFI_H
+#define HW_I386_UEFI_H
+
+/***************************************************************************/
+/*
+ * basic EFI definitions
+ * supplemented with UEFI Specification Version 2.8 (Errata A)
+ * released February 2020
+ */
+/* UEFI integer is little endian */
+
+typedef struct {
+ uint32_t Data1;
+ uint16_t Data2;
+ uint16_t Data3;
+ uint8_t Data4[8];
+} EFI_GUID;
+
+typedef enum {
+ EfiReservedMemoryType,
+ EfiLoaderCode,
+ EfiLoaderData,
+ EfiBootServicesCode,
+ EfiBootServicesData,
+ EfiRuntimeServicesCode,
+ EfiRuntimeServicesData,
+ EfiConventionalMemory,
+ EfiUnusableMemory,
+ EfiACPIReclaimMemory,
+ EfiACPIMemoryNVS,
+ EfiMemoryMappedIO,
+ EfiMemoryMappedIOPortSpace,
+ EfiPalCode,
+ EfiPersistentMemory,
+ EfiUnacceptedMemoryType,
+ EfiMaxMemoryType
+} EFI_MEMORY_TYPE;
+
+#define EFI_HOB_HANDOFF_TABLE_VERSION 0x0009
+
+#define EFI_HOB_TYPE_HANDOFF 0x0001
+#define EFI_HOB_TYPE_MEMORY_ALLOCATION 0x0002
+#define EFI_HOB_TYPE_RESOURCE_DESCRIPTOR 0x0003
+#define EFI_HOB_TYPE_GUID_EXTENSION 0x0004
+#define EFI_HOB_TYPE_FV 0x0005
+#define EFI_HOB_TYPE_CPU 0x0006
+#define EFI_HOB_TYPE_MEMORY_POOL 0x0007
+#define EFI_HOB_TYPE_FV2 0x0009
+#define EFI_HOB_TYPE_LOAD_PEIM_UNUSED 0x000A
+#define EFI_HOB_TYPE_UEFI_CAPSULE 0x000B
+#define EFI_HOB_TYPE_FV3 0x000C
+#define EFI_HOB_TYPE_UNUSED 0xFFFE
+#define EFI_HOB_TYPE_END_OF_HOB_LIST 0xFFFF
+
+typedef struct {
+ uint16_t HobType;
+ uint16_t HobLength;
+ uint32_t Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef uint64_t EFI_PHYSICAL_ADDRESS;
+typedef uint32_t EFI_BOOT_MODE;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ uint32_t Version;
+ EFI_BOOT_MODE BootMode;
+ EFI_PHYSICAL_ADDRESS EfiMemoryTop;
+ EFI_PHYSICAL_ADDRESS EfiMemoryBottom;
+ EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop;
+ EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom;
+ EFI_PHYSICAL_ADDRESS EfiEndOfHobList;
+} EFI_HOB_HANDOFF_INFO_TABLE;
+
+#define EFI_RESOURCE_SYSTEM_MEMORY 0x00000000
+#define EFI_RESOURCE_MEMORY_MAPPED_IO 0x00000001
+#define EFI_RESOURCE_IO 0x00000002
+#define EFI_RESOURCE_FIRMWARE_DEVICE 0x00000003
+#define EFI_RESOURCE_MEMORY_MAPPED_IO_PORT 0x00000004
+#define EFI_RESOURCE_MEMORY_RESERVED 0x00000005
+#define EFI_RESOURCE_IO_RESERVED 0x00000006
+#define EFI_RESOURCE_MEMORY_UNACCEPTED 0x00000007
+#define EFI_RESOURCE_MAX_MEMORY_TYPE 0x00000008
+
+#define EFI_RESOURCE_ATTRIBUTE_PRESENT 0x00000001
+#define EFI_RESOURCE_ATTRIBUTE_INITIALIZED 0x00000002
+#define EFI_RESOURCE_ATTRIBUTE_TESTED 0x00000004
+#define EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC 0x00000008
+#define EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC 0x00000010
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 0x00000020
+#define EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 0x00000040
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED 0x00000080
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED 0x00000100
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED 0x00000200
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE 0x00000400
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE 0x00000800
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE 0x00001000
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE 0x00002000
+#define EFI_RESOURCE_ATTRIBUTE_16_BIT_IO 0x00004000
+#define EFI_RESOURCE_ATTRIBUTE_32_BIT_IO 0x00008000
+#define EFI_RESOURCE_ATTRIBUTE_64_BIT_IO 0x00010000
+#define EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED 0x00020000
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED 0x00040000
+#define EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE 0x00080000
+#define EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE 0x00100000
+#define EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE 0x00200000
+#define EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE 0x00400000
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTENT 0x00800000
+#define EFI_RESOURCE_ATTRIBUTE_PERSISTABLE 0x01000000
+#define EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE 0x02000000
+
+typedef uint32_t EFI_RESOURCE_TYPE;
+typedef uint32_t EFI_RESOURCE_ATTRIBUTE_TYPE;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Owner;
+ EFI_RESOURCE_TYPE ResourceType;
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;
+ EFI_PHYSICAL_ADDRESS PhysicalStart;
+ uint64_t ResourceLength;
+} EFI_HOB_RESOURCE_DESCRIPTOR;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Name;
+
+ /* guid specific data follows */
+} EFI_HOB_GUID_TYPE;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+} EFI_HOB_FIRMWARE_VOLUME;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+ EFI_GUID FvName;
+ EFI_GUID FileName;
+} EFI_HOB_FIRMWARE_VOLUME2;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+ uint32_t AuthenticationStatus;
+ bool ExtractedFv;
+ EFI_GUID FvName;
+ EFI_GUID FileName;
+} EFI_HOB_FIRMWARE_VOLUME3;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+ uint8_t SizeOfMemorySpace;
+ uint8_t SizeOfIoSpace;
+ uint8_t Reserved[6];
+} EFI_HOB_CPU;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+} EFI_HOB_MEMORY_POOL;
+
+typedef struct {
+ EFI_HOB_GENERIC_HEADER Header;
+
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ uint64_t Length;
+} EFI_HOB_UEFI_CAPSULE;
+
+#define EFI_HOB_OWNER_ZERO \
+ ((EFI_GUID){ 0x00000000, 0x0000, 0x0000, \
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } })
+
+#endif
diff --git a/include/sysemu/iommufd.h b/include/sysemu/iommufd.h
deleted file mode 100644
index 293bfbe..0000000
--- a/include/sysemu/iommufd.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef SYSEMU_IOMMUFD_H
-#define SYSEMU_IOMMUFD_H
-
-#include "qom/object.h"
-#include "exec/hwaddr.h"
-#include "exec/cpu-common.h"
-
-#define TYPE_IOMMUFD_BACKEND "iommufd"
-OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND)
-
-struct IOMMUFDBackendClass {
- ObjectClass parent_class;
-};
-
-struct IOMMUFDBackend {
- Object parent;
-
- /*< protected >*/
- int fd; /* /dev/iommu file descriptor */
- bool owned; /* is the /dev/iommu opened internally */
- uint32_t users;
-
- /*< public >*/
-};
-
-bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
-void iommufd_backend_disconnect(IOMMUFDBackend *be);
-
-bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
- Error **errp);
-void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id);
-int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
- ram_addr_t size, void *vaddr, bool readonly);
-int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
- hwaddr iova, ram_addr_t size);
-#endif
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
deleted file mode 100644
index b5e3ea1..0000000
--- a/include/sysemu/xen-mapcache.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 Citrix Ltd.
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef XEN_MAPCACHE_H
-#define XEN_MAPCACHE_H
-
-#include "exec/cpu-common.h"
-#include "sysemu/xen.h"
-
-typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
- ram_addr_t size);
-#ifdef CONFIG_XEN_IS_POSSIBLE
-
-void xen_map_cache_init(phys_offset_to_gaddr_t f,
- void *opaque);
-uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
- ram_addr_t ram_addr_offset,
- uint8_t lock, bool dma,
- bool is_write);
-ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
-void xen_invalidate_map_cache_entry(uint8_t *buffer);
-void xen_invalidate_map_cache(void);
-uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
- hwaddr new_phys_addr,
- hwaddr size);
-#else
-
-static inline void xen_map_cache_init(phys_offset_to_gaddr_t f,
- void *opaque)
-{
-}
-
-static inline uint8_t *xen_map_cache(MemoryRegion *mr,
- hwaddr phys_addr,
- hwaddr size,
- ram_addr_t ram_addr_offset,
- uint8_t lock,
- bool dma,
- bool is_write)
-{
- abort();
-}
-
-static inline ram_addr_t xen_ram_addr_from_mapcache(void *ptr)
-{
- abort();
-}
-
-static inline void xen_invalidate_map_cache_entry(uint8_t *buffer)
-{
-}
-
-static inline void xen_invalidate_map_cache(void)
-{
-}
-
-static inline uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
- hwaddr new_phys_addr,
- hwaddr size)
-{
- abort();
-}
-
-#endif
-
-#endif /* XEN_MAPCACHE_H */
diff --git a/include/sysemu/accel-blocker.h b/include/system/accel-blocker.h
index f07f368..e10099d 100644
--- a/include/sysemu/accel-blocker.h
+++ b/include/system/accel-blocker.h
@@ -14,7 +14,7 @@
#ifndef ACCEL_BLOCKER_H
#define ACCEL_BLOCKER_H
-#include "sysemu/cpus.h"
+#include "system/cpus.h"
void accel_blocker_init(void);
diff --git a/include/sysemu/accel-ops.h b/include/system/accel-ops.h
index a088672..4c99d25 100644
--- a/include/sysemu/accel-ops.h
+++ b/include/system/accel-ops.h
@@ -10,14 +10,13 @@
#ifndef ACCEL_OPS_H
#define ACCEL_OPS_H
-#include "exec/cpu-common.h"
+#include "exec/vaddr.h"
#include "qom/object.h"
#define ACCEL_OPS_SUFFIX "-ops"
#define TYPE_ACCEL_OPS "accel" ACCEL_OPS_SUFFIX
#define ACCEL_OPS_NAME(name) (name "-" TYPE_ACCEL_OPS)
-typedef struct AccelOpsClass AccelOpsClass;
DECLARE_CLASS_CHECKERS(AccelOpsClass, ACCEL_OPS, TYPE_ACCEL_OPS)
/**
diff --git a/include/exec/address-spaces.h b/include/system/address-spaces.h
index 0d0aa61..72d17af 100644
--- a/include/exec/address-spaces.h
+++ b/include/system/address-spaces.h
@@ -11,16 +11,14 @@
*
*/
-#ifndef EXEC_ADDRESS_SPACES_H
-#define EXEC_ADDRESS_SPACES_H
+#ifndef SYSTEM_ADDRESS_SPACES_H
+#define SYSTEM_ADDRESS_SPACES_H
/*
* Internal interfaces between memory.c/exec.c/vl.c. Do not #include unless
* you're one of them.
*/
-#ifndef CONFIG_USER_ONLY
-
/* Get the root memory region. This interface should only be used temporarily
* until a proper bus interface is available.
*/
@@ -35,5 +33,3 @@ extern AddressSpace address_space_memory;
extern AddressSpace address_space_io;
#endif
-
-#endif
diff --git a/include/sysemu/arch_init.h b/include/system/arch_init.h
index 8d041aa..51e24c3 100644
--- a/include/sysemu/arch_init.h
+++ b/include/system/arch_init.h
@@ -6,7 +6,6 @@ enum {
QEMU_ARCH_ALL = -1,
QEMU_ARCH_ALPHA = (1 << 0),
QEMU_ARCH_ARM = (1 << 1),
- QEMU_ARCH_CRIS = (1 << 2),
QEMU_ARCH_I386 = (1 << 3),
QEMU_ARCH_M68K = (1 << 4),
QEMU_ARCH_MICROBLAZE = (1 << 6),
@@ -26,8 +25,6 @@ enum {
QEMU_ARCH_LOONGARCH = (1 << 23),
};
-extern const uint32_t arch_type;
-
-void qemu_init_arch_modules(void);
+bool qemu_arch_available(unsigned qemu_arch_mask);
#endif
diff --git a/include/sysemu/balloon.h b/include/system/balloon.h
index 867687b..867687b 100644
--- a/include/sysemu/balloon.h
+++ b/include/system/balloon.h
diff --git a/include/sysemu/block-backend-common.h b/include/system/block-backend-common.h
index 780cea7..780cea7 100644
--- a/include/sysemu/block-backend-common.h
+++ b/include/system/block-backend-common.h
diff --git a/include/sysemu/block-backend-global-state.h b/include/system/block-backend-global-state.h
index 49c12b0f..35b5e83 100644
--- a/include/sysemu/block-backend-global-state.h
+++ b/include/system/block-backend-global-state.h
@@ -54,7 +54,6 @@ bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
void monitor_remove_blk(BlockBackend *blk);
BlockBackendPublic *blk_get_public(BlockBackend *blk);
-BlockBackend *blk_by_public(BlockBackendPublic *public);
void blk_remove_bs(BlockBackend *blk);
int blk_insert_bs(BlockBackend *blk, BlockDriverState *bs, Error **errp);
@@ -67,7 +66,6 @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
void blk_iostatus_enable(BlockBackend *blk);
BlockDeviceIoStatus blk_iostatus(const BlockBackend *blk);
-void blk_iostatus_disable(BlockBackend *blk);
void blk_iostatus_reset(BlockBackend *blk);
int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
void blk_detach_dev(BlockBackend *blk, DeviceState *dev);
@@ -76,8 +74,6 @@ BlockBackend *blk_by_dev(void *dev);
BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
-void blk_activate(BlockBackend *blk, Error **errp);
-
int blk_make_zero(BlockBackend *blk, BdrvRequestFlags flags);
void blk_aio_cancel(BlockAIOCB *acb);
int blk_commit_all(void);
@@ -90,10 +86,6 @@ bool blk_supports_write_perm(BlockBackend *blk);
bool blk_is_sg(BlockBackend *blk);
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
int blk_get_flags(BlockBackend *blk);
-bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp);
-void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason);
-void blk_op_block_all(BlockBackend *blk, Error *reason);
-void blk_op_unblock_all(BlockBackend *blk, Error *reason);
int blk_set_aio_context(BlockBackend *blk, AioContext *new_context,
Error **errp);
void blk_add_aio_context_notifier(BlockBackend *blk,
@@ -105,7 +97,6 @@ void blk_remove_aio_context_notifier(BlockBackend *blk,
void (*detach_aio_context)(void *),
void *opaque);
void blk_add_remove_bs_notifier(BlockBackend *blk, Notifier *notify);
-void blk_add_insert_bs_notifier(BlockBackend *blk, Notifier *notify);
BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
void blk_update_root_state(BlockBackend *blk);
bool blk_get_detect_zeroes_from_root_state(BlockBackend *blk);
diff --git a/include/sysemu/block-backend-io.h b/include/system/block-backend-io.h
index d174275..ba8dfcc 100644
--- a/include/sysemu/block-backend-io.h
+++ b/include/system/block-backend-io.h
@@ -32,6 +32,13 @@ void blk_set_allow_aio_context_change(BlockBackend *blk, bool allow);
void blk_set_disable_request_queuing(BlockBackend *blk, bool disable);
bool blk_iostatus_is_enabled(const BlockBackend *blk);
+/*
+ * Return the qdev ID, or if no ID is assigned the QOM path,
+ * of the block device attached to the BlockBackend.
+ *
+ * The caller is responsible for releasing the value returned
+ * with g_free() after use.
+ */
char *blk_get_attached_dev_id(BlockBackend *blk);
BlockAIOCB *blk_aio_pwrite_zeroes(BlockBackend *blk, int64_t offset,
diff --git a/include/sysemu/block-backend.h b/include/system/block-backend.h
index 038be9f..038be9f 100644
--- a/include/sysemu/block-backend.h
+++ b/include/system/block-backend.h
diff --git a/include/sysemu/block-ram-registrar.h b/include/system/block-ram-registrar.h
index d8b2f79..d8b2f79 100644
--- a/include/sysemu/block-ram-registrar.h
+++ b/include/system/block-ram-registrar.h
diff --git a/include/sysemu/blockdev.h b/include/system/blockdev.h
index 3211b16..3211b16 100644
--- a/include/sysemu/blockdev.h
+++ b/include/system/blockdev.h
diff --git a/include/exec/confidential-guest-support.h b/include/system/confidential-guest-support.h
index 02dc4e5..ea46b50 100644
--- a/include/exec/confidential-guest-support.h
+++ b/include/system/confidential-guest-support.h
@@ -18,8 +18,6 @@
#ifndef QEMU_CONFIDENTIAL_GUEST_SUPPORT_H
#define QEMU_CONFIDENTIAL_GUEST_SUPPORT_H
-#ifndef CONFIG_USER_ONLY
-
#include "qom/object.h"
#define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
@@ -94,6 +92,4 @@ static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs,
return 0;
}
-#endif /* !CONFIG_USER_ONLY */
-
#endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */
diff --git a/include/sysemu/cpu-throttle.h b/include/system/cpu-throttle.h
index d65bdef..44bf6a5 100644
--- a/include/sysemu/cpu-throttle.h
+++ b/include/system/cpu-throttle.h
@@ -16,8 +16,8 @@
* <http://www.gnu.org/licenses/gpl-2.0.html>
*/
-#ifndef SYSEMU_CPU_THROTTLE_H
-#define SYSEMU_CPU_THROTTLE_H
+#ifndef SYSTEM_CPU_THROTTLE_H
+#define SYSTEM_CPU_THROTTLE_H
#include "qemu/timer.h"
@@ -65,4 +65,18 @@ bool cpu_throttle_active(void);
*/
int cpu_throttle_get_percentage(void);
-#endif /* SYSEMU_CPU_THROTTLE_H */
+/**
+ * cpu_throttle_dirty_sync_timer_tick:
+ *
+ * Dirty sync timer hook.
+ */
+void cpu_throttle_dirty_sync_timer_tick(void *opaque);
+
+/**
+ * cpu_throttle_dirty_sync_timer:
+ *
+ * Start or stop the dirty sync timer.
+ */
+void cpu_throttle_dirty_sync_timer(bool enable);
+
+#endif /* SYSTEM_CPU_THROTTLE_H */
diff --git a/include/sysemu/cpu-timers-internal.h b/include/system/cpu-timers-internal.h
index 94bb739..94bb739 100644
--- a/include/sysemu/cpu-timers-internal.h
+++ b/include/system/cpu-timers-internal.h
diff --git a/include/system/cpu-timers.h b/include/system/cpu-timers.h
new file mode 100644
index 0000000..a1abed0
--- /dev/null
+++ b/include/system/cpu-timers.h
@@ -0,0 +1,46 @@
+/*
+ * CPU timers state API
+ *
+ * Copyright 2020 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 SYSTEM_CPU_TIMERS_H
+#define SYSTEM_CPU_TIMERS_H
+
+#include "qemu/timer.h"
+
+/* init the whole cpu timers API, including icount, ticks, and cpu_throttle */
+void cpu_timers_init(void);
+
+/*
+ * CPU Ticks and Clock
+ */
+
+/* Caller must hold BQL */
+void cpu_enable_ticks(void);
+/* Caller must hold BQL */
+void cpu_disable_ticks(void);
+
+/*
+ * return the time elapsed in VM between vm_start and vm_stop.
+ * cpu_get_ticks() uses units of the host CPU cycle counter.
+ */
+int64_t cpu_get_ticks(void);
+
+/*
+ * Returns the monotonic time elapsed in VM, i.e.,
+ * the time between vm_start and vm_stop
+ */
+int64_t cpu_get_clock(void);
+
+void qemu_timer_notify_cb(void *opaque, QEMUClockType type);
+
+/* get/set VIRTUAL clock and VM elapsed ticks via the cpus accel interface */
+int64_t cpus_get_virtual_clock(void);
+void cpus_set_virtual_clock(int64_t new_time);
+int64_t cpus_get_elapsed_ticks(void);
+
+#endif /* SYSTEM_CPU_TIMERS_H */
diff --git a/include/sysemu/cpus.h b/include/system/cpus.h
index b4a566c..3226c76 100644
--- a/include/sysemu/cpus.h
+++ b/include/system/cpus.h
@@ -1,8 +1,6 @@
#ifndef QEMU_CPUS_H
#define QEMU_CPUS_H
-#include "sysemu/accel-ops.h"
-
/* register accel-specific operations */
void cpus_register_accel(const AccelOpsClass *i);
@@ -38,8 +36,6 @@ void resume_all_vcpus(void);
void pause_all_vcpus(void);
void cpu_stop_current(void);
-extern int icount_align_option;
-
/* Unblock cpu */
void qemu_cpu_kick_self(void);
diff --git a/include/sysemu/cryptodev-vhost-user.h b/include/system/cryptodev-vhost-user.h
index 6071050..5138c14 100644
--- a/include/sysemu/cryptodev-vhost-user.h
+++ b/include/system/cryptodev-vhost-user.h
@@ -24,7 +24,7 @@
#ifndef CRYPTODEV_VHOST_USER_H
#define CRYPTODEV_VHOST_USER_H
-#include "sysemu/cryptodev-vhost.h"
+#include "system/cryptodev-vhost.h"
#define VHOST_USER_MAX_AUTH_KEY_LEN 512
#define VHOST_USER_MAX_CIPHER_KEY_LEN 64
diff --git a/include/sysemu/cryptodev-vhost.h b/include/system/cryptodev-vhost.h
index 4c3c22a..b0bb09e 100644
--- a/include/sysemu/cryptodev-vhost.h
+++ b/include/system/cryptodev-vhost.h
@@ -28,7 +28,7 @@
#include "hw/virtio/vhost-backend.h"
#include "chardev/char.h"
-#include "sysemu/cryptodev.h"
+#include "system/cryptodev.h"
typedef struct CryptoDevBackendVhostOptions {
diff --git a/include/sysemu/cryptodev.h b/include/system/cryptodev.h
index 96d3998..b20822d 100644
--- a/include/sysemu/cryptodev.h
+++ b/include/system/cryptodev.h
@@ -178,7 +178,7 @@ typedef struct CryptoDevBackendAsymOpInfo {
typedef void (*CryptoDevCompletionFunc) (void *opaque, int ret);
typedef struct CryptoDevBackendOpInfo {
- QCryptodevBackendAlgType algtype;
+ QCryptodevBackendAlgoType algtype;
uint32_t op_code;
uint32_t queue_index;
CryptoDevCompletionFunc cb;
diff --git a/include/sysemu/device_tree.h b/include/system/device_tree.h
index eb60152..49d8482 100644
--- a/include/sysemu/device_tree.h
+++ b/include/system/device_tree.h
@@ -133,8 +133,6 @@ int qemu_fdt_add_path(void *fdt, const char *path);
sizeof(qdt_tmp)); \
} while (0)
-void qemu_fdt_dumpdtb(void *fdt, int size);
-
/**
* qemu_fdt_setprop_sized_cells_from_array:
* @fdt: device tree blob
diff --git a/include/sysemu/dirtylimit.h b/include/system/dirtylimit.h
index d11ebbb..d11ebbb 100644
--- a/include/sysemu/dirtylimit.h
+++ b/include/system/dirtylimit.h
diff --git a/include/sysemu/dirtyrate.h b/include/system/dirtyrate.h
index 20813f3..20813f3 100644
--- a/include/sysemu/dirtyrate.h
+++ b/include/system/dirtyrate.h
diff --git a/include/sysemu/dma.h b/include/system/dma.h
index a1ac5bc..82e7ad5 100644
--- a/include/sysemu/dma.h
+++ b/include/system/dma.h
@@ -10,8 +10,8 @@
#ifndef DMA_H
#define DMA_H
-#include "exec/memory.h"
-#include "exec/address-spaces.h"
+#include "system/memory.h"
+#include "system/address-spaces.h"
#include "block/block.h"
#include "block/accounting.h"
@@ -152,7 +152,7 @@ static inline MemTxResult dma_memory_read(AddressSpace *as, dma_addr_t addr,
}
/**
- * address_space_write: Write to address space from DMA controller.
+ * dma_memory_write: Write to address space from DMA controller.
*
* Return a MemTxResult indicating whether the operation succeeded
* or failed (eg unassigned memory, device rejected the transaction,
@@ -189,7 +189,7 @@ MemTxResult dma_memory_set(AddressSpace *as, dma_addr_t addr,
uint8_t c, dma_addr_t len, MemTxAttrs attrs);
/**
- * address_space_map: Map a physical memory region into a host virtual address.
+ * dma_memory_map: Map a physical memory region into a host virtual address.
*
* May map a subset of the requested range, given by and returned in @plen.
* May return %NULL and set *@plen to zero(0), if resources needed to perform
@@ -216,16 +216,15 @@ static inline void *dma_memory_map(AddressSpace *as,
}
/**
- * address_space_unmap: Unmaps a memory region previously mapped
- * by dma_memory_map()
+ * dma_memory_unmap: Unmaps a memory region previously mapped by dma_memory_map()
*
* Will also mark the memory as dirty if @dir == %DMA_DIRECTION_FROM_DEVICE.
* @access_len gives the amount of memory that was actually read or written
* by the caller.
*
* @as: #AddressSpace used
- * @buffer: host pointer as returned by address_space_map()
- * @len: buffer length as returned by address_space_map()
+ * @buffer: host pointer as returned by dma_memory_map()
+ * @len: buffer length as returned by dma_memory_map()
* @dir: indicates the transfer direction
* @access_len: amount of data actually transferred
*/
@@ -291,8 +290,7 @@ typedef BlockAIOCB *DMAIOFunc(int64_t offset, QEMUIOVector *iov,
BlockCompletionFunc *cb, void *cb_opaque,
void *opaque);
-BlockAIOCB *dma_blk_io(AioContext *ctx,
- QEMUSGList *sg, uint64_t offset, uint32_t align,
+BlockAIOCB *dma_blk_io(QEMUSGList *sg, uint64_t offset, uint32_t align,
DMAIOFunc *io_func, void *io_func_opaque,
BlockCompletionFunc *cb, void *opaque, DMADirection dir);
BlockAIOCB *dma_blk_read(BlockBackend *blk,
diff --git a/include/sysemu/dump-arch.h b/include/system/dump-arch.h
index 743916e..743916e 100644
--- a/include/sysemu/dump-arch.h
+++ b/include/system/dump-arch.h
diff --git a/include/sysemu/dump.h b/include/system/dump.h
index d702854..607bd7b 100644
--- a/include/sysemu/dump.h
+++ b/include/system/dump.h
@@ -39,8 +39,8 @@
#define DUMP_LEVEL (1)
#define DISKDUMP_HEADER_BLOCKS (1)
-#include "sysemu/dump-arch.h"
-#include "sysemu/memory_mapping.h"
+#include "system/dump-arch.h"
+#include "system/memory_mapping.h"
typedef struct QEMU_PACKED MakedumpfileHeader {
char signature[16]; /* = "makedumpfile" */
diff --git a/include/sysemu/event-loop-base.h b/include/system/event-loop-base.h
index a6c24f1..a6c24f1 100644
--- a/include/sysemu/event-loop-base.h
+++ b/include/system/event-loop-base.h
diff --git a/include/system/host_iommu_device.h b/include/system/host_iommu_device.h
new file mode 100644
index 0000000..ab849a4
--- /dev/null
+++ b/include/system/host_iommu_device.h
@@ -0,0 +1,125 @@
+/*
+ * Host IOMMU device abstract declaration
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ *
+ * Authors: Zhenzhong Duan <zhenzhong.duan@intel.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef HOST_IOMMU_DEVICE_H
+#define HOST_IOMMU_DEVICE_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#ifdef CONFIG_LINUX
+#include "linux/iommufd.h"
+
+typedef union VendorCaps {
+ struct iommu_hw_info_vtd vtd;
+ struct iommu_hw_info_arm_smmuv3 smmuv3;
+} VendorCaps;
+
+/**
+ * struct HostIOMMUDeviceCaps - Define host IOMMU device capabilities.
+ *
+ * @type: host platform IOMMU type.
+ *
+ * @hw_caps: host platform IOMMU capabilities (e.g. on IOMMUFD this represents
+ * the @out_capabilities value returned from IOMMU_GET_HW_INFO ioctl)
+ *
+ * @vendor_caps: host platform IOMMU vendor specific capabilities (e.g. on
+ * IOMMUFD this represents a user-space buffer filled by kernel
+ * with host IOMMU @type specific hardware information data)
+ */
+typedef struct HostIOMMUDeviceCaps {
+ uint32_t type;
+ uint64_t hw_caps;
+ VendorCaps vendor_caps;
+} HostIOMMUDeviceCaps;
+#endif
+
+#define TYPE_HOST_IOMMU_DEVICE "host-iommu-device"
+OBJECT_DECLARE_TYPE(HostIOMMUDevice, HostIOMMUDeviceClass, HOST_IOMMU_DEVICE)
+
+struct HostIOMMUDevice {
+ Object parent_obj;
+
+ char *name;
+ void *agent; /* pointer to agent device, ie. VFIO or VDPA device */
+ PCIBus *aliased_bus;
+ int aliased_devfn;
+#ifdef CONFIG_LINUX
+ HostIOMMUDeviceCaps caps;
+#endif
+};
+
+/**
+ * struct HostIOMMUDeviceClass - The base class for all host IOMMU devices.
+ *
+ * Different types of host devices (e.g., VFIO or VDPA device) or devices
+ * with different backend (e.g., VFIO legacy container or IOMMUFD backend)
+ * will have different implementations of the HostIOMMUDeviceClass.
+ */
+struct HostIOMMUDeviceClass {
+ ObjectClass parent_class;
+
+ /**
+ * @realize: initialize host IOMMU device instance further.
+ *
+ * Mandatory callback.
+ *
+ * @hiod: pointer to a host IOMMU device instance.
+ *
+ * @opaque: pointer to agent device of this host IOMMU device,
+ * e.g., VFIO base device or VDPA device.
+ *
+ * @errp: pass an Error out when realize fails.
+ *
+ * Returns: true on success, false on failure.
+ */
+ bool (*realize)(HostIOMMUDevice *hiod, void *opaque, Error **errp);
+ /**
+ * @get_cap: check if a host IOMMU device capability is supported.
+ *
+ * Optional callback, if not implemented, hint not supporting query
+ * of @cap.
+ *
+ * @hiod: pointer to a host IOMMU device instance.
+ *
+ * @cap: capability to check.
+ *
+ * @errp: pass an Error out when fails to query capability.
+ *
+ * Returns: <0 on failure, 0 if a @cap is unsupported, or else
+ * 1 or some positive value for some special @cap,
+ * i.e., HOST_IOMMU_DEVICE_CAP_AW_BITS.
+ */
+ int (*get_cap)(HostIOMMUDevice *hiod, int cap, Error **errp);
+ /**
+ * @get_iova_ranges: Return the list of usable iova_ranges along with
+ * @hiod Host IOMMU device
+ *
+ * @hiod: handle to the host IOMMU device
+ */
+ GList* (*get_iova_ranges)(HostIOMMUDevice *hiod);
+ /**
+ *
+ * @get_page_size_mask: Return the page size mask supported along this
+ * @hiod Host IOMMU device
+ *
+ * @hiod: handle to the host IOMMU device
+ */
+ uint64_t (*get_page_size_mask)(HostIOMMUDevice *hiod);
+};
+
+/*
+ * Host IOMMU device capability list.
+ */
+#define HOST_IOMMU_DEVICE_CAP_IOMMU_TYPE 0
+#define HOST_IOMMU_DEVICE_CAP_AW_BITS 1
+
+#define HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX 64
+#endif
diff --git a/include/sysemu/hostmem.h b/include/system/hostmem.h
index de47ae5..88fa791 100644
--- a/include/sysemu/hostmem.h
+++ b/include/system/hostmem.h
@@ -10,13 +10,13 @@
* See the COPYING file in the top-level directory.
*/
-#ifndef SYSEMU_HOSTMEM_H
-#define SYSEMU_HOSTMEM_H
+#ifndef SYSTEM_HOSTMEM_H
+#define SYSTEM_HOSTMEM_H
-#include "sysemu/numa.h"
+#include "system/numa.h"
#include "qapi/qapi-types-machine.h"
#include "qom/object.h"
-#include "exec/memory.h"
+#include "system/memory.h"
#include "qemu/bitmap.h"
#include "qemu/thread-context.h"
@@ -39,6 +39,8 @@ OBJECT_DECLARE_TYPE(HostMemoryBackend, HostMemoryBackendClass,
*/
#define TYPE_MEMORY_BACKEND_FILE "memory-backend-file"
+#define TYPE_MEMORY_BACKEND_MEMFD "memory-backend-memfd"
+
/**
* HostMemoryBackendClass:
@@ -91,4 +93,7 @@ bool host_memory_backend_is_mapped(HostMemoryBackend *backend);
size_t host_memory_backend_pagesize(HostMemoryBackend *memdev);
char *host_memory_backend_get_name(HostMemoryBackend *backend);
+long qemu_minrampagesize(void);
+long qemu_maxrampagesize(void);
+
#endif
diff --git a/include/sysemu/hvf.h b/include/system/hvf.h
index 730f927..a9a502f 100644
--- a/include/sysemu/hvf.h
+++ b/include/system/hvf.h
@@ -14,19 +14,25 @@
#define HVF_H
#include "qemu/accel.h"
+#include "qemu/queue.h"
+#include "exec/vaddr.h"
#include "qom/object.h"
+#include "exec/vaddr.h"
#ifdef COMPILING_PER_TARGET
-#include "cpu.h"
+# ifdef CONFIG_HVF
+# define CONFIG_HVF_IS_POSSIBLE
+# endif /* !CONFIG_HVF */
+#else
+# define CONFIG_HVF_IS_POSSIBLE
+#endif /* COMPILING_PER_TARGET */
-#ifdef CONFIG_HVF
+#ifdef CONFIG_HVF_IS_POSSIBLE
extern bool hvf_allowed;
#define hvf_enabled() (hvf_allowed)
-#else /* !CONFIG_HVF */
+#else /* !CONFIG_HVF_IS_POSSIBLE */
#define hvf_enabled() 0
-#endif /* !CONFIG_HVF */
-
-#endif /* COMPILING_PER_TARGET */
+#endif /* !CONFIG_HVF_IS_POSSIBLE */
#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
diff --git a/include/sysemu/hvf_int.h b/include/system/hvf_int.h
index 5b28d17..d774e58 100644
--- a/include/sysemu/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -11,6 +11,8 @@
#ifndef HVF_INT_H
#define HVF_INT_H
+#include "qemu/queue.h"
+
#ifdef __aarch64__
#include <Hypervisor/Hypervisor.h>
typedef hv_vcpu_t hvf_vcpuid;
@@ -42,6 +44,7 @@ typedef struct hvf_vcpu_caps {
struct HVFState {
AccelState parent;
+
hvf_slot slots[32];
int num_slots;
@@ -65,6 +68,7 @@ void assert_hvf_ok_impl(hv_return_t ret, const char *file, unsigned int line,
#define assert_hvf_ok(EX) assert_hvf_ok_impl((EX), __FILE__, __LINE__, #EX)
const char *hvf_return_string(hv_return_t ret);
int hvf_arch_init(void);
+hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range);
int hvf_arch_init_vcpu(CPUState *cpu);
void hvf_arch_vcpu_destroy(CPUState *cpu);
int hvf_vcpu_exec(CPUState *);
diff --git a/include/sysemu/hw_accel.h b/include/system/hw_accel.h
index c71b77e..380e9e6 100644
--- a/include/sysemu/hw_accel.h
+++ b/include/system/hw_accel.h
@@ -12,10 +12,10 @@
#define QEMU_HW_ACCEL_H
#include "hw/core/cpu.h"
-#include "sysemu/kvm.h"
-#include "sysemu/hvf.h"
-#include "sysemu/whpx.h"
-#include "sysemu/nvmm.h"
+#include "system/kvm.h"
+#include "system/hvf.h"
+#include "system/whpx.h"
+#include "system/nvmm.h"
void cpu_synchronize_state(CPUState *cpu);
void cpu_synchronize_post_reset(CPUState *cpu);
diff --git a/include/system/iommufd.h b/include/system/iommufd.h
new file mode 100644
index 0000000..283861b
--- /dev/null
+++ b/include/system/iommufd.h
@@ -0,0 +1,120 @@
+/*
+ * iommufd container backend declaration
+ *
+ * Copyright (C) 2024 Intel Corporation.
+ * Copyright Red Hat, Inc. 2024
+ *
+ * Authors: Yi Liu <yi.l.liu@intel.com>
+ * Eric Auger <eric.auger@redhat.com>
+ * Zhenzhong Duan <zhenzhong.duan@intel.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef SYSTEM_IOMMUFD_H
+#define SYSTEM_IOMMUFD_H
+
+#include "qom/object.h"
+#include "exec/hwaddr.h"
+#include "exec/cpu-common.h"
+#include "system/host_iommu_device.h"
+
+#define TYPE_IOMMUFD_BACKEND "iommufd"
+OBJECT_DECLARE_TYPE(IOMMUFDBackend, IOMMUFDBackendClass, IOMMUFD_BACKEND)
+
+struct IOMMUFDBackendClass {
+ ObjectClass parent_class;
+};
+
+struct IOMMUFDBackend {
+ Object parent;
+
+ /*< protected >*/
+ int fd; /* /dev/iommu file descriptor */
+ bool owned; /* is the /dev/iommu opened internally */
+ uint32_t users;
+
+ /*< public >*/
+};
+
+bool iommufd_backend_connect(IOMMUFDBackend *be, Error **errp);
+void iommufd_backend_disconnect(IOMMUFDBackend *be);
+
+bool iommufd_backend_alloc_ioas(IOMMUFDBackend *be, uint32_t *ioas_id,
+ Error **errp);
+void iommufd_backend_free_id(IOMMUFDBackend *be, uint32_t id);
+int iommufd_backend_map_dma(IOMMUFDBackend *be, uint32_t ioas_id, hwaddr iova,
+ ram_addr_t size, void *vaddr, bool readonly);
+int iommufd_backend_unmap_dma(IOMMUFDBackend *be, uint32_t ioas_id,
+ hwaddr iova, ram_addr_t size);
+bool iommufd_backend_get_device_info(IOMMUFDBackend *be, uint32_t devid,
+ uint32_t *type, void *data, uint32_t len,
+ uint64_t *caps, Error **errp);
+bool iommufd_backend_alloc_hwpt(IOMMUFDBackend *be, uint32_t dev_id,
+ uint32_t pt_id, uint32_t flags,
+ uint32_t data_type, uint32_t data_len,
+ void *data_ptr, uint32_t *out_hwpt,
+ Error **errp);
+bool iommufd_backend_set_dirty_tracking(IOMMUFDBackend *be, uint32_t hwpt_id,
+ bool start, Error **errp);
+bool iommufd_backend_get_dirty_bitmap(IOMMUFDBackend *be, uint32_t hwpt_id,
+ uint64_t iova, ram_addr_t size,
+ uint64_t page_size, uint64_t *data,
+ Error **errp);
+bool iommufd_backend_invalidate_cache(IOMMUFDBackend *be, uint32_t id,
+ uint32_t data_type, uint32_t entry_len,
+ uint32_t *entry_num, void *data,
+ Error **errp);
+
+#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD TYPE_HOST_IOMMU_DEVICE "-iommufd"
+OBJECT_DECLARE_TYPE(HostIOMMUDeviceIOMMUFD, HostIOMMUDeviceIOMMUFDClass,
+ HOST_IOMMU_DEVICE_IOMMUFD)
+
+/* Overload of the host IOMMU device for the iommufd backend */
+struct HostIOMMUDeviceIOMMUFD {
+ HostIOMMUDevice parent_obj;
+
+ IOMMUFDBackend *iommufd;
+ uint32_t devid;
+ uint32_t hwpt_id;
+};
+
+struct HostIOMMUDeviceIOMMUFDClass {
+ HostIOMMUDeviceClass parent_class;
+
+ /**
+ * @attach_hwpt: attach host IOMMU device to IOMMUFD hardware page table.
+ * VFIO and VDPA device can have different implementation.
+ *
+ * Mandatory callback.
+ *
+ * @idev: host IOMMU device backed by IOMMUFD backend.
+ *
+ * @hwpt_id: ID of IOMMUFD hardware page table.
+ *
+ * @errp: pass an Error out when attachment fails.
+ *
+ * Returns: true on success, false on failure.
+ */
+ bool (*attach_hwpt)(HostIOMMUDeviceIOMMUFD *idev, uint32_t hwpt_id,
+ Error **errp);
+ /**
+ * @detach_hwpt: detach host IOMMU device from IOMMUFD hardware page table.
+ * VFIO and VDPA device can have different implementation.
+ *
+ * Mandatory callback.
+ *
+ * @idev: host IOMMU device backed by IOMMUFD backend.
+ *
+ * @errp: pass an Error out when attachment fails.
+ *
+ * Returns: true on success, false on failure.
+ */
+ bool (*detach_hwpt)(HostIOMMUDeviceIOMMUFD *idev, Error **errp);
+};
+
+bool host_iommu_device_iommufd_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
+ uint32_t hwpt_id, Error **errp);
+bool host_iommu_device_iommufd_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev,
+ Error **errp);
+#endif
diff --git a/include/exec/ioport.h b/include/system/ioport.h
index 4397f12..780ea5a 100644
--- a/include/exec/ioport.h
+++ b/include/system/ioport.h
@@ -21,10 +21,10 @@
* IO ports API
*/
-#ifndef IOPORT_H
-#define IOPORT_H
+#ifndef SYSTEM_IOPORT_H
+#define SYSTEM_IOPORT_H
-#include "exec/memory.h"
+#include "system/memory.h"
#define MAX_IOPORTS (64 * 1024)
#define IOPORTS_MASK (MAX_IOPORTS - 1)
@@ -39,9 +39,7 @@ typedef struct MemoryRegionPortio {
#define PORTIO_END_OF_LIST() { }
-#ifndef CONFIG_USER_ONLY
extern const MemoryRegionOps unassigned_io_ops;
-#endif
void cpu_outb(uint32_t addr, uint8_t val);
void cpu_outw(uint32_t addr, uint16_t val);
diff --git a/include/sysemu/iothread.h b/include/system/iothread.h
index 2102a90..d95c17a 100644
--- a/include/sysemu/iothread.h
+++ b/include/system/iothread.h
@@ -17,7 +17,7 @@
#include "block/aio.h"
#include "qemu/thread.h"
#include "qom/object.h"
-#include "sysemu/event-loop-base.h"
+#include "system/event-loop-base.h"
#define TYPE_IOTHREAD "iothread"
diff --git a/include/sysemu/kvm.h b/include/system/kvm.h
index c31d9c7..7cc60d2 100644
--- a/include/sysemu/kvm.h
+++ b/include/system/kvm.h
@@ -42,6 +42,7 @@ extern bool kvm_gsi_routing_allowed;
extern bool kvm_gsi_direct_mapping;
extern bool kvm_readonly_mem_allowed;
extern bool kvm_msi_use_devid;
+extern bool kvm_pre_fault_memory_supported;
#define kvm_enabled() (kvm_allowed)
/**
@@ -210,11 +211,15 @@ bool kvm_arm_supports_user_irq(void);
int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
int kvm_on_sigbus(int code, void *addr);
-#ifdef COMPILING_PER_TARGET
-#include "cpu.h"
+int kvm_check_extension(KVMState *s, unsigned int extension);
+
+int kvm_vm_ioctl(KVMState *s, unsigned long type, ...);
void kvm_flush_coalesced_mmio_buffer(void);
+#ifdef COMPILING_PER_TARGET
+#include "cpu.h"
+
/**
* kvm_update_guest_debug(): ensure KVM debug structures updated
* @cs: the CPUState for this cpu
@@ -235,11 +240,9 @@ static inline int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_t
/* internal API */
-int kvm_ioctl(KVMState *s, int type, ...);
-
-int kvm_vm_ioctl(KVMState *s, int type, ...);
+int kvm_ioctl(KVMState *s, unsigned long type, ...);
-int kvm_vcpu_ioctl(CPUState *cpu, int type, ...);
+int kvm_vcpu_ioctl(CPUState *cpu, unsigned long type, ...);
/**
* kvm_device_ioctl - call an ioctl on a kvm device
@@ -248,7 +251,7 @@ int kvm_vcpu_ioctl(CPUState *cpu, int type, ...);
*
* Returns: -errno on error, nonnegative on success
*/
-int kvm_device_ioctl(int fd, int type, ...);
+int kvm_device_ioctl(int fd, unsigned long type, ...);
/**
* kvm_vm_check_attr - check for existence of a specific vm attribute
@@ -313,6 +316,39 @@ int kvm_create_device(KVMState *s, uint64_t type, bool test);
*/
bool kvm_device_supported(int vmfd, uint64_t type);
+/**
+ * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be fetched/created.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_vcpu(CPUState *cpu);
+
+/**
+ * kvm_park_vcpu - Park QEMU KVM vCPU context
+ * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to be parked.
+ *
+ * @returns: none
+ */
+void kvm_park_vcpu(CPUState *cpu);
+
+/**
+ * kvm_unpark_vcpu - unpark QEMU KVM vCPU context
+ * @s: KVM State
+ * @vcpu_id: Architecture vCPU ID of the parked vCPU
+ *
+ * @returns: KVM fd
+ */
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
+
+/**
+ * kvm_create_and_park_vcpu - Create and park a KVM vCPU
+ * @cpu: QOM CPUState object for which KVM vCPU has to be created and parked.
+ *
+ * @returns: 0 when success, errno (<0) when failed.
+ */
+int kvm_create_and_park_vcpu(CPUState *cpu);
+
/* Arch specific hooks */
extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
@@ -326,7 +362,7 @@ int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run);
int kvm_arch_process_async_events(CPUState *cpu);
-int kvm_arch_get_registers(CPUState *cpu);
+int kvm_arch_get_registers(CPUState *cpu, Error **errp);
/* state subset only touched by the VCPU itself during runtime */
#define KVM_PUT_RUNTIME_STATE 1
@@ -335,23 +371,30 @@ int kvm_arch_get_registers(CPUState *cpu);
/* full state set, modified during initialization or on vmload */
#define KVM_PUT_FULL_STATE 3
-int kvm_arch_put_registers(CPUState *cpu, int level);
+int kvm_arch_put_registers(CPUState *cpu, int level, Error **errp);
int kvm_arch_get_default_type(MachineState *ms);
int kvm_arch_init(MachineState *ms, KVMState *s);
+int kvm_arch_pre_create_vcpu(CPUState *cpu, Error **errp);
int kvm_arch_init_vcpu(CPUState *cpu);
int kvm_arch_destroy_vcpu(CPUState *cpu);
+#ifdef TARGET_KVM_HAVE_RESET_PARKED_VCPU
+void kvm_arch_reset_parked_vcpu(unsigned long vcpu_id, int kvm_fd);
+#else
+static inline void kvm_arch_reset_parked_vcpu(unsigned long vcpu_id, int kvm_fd)
+{
+}
+#endif
+
bool kvm_vcpu_id_is_valid(int vcpu_id);
/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
unsigned long kvm_arch_vcpu_id(CPUState *cpu);
-#ifdef KVM_HAVE_MCE_INJECTION
void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
-#endif
void kvm_arch_init_irq_routing(KVMState *s);
@@ -402,8 +445,6 @@ void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg);
bool kvm_arch_stop_on_emulation_error(CPUState *cpu);
-int kvm_check_extension(KVMState *s, unsigned int extension);
-
int kvm_vm_check_extension(KVMState *s, unsigned int extension);
#define kvm_vm_enable_cap(s, capability, cap_flags, ...) \
diff --git a/include/sysemu/kvm_int.h b/include/system/kvm_int.h
index 3f3d13f..756a3c0 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/system/kvm_int.h
@@ -9,11 +9,14 @@
#ifndef QEMU_KVM_INT_H
#define QEMU_KVM_INT_H
-#include "exec/memory.h"
+#include "system/memory.h"
#include "qapi/qapi-types-common.h"
#include "qemu/accel.h"
#include "qemu/queue.h"
-#include "sysemu/kvm.h"
+#include "system/kvm.h"
+#include "hw/boards.h"
+#include "hw/i386/topology.h"
+#include "io/channel-socket.h"
typedef struct KVMSlot
{
@@ -42,7 +45,8 @@ typedef struct KVMMemoryUpdate {
typedef struct KVMMemoryListener {
MemoryListener listener;
KVMSlot *slots;
- unsigned int nr_used_slots;
+ unsigned int nr_slots_used;
+ unsigned int nr_slots_allocated;
int as_id;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_add;
QSIMPLEQ_HEAD(, KVMMemoryUpdate) transaction_del;
@@ -50,6 +54,34 @@ typedef struct KVMMemoryListener {
#define KVM_MSI_HASHTAB_SIZE 256
+typedef struct KVMHostTopoInfo {
+ /* Number of package on the Host */
+ unsigned int maxpkgs;
+ /* Number of cpus on the Host */
+ unsigned int maxcpus;
+ /* Number of cpus on each different package */
+ unsigned int *pkg_cpu_count;
+ /* Each package can have different maxticks */
+ unsigned int *maxticks;
+} KVMHostTopoInfo;
+
+struct KVMMsrEnergy {
+ pid_t pid;
+ bool enable;
+ char *socket_path;
+ QIOChannelSocket *sioc;
+ QemuThread msr_thr;
+ unsigned int guest_vcpus;
+ unsigned int guest_vsockets;
+ X86CPUTopoInfo guest_topo_info;
+ KVMHostTopoInfo host_topo;
+ const CPUArchIdList *guest_cpu_list;
+ uint64_t *msr_value;
+ uint64_t msr_unit;
+ uint64_t msr_limit;
+ uint64_t msr_info;
+};
+
enum KVMDirtyRingReaperState {
KVM_DIRTY_RING_REAPER_NONE = 0,
/* The reaper is sleeping */
@@ -71,8 +103,8 @@ struct KVMDirtyRingReaper {
struct KVMState
{
AccelState parent_obj;
-
- int nr_slots;
+ /* Max number of KVM slots supported */
+ int nr_slots_max;
int fd;
int vmfd;
int coalesced_mmio;
@@ -91,10 +123,19 @@ struct KVMState
bool sync_mmu;
bool guest_state_protected;
uint64_t manual_dirty_log_protect;
- /* The man page (and posix) say ioctl numbers are signed int, but
- * they're not. Linux, glibc and *BSD all treat ioctl numbers as
- * unsigned, and treating them as signed here can break things */
- unsigned irq_set_ioctl;
+ /*
+ * Older POSIX says that ioctl numbers are signed int, but in
+ * practice they are not. (Newer POSIX doesn't specify ioctl
+ * at all.) Linux, glibc and *BSD all treat ioctl numbers as
+ * unsigned, and real-world ioctl values like KVM_GET_XSAVE have
+ * bit 31 set, which means that passing them via an 'int' will
+ * result in sign-extension when they get converted back to the
+ * 'unsigned long' which the ioctl() prototype uses. Luckily Linux
+ * always treats the argument as an unsigned 32-bit int, so any
+ * possible sign-extension is deliberately ignored, but for
+ * consistency we keep to the same type that glibc is using.
+ */
+ unsigned long irq_set_ioctl;
unsigned int sigmask_len;
GHashTable *gsimap;
#ifdef KVM_CAP_IRQ_ROUTING
@@ -117,6 +158,7 @@ struct KVMState
bool kvm_dirty_ring_with_bitmap;
uint64_t kvm_eager_split_size; /* Eager Page Splitting chunk size */
struct KVMDirtyRingReaper reaper;
+ struct KVMMsrEnergy msr_energy;
NotifyVmexitOption notify_vmexit;
uint32_t notify_window;
uint32_t xen_version;
diff --git a/include/sysemu/kvm_xen.h b/include/system/kvm_xen.h
index 961c702..7d0e69f 100644
--- a/include/sysemu/kvm_xen.h
+++ b/include/system/kvm_xen.h
@@ -9,8 +9,8 @@
*
*/
-#ifndef QEMU_SYSEMU_KVM_XEN_H
-#define QEMU_SYSEMU_KVM_XEN_H
+#ifndef QEMU_SYSTEM_KVM_XEN_H
+#define QEMU_SYSTEM_KVM_XEN_H
/* The KVM API uses these to indicate "no GPA" or "no GFN" */
#define INVALID_GPA UINT64_MAX
@@ -41,4 +41,4 @@ uint16_t kvm_xen_get_evtchn_max_pirq(void);
#define XEN_SPECIAL_PFN(x) ((XEN_SPECIAL_AREA_ADDR >> TARGET_PAGE_BITS) + \
XEN_SPECIALPAGE_##x)
-#endif /* QEMU_SYSEMU_KVM_XEN_H */
+#endif /* QEMU_SYSTEM_KVM_XEN_H */
diff --git a/include/exec/memory.h b/include/system/memory.h
index 2d7c278..46248d4 100644
--- a/include/exec/memory.h
+++ b/include/system/memory.h
@@ -11,16 +11,15 @@
*
*/
-#ifndef MEMORY_H
-#define MEMORY_H
-
-#ifndef CONFIG_USER_ONLY
+#ifndef SYSTEM_MEMORY_H
+#define SYSTEM_MEMORY_H
#include "exec/cpu-common.h"
#include "exec/hwaddr.h"
#include "exec/memattrs.h"
#include "exec/memop.h"
#include "exec/ramlist.h"
+#include "exec/tswap.h"
#include "qemu/bswap.h"
#include "qemu/queue.h"
#include "qemu/int128.h"
@@ -184,6 +183,7 @@ struct IOMMUNotifier {
hwaddr start;
hwaddr end;
int iommu_idx;
+ void *opaque;
QLIST_ENTRY(IOMMUNotifier) node;
};
typedef struct IOMMUNotifier IOMMUNotifier;
@@ -246,6 +246,16 @@ typedef struct IOMMUTLBEvent {
/* RAM can be private that has kvm guest memfd backend */
#define RAM_GUEST_MEMFD (1 << 12)
+/*
+ * In RAMBlock creation functions, if MAP_SHARED is 0 in the flags parameter,
+ * the implementation may still create a shared mapping if other conditions
+ * require it. Callers who specifically want a private mapping, eg objects
+ * specified by the user, must pass RAM_PRIVATE.
+ * After RAMBlock creation, MAP_SHARED in the block's flags indicates whether
+ * the block is shared or private, and MAP_PRIVATE is omitted.
+ */
+#define RAM_PRIVATE (1 << 13)
+
static inline void iommu_notifier_init(IOMMUNotifier *n, IOMMUNotify fn,
IOMMUNotifierFlag flags,
hwaddr start, hwaddr end,
@@ -504,52 +514,6 @@ struct IOMMUMemoryRegionClass {
* @iommu: the IOMMUMemoryRegion
*/
int (*num_indexes)(IOMMUMemoryRegion *iommu);
-
- /**
- * @iommu_set_page_size_mask:
- *
- * Restrict the page size mask that can be supported with a given IOMMU
- * memory region. Used for example to propagate host physical IOMMU page
- * size mask limitations to the virtual IOMMU.
- *
- * Optional method: if this method is not provided, then the default global
- * page mask is used.
- *
- * @iommu: the IOMMUMemoryRegion
- *
- * @page_size_mask: a bitmask of supported page sizes. At least one bit,
- * representing the smallest page size, must be set. Additional set bits
- * represent supported block sizes. For example a host physical IOMMU that
- * uses page tables with a page size of 4kB, and supports 2MB and 4GB
- * blocks, will set mask 0x40201000. A granule of 4kB with indiscriminate
- * block sizes is specified with mask 0xfffffffffffff000.
- *
- * Returns 0 on success, or a negative error. In case of failure, the error
- * object must be created.
- */
- int (*iommu_set_page_size_mask)(IOMMUMemoryRegion *iommu,
- uint64_t page_size_mask,
- Error **errp);
- /**
- * @iommu_set_iova_ranges:
- *
- * Propagate information about the usable IOVA ranges for a given IOMMU
- * memory region. Used for example to propagate host physical device
- * reserved memory region constraints to the virtual IOMMU.
- *
- * Optional method: if this method is not provided, then the default IOVA
- * aperture is used.
- *
- * @iommu: the IOMMUMemoryRegion
- *
- * @iova_ranges: list of ordered IOVA ranges (at least one range)
- *
- * Returns 0 on success, or a negative error. In case of failure, the error
- * object must be created.
- */
- int (*iommu_set_iova_ranges)(IOMMUMemoryRegion *iommu,
- GList *iova_ranges,
- Error **errp);
};
typedef struct RamDiscardListener RamDiscardListener;
@@ -612,8 +576,20 @@ static inline void ram_discard_listener_init(RamDiscardListener *rdl,
rdl->double_discard_supported = double_discard_supported;
}
-typedef int (*ReplayRamPopulate)(MemoryRegionSection *section, void *opaque);
-typedef void (*ReplayRamDiscard)(MemoryRegionSection *section, void *opaque);
+/**
+ * typedef ReplayRamDiscardState:
+ *
+ * The callback handler for #RamDiscardManagerClass.replay_populated/
+ * #RamDiscardManagerClass.replay_discarded to invoke on populated/discarded
+ * parts.
+ *
+ * @section: the #MemoryRegionSection of populated/discarded part
+ * @opaque: pointer to forward to the callback
+ *
+ * Returns 0 on success, or a negative error if failed.
+ */
+typedef int (*ReplayRamDiscardState)(MemoryRegionSection *section,
+ void *opaque);
/*
* RamDiscardManagerClass:
@@ -687,36 +663,38 @@ struct RamDiscardManagerClass {
/**
* @replay_populated:
*
- * Call the #ReplayRamPopulate callback for all populated parts within the
- * #MemoryRegionSection via the #RamDiscardManager.
+ * Call the #ReplayRamDiscardState callback for all populated parts within
+ * the #MemoryRegionSection via the #RamDiscardManager.
*
* In case any call fails, no further calls are made.
*
* @rdm: the #RamDiscardManager
* @section: the #MemoryRegionSection
- * @replay_fn: the #ReplayRamPopulate callback
+ * @replay_fn: the #ReplayRamDiscardState callback
* @opaque: pointer to forward to the callback
*
* Returns 0 on success, or a negative error if any notification failed.
*/
int (*replay_populated)(const RamDiscardManager *rdm,
MemoryRegionSection *section,
- ReplayRamPopulate replay_fn, void *opaque);
+ ReplayRamDiscardState replay_fn, void *opaque);
/**
* @replay_discarded:
*
- * Call the #ReplayRamDiscard callback for all discarded parts within the
- * #MemoryRegionSection via the #RamDiscardManager.
+ * Call the #ReplayRamDiscardState callback for all discarded parts within
+ * the #MemoryRegionSection via the #RamDiscardManager.
*
* @rdm: the #RamDiscardManager
* @section: the #MemoryRegionSection
- * @replay_fn: the #ReplayRamDiscard callback
+ * @replay_fn: the #ReplayRamDiscardState callback
* @opaque: pointer to forward to the callback
+ *
+ * Returns 0 on success, or a negative error if any notification failed.
*/
- void (*replay_discarded)(const RamDiscardManager *rdm,
- MemoryRegionSection *section,
- ReplayRamDiscard replay_fn, void *opaque);
+ int (*replay_discarded)(const RamDiscardManager *rdm,
+ MemoryRegionSection *section,
+ ReplayRamDiscardState replay_fn, void *opaque);
/**
* @register_listener:
@@ -757,15 +735,41 @@ uint64_t ram_discard_manager_get_min_granularity(const RamDiscardManager *rdm,
bool ram_discard_manager_is_populated(const RamDiscardManager *rdm,
const MemoryRegionSection *section);
+/**
+ * ram_discard_manager_replay_populated:
+ *
+ * A wrapper to call the #RamDiscardManagerClass.replay_populated callback
+ * of the #RamDiscardManager.
+ *
+ * @rdm: the #RamDiscardManager
+ * @section: the #MemoryRegionSection
+ * @replay_fn: the #ReplayRamDiscardState callback
+ * @opaque: pointer to forward to the callback
+ *
+ * Returns 0 on success, or a negative error if any notification failed.
+ */
int ram_discard_manager_replay_populated(const RamDiscardManager *rdm,
MemoryRegionSection *section,
- ReplayRamPopulate replay_fn,
+ ReplayRamDiscardState replay_fn,
void *opaque);
-void ram_discard_manager_replay_discarded(const RamDiscardManager *rdm,
- MemoryRegionSection *section,
- ReplayRamDiscard replay_fn,
- void *opaque);
+/**
+ * ram_discard_manager_replay_discarded:
+ *
+ * A wrapper to call the #RamDiscardManagerClass.replay_discarded callback
+ * of the #RamDiscardManager.
+ *
+ * @rdm: the #RamDiscardManager
+ * @section: the #MemoryRegionSection
+ * @replay_fn: the #ReplayRamDiscardState callback
+ * @opaque: pointer to forward to the callback
+ *
+ * Returns 0 on success, or a negative error if any notification failed.
+ */
+int ram_discard_manager_replay_discarded(const RamDiscardManager *rdm,
+ MemoryRegionSection *section,
+ ReplayRamDiscardState replay_fn,
+ void *opaque);
void ram_discard_manager_register_listener(RamDiscardManager *rdm,
RamDiscardListener *rdl,
@@ -775,21 +779,20 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
RamDiscardListener *rdl);
/**
- * memory_get_xlat_addr: Extract addresses from a TLB entry
+ * memory_translate_iotlb: Extract addresses from a TLB entry.
+ * Called with rcu_read_lock held.
*
* @iotlb: pointer to an #IOMMUTLBEntry
- * @vaddr: virtual address
- * @ram_addr: RAM address
- * @read_only: indicates if writes are allowed
- * @mr_has_discard_manager: indicates memory is controlled by a
- * RamDiscardManager
+ * @xlat_p: return the offset of the entry from the start of the returned
+ * MemoryRegion.
* @errp: pointer to Error*, to store an error if it happens.
*
- * Return: true on success, else false setting @errp with error.
+ * Return: On success, return the MemoryRegion containing the @iotlb translated
+ * addr. The MemoryRegion must not be accessed after rcu_read_unlock.
+ * On failure, return NULL, setting @errp with error.
*/
-bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
- ram_addr_t *ram_addr, bool *read_only,
- bool *mr_has_discard_manager, Error **errp);
+MemoryRegion *memory_translate_iotlb(IOMMUTLBEntry *iotlb, hwaddr *xlat_p,
+ Error **errp);
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
@@ -830,7 +833,6 @@ struct MemoryRegion {
bool terminates;
bool ram_device;
bool enabled;
- bool warning_printed; /* For reservations */
uint8_t vga_logging_count;
MemoryRegion *alias;
hwaddr alias_offset;
@@ -945,7 +947,7 @@ struct MemoryListener {
* the current transaction.
*/
void (*log_start)(MemoryListener *listener, MemoryRegionSection *section,
- int old, int new);
+ int old_val, int new_val);
/**
* @log_stop:
@@ -964,7 +966,7 @@ struct MemoryListener {
* the current transaction.
*/
void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section,
- int old, int new);
+ int old_val, int new_val);
/**
* @log_sync:
@@ -1130,13 +1132,7 @@ typedef struct AddressSpaceMapClient {
QLIST_ENTRY(AddressSpaceMapClient) link;
} AddressSpaceMapClient;
-typedef struct {
- MemoryRegion *mr;
- void *buffer;
- hwaddr addr;
- hwaddr len;
- bool in_use;
-} BounceBuffer;
+#define DEFAULT_MAX_BOUNCE_BUFFER_SIZE (4096)
/**
* struct AddressSpace: describes a mapping of addresses to #MemoryRegion objects
@@ -1156,8 +1152,17 @@ struct AddressSpace {
QTAILQ_HEAD(, MemoryListener) listeners;
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
- /* Bounce buffer to use for this address space. */
- BounceBuffer bounce;
+ /*
+ * Maximum DMA bounce buffer size used for indirect memory map requests.
+ * This limits the total size of bounce buffer allocations made for
+ * DMA requests to indirect memory regions within this AddressSpace. DMA
+ * requests that exceed the limit (e.g. due to overly large requested size
+ * or concurrent DMA requests having claimed too much buffer space) will be
+ * rejected and left to the caller to handle.
+ */
+ size_t max_bounce_buffer_size;
+ /* Total size of bounce buffers currently allocated, atomically accessed */
+ size_t bounce_buffer_size;
/* List of callbacks to invoke when buffers free up */
QemuMutex map_client_list_lock;
QLIST_HEAD(, AddressSpaceMapClient) map_client_list;
@@ -1237,7 +1242,7 @@ static inline bool MemoryRegionSection_eq(MemoryRegionSection *a,
MemoryRegionSection *memory_region_section_new_copy(MemoryRegionSection *s);
/**
- * memory_region_section_new_copy: Free a copied memory region section
+ * memory_region_section_free_copy: Free a copied memory region section
*
* Free a copy of a memory section created via memory_region_section_new_copy().
* properly dropping references on all relevant members.
@@ -1247,6 +1252,36 @@ MemoryRegionSection *memory_region_section_new_copy(MemoryRegionSection *s);
void memory_region_section_free_copy(MemoryRegionSection *s);
/**
+ * memory_region_section_intersect_range: Adjust the memory section to cover
+ * the intersection with the given range.
+ *
+ * @s: the #MemoryRegionSection to be adjusted
+ * @offset: the offset of the given range in the memory region
+ * @size: the size of the given range
+ *
+ * Returns false if the intersection is empty, otherwise returns true.
+ */
+static inline bool memory_region_section_intersect_range(MemoryRegionSection *s,
+ uint64_t offset,
+ uint64_t size)
+{
+ uint64_t start = MAX(s->offset_within_region, offset);
+ Int128 end = int128_min(int128_add(int128_make64(s->offset_within_region),
+ s->size),
+ int128_add(int128_make64(offset),
+ int128_make64(size)));
+
+ if (int128_le(end, int128_make64(start))) {
+ return false;
+ }
+
+ s->offset_within_address_space += start - s->offset_within_region;
+ s->offset_within_region = start;
+ s->size = int128_sub(end, int128_make64(start));
+ return true;
+}
+
+/**
* memory_region_init: Initialize a memory region
*
* The region typically acts as a container for other memory regions. Use
@@ -1898,7 +1933,7 @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
* memory_region_unregister_iommu_notifier: unregister a notifier for
* changes to IOMMU translation entries.
*
- * @mr: the memory region which was observed and for which notity_stopped()
+ * @mr: the memory region which was observed and for which notify_stopped()
* needs to be called
* @n: the notifier to be removed.
*/
@@ -1940,30 +1975,6 @@ int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr,
int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr);
/**
- * memory_region_iommu_set_page_size_mask: set the supported page
- * sizes for a given IOMMU memory region
- *
- * @iommu_mr: IOMMU memory region
- * @page_size_mask: supported page size mask
- * @errp: pointer to Error*, to store an error if it happens.
- */
-int memory_region_iommu_set_page_size_mask(IOMMUMemoryRegion *iommu_mr,
- uint64_t page_size_mask,
- Error **errp);
-
-/**
- * memory_region_iommu_set_iova_ranges - Set the usable IOVA ranges
- * for a given IOMMU MR region
- *
- * @iommu: IOMMU memory region
- * @iova_ranges: list of ordered IOVA ranges (at least one range)
- * @errp: pointer to Error*, to store an error if it happens.
- */
-int memory_region_iommu_set_iova_ranges(IOMMUMemoryRegion *iommu,
- GList *iova_ranges,
- Error **errp);
-
-/**
* memory_region_name: get a memory region's name
*
* Returns the string that was used to initialize the memory region.
@@ -2220,7 +2231,7 @@ void memory_region_flush_rom_device(MemoryRegion *mr, hwaddr addr, hwaddr size);
* only useful on RAM regions.
*
* @mr: the region being updated.
- * @readonly: whether rhe region is to be ROM or RAM.
+ * @readonly: whether the region is to be ROM or RAM.
*/
void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
@@ -2231,7 +2242,7 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
* only useful on RAM regions.
*
* @mr: the region being updated.
- * @nonvolatile: whether rhe region is to be non-volatile.
+ * @nonvolatile: whether the region is to be non-volatile.
*/
void memory_region_set_nonvolatile(MemoryRegion *mr, bool nonvolatile);
@@ -2528,13 +2539,13 @@ static inline bool memory_region_has_ram_discard_manager(MemoryRegion *mr)
*
* This function must not be called for a mapped #MemoryRegion, a #MemoryRegion
* that does not cover RAM, or a #MemoryRegion that already has a
- * #RamDiscardManager assigned.
+ * #RamDiscardManager assigned. Return 0 if the rdm is set successfully.
*
* @mr: the #MemoryRegion
* @rdm: #RamDiscardManager to set
*/
-void memory_region_set_ram_discard_manager(MemoryRegion *mr,
- RamDiscardManager *rdm);
+int memory_region_set_ram_discard_manager(MemoryRegion *mr,
+ RamDiscardManager *rdm);
/**
* memory_region_find: translate an address/size relative to a
@@ -2577,7 +2588,7 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
void memory_global_dirty_log_sync(bool last_stage);
/**
- * memory_global_dirty_log_sync: synchronize the dirty log for all memory
+ * memory_global_after_dirty_log_sync: synchronize the dirty log for all memory
*
* Synchronizes the vCPUs with a thread that is reading the dirty bitmap.
* This function must be called after the dirty log bitmap is cleared, and
@@ -2790,13 +2801,19 @@ MemTxResult address_space_write_rom(AddressSpace *as, hwaddr addr,
#define ARG1_DECL AddressSpace *as
#include "exec/memory_ldst.h.inc"
+static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val)
+{
+ address_space_stl_notdirty(as, addr, val,
+ MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
#define SUFFIX
#define ARG1 as
#define ARG1_DECL AddressSpace *as
#include "exec/memory_ldst_phys.h.inc"
struct MemoryRegionCache {
- void *ptr;
+ uint8_t *ptr;
hwaddr xlat;
hwaddr len;
FlatView *fv;
@@ -2856,6 +2873,9 @@ static inline void address_space_stb_cached(MemoryRegionCache *cache,
}
}
+#define ENDIANNESS
+#include "exec/memory_ldst_cached.h.inc"
+
#define ENDIANNESS _le
#include "exec/memory_ldst_cached.h.inc"
@@ -3053,15 +3073,34 @@ MemTxResult address_space_write_cached_slow(MemoryRegionCache *cache,
int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr);
bool prepare_mmio_access(MemoryRegion *mr);
-static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+static inline bool memory_region_supports_direct_access(MemoryRegion *mr)
{
- if (is_write) {
- return memory_region_is_ram(mr) && !mr->readonly &&
- !mr->rom_device && !memory_region_is_ram_device(mr);
- } else {
- return (memory_region_is_ram(mr) && !memory_region_is_ram_device(mr)) ||
- memory_region_is_romd(mr);
+ /* ROM DEVICE regions only allow direct access if in ROMD mode. */
+ if (memory_region_is_romd(mr)) {
+ return true;
+ }
+ if (!memory_region_is_ram(mr)) {
+ return false;
}
+ /*
+ * RAM DEVICE regions can be accessed directly using memcpy, but it might
+ * be MMIO and access using mempy can be wrong (e.g., using instructions not
+ * intended for MMIO access). So we treat this as IO.
+ */
+ return !memory_region_is_ram_device(mr);
+}
+
+static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write,
+ MemTxAttrs attrs)
+{
+ if (!memory_region_supports_direct_access(mr)) {
+ return false;
+ }
+ /* Debug access can write to ROM. */
+ if (is_write && !attrs.debug) {
+ return !mr->readonly && !mr->rom_device;
+ }
+ return true;
}
/**
@@ -3094,7 +3133,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
fv = address_space_to_flatview(as);
l = len;
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
- if (len == l && memory_access_is_direct(mr, false)) {
+ if (len == l && memory_access_is_direct(mr, false, attrs)) {
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
memcpy(buf, ptr, len);
} else {
@@ -3167,26 +3206,6 @@ address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
MemTxResult address_space_set(AddressSpace *as, hwaddr addr,
uint8_t c, hwaddr len, MemTxAttrs attrs);
-#ifdef COMPILING_PER_TARGET
-/* enum device_endian to MemOp. */
-static inline MemOp devend_memop(enum device_endian end)
-{
- QEMU_BUILD_BUG_ON(DEVICE_HOST_ENDIAN != DEVICE_LITTLE_ENDIAN &&
- DEVICE_HOST_ENDIAN != DEVICE_BIG_ENDIAN);
-
-#if HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN
- /* Swap if non-host endianness or native (target) endianness */
- return (end == DEVICE_HOST_ENDIAN) ? 0 : MO_BSWAP;
-#else
- const int non_host_endianness =
- DEVICE_LITTLE_ENDIAN ^ DEVICE_BIG_ENDIAN ^ DEVICE_HOST_ENDIAN;
-
- /* In this case, native (target) endianness needs no swap. */
- return (end == non_host_endianness) ? MO_BSWAP : 0;
-#endif
-}
-#endif /* COMPILING_PER_TARGET */
-
/*
* Inhibit technologies that require discarding of pages in RAM blocks, e.g.,
* to manage the actual amount of memory consumed by the VM (then, the memory
@@ -3242,6 +3261,7 @@ bool ram_block_discard_is_disabled(void);
*/
bool ram_block_discard_is_required(void);
-#endif
+void ram_block_add_cpr_blocker(RAMBlock *rb, Error **errp);
+void ram_block_del_cpr_blocker(RAMBlock *rb);
#endif
diff --git a/include/sysemu/memory_mapping.h b/include/system/memory_mapping.h
index 021e0a6..021e0a6 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/system/memory_mapping.h
diff --git a/include/sysemu/numa.h b/include/system/numa.h
index 0467614..1044b0e 100644
--- a/include/sysemu/numa.h
+++ b/include/system/numa.h
@@ -1,9 +1,8 @@
-#ifndef SYSEMU_NUMA_H
-#define SYSEMU_NUMA_H
+#ifndef SYSTEM_NUMA_H
+#define SYSTEM_NUMA_H
#include "qemu/bitmap.h"
#include "qapi/qapi-types-machine.h"
-#include "exec/cpu-common.h"
struct CPUArchId;
diff --git a/include/sysemu/nvmm.h b/include/system/nvmm.h
index 6971ddb..6971ddb 100644
--- a/include/sysemu/nvmm.h
+++ b/include/system/nvmm.h
diff --git a/include/sysemu/os-posix.h b/include/system/os-posix.h
index b881ac6..ce5b3bc 100644
--- a/include/sysemu/os-posix.h
+++ b/include/system/os-posix.h
@@ -53,7 +53,7 @@ bool os_set_runas(const char *user_id);
void os_set_chroot(const char *path);
void os_setup_limits(void);
void os_setup_post(void);
-int os_mlock(void);
+int os_mlock(bool on_fault);
/**
* qemu_alloc_stack:
diff --git a/include/system/os-wasm.h b/include/system/os-wasm.h
new file mode 100644
index 0000000..3abb3aa
--- /dev/null
+++ b/include/system/os-wasm.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * posix specific declarations forked from os-posix.h, removing functions not
+ * working on Emscripten
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010 Jes Sorensen <Jes.Sorensen@redhat.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 QEMU_OS_WASM_H
+#define QEMU_OS_WASM_H
+
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/un.h>
+
+#ifdef CONFIG_SYSMACROS
+#include <sys/sysmacros.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void os_set_line_buffering(void);
+void os_setup_early_signal_handling(void);
+void os_set_proc_name(const char *s);
+void os_setup_signal_handling(void);
+void os_setup_limits(void);
+void os_setup_post(void);
+int os_mlock(bool on_fault);
+static inline int os_set_daemonize(bool d)
+{
+ return -1;
+};
+bool is_daemonized(void);
+static inline void os_daemonize(void) {}
+
+/**
+ * qemu_alloc_stack:
+ * @sz: pointer to a size_t holding the requested usable stack size
+ *
+ * Allocate memory that can be used as a stack, for instance for
+ * coroutines. If the memory cannot be allocated, this function
+ * will abort (like g_malloc()). This function also inserts an
+ * additional guard page to catch a potential stack overflow.
+ * Note that the memory required for the guard page and alignment
+ * and minimal stack size restrictions will increase the value of sz.
+ *
+ * The allocated stack must be freed with qemu_free_stack().
+ *
+ * Returns: pointer to (the lowest address of) the stack memory.
+ */
+void *qemu_alloc_stack(size_t *sz);
+
+/**
+ * qemu_free_stack:
+ * @stack: stack to free
+ * @sz: size of stack in bytes
+ *
+ * Free a stack allocated via qemu_alloc_stack(). Note that sz must
+ * be exactly the adjusted stack size returned by qemu_alloc_stack.
+ */
+void qemu_free_stack(void *stack, size_t sz);
+
+/* POSIX and Mingw32 differ in the name of the stdio lock functions. */
+
+static inline void qemu_flockfile(FILE *f)
+{
+ flockfile(f);
+}
+
+static inline void qemu_funlockfile(FILE *f)
+{
+ funlockfile(f);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/sysemu/os-win32.h b/include/system/os-win32.h
index b82a5d3..3aa6cee 100644
--- a/include/sysemu/os-win32.h
+++ b/include/system/os-win32.h
@@ -123,14 +123,13 @@ static inline bool is_daemonized(void)
return false;
}
-static inline int os_mlock(void)
+static inline int os_mlock(bool on_fault G_GNUC_UNUSED)
{
return -ENOSYS;
}
static inline void os_setup_limits(void)
{
- return;
}
#define fsync _commit
diff --git a/include/sysemu/qtest.h b/include/system/qtest.h
index c161d75..84b1f8c 100644
--- a/include/sysemu/qtest.h
+++ b/include/system/qtest.h
@@ -23,8 +23,6 @@ static inline bool qtest_enabled(void)
return qtest_allowed;
}
-#ifndef CONFIG_USER_ONLY
-void qtest_send_prefix(CharBackend *chr);
void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, const char *fmt, ...);
void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words));
bool qtest_driver(void);
@@ -34,6 +32,5 @@ void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **
void qtest_server_set_send_handler(void (*send)(void *, const char *),
void *opaque);
void qtest_server_inproc_recv(void *opaque, const char *buf);
-#endif
#endif
diff --git a/include/exec/ram_addr.h b/include/system/ram_addr.h
index 891c44c..15a1b1a 100644
--- a/include/exec/ram_addr.h
+++ b/include/system/ram_addr.h
@@ -16,18 +16,21 @@
* The functions declared here will be removed soon.
*/
-#ifndef RAM_ADDR_H
-#define RAM_ADDR_H
+#ifndef SYSTEM_RAM_ADDR_H
+#define SYSTEM_RAM_ADDR_H
-#ifndef CONFIG_USER_ONLY
-#include "cpu.h"
-#include "sysemu/xen.h"
-#include "sysemu/tcg.h"
+#include "system/xen.h"
+#include "system/tcg.h"
+#include "exec/cputlb.h"
#include "exec/ramlist.h"
-#include "exec/ramblock.h"
-#include "exec/exec-all.h"
+#include "system/ramblock.h"
+#include "system/memory.h"
+#include "exec/target_page.h"
#include "qemu/rcu.h"
+#include "exec/hwaddr.h"
+#include "exec/cpu-common.h"
+
extern uint64_t total_dirty_pages;
/**
@@ -98,9 +101,6 @@ static inline unsigned long int ramblock_recv_bitmap_offset(void *host_addr,
bool ramblock_is_pmem(RAMBlock *rb);
-long qemu_minrampagesize(void);
-long qemu_maxrampagesize(void);
-
/**
* qemu_ram_alloc_from_file,
* qemu_ram_alloc_from_fd: Allocate a ram block from the specified backing
@@ -108,23 +108,30 @@ long qemu_maxrampagesize(void);
*
* Parameters:
* @size: the size in bytes of the ram block
+ * @max_size: the maximum size of the block after resizing
* @mr: the memory region where the ram block is
+ * @resized: callback after calls to qemu_ram_resize
* @ram_flags: RamBlock flags. Supported flags: RAM_SHARED, RAM_PMEM,
* RAM_NORESERVE, RAM_PROTECTED, RAM_NAMED_FILE, RAM_READONLY,
* RAM_READONLY_FD, RAM_GUEST_MEMFD
* @mem_path or @fd: specify the backing file or device
* @offset: Offset into target file
+ * @grow: extend file if necessary (but an empty file is always extended).
* @errp: pointer to Error*, to store an error if it happens
*
* Return:
* On success, return a pointer to the ram block.
* On failure, return NULL.
*/
+typedef void (*qemu_ram_resize_cb)(const char *, uint64_t length, void *host);
+
RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, MemoryRegion *mr,
uint32_t ram_flags, const char *mem_path,
off_t offset, Error **errp);
-RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
+RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, ram_addr_t max_size,
+ qemu_ram_resize_cb resized, MemoryRegion *mr,
uint32_t ram_flags, int fd, off_t offset,
+ bool grow,
Error **errp);
RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
@@ -132,9 +139,7 @@ RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
RAMBlock *qemu_ram_alloc(ram_addr_t size, uint32_t ram_flags, MemoryRegion *mr,
Error **errp);
RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
- void (*resized)(const char*,
- uint64_t length,
- void *host),
+ qemu_ram_resize_cb resized,
MemoryRegion *mr, Error **errp);
void qemu_ram_free(RAMBlock *block);
@@ -332,7 +337,9 @@ static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start,
}
}
- xen_hvm_modified_memory(start, length);
+ if (xen_enabled()) {
+ xen_hvm_modified_memory(start, length);
+ }
}
#if !defined(_WIN32)
@@ -408,7 +415,9 @@ uint64_t cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
}
}
- xen_hvm_modified_memory(start, pages << TARGET_PAGE_BITS);
+ if (xen_enabled()) {
+ xen_hvm_modified_memory(start, pages << TARGET_PAGE_BITS);
+ }
} else {
uint8_t clients = tcg_enabled() ? DIRTY_CLIENTS_ALL : DIRTY_CLIENTS_NOCODE;
@@ -548,5 +557,5 @@ uint64_t cpu_physical_memory_sync_dirty_bitmap(RAMBlock *rb,
return num_dirty;
}
-#endif
+
#endif
diff --git a/include/exec/ramblock.h b/include/system/ramblock.h
index 0babd10..87e847e 100644
--- a/include/exec/ramblock.h
+++ b/include/system/ramblock.h
@@ -16,13 +16,16 @@
* The functions declared here will be removed soon.
*/
-#ifndef QEMU_EXEC_RAMBLOCK_H
-#define QEMU_EXEC_RAMBLOCK_H
+#ifndef SYSTEM_RAMBLOCK_H
+#define SYSTEM_RAMBLOCK_H
-#ifndef CONFIG_USER_ONLY
-#include "cpu-common.h"
+#include "exec/cpu-common.h"
#include "qemu/rcu.h"
#include "exec/ramlist.h"
+#include "system/hostmem.h"
+
+#define TYPE_RAM_BLOCK_ATTRIBUTES "ram-block-attributes"
+OBJECT_DECLARE_SIMPLE_TYPE(RamBlockAttributes, RAM_BLOCK_ATTRIBUTES)
struct RAMBlock {
struct rcu_head rcu;
@@ -39,9 +42,11 @@ struct RAMBlock {
/* RCU-enabled, writes protected by the ramlist lock */
QLIST_ENTRY(RAMBlock) next;
QLIST_HEAD(, RAMBlockNotifier) ramblock_notifiers;
+ Error *cpr_blocker;
int fd;
uint64_t fd_offset;
int guest_memfd;
+ RamBlockAttributes *attributes;
size_t page_size;
/* dirty bitmap used during migration */
unsigned long *bmap;
@@ -90,5 +95,22 @@ struct RAMBlock {
*/
ram_addr_t postcopy_length;
};
-#endif
+
+struct RamBlockAttributes {
+ Object parent;
+
+ RAMBlock *ram_block;
+
+ /* 1-setting of the bitmap represents ram is populated (shared) */
+ unsigned bitmap_size;
+ unsigned long *bitmap;
+
+ QLIST_HEAD(, RamDiscardListener) rdl_list;
+};
+
+RamBlockAttributes *ram_block_attributes_create(RAMBlock *ram_block);
+void ram_block_attributes_destroy(RamBlockAttributes *attr);
+int ram_block_attributes_state_change(RamBlockAttributes *attr, uint64_t offset,
+ uint64_t size, bool to_discard);
+
#endif
diff --git a/include/sysemu/replay.h b/include/system/replay.h
index f229b21..1c87c97 100644
--- a/include/sysemu/replay.h
+++ b/include/system/replay.h
@@ -8,12 +8,8 @@
* See the COPYING file in the top-level directory.
*
*/
-#ifndef SYSEMU_REPLAY_H
-#define SYSEMU_REPLAY_H
-
-#ifdef CONFIG_USER_ONLY
-#error Cannot include this header from user emulation
-#endif
+#ifndef SYSTEM_REPLAY_H
+#define SYSTEM_REPLAY_H
#include "exec/replay-core.h"
#include "qapi/qapi-types-misc.h"
@@ -73,11 +69,6 @@ int replay_get_instructions(void);
/*! Updates instructions counter in replay mode. */
void replay_account_executed_instructions(void);
-/**
- * replay_can_wait: check if we should pause for wait-io
- */
-bool replay_can_wait(void);
-
/* Processing clocks and other time sources */
/*! Save the specified clock */
@@ -122,8 +113,6 @@ void replay_async_events(void);
/* Asynchronous events queue */
-/*! Disables storing events in the queue */
-void replay_disable_events(void);
/*! Enables storing events in the queue */
void replay_enable_events(void);
/*! Returns true when saving events is enabled */
diff --git a/include/sysemu/reset.h b/include/system/reset.h
index ae43604..97131d9 100644
--- a/include/sysemu/reset.h
+++ b/include/system/reset.h
@@ -24,9 +24,10 @@
* THE SOFTWARE.
*/
-#ifndef QEMU_SYSEMU_RESET_H
-#define QEMU_SYSEMU_RESET_H
+#ifndef QEMU_SYSTEM_RESET_H
+#define QEMU_SYSTEM_RESET_H
+#include "hw/resettable.h"
#include "qapi/qapi-events-run-state.h"
typedef void QEMUResetHandler(void *opaque);
@@ -110,7 +111,7 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
/**
* qemu_devices_reset: Perform a complete system reset
- * @reason: reason for the reset
+ * @reason: type of the reset
*
* This function performs the low-level work needed to do a complete reset
* of the system (calling all the callbacks registered with
@@ -121,6 +122,6 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
* If you want to trigger a system reset from, for instance, a device
* model, don't use this function. Use qemu_system_reset_request().
*/
-void qemu_devices_reset(ShutdownCause reason);
+void qemu_devices_reset(ResetType type);
#endif
diff --git a/include/sysemu/rng-random.h b/include/system/rng-random.h
index 0fdc6c6..0fdc6c6 100644
--- a/include/sysemu/rng-random.h
+++ b/include/system/rng-random.h
diff --git a/include/sysemu/rng.h b/include/system/rng.h
index e383f87..e383f87 100644
--- a/include/sysemu/rng.h
+++ b/include/system/rng.h
diff --git a/include/sysemu/rtc.h b/include/system/rtc.h
index 0fc8ad6..cde83fa 100644
--- a/include/sysemu/rtc.h
+++ b/include/system/rtc.h
@@ -22,8 +22,8 @@
* THE SOFTWARE.
*/
-#ifndef SYSEMU_RTC_H
-#define SYSEMU_RTC_H
+#ifndef SYSTEM_RTC_H
+#define SYSTEM_RTC_H
/**
* qemu_get_timedate: Get the current RTC time
diff --git a/include/sysemu/runstate-action.h b/include/system/runstate-action.h
index db4e309..db4e309 100644
--- a/include/sysemu/runstate-action.h
+++ b/include/system/runstate-action.h
diff --git a/include/sysemu/runstate.h b/include/system/runstate.h
index 0117d24..fdd5c4a 100644
--- a/include/sysemu/runstate.h
+++ b/include/system/runstate.h
@@ -1,5 +1,5 @@
-#ifndef SYSEMU_RUNSTATE_H
-#define SYSEMU_RUNSTATE_H
+#ifndef SYSTEM_RUNSTATE_H
+#define SYSTEM_RUNSTATE_H
#include "qapi/qapi-types-run-state.h"
#include "qemu/notify.h"
@@ -9,8 +9,10 @@ void runstate_set(RunState new_state);
RunState runstate_get(void);
bool runstate_is_running(void);
bool runstate_needs_reset(void);
+void runstate_replay_enable(void);
typedef void VMChangeStateHandler(void *opaque, bool running, RunState state);
+typedef int VMChangeStateHandlerWithRet(void *opaque, bool running, RunState state);
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque);
@@ -19,21 +21,27 @@ VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
VMChangeStateEntry *
qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler *cb,
VMChangeStateHandler *prepare_cb,
+ VMChangeStateHandlerWithRet *cb_ret,
void *opaque, int priority);
VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev,
VMChangeStateHandler *cb,
+ VMChangeStateHandlerWithRet *cb_ret,
void *opaque);
VMChangeStateEntry *qdev_add_vm_change_state_handler_full(
- DeviceState *dev, VMChangeStateHandler *cb,
- VMChangeStateHandler *prepare_cb, void *opaque);
+ DeviceState *dev, VMChangeStateHandler *cb, VMChangeStateHandler *prepare_cb,
+ VMChangeStateHandlerWithRet *cb_ret, void *opaque);
void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
/**
* vm_state_notify: Notify the state of the VM
*
* @running: whether the VM is running or not.
* @state: the #RunState of the VM.
+ *
+ * Return the result of the callback which has return value.
+ * If no callback has return value, still return 0 and the
+ * upper layer should not do additional processing.
*/
-void vm_state_notify(bool running, RunState state);
+int vm_state_notify(bool running, RunState state);
static inline bool shutdown_caused_by_guest(ShutdownCause cause)
{
@@ -104,6 +112,7 @@ void qemu_system_killed(int signal, pid_t pid);
void qemu_system_reset(ShutdownCause reason);
void qemu_system_guest_panicked(GuestPanicInformation *info);
void qemu_system_guest_crashloaded(GuestPanicInformation *info);
+void qemu_system_guest_pvshutdown(void);
bool qemu_system_dump_in_progress(void);
#endif
diff --git a/include/sysemu/seccomp.h b/include/system/seccomp.h
index fe85989..fe85989 100644
--- a/include/sysemu/seccomp.h
+++ b/include/system/seccomp.h
diff --git a/include/system/spdm-socket.h b/include/system/spdm-socket.h
new file mode 100644
index 0000000..5d8bd9a
--- /dev/null
+++ b/include/system/spdm-socket.h
@@ -0,0 +1,74 @@
+/*
+ * QEMU SPDM socket support
+ *
+ * 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 SPDM_REQUESTER_H
+#define SPDM_REQUESTER_H
+
+/**
+ * spdm_socket_connect: connect to an external SPDM socket
+ * @port: port to connect to
+ * @errp: error object handle
+ *
+ * This will connect to an external SPDM socket server. On error
+ * it will return -1 and errp will be set. On success this function
+ * will return the socket number.
+ */
+int spdm_socket_connect(uint16_t port, Error **errp);
+
+/**
+ * spdm_socket_rsp: send and receive a message to a SPDM server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ * @req: request buffer
+ * @req_len: request buffer length
+ * @rsp: response buffer
+ * @rsp_len: response buffer length
+ *
+ * Send platform data to a SPDM server on socket and then receive
+ * a response.
+ */
+uint32_t spdm_socket_rsp(const int socket, uint32_t transport_type,
+ void *req, uint32_t req_len,
+ void *rsp, uint32_t rsp_len);
+
+/**
+ * spdm_socket_close: send a shutdown command to the server
+ * @socket: socket returned from spdm_socket_connect()
+ * @transport_type: SPDM_SOCKET_TRANSPORT_TYPE_* macro
+ *
+ * This will issue a shutdown command to the server.
+ */
+void spdm_socket_close(const int socket, uint32_t transport_type);
+
+#define SPDM_SOCKET_COMMAND_NORMAL 0x0001
+#define SPDM_SOCKET_COMMAND_OOB_ENCAP_KEY_UPDATE 0x8001
+#define SPDM_SOCKET_COMMAND_CONTINUE 0xFFFD
+#define SPDM_SOCKET_COMMAND_SHUTDOWN 0xFFFE
+#define SPDM_SOCKET_COMMAND_UNKOWN 0xFFFF
+#define SPDM_SOCKET_COMMAND_TEST 0xDEAD
+
+#define SPDM_SOCKET_TRANSPORT_TYPE_MCTP 0x01
+#define SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE 0x02
+
+#define SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE 0x1200
+
+#endif
diff --git a/include/sysemu/stats.h b/include/system/stats.h
index 42c236c..42c236c 100644
--- a/include/sysemu/stats.h
+++ b/include/system/stats.h
diff --git a/include/sysemu/sysemu.h b/include/system/system.h
index 5b4397e..a7effe7 100644
--- a/include/sysemu/sysemu.h
+++ b/include/system/system.h
@@ -1,5 +1,5 @@
-#ifndef SYSEMU_H
-#define SYSEMU_H
+#ifndef SYSTEM_H
+#define SYSTEM_H
/* Misc. things related to the system emulator. */
#include "qemu/timer.h"
@@ -15,6 +15,7 @@ extern bool qemu_uuid_set;
const char *qemu_get_vm_name(void);
+/* Exit notifiers will run with BQL held. */
void qemu_add_exit_notifier(Notifier *notify);
void qemu_remove_exit_notifier(Notifier *notify);
@@ -41,13 +42,22 @@ extern int graphic_height;
extern int graphic_depth;
extern int display_opengl;
extern const char *keyboard_layout;
-extern int graphic_rotate;
extern int old_param;
extern uint8_t *boot_splash_filedata;
-extern bool enable_mlock;
extern bool enable_cpu_pm;
extern QEMUClockType rtc_clock;
+typedef enum {
+ MLOCK_OFF = 0,
+ MLOCK_ON,
+ MLOCK_ON_FAULT,
+} MlockState;
+
+bool should_mlock(MlockState);
+bool is_mlock_on_fault(MlockState);
+
+extern MlockState mlock_state;
+
#define MAX_OPTION_ROMS 16
typedef struct QEMUOptionRom {
const char *name;
diff --git a/include/sysemu/tcg.h b/include/system/tcg.h
index 5e2ca9a..7622dce 100644
--- a/include/sysemu/tcg.h
+++ b/include/system/tcg.h
@@ -7,8 +7,8 @@
/* header to be included in non-TCG-specific code */
-#ifndef SYSEMU_TCG_H
-#define SYSEMU_TCG_H
+#ifndef SYSTEM_TCG_H
+#define SYSTEM_TCG_H
#ifdef CONFIG_TCG
extern bool tcg_allowed;
@@ -17,4 +17,12 @@ extern bool tcg_allowed;
#define tcg_enabled() 0
#endif
+/**
+ * qemu_tcg_mttcg_enabled:
+ * Check whether we are running MultiThread TCG or not.
+ *
+ * Returns: %true if we are in MTTCG mode %false otherwise.
+ */
+bool qemu_tcg_mttcg_enabled(void);
+
#endif
diff --git a/include/sysemu/tpm.h b/include/system/tpm.h
index 1ee568b..1ee568b 100644
--- a/include/sysemu/tpm.h
+++ b/include/system/tpm.h
diff --git a/include/sysemu/tpm_backend.h b/include/system/tpm_backend.h
index 7fabafe..01b11f6 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/system/tpm_backend.h
@@ -15,7 +15,7 @@
#include "qom/object.h"
#include "qemu/option.h"
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
#include "qapi/error.h"
#ifdef CONFIG_TPM
diff --git a/include/sysemu/tpm_util.h b/include/system/tpm_util.h
index 08f0517..1858693 100644
--- a/include/sysemu/tpm_util.h
+++ b/include/system/tpm_util.h
@@ -19,10 +19,10 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>
*/
-#ifndef SYSEMU_TPM_UTIL_H
-#define SYSEMU_TPM_UTIL_H
+#ifndef SYSTEM_TPM_UTIL_H
+#define SYSTEM_TPM_UTIL_H
-#include "sysemu/tpm.h"
+#include "system/tpm.h"
#include "qemu/bswap.h"
void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t out_len);
@@ -69,4 +69,4 @@ static inline void tpm_cmd_set_error(void *b, uint32_t error)
void tpm_util_show_buffer(const unsigned char *buffer,
size_t buffer_size, const char *string);
-#endif /* SYSEMU_TPM_UTIL_H */
+#endif /* SYSTEM_TPM_UTIL_H */
diff --git a/include/sysemu/vhost-user-backend.h b/include/system/vhost-user-backend.h
index 327b0b8..5634ebd 100644
--- a/include/sysemu/vhost-user-backend.h
+++ b/include/system/vhost-user-backend.h
@@ -13,7 +13,7 @@
#define QEMU_VHOST_USER_BACKEND_H
#include "qom/object.h"
-#include "exec/memory.h"
+#include "system/memory.h"
#include "qemu/option.h"
#include "qemu/bitmap.h"
#include "hw/virtio/vhost.h"
@@ -43,6 +43,6 @@ struct VhostUserBackend {
int vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
unsigned nvqs, Error **errp);
void vhost_user_backend_start(VhostUserBackend *b);
-void vhost_user_backend_stop(VhostUserBackend *b);
+int vhost_user_backend_stop(VhostUserBackend *b);
#endif
diff --git a/include/sysemu/watchdog.h b/include/system/watchdog.h
index 745c89b..745c89b 100644
--- a/include/sysemu/watchdog.h
+++ b/include/system/watchdog.h
diff --git a/include/sysemu/whpx.h b/include/system/whpx.h
index 00ff409..00ff409 100644
--- a/include/sysemu/whpx.h
+++ b/include/system/whpx.h
diff --git a/include/system/xen-mapcache.h b/include/system/xen-mapcache.h
new file mode 100644
index 0000000..bb454a7
--- /dev/null
+++ b/include/system/xen-mapcache.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 Citrix Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef XEN_MAPCACHE_H
+#define XEN_MAPCACHE_H
+
+#include "exec/cpu-common.h"
+#include "system/xen.h"
+
+typedef hwaddr (*phys_offset_to_gaddr_t)(hwaddr phys_offset,
+ ram_addr_t size);
+void xen_map_cache_init(phys_offset_to_gaddr_t f,
+ void *opaque);
+uint8_t *xen_map_cache(MemoryRegion *mr, hwaddr phys_addr, hwaddr size,
+ ram_addr_t ram_addr_offset,
+ uint8_t lock, bool dma,
+ bool is_write);
+ram_addr_t xen_ram_addr_from_mapcache(void *ptr);
+void xen_invalidate_map_cache_entry(uint8_t *buffer);
+void xen_invalidate_map_cache(void);
+uint8_t *xen_replace_cache_entry(hwaddr old_phys_addr,
+ hwaddr new_phys_addr,
+ hwaddr size);
+
+#endif /* XEN_MAPCACHE_H */
diff --git a/include/sysemu/xen.h b/include/system/xen.h
index d70eacf..c2f283d 100644
--- a/include/sysemu/xen.h
+++ b/include/system/xen.h
@@ -7,12 +7,8 @@
/* header to be included in non-Xen-specific code */
-#ifndef SYSEMU_XEN_H
-#define SYSEMU_XEN_H
-
-#ifdef CONFIG_USER_ONLY
-#error Cannot include sysemu/xen.h from user emulation
-#endif
+#ifndef SYSTEM_XEN_H
+#define SYSTEM_XEN_H
#include "exec/cpu-common.h"
@@ -25,30 +21,15 @@
#endif /* COMPILING_PER_TARGET */
#ifdef CONFIG_XEN_IS_POSSIBLE
-
extern bool xen_allowed;
-
#define xen_enabled() (xen_allowed)
-
-void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length);
-void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
- struct MemoryRegion *mr, Error **errp);
-
#else /* !CONFIG_XEN_IS_POSSIBLE */
-
#define xen_enabled() 0
-static inline void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length)
-{
- /* nothing */
-}
-static inline void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
- MemoryRegion *mr, Error **errp)
-{
- g_assert_not_reached();
-}
-
#endif /* CONFIG_XEN_IS_POSSIBLE */
+void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length);
+void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size,
+ struct MemoryRegion *mr, Error **errp);
bool xen_mr_is_memory(MemoryRegion *mr);
bool xen_mr_is_grants(MemoryRegion *mr);
#endif
diff --git a/include/tcg/insn-start-words.h b/include/tcg/insn-start-words.h
index 50c18bd..c52aec5 100644
--- a/include/tcg/insn-start-words.h
+++ b/include/tcg/insn-start-words.h
@@ -1,17 +1,12 @@
/* SPDX-License-Identifier: MIT */
/*
- * Define TARGET_INSN_START_WORDS
+ * Define INSN_START_WORDS
* Copyright (c) 2008 Fabrice Bellard
*/
-#ifndef TARGET_INSN_START_WORDS
+#ifndef TCG_INSN_START_WORDS
+#define TCG_INSN_START_WORDS
-#include "cpu.h"
+#define INSN_START_WORDS 3
-#ifndef TARGET_INSN_START_EXTRA_WORDS
-# define TARGET_INSN_START_WORDS 1
-#else
-# define TARGET_INSN_START_WORDS (1 + TARGET_INSN_START_EXTRA_WORDS)
-#endif
-
-#endif /* TARGET_INSN_START_WORDS */
+#endif /* TCG_INSN_START_WORDS */
diff --git a/include/tcg/oversized-guest.h b/include/tcg/oversized-guest.h
deleted file mode 100644
index 641b974..0000000
--- a/include/tcg/oversized-guest.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Define TCG_OVERSIZED_GUEST
- * Copyright (c) 2008 Fabrice Bellard
- */
-
-#ifndef EXEC_TCG_OVERSIZED_GUEST_H
-#define EXEC_TCG_OVERSIZED_GUEST_H
-
-#include "tcg-target-reg-bits.h"
-#include "cpu-param.h"
-
-/*
- * Oversized TCG guests make things like MTTCG hard
- * as we can't use atomics for cputlb updates.
- */
-#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
-#define TCG_OVERSIZED_GUEST 1
-#else
-#define TCG_OVERSIZED_GUEST 0
-#endif
-
-#endif
diff --git a/include/tcg/startup.h b/include/tcg/startup.h
index f713057..95f574a 100644
--- a/include/tcg/startup.h
+++ b/include/tcg/startup.h
@@ -29,12 +29,12 @@
* tcg_init: Initialize the TCG runtime
* @tb_size: translation buffer size
* @splitwx: use separate rw and rx mappings
- * @max_cpus: number of vcpus in system mode
+ * @max_threads: number of vcpu threads in system mode
*
* Allocate and initialize TCG resources, especially the JIT buffer.
- * In user-only mode, @max_cpus is unused.
+ * In user-only mode, @max_threads is unused.
*/
-void tcg_init(size_t tb_size, int splitwx, unsigned max_cpus);
+void tcg_init(size_t tb_size, int splitwx, unsigned max_threads);
/**
* tcg_register_thread: Register this thread with the TCG runtime
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
index 009e277..e1071ad 100644
--- a/include/tcg/tcg-op-common.h
+++ b/include/tcg/tcg-op-common.h
@@ -14,6 +14,7 @@
TCGv_i32 tcg_constant_i32(int32_t val);
TCGv_i64 tcg_constant_i64(int64_t val);
+TCGv_vaddr tcg_constant_vaddr(uintptr_t val);
TCGv_vec tcg_constant_vec(TCGType type, unsigned vece, int64_t val);
TCGv_vec tcg_constant_vec_matching(TCGv_vec match, unsigned vece, int64_t val);
@@ -135,6 +136,8 @@ void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh);
void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh);
+void tcg_gen_addcio_i32(TCGv_i32 r, TCGv_i32 co,
+ TCGv_i32 a, TCGv_i32 b, TCGv_i32 ci);
void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
void tcg_gen_mulsu2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 arg1, TCGv_i32 arg2);
@@ -238,6 +241,8 @@ void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh);
void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh);
+void tcg_gen_addcio_i64(TCGv_i64 r, TCGv_i64 co,
+ TCGv_i64 a, TCGv_i64 b, TCGv_i64 ci);
void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2);
diff --git a/include/tcg/tcg-op-gvec-common.h b/include/tcg/tcg-op-gvec-common.h
index 65553f5..ea0c87f 100644
--- a/include/tcg/tcg-op-gvec-common.h
+++ b/include/tcg/tcg-op-gvec-common.h
@@ -227,25 +227,66 @@ typedef struct {
bool prefer_i64;
} GVecGen4i;
+/* Expand (dbase+dofs) = op(abase+aofs), length @oprsz, clearing to @maxsz. */
+void tcg_gen_gvec_2_var(TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ uint32_t oprsz, uint32_t maxsz, const GVecGen2 *op);
+/* Similarly, expand (env+dofs) = op(env+aofs). */
void tcg_gen_gvec_2(uint32_t dofs, uint32_t aofs,
- uint32_t oprsz, uint32_t maxsz, const GVecGen2 *);
+ uint32_t oprsz, uint32_t maxsz, const GVecGen2 *op);
+/* Similarly, expand (env+dofs) = op(env+aofs, c). */
void tcg_gen_gvec_2i(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
- uint32_t maxsz, int64_t c, const GVecGen2i *);
+ uint32_t maxsz, int64_t c, const GVecGen2i *op);
+/* Similarly, expand (env+dofs) = op(env+aofs, s). */
void tcg_gen_gvec_2s(uint32_t dofs, uint32_t aofs, uint32_t oprsz,
- uint32_t maxsz, TCGv_i64 c, const GVecGen2s *);
+ uint32_t maxsz, TCGv_i64 c, const GVecGen2s *op);
+
+/*
+ * Expand (dbase+dofs) = op(abase+aofs, bbase+bofs),
+ * length @oprsz, clearing to @maxsz.
+ */
+void tcg_gen_gvec_3_var(TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ TCGv_ptr bbase, uint32_t bofs,
+ uint32_t oprsz, uint32_t maxsz, const GVecGen3 *op);
+/* Similarly, expand (env+dofs) = op(env+aofs, env+bofs). */
void tcg_gen_gvec_3(uint32_t dofs, uint32_t aofs, uint32_t bofs,
- uint32_t oprsz, uint32_t maxsz, const GVecGen3 *);
+ uint32_t oprsz, uint32_t maxsz, const GVecGen3 *op);
+
+/*
+ * Depending on op->load_dest and op->write_aofs, expand
+ * (env+dofs) = op(env+aofs, env+bofs, c)
+ * or
+ * (env+dofs) = op(env+dofs, env+aofs, env+bofs, c)
+ * or
+ * (env+dofs), (env+aofs) = op(env+aofs, env+bofs, c)
+ * or
+ * (env+dofs), (env+aofs) = op(env+dofs, env+aofs, env+bofs, c)
+ */
void tcg_gen_gvec_3i(uint32_t dofs, uint32_t aofs, uint32_t bofs,
uint32_t oprsz, uint32_t maxsz, int64_t c,
- const GVecGen3i *);
+ const GVecGen3i *op);
+
+/*
+ * Depending on op->write_aofs, expand
+ * (env+dofs) = op(env+aofs, env+bofs, env+cofs)
+ * or
+ * (env+dofs), (env+aofs) = op(env+aofs, env+bofs, env+cofs)
+ */
void tcg_gen_gvec_4(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs,
uint32_t oprsz, uint32_t maxsz, const GVecGen4 *);
+
+/* Expand (env+dofs) = op(env+aofs, env+bofs, env+cofs, c). */
void tcg_gen_gvec_4i(uint32_t dofs, uint32_t aofs, uint32_t bofs, uint32_t cofs,
uint32_t oprsz, uint32_t maxsz, int64_t c,
const GVecGen4i *);
/* Expand a specific vector operation. */
+void tcg_gen_gvec_mov_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ uint32_t oprsz, uint32_t maxsz);
+
void tcg_gen_gvec_mov(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_not(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -255,6 +296,15 @@ void tcg_gen_gvec_neg(unsigned vece, uint32_t dofs, uint32_t aofs,
void tcg_gen_gvec_abs(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_add_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ TCGv_ptr bbase, uint32_t bofs,
+ uint32_t oprsz, uint32_t maxsz);
+void tcg_gen_gvec_sub_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ TCGv_ptr abase, uint32_t aofs,
+ TCGv_ptr bbase, uint32_t bofs,
+ uint32_t oprsz, uint32_t maxsz);
+
void tcg_gen_gvec_add(unsigned vece, uint32_t dofs, uint32_t aofs,
uint32_t bofs, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_sub(unsigned vece, uint32_t dofs, uint32_t aofs,
@@ -336,6 +386,9 @@ void tcg_gen_gvec_dup_i32(unsigned vece, uint32_t dofs, uint32_t s,
void tcg_gen_gvec_dup_i64(unsigned vece, uint32_t dofs, uint32_t s,
uint32_t m, TCGv_i64);
+void tcg_gen_gvec_dup_imm_var(unsigned vece, TCGv_ptr dbase, uint32_t dofs,
+ uint32_t oprsz, uint32_t maxsz, uint64_t imm);
+
void tcg_gen_gvec_shli(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t shift, uint32_t oprsz, uint32_t maxsz);
void tcg_gen_gvec_shri(unsigned vece, uint32_t dofs, uint32_t aofs,
diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index a028505..c912578 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -9,6 +9,8 @@
#define TCG_TCG_OP_H
#include "tcg/tcg-op-common.h"
+#include "tcg/insn-start-words.h"
+#include "exec/target_long.h"
#ifndef TARGET_LONG_BITS
#error must include QEMU headers
@@ -22,24 +24,34 @@
# error
#endif
-#ifndef TARGET_INSN_START_EXTRA_WORDS
+#if INSN_START_WORDS != 3
+# error Mismatch with insn-start-words.h
+#endif
+
+#if TARGET_INSN_START_EXTRA_WORDS == 0
static inline void tcg_gen_insn_start(target_ulong pc)
{
- TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 64 / TCG_TARGET_REG_BITS);
+ TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
+ INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
tcg_set_insn_start_param(op, 0, pc);
+ tcg_set_insn_start_param(op, 1, 0);
+ tcg_set_insn_start_param(op, 2, 0);
}
#elif TARGET_INSN_START_EXTRA_WORDS == 1
static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1)
{
- TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 2 * 64 / TCG_TARGET_REG_BITS);
+ TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
+ INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
tcg_set_insn_start_param(op, 0, pc);
tcg_set_insn_start_param(op, 1, a1);
+ tcg_set_insn_start_param(op, 2, 0);
}
#elif TARGET_INSN_START_EXTRA_WORDS == 2
static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1,
target_ulong a2)
{
- TCGOp *op = tcg_emit_op(INDEX_op_insn_start, 3 * 64 / TCG_TARGET_REG_BITS);
+ TCGOp *op = tcg_emit_op(INDEX_op_insn_start,
+ INSN_START_WORDS * 64 / TCG_TARGET_REG_BITS);
tcg_set_insn_start_param(op, 0, pc);
tcg_set_insn_start_param(op, 1, a1);
tcg_set_insn_start_param(op, 2, a2);
@@ -252,6 +264,7 @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
#define tcg_gen_movcond_tl tcg_gen_movcond_i64
#define tcg_gen_add2_tl tcg_gen_add2_i64
#define tcg_gen_sub2_tl tcg_gen_sub2_i64
+#define tcg_gen_addcio_tl tcg_gen_addcio_i64
#define tcg_gen_mulu2_tl tcg_gen_mulu2_i64
#define tcg_gen_muls2_tl tcg_gen_muls2_i64
#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i64
@@ -370,6 +383,7 @@ DEF_ATOMIC2(tcg_gen_atomic_umax_fetch, i64)
#define tcg_gen_movcond_tl tcg_gen_movcond_i32
#define tcg_gen_add2_tl tcg_gen_add2_i32
#define tcg_gen_sub2_tl tcg_gen_sub2_i32
+#define tcg_gen_addcio_tl tcg_gen_addcio_i32
#define tcg_gen_mulu2_tl tcg_gen_mulu2_i32
#define tcg_gen_muls2_tl tcg_gen_muls2_i32
#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i32
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
index 546eb49..e988edd 100644
--- a/include/tcg/tcg-opc.h
+++ b/include/tcg/tcg-opc.h
@@ -33,286 +33,160 @@ DEF(set_label, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
/* variable number of parameters */
DEF(call, 0, 0, 3, TCG_OPF_CALL_CLOBBER | TCG_OPF_NOT_PRESENT)
-DEF(br, 0, 0, 1, TCG_OPF_BB_END)
-
-#define IMPL(X) (__builtin_constant_p(X) && (X) <= 0 ? TCG_OPF_NOT_PRESENT : 0)
-#if TCG_TARGET_REG_BITS == 32
-# define IMPL64 TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT
-#else
-# define IMPL64 TCG_OPF_64BIT
-#endif
-
-DEF(mb, 0, 0, 1, 0)
-
-DEF(mov_i32, 1, 1, 0, TCG_OPF_NOT_PRESENT)
-DEF(setcond_i32, 1, 2, 1, 0)
-DEF(negsetcond_i32, 1, 2, 1, IMPL(TCG_TARGET_HAS_negsetcond_i32))
-DEF(movcond_i32, 1, 4, 1, 0)
-/* load/store */
-DEF(ld8u_i32, 1, 1, 1, 0)
-DEF(ld8s_i32, 1, 1, 1, 0)
-DEF(ld16u_i32, 1, 1, 1, 0)
-DEF(ld16s_i32, 1, 1, 1, 0)
-DEF(ld_i32, 1, 1, 1, 0)
-DEF(st8_i32, 0, 2, 1, 0)
-DEF(st16_i32, 0, 2, 1, 0)
-DEF(st_i32, 0, 2, 1, 0)
-/* arith */
-DEF(add_i32, 1, 2, 0, 0)
-DEF(sub_i32, 1, 2, 0, 0)
-DEF(mul_i32, 1, 2, 0, 0)
-DEF(div_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
-DEF(divu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
-DEF(rem_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32))
-DEF(remu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rem_i32))
-DEF(div2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
-DEF(divu2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
-DEF(and_i32, 1, 2, 0, 0)
-DEF(or_i32, 1, 2, 0, 0)
-DEF(xor_i32, 1, 2, 0, 0)
-/* shifts/rotates */
-DEF(shl_i32, 1, 2, 0, 0)
-DEF(shr_i32, 1, 2, 0, 0)
-DEF(sar_i32, 1, 2, 0, 0)
-DEF(rotl_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
-DEF(rotr_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
-DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32))
-DEF(extract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_extract_i32))
-DEF(sextract_i32, 1, 1, 2, IMPL(TCG_TARGET_HAS_sextract_i32))
-DEF(extract2_i32, 1, 2, 1, IMPL(TCG_TARGET_HAS_extract2_i32))
-
-DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
-
-DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_add2_i32))
-DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32))
-DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32))
-DEF(muls2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_muls2_i32))
-DEF(muluh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i32))
-DEF(mulsh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i32))
-DEF(brcond2_i32, 0, 4, 2,
- TCG_OPF_BB_END | TCG_OPF_COND_BRANCH | IMPL(TCG_TARGET_REG_BITS == 32))
-DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32))
-
-DEF(ext8s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8s_i32))
-DEF(ext16s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16s_i32))
-DEF(ext8u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8u_i32))
-DEF(ext16u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16u_i32))
-DEF(bswap16_i32, 1, 1, 1, IMPL(TCG_TARGET_HAS_bswap16_i32))
-DEF(bswap32_i32, 1, 1, 1, IMPL(TCG_TARGET_HAS_bswap32_i32))
-DEF(not_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_not_i32))
-DEF(neg_i32, 1, 1, 0, 0)
-DEF(andc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_andc_i32))
-DEF(orc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_orc_i32))
-DEF(eqv_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_eqv_i32))
-DEF(nand_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nand_i32))
-DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32))
-DEF(clz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_clz_i32))
-DEF(ctz_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_ctz_i32))
-DEF(ctpop_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ctpop_i32))
-
-DEF(mov_i64, 1, 1, 0, TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT)
-DEF(setcond_i64, 1, 2, 1, IMPL64)
-DEF(negsetcond_i64, 1, 2, 1, IMPL64 | IMPL(TCG_TARGET_HAS_negsetcond_i64))
-DEF(movcond_i64, 1, 4, 1, IMPL64)
-/* load/store */
-DEF(ld8u_i64, 1, 1, 1, IMPL64)
-DEF(ld8s_i64, 1, 1, 1, IMPL64)
-DEF(ld16u_i64, 1, 1, 1, IMPL64)
-DEF(ld16s_i64, 1, 1, 1, IMPL64)
-DEF(ld32u_i64, 1, 1, 1, IMPL64)
-DEF(ld32s_i64, 1, 1, 1, IMPL64)
-DEF(ld_i64, 1, 1, 1, IMPL64)
-DEF(st8_i64, 0, 2, 1, IMPL64)
-DEF(st16_i64, 0, 2, 1, IMPL64)
-DEF(st32_i64, 0, 2, 1, IMPL64)
-DEF(st_i64, 0, 2, 1, IMPL64)
-/* arith */
-DEF(add_i64, 1, 2, 0, IMPL64)
-DEF(sub_i64, 1, 2, 0, IMPL64)
-DEF(mul_i64, 1, 2, 0, IMPL64)
-DEF(div_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
-DEF(divu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
-DEF(rem_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64))
-DEF(remu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rem_i64))
-DEF(div2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
-DEF(divu2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
-DEF(and_i64, 1, 2, 0, IMPL64)
-DEF(or_i64, 1, 2, 0, IMPL64)
-DEF(xor_i64, 1, 2, 0, IMPL64)
-/* shifts/rotates */
-DEF(shl_i64, 1, 2, 0, IMPL64)
-DEF(shr_i64, 1, 2, 0, IMPL64)
-DEF(sar_i64, 1, 2, 0, IMPL64)
-DEF(rotl_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
-DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
-DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64))
-DEF(extract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_extract_i64))
-DEF(sextract_i64, 1, 1, 2, IMPL64 | IMPL(TCG_TARGET_HAS_sextract_i64))
-DEF(extract2_i64, 1, 2, 1, IMPL64 | IMPL(TCG_TARGET_HAS_extract2_i64))
+DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
+DEF(brcond, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH | TCG_OPF_INT)
+
+DEF(mb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
+
+DEF(mov, 1, 1, 0, TCG_OPF_INT | TCG_OPF_NOT_PRESENT)
+
+DEF(add, 1, 2, 0, TCG_OPF_INT)
+DEF(and, 1, 2, 0, TCG_OPF_INT)
+DEF(andc, 1, 2, 0, TCG_OPF_INT)
+DEF(bswap16, 1, 1, 1, TCG_OPF_INT)
+DEF(bswap32, 1, 1, 1, TCG_OPF_INT)
+DEF(bswap64, 1, 1, 1, TCG_OPF_INT)
+DEF(clz, 1, 2, 0, TCG_OPF_INT)
+DEF(ctpop, 1, 1, 0, TCG_OPF_INT)
+DEF(ctz, 1, 2, 0, TCG_OPF_INT)
+DEF(deposit, 1, 2, 2, TCG_OPF_INT)
+DEF(divs, 1, 2, 0, TCG_OPF_INT)
+DEF(divs2, 2, 3, 0, TCG_OPF_INT)
+DEF(divu, 1, 2, 0, TCG_OPF_INT)
+DEF(divu2, 2, 3, 0, TCG_OPF_INT)
+DEF(eqv, 1, 2, 0, TCG_OPF_INT)
+DEF(extract, 1, 1, 2, TCG_OPF_INT)
+DEF(extract2, 1, 2, 1, TCG_OPF_INT)
+DEF(ld8u, 1, 1, 1, TCG_OPF_INT)
+DEF(ld8s, 1, 1, 1, TCG_OPF_INT)
+DEF(ld16u, 1, 1, 1, TCG_OPF_INT)
+DEF(ld16s, 1, 1, 1, TCG_OPF_INT)
+DEF(ld32u, 1, 1, 1, TCG_OPF_INT)
+DEF(ld32s, 1, 1, 1, TCG_OPF_INT)
+DEF(ld, 1, 1, 1, TCG_OPF_INT)
+DEF(movcond, 1, 4, 1, TCG_OPF_INT)
+DEF(mul, 1, 2, 0, TCG_OPF_INT)
+DEF(muls2, 2, 2, 0, TCG_OPF_INT)
+DEF(mulsh, 1, 2, 0, TCG_OPF_INT)
+DEF(mulu2, 2, 2, 0, TCG_OPF_INT)
+DEF(muluh, 1, 2, 0, TCG_OPF_INT)
+DEF(nand, 1, 2, 0, TCG_OPF_INT)
+DEF(neg, 1, 1, 0, TCG_OPF_INT)
+DEF(negsetcond, 1, 2, 1, TCG_OPF_INT)
+DEF(nor, 1, 2, 0, TCG_OPF_INT)
+DEF(not, 1, 1, 0, TCG_OPF_INT)
+DEF(or, 1, 2, 0, TCG_OPF_INT)
+DEF(orc, 1, 2, 0, TCG_OPF_INT)
+DEF(rems, 1, 2, 0, TCG_OPF_INT)
+DEF(remu, 1, 2, 0, TCG_OPF_INT)
+DEF(rotl, 1, 2, 0, TCG_OPF_INT)
+DEF(rotr, 1, 2, 0, TCG_OPF_INT)
+DEF(sar, 1, 2, 0, TCG_OPF_INT)
+DEF(setcond, 1, 2, 1, TCG_OPF_INT)
+DEF(sextract, 1, 1, 2, TCG_OPF_INT)
+DEF(shl, 1, 2, 0, TCG_OPF_INT)
+DEF(shr, 1, 2, 0, TCG_OPF_INT)
+DEF(st8, 0, 2, 1, TCG_OPF_INT)
+DEF(st16, 0, 2, 1, TCG_OPF_INT)
+DEF(st32, 0, 2, 1, TCG_OPF_INT)
+DEF(st, 0, 2, 1, TCG_OPF_INT)
+DEF(sub, 1, 2, 0, TCG_OPF_INT)
+DEF(xor, 1, 2, 0, TCG_OPF_INT)
+
+DEF(addco, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_OUT)
+DEF(addc1o, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_OUT)
+DEF(addci, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_IN)
+DEF(addcio, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_IN | TCG_OPF_CARRY_OUT)
+
+DEF(subbo, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_OUT)
+DEF(subb1o, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_OUT)
+DEF(subbi, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_IN)
+DEF(subbio, 1, 2, 0, TCG_OPF_INT | TCG_OPF_CARRY_IN | TCG_OPF_CARRY_OUT)
+
+DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH)
+DEF(setcond2_i32, 1, 4, 1, 0)
/* size changing ops */
-DEF(ext_i32_i64, 1, 1, 0, IMPL64)
-DEF(extu_i32_i64, 1, 1, 0, IMPL64)
-DEF(extrl_i64_i32, 1, 1, 0,
- IMPL(TCG_TARGET_HAS_extr_i64_i32)
- | (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0))
-DEF(extrh_i64_i32, 1, 1, 0,
- IMPL(TCG_TARGET_HAS_extr_i64_i32)
- | (TCG_TARGET_REG_BITS == 32 ? TCG_OPF_NOT_PRESENT : 0))
-
-DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_COND_BRANCH | IMPL64)
-DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64))
-DEF(ext16s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16s_i64))
-DEF(ext32s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32s_i64))
-DEF(ext8u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8u_i64))
-DEF(ext16u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16u_i64))
-DEF(ext32u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32u_i64))
-DEF(bswap16_i64, 1, 1, 1, IMPL64 | IMPL(TCG_TARGET_HAS_bswap16_i64))
-DEF(bswap32_i64, 1, 1, 1, IMPL64 | IMPL(TCG_TARGET_HAS_bswap32_i64))
-DEF(bswap64_i64, 1, 1, 1, IMPL64 | IMPL(TCG_TARGET_HAS_bswap64_i64))
-DEF(not_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_not_i64))
-DEF(neg_i64, 1, 1, 0, IMPL64)
-DEF(andc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_andc_i64))
-DEF(orc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_orc_i64))
-DEF(eqv_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_eqv_i64))
-DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64))
-DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64))
-DEF(clz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_clz_i64))
-DEF(ctz_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctz_i64))
-DEF(ctpop_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ctpop_i64))
-
-DEF(add2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_add2_i64))
-DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64))
-DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64))
-DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64))
-DEF(muluh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muluh_i64))
-DEF(mulsh_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulsh_i64))
+DEF(ext_i32_i64, 1, 1, 0, 0)
+DEF(extu_i32_i64, 1, 1, 0, 0)
+DEF(extrl_i64_i32, 1, 1, 0, 0)
+DEF(extrh_i64_i32, 1, 1, 0, 0)
#define DATA64_ARGS (TCG_TARGET_REG_BITS == 64 ? 1 : 2)
-/* There are tcg_ctx->insn_start_words here, not just one. */
-DEF(insn_start, 0, 0, DATA64_ARGS, TCG_OPF_NOT_PRESENT)
+DEF(insn_start, 0, 0, DATA64_ARGS * INSN_START_WORDS, TCG_OPF_NOT_PRESENT)
-DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
-DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
+DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END | TCG_OPF_NOT_PRESENT)
DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(plugin_mem_cb, 0, 1, 1, TCG_OPF_NOT_PRESENT)
-/* Replicate ld/st ops for 32 and 64-bit guest addresses. */
-DEF(qemu_ld_a32_i32, 1, 1, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF(qemu_st_a32_i32, 0, 1 + 1, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF(qemu_ld_a32_i64, DATA64_ARGS, 1, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-DEF(qemu_st_a32_i64, 0, DATA64_ARGS + 1, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-
-DEF(qemu_ld_a64_i32, 1, DATA64_ARGS, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF(qemu_st_a64_i32, 0, 1 + DATA64_ARGS, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
-DEF(qemu_ld_a64_i64, DATA64_ARGS, DATA64_ARGS, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-DEF(qemu_st_a64_i64, 0, DATA64_ARGS + DATA64_ARGS, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-
-/* Only used by i386 to cope with stupid register constraints. */
-DEF(qemu_st8_a32_i32, 0, 1 + 1, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS |
- IMPL(TCG_TARGET_HAS_qemu_st8_i32))
-DEF(qemu_st8_a64_i32, 0, 1 + DATA64_ARGS, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS |
- IMPL(TCG_TARGET_HAS_qemu_st8_i32))
-
-/* Only for 64-bit hosts at the moment. */
-DEF(qemu_ld_a32_i128, 2, 1, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
- IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
-DEF(qemu_ld_a64_i128, 2, 1, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
- IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
-DEF(qemu_st_a32_i128, 0, 3, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
- IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
-DEF(qemu_st_a64_i128, 0, 3, 1,
- TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT |
- IMPL(TCG_TARGET_HAS_qemu_ldst_i128))
+DEF(qemu_ld, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_INT)
+DEF(qemu_st, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_INT)
+DEF(qemu_ld2, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_INT)
+DEF(qemu_st2, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS | TCG_OPF_INT)
/* Host vector support. */
-#define IMPLVEC TCG_OPF_VECTOR | IMPL(TCG_TARGET_MAYBE_vec)
-
DEF(mov_vec, 1, 1, 0, TCG_OPF_VECTOR | TCG_OPF_NOT_PRESENT)
-DEF(dup_vec, 1, 1, 0, IMPLVEC)
-DEF(dup2_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_REG_BITS == 32))
-
-DEF(ld_vec, 1, 1, 1, IMPLVEC)
-DEF(st_vec, 0, 2, 1, IMPLVEC)
-DEF(dupm_vec, 1, 1, 1, IMPLVEC)
-
-DEF(add_vec, 1, 2, 0, IMPLVEC)
-DEF(sub_vec, 1, 2, 0, IMPLVEC)
-DEF(mul_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_mul_vec))
-DEF(neg_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_neg_vec))
-DEF(abs_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_abs_vec))
-DEF(ssadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
-DEF(usadd_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
-DEF(sssub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
-DEF(ussub_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_sat_vec))
-DEF(smin_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
-DEF(umin_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
-DEF(smax_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
-DEF(umax_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_minmax_vec))
-
-DEF(and_vec, 1, 2, 0, IMPLVEC)
-DEF(or_vec, 1, 2, 0, IMPLVEC)
-DEF(xor_vec, 1, 2, 0, IMPLVEC)
-DEF(andc_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_andc_vec))
-DEF(orc_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_orc_vec))
-DEF(nand_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_nand_vec))
-DEF(nor_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_nor_vec))
-DEF(eqv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_eqv_vec))
-DEF(not_vec, 1, 1, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_not_vec))
-
-DEF(shli_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_shi_vec))
-DEF(shri_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_shi_vec))
-DEF(sari_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_shi_vec))
-DEF(rotli_vec, 1, 1, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_roti_vec))
-
-DEF(shls_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shs_vec))
-DEF(shrs_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shs_vec))
-DEF(sars_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shs_vec))
-DEF(rotls_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_rots_vec))
-
-DEF(shlv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shv_vec))
-DEF(shrv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shv_vec))
-DEF(sarv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_shv_vec))
-DEF(rotlv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_rotv_vec))
-DEF(rotrv_vec, 1, 2, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_rotv_vec))
-
-DEF(cmp_vec, 1, 2, 1, IMPLVEC)
-
-DEF(bitsel_vec, 1, 3, 0, IMPLVEC | IMPL(TCG_TARGET_HAS_bitsel_vec))
-DEF(cmpsel_vec, 1, 4, 1, IMPLVEC | IMPL(TCG_TARGET_HAS_cmpsel_vec))
+DEF(dup_vec, 1, 1, 0, TCG_OPF_VECTOR)
+DEF(dup2_vec, 1, 2, 0, TCG_OPF_VECTOR)
+
+DEF(ld_vec, 1, 1, 1, TCG_OPF_VECTOR)
+DEF(st_vec, 0, 2, 1, TCG_OPF_VECTOR)
+DEF(dupm_vec, 1, 1, 1, TCG_OPF_VECTOR)
+
+DEF(add_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(sub_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(mul_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(neg_vec, 1, 1, 0, TCG_OPF_VECTOR)
+DEF(abs_vec, 1, 1, 0, TCG_OPF_VECTOR)
+DEF(ssadd_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(usadd_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(sssub_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(ussub_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(smin_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(umin_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(smax_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(umax_vec, 1, 2, 0, TCG_OPF_VECTOR)
+
+DEF(and_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(or_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(xor_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(andc_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(orc_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(nand_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(nor_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(eqv_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(not_vec, 1, 1, 0, TCG_OPF_VECTOR)
+
+DEF(shli_vec, 1, 1, 1, TCG_OPF_VECTOR)
+DEF(shri_vec, 1, 1, 1, TCG_OPF_VECTOR)
+DEF(sari_vec, 1, 1, 1, TCG_OPF_VECTOR)
+DEF(rotli_vec, 1, 1, 1, TCG_OPF_VECTOR)
+
+DEF(shls_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(shrs_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(sars_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(rotls_vec, 1, 2, 0, TCG_OPF_VECTOR)
+
+DEF(shlv_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(shrv_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(sarv_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(rotlv_vec, 1, 2, 0, TCG_OPF_VECTOR)
+DEF(rotrv_vec, 1, 2, 0, TCG_OPF_VECTOR)
+
+DEF(cmp_vec, 1, 2, 1, TCG_OPF_VECTOR)
+
+DEF(bitsel_vec, 1, 3, 0, TCG_OPF_VECTOR)
+DEF(cmpsel_vec, 1, 4, 1, TCG_OPF_VECTOR)
DEF(last_generic, 0, 0, 0, TCG_OPF_NOT_PRESENT)
-#if TCG_TARGET_MAYBE_vec
-#include "tcg-target.opc.h"
-#endif
-
-#ifdef TCG_TARGET_INTERPRETER
-/* These opcodes are only for use between the tci generator and interpreter. */
-DEF(tci_movi, 1, 0, 1, TCG_OPF_NOT_PRESENT)
-DEF(tci_movl, 1, 0, 1, TCG_OPF_NOT_PRESENT)
-#endif
+#include "tcg-target-opc.h.inc"
#undef DATA64_ARGS
-#undef IMPL
-#undef IMPL64
-#undef IMPLVEC
#undef DEF
diff --git a/include/tcg/tcg-temp-internal.h b/include/tcg/tcg-temp-internal.h
index 44192c5..98f91e6 100644
--- a/include/tcg/tcg-temp-internal.h
+++ b/include/tcg/tcg-temp-internal.h
@@ -42,4 +42,10 @@ TCGv_i64 tcg_temp_ebb_new_i64(void);
TCGv_ptr tcg_temp_ebb_new_ptr(void);
TCGv_i128 tcg_temp_ebb_new_i128(void);
+/* Forget all freed EBB temps, so that new allocations produce new temps. */
+static inline void tcg_temp_ebb_reset_freed(TCGContext *s)
+{
+ memset(s->free_temps, 0, sizeof(s->free_temps));
+}
+
#endif /* TCG_TEMP_FREE_H */
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 21d5884..125323f 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -34,6 +34,7 @@
#include "tcg-target-reg-bits.h"
#include "tcg-target.h"
#include "tcg/tcg-cond.h"
+#include "tcg/insn-start-words.h"
#include "tcg/debug-assert.h"
/* XXX: make safe guess about sizes */
@@ -64,111 +65,6 @@ typedef uint64_t TCGRegSet;
#error unsupported
#endif
-#if TCG_TARGET_REG_BITS == 32
-/* Turn some undef macros into false macros. */
-#define TCG_TARGET_HAS_extr_i64_i32 0
-#define TCG_TARGET_HAS_div_i64 0
-#define TCG_TARGET_HAS_rem_i64 0
-#define TCG_TARGET_HAS_div2_i64 0
-#define TCG_TARGET_HAS_rot_i64 0
-#define TCG_TARGET_HAS_ext8s_i64 0
-#define TCG_TARGET_HAS_ext16s_i64 0
-#define TCG_TARGET_HAS_ext32s_i64 0
-#define TCG_TARGET_HAS_ext8u_i64 0
-#define TCG_TARGET_HAS_ext16u_i64 0
-#define TCG_TARGET_HAS_ext32u_i64 0
-#define TCG_TARGET_HAS_bswap16_i64 0
-#define TCG_TARGET_HAS_bswap32_i64 0
-#define TCG_TARGET_HAS_bswap64_i64 0
-#define TCG_TARGET_HAS_not_i64 0
-#define TCG_TARGET_HAS_andc_i64 0
-#define TCG_TARGET_HAS_orc_i64 0
-#define TCG_TARGET_HAS_eqv_i64 0
-#define TCG_TARGET_HAS_nand_i64 0
-#define TCG_TARGET_HAS_nor_i64 0
-#define TCG_TARGET_HAS_clz_i64 0
-#define TCG_TARGET_HAS_ctz_i64 0
-#define TCG_TARGET_HAS_ctpop_i64 0
-#define TCG_TARGET_HAS_deposit_i64 0
-#define TCG_TARGET_HAS_extract_i64 0
-#define TCG_TARGET_HAS_sextract_i64 0
-#define TCG_TARGET_HAS_extract2_i64 0
-#define TCG_TARGET_HAS_negsetcond_i64 0
-#define TCG_TARGET_HAS_add2_i64 0
-#define TCG_TARGET_HAS_sub2_i64 0
-#define TCG_TARGET_HAS_mulu2_i64 0
-#define TCG_TARGET_HAS_muls2_i64 0
-#define TCG_TARGET_HAS_muluh_i64 0
-#define TCG_TARGET_HAS_mulsh_i64 0
-/* Turn some undef macros into true macros. */
-#define TCG_TARGET_HAS_add2_i32 1
-#define TCG_TARGET_HAS_sub2_i32 1
-#endif
-
-#ifndef TCG_TARGET_deposit_i32_valid
-#define TCG_TARGET_deposit_i32_valid(ofs, len) 1
-#endif
-#ifndef TCG_TARGET_deposit_i64_valid
-#define TCG_TARGET_deposit_i64_valid(ofs, len) 1
-#endif
-#ifndef TCG_TARGET_extract_i32_valid
-#define TCG_TARGET_extract_i32_valid(ofs, len) 1
-#endif
-#ifndef TCG_TARGET_extract_i64_valid
-#define TCG_TARGET_extract_i64_valid(ofs, len) 1
-#endif
-
-/* Only one of DIV or DIV2 should be defined. */
-#if defined(TCG_TARGET_HAS_div_i32)
-#define TCG_TARGET_HAS_div2_i32 0
-#elif defined(TCG_TARGET_HAS_div2_i32)
-#define TCG_TARGET_HAS_div_i32 0
-#define TCG_TARGET_HAS_rem_i32 0
-#endif
-#if defined(TCG_TARGET_HAS_div_i64)
-#define TCG_TARGET_HAS_div2_i64 0
-#elif defined(TCG_TARGET_HAS_div2_i64)
-#define TCG_TARGET_HAS_div_i64 0
-#define TCG_TARGET_HAS_rem_i64 0
-#endif
-
-#if !defined(TCG_TARGET_HAS_v64) \
- && !defined(TCG_TARGET_HAS_v128) \
- && !defined(TCG_TARGET_HAS_v256)
-#define TCG_TARGET_MAYBE_vec 0
-#define TCG_TARGET_HAS_abs_vec 0
-#define TCG_TARGET_HAS_neg_vec 0
-#define TCG_TARGET_HAS_not_vec 0
-#define TCG_TARGET_HAS_andc_vec 0
-#define TCG_TARGET_HAS_orc_vec 0
-#define TCG_TARGET_HAS_nand_vec 0
-#define TCG_TARGET_HAS_nor_vec 0
-#define TCG_TARGET_HAS_eqv_vec 0
-#define TCG_TARGET_HAS_roti_vec 0
-#define TCG_TARGET_HAS_rots_vec 0
-#define TCG_TARGET_HAS_rotv_vec 0
-#define TCG_TARGET_HAS_shi_vec 0
-#define TCG_TARGET_HAS_shs_vec 0
-#define TCG_TARGET_HAS_shv_vec 0
-#define TCG_TARGET_HAS_mul_vec 0
-#define TCG_TARGET_HAS_sat_vec 0
-#define TCG_TARGET_HAS_minmax_vec 0
-#define TCG_TARGET_HAS_bitsel_vec 0
-#define TCG_TARGET_HAS_cmpsel_vec 0
-#define TCG_TARGET_HAS_tst_vec 0
-#else
-#define TCG_TARGET_MAYBE_vec 1
-#endif
-#ifndef TCG_TARGET_HAS_v64
-#define TCG_TARGET_HAS_v64 0
-#endif
-#ifndef TCG_TARGET_HAS_v128
-#define TCG_TARGET_HAS_v128 0
-#endif
-#ifndef TCG_TARGET_HAS_v256
-#define TCG_TARGET_HAS_v256 0
-#endif
-
typedef enum TCGOpcode {
#define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
#include "tcg/tcg-opc.h"
@@ -281,29 +177,6 @@ static inline int tcg_type_size(TCGType t)
return 4 << i;
}
-/**
- * get_alignment_bits
- * @memop: MemOp value
- *
- * Extract the alignment size from the memop.
- */
-static inline unsigned get_alignment_bits(MemOp memop)
-{
- unsigned a = memop & MO_AMASK;
-
- if (a == MO_UNALN) {
- /* No alignment required. */
- a = 0;
- } else if (a == MO_ALIGN) {
- /* A natural alignment requirement. */
- a = memop & MO_SIZE;
- } else {
- /* A specific alignment requirement. */
- a = a >> MO_ASHIFT;
- }
- return a;
-}
-
typedef tcg_target_ulong TCGArg;
/* Define type and accessor macros for TCG variables.
@@ -316,6 +189,7 @@ typedef tcg_target_ulong TCGArg;
* TCGv_i64 : 64 bit integer type
* TCGv_i128 : 128 bit integer type
* TCGv_ptr : a host pointer type
+ * TCGv_vaddr: an integer type wide enough to hold a target pointer type
* TCGv_vec : a host vector type; the exact size is not exposed
to the CPU front-end code.
* TCGv : an integer type the same size as target_ulong
@@ -344,6 +218,14 @@ typedef struct TCGv_ptr_d *TCGv_ptr;
typedef struct TCGv_vec_d *TCGv_vec;
typedef TCGv_ptr TCGv_env;
+#if __SIZEOF_POINTER__ == 4
+typedef TCGv_i32 TCGv_vaddr;
+#elif __SIZEOF_POINTER__ == 8
+typedef TCGv_i64 TCGv_vaddr;
+#else
+# error "sizeof pointer is different from {4,8}"
+#endif /* __SIZEOF_POINTER__ */
+
/* call flags */
/* Helper does not read globals (either directly or through an exception). It
implies TCG_CALL_NO_WRITE_GLOBALS. */
@@ -462,7 +344,8 @@ struct TCGOp {
#define TCGOP_CALLI(X) (X)->param1
#define TCGOP_CALLO(X) (X)->param2
-#define TCGOP_VECL(X) (X)->param1
+#define TCGOP_TYPE(X) (X)->param1
+#define TCGOP_FLAGS(X) (X)->param2
#define TCGOP_VECE(X) (X)->param2
/* Make sure operands fit in the bitfields above. */
@@ -482,11 +365,6 @@ struct TCGContext {
int nb_indirects;
int nb_ops;
TCGType addr_type; /* TCG_TYPE_I32 or TCG_TYPE_I64 */
-
- int page_mask;
- uint8_t page_bits;
- uint8_t tlb_dyn_max_bits;
- uint8_t insn_start_words;
TCGBar guest_mo;
TCGRegSet reserved_regs;
@@ -520,12 +398,8 @@ struct TCGContext {
CPUState *cpu; /* *_trans */
/* These structures are private to tcg-target.c.inc. */
-#ifdef TCG_TARGET_NEED_LDST_LABELS
QSIMPLEQ_HEAD(, TCGLabelQemuLdst) ldst_labels;
-#endif
-#ifdef TCG_TARGET_NEED_POOL_LABELS
struct TCGLabelPoolData *pool_labels;
-#endif
TCGLabel *exitreq_label;
@@ -544,6 +418,17 @@ struct TCGContext {
struct qemu_plugin_insn *plugin_insn;
#endif
+ /* For host-specific values. */
+#ifdef __riscv
+ MemOp riscv_cur_vsew;
+ TCGType riscv_cur_type;
+#endif
+ /*
+ * During the tcg_reg_alloc_op loop, we are within a sequence of
+ * carry-using opcodes like addco+addci.
+ */
+ bool carry_live;
+
GHashTable *const_table[TCG_TYPE_COUNT];
TCGTempSet free_temps[TCG_TYPE_COUNT];
TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
@@ -697,23 +582,29 @@ static inline TCGv_ptr temp_tcgv_ptr(TCGTemp *t)
return (TCGv_ptr)temp_tcgv_i32(t);
}
+static inline TCGv_vaddr temp_tcgv_vaddr(TCGTemp *t)
+{
+ return (TCGv_vaddr)temp_tcgv_i32(t);
+}
+
static inline TCGv_vec temp_tcgv_vec(TCGTemp *t)
{
return (TCGv_vec)temp_tcgv_i32(t);
}
-static inline TCGArg tcg_get_insn_param(TCGOp *op, int arg)
+static inline TCGArg tcg_get_insn_param(TCGOp *op, unsigned arg)
{
return op->args[arg];
}
-static inline void tcg_set_insn_param(TCGOp *op, int arg, TCGArg v)
+static inline void tcg_set_insn_param(TCGOp *op, unsigned arg, TCGArg v)
{
op->args[arg] = v;
}
-static inline uint64_t tcg_get_insn_start_param(TCGOp *op, int arg)
+static inline uint64_t tcg_get_insn_start_param(TCGOp *op, unsigned arg)
{
+ tcg_debug_assert(arg < INSN_START_WORDS);
if (TCG_TARGET_REG_BITS == 64) {
return tcg_get_insn_param(op, arg);
} else {
@@ -722,8 +613,9 @@ static inline uint64_t tcg_get_insn_start_param(TCGOp *op, int arg)
}
}
-static inline void tcg_set_insn_start_param(TCGOp *op, int arg, uint64_t v)
+static inline void tcg_set_insn_start_param(TCGOp *op, unsigned arg, uint64_t v)
{
+ tcg_debug_assert(arg < INSN_START_WORDS);
if (TCG_TARGET_REG_BITS == 64) {
tcg_set_insn_param(op, arg, v);
} else {
@@ -763,10 +655,51 @@ void tcg_region_reset_all(void);
size_t tcg_code_size(void);
size_t tcg_code_capacity(void);
+/**
+ * tcg_tb_insert:
+ * @tb: translation block to insert
+ *
+ * Insert @tb into the region trees.
+ */
void tcg_tb_insert(TranslationBlock *tb);
+
+/**
+ * tcg_tb_remove:
+ * @tb: translation block to remove
+ *
+ * Remove @tb from the region trees.
+ */
void tcg_tb_remove(TranslationBlock *tb);
+
+/**
+ * tcg_tb_lookup:
+ * @tc_ptr: host PC to look up
+ *
+ * Look up a translation block inside the region trees by @tc_ptr. This is
+ * useful for exception handling, but must not be used for the purposes of
+ * executing the returned translation block. See struct tb_tc for more
+ * information.
+ *
+ * Returns: a translation block previously inserted into the region trees,
+ * such that @tc_ptr points anywhere inside the code generated for it, or
+ * NULL.
+ */
TranslationBlock *tcg_tb_lookup(uintptr_t tc_ptr);
+
+/**
+ * tcg_tb_foreach:
+ * @func: callback
+ * @user_data: opaque value to pass to @callback
+ *
+ * Call @func for each translation block inserted into the region trees.
+ */
void tcg_tb_foreach(GTraverseFunc func, gpointer user_data);
+
+/**
+ * tcg_nb_tbs:
+ *
+ * Returns: the number of translation blocks inserted into the region trees.
+ */
size_t tcg_nb_tbs(void);
/* user-mode: Called with mmap_lock held. */
@@ -797,7 +730,8 @@ void tb_target_set_jmp_target(const TranslationBlock *, int,
void tcg_set_frame(TCGContext *s, TCGReg reg, intptr_t start, intptr_t size);
-#define TCG_CT_CONST 1 /* any constant of register size */
+#define TCG_CT_CONST 1 /* any constant of register size */
+#define TCG_CT_REG_ZERO 2 /* zero, in TCG_REG_ZERO */
typedef struct TCGArgConstraint {
unsigned ct : 16;
@@ -824,33 +758,42 @@ enum {
/* Instruction has side effects: it cannot be removed if its outputs
are not used, and might trigger exceptions. */
TCG_OPF_SIDE_EFFECTS = 0x08,
- /* Instruction operands are 64-bits (otherwise 32-bits). */
- TCG_OPF_64BIT = 0x10,
+ /* Instruction operands may be I32 or I64 */
+ TCG_OPF_INT = 0x10,
/* Instruction is optional and not implemented by the host, or insn
is generic and should not be implemented by the host. */
TCG_OPF_NOT_PRESENT = 0x20,
/* Instruction operands are vectors. */
TCG_OPF_VECTOR = 0x40,
/* Instruction is a conditional branch. */
- TCG_OPF_COND_BRANCH = 0x80
+ TCG_OPF_COND_BRANCH = 0x80,
+ /* Instruction produces carry out. */
+ TCG_OPF_CARRY_OUT = 0x100,
+ /* Instruction consumes carry in. */
+ TCG_OPF_CARRY_IN = 0x200,
};
typedef struct TCGOpDef {
const char *name;
uint8_t nb_oargs, nb_iargs, nb_cargs, nb_args;
- uint8_t flags;
- TCGArgConstraint *args_ct;
+ uint16_t flags;
} TCGOpDef;
-extern TCGOpDef tcg_op_defs[];
+extern const TCGOpDef tcg_op_defs[];
extern const size_t tcg_op_defs_max;
-typedef struct TCGTargetOpDef {
- TCGOpcode op;
- const char *args_ct_str[TCG_MAX_OP_ARGS];
-} TCGTargetOpDef;
-
-bool tcg_op_supported(TCGOpcode op);
+/*
+ * tcg_op_supported:
+ * Query if @op, for @type and @flags, is supported by the host
+ * on which we are currently executing.
+ */
+bool tcg_op_supported(TCGOpcode op, TCGType type, unsigned flags);
+/*
+ * tcg_op_deposit_valid:
+ * Query if a deposit into (ofs, len) is supported for @type by
+ * the host on which we are currently executing.
+ */
+bool tcg_op_deposit_valid(TCGType type, unsigned ofs, unsigned len);
void tcg_gen_call0(void *func, TCGHelperInfo *, TCGTemp *ret);
void tcg_gen_call1(void *func, TCGHelperInfo *, TCGTemp *ret, TCGTemp *);
@@ -871,10 +814,6 @@ void tcg_gen_call7(void *func, TCGHelperInfo *, TCGTemp *ret,
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
void tcg_op_remove(TCGContext *s, TCGOp *op);
-TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op,
- TCGOpcode opc, unsigned nargs);
-TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op,
- TCGOpcode opc, unsigned nargs);
/**
* tcg_remove_ops_after:
@@ -1033,17 +972,10 @@ extern tcg_prologue_fn *tcg_qemu_tb_exec;
void tcg_register_jit(const void *buf, size_t buf_size);
-#if TCG_TARGET_MAYBE_vec
/* Return zero if the tuple (opc, type, vece) is unsupportable;
return > 0 if it is directly supportable;
return < 0 if we must call tcg_expand_vec_op. */
int tcg_can_emit_vec_op(TCGOpcode, TCGType, unsigned);
-#else
-static inline int tcg_can_emit_vec_op(TCGOpcode o, TCGType t, unsigned ve)
-{
- return 0;
-}
-#endif
/* Expand the tuple (opc, type, vece) on the given arguments. */
void tcg_expand_vec_op(TCGOpcode, TCGType, unsigned, TCGArg, ...);
diff --git a/include/ui/clipboard.h b/include/ui/clipboard.h
index ab6acdb..62a96ce 100644
--- a/include/ui/clipboard.h
+++ b/include/ui/clipboard.h
@@ -2,6 +2,7 @@
#define QEMU_CLIPBOARD_H
#include "qemu/notify.h"
+#include "migration/vmstate.h"
/**
* DOC: Introduction
@@ -25,6 +26,9 @@ typedef enum QemuClipboardSelection QemuClipboardSelection;
typedef struct QemuClipboardPeer QemuClipboardPeer;
typedef struct QemuClipboardNotify QemuClipboardNotify;
typedef struct QemuClipboardInfo QemuClipboardInfo;
+typedef struct QemuClipboardContent QemuClipboardContent;
+
+extern const VMStateDescription vmstate_cbinfo;
/**
* enum QemuClipboardType
@@ -97,6 +101,24 @@ struct QemuClipboardNotify {
};
};
+
+/**
+ * struct QemuClipboardContent
+ *
+ * @available: whether the data is available
+ * @requested: whether the data was requested
+ * @size: the size of the @data
+ * @data: the clipboard data
+ *
+ * Clipboard content.
+ */
+struct QemuClipboardContent {
+ bool available;
+ bool requested;
+ uint32_t size;
+ void *data;
+};
+
/**
* struct QemuClipboardInfo
*
@@ -112,15 +134,10 @@ struct QemuClipboardNotify {
struct QemuClipboardInfo {
uint32_t refcount;
QemuClipboardPeer *owner;
- QemuClipboardSelection selection;
+ int selection; /* QemuClipboardSelection */
bool has_serial;
uint32_t serial;
- struct {
- bool available;
- bool requested;
- size_t size;
- void *data;
- } types[QEMU_CLIPBOARD_TYPE__COUNT];
+ QemuClipboardContent types[QEMU_CLIPBOARD_TYPE__COUNT];
};
/**
diff --git a/include/ui/console.h b/include/ui/console.h
index a208a68..46b3128 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -70,8 +70,6 @@ typedef struct QEMUPutMouseEntry QEMUPutMouseEntry;
typedef struct QEMUPutKbdEntry QEMUPutKbdEntry;
typedef struct QEMUPutLEDEntry QEMUPutLEDEntry;
-QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func,
- void *opaque);
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
void *opaque, int absolute,
const char *name);
@@ -175,7 +173,6 @@ int cursor_get_mono_bpl(QEMUCursor *c);
void cursor_set_mono(QEMUCursor *c,
uint32_t foreground, uint32_t background, uint8_t *image,
int transparent, uint8_t *mask);
-void cursor_get_mono_image(QEMUCursor *c, int foreground, uint8_t *mask);
void cursor_get_mono_mask(QEMUCursor *c, int transparent, uint8_t *mask);
typedef void *QEMUGLContext;
@@ -233,7 +230,7 @@ typedef struct DisplayChangeListenerOps {
/* optional */
void (*dpy_mouse_set)(DisplayChangeListener *dcl,
- int x, int y, int on);
+ int x, int y, bool on);
/* optional */
void (*dpy_cursor_define)(DisplayChangeListener *dcl,
QEMUCursor *cursor);
@@ -322,9 +319,8 @@ void dpy_gfx_replace_surface(QemuConsole *con,
void dpy_text_cursor(QemuConsole *con, int x, int y);
void dpy_text_update(QemuConsole *con, int x, int y, int w, int h);
void dpy_text_resize(QemuConsole *con, int w, int h);
-void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
+void dpy_mouse_set(QemuConsole *con, int x, int y, bool on);
void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
-bool dpy_cursor_define_supported(QemuConsole *con);
bool dpy_gfx_check_format(QemuConsole *con,
pixman_format_code_t format);
diff --git a/include/ui/dmabuf.h b/include/ui/dmabuf.h
index dc74ba8..3decdca 100644
--- a/include/ui/dmabuf.h
+++ b/include/ui/dmabuf.h
@@ -10,24 +10,29 @@
#ifndef DMABUF_H
#define DMABUF_H
+#define DMABUF_MAX_PLANES 4
+
typedef struct QemuDmaBuf QemuDmaBuf;
QemuDmaBuf *qemu_dmabuf_new(uint32_t width, uint32_t height,
- uint32_t stride, uint32_t x,
- uint32_t y, uint32_t backing_width,
- uint32_t backing_height, uint32_t fourcc,
- uint64_t modifier, int dmabuf_fd,
+ const uint32_t *offset, const uint32_t *stride,
+ uint32_t x, uint32_t y,
+ uint32_t backing_width, uint32_t backing_height,
+ uint32_t fourcc, uint64_t modifier,
+ const int32_t *dmabuf_fd, uint32_t num_planes,
bool allow_fences, bool y0_top);
void qemu_dmabuf_free(QemuDmaBuf *dmabuf);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QemuDmaBuf, qemu_dmabuf_free);
-int qemu_dmabuf_get_fd(QemuDmaBuf *dmabuf);
-int qemu_dmabuf_dup_fd(QemuDmaBuf *dmabuf);
+const int *qemu_dmabuf_get_fds(QemuDmaBuf *dmabuf, int *nfds);
+void qemu_dmabuf_dup_fds(QemuDmaBuf *dmabuf, int *fds, int nfds);
void qemu_dmabuf_close(QemuDmaBuf *dmabuf);
uint32_t qemu_dmabuf_get_width(QemuDmaBuf *dmabuf);
uint32_t qemu_dmabuf_get_height(QemuDmaBuf *dmabuf);
-uint32_t qemu_dmabuf_get_stride(QemuDmaBuf *dmabuf);
+const uint32_t *qemu_dmabuf_get_offsets(QemuDmaBuf *dmabuf, int *noffsets);
+const uint32_t *qemu_dmabuf_get_strides(QemuDmaBuf *dmabuf, int *nstrides);
+uint32_t qemu_dmabuf_get_num_planes(QemuDmaBuf *dmabuf);
uint32_t qemu_dmabuf_get_fourcc(QemuDmaBuf *dmabuf);
uint64_t qemu_dmabuf_get_modifier(QemuDmaBuf *dmabuf);
uint32_t qemu_dmabuf_get_texture(QemuDmaBuf *dmabuf);
@@ -44,6 +49,5 @@ void qemu_dmabuf_set_texture(QemuDmaBuf *dmabuf, uint32_t texture);
void qemu_dmabuf_set_fence_fd(QemuDmaBuf *dmabuf, int32_t fence_fd);
void qemu_dmabuf_set_sync(QemuDmaBuf *dmabuf, void *sync);
void qemu_dmabuf_set_draw_submitted(QemuDmaBuf *dmabuf, bool draw_submitted);
-void qemu_dmabuf_set_fd(QemuDmaBuf *dmabuf, int32_t fd);
#endif
diff --git a/include/ui/egl-helpers.h b/include/ui/egl-helpers.h
index 4b8c0d2..acf993f 100644
--- a/include/ui/egl-helpers.h
+++ b/include/ui/egl-helpers.h
@@ -17,6 +17,8 @@ extern bool qemu_egl_angle_d3d;
typedef struct egl_fb {
int width;
int height;
+ int x;
+ int y;
GLuint texture;
GLuint framebuffer;
bool delete_texture;
@@ -26,7 +28,7 @@ typedef struct egl_fb {
#define EGL_FB_INIT { 0, }
void egl_fb_destroy(egl_fb *fb);
-void egl_fb_setup_default(egl_fb *fb, int width, int height);
+void egl_fb_setup_default(egl_fb *fb, int width, int height, int x, int y);
void egl_fb_setup_for_tex(egl_fb *fb, int width, int height,
GLuint texture, bool delete);
void egl_fb_setup_new_tex(egl_fb *fb, int width, int height);
@@ -46,8 +48,9 @@ extern int qemu_egl_rn_fd;
extern struct gbm_device *qemu_egl_rn_gbm_dev;
int egl_rendernode_init(const char *rendernode, DisplayGLMode mode);
-int egl_get_fd_for_texture(uint32_t tex_id, EGLint *stride, EGLint *fourcc,
- EGLuint64KHR *modifier);
+bool egl_dmabuf_export_texture(uint32_t tex_id, int *fd, EGLint *offset,
+ EGLint *stride, EGLint *fourcc, int *num_planes,
+ EGLuint64KHR *modifier);
void egl_dmabuf_import_texture(QemuDmaBuf *dmabuf);
void egl_dmabuf_release_texture(QemuDmaBuf *dmabuf);
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index aa3d637..d394404 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -224,4 +224,6 @@ int gd_gl_area_make_current(DisplayGLCtx *dgc,
/* gtk-clipboard.c */
void gd_clipboard_init(GtkDisplayState *gd);
+void gd_update_scale(VirtualConsole *vc, int ww, int wh, int fbw, int fbh);
+
#endif /* UI_GTK_H */
diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index ef13a82..2ca0ed7 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -12,6 +12,8 @@
#include "pixman-minimal.h"
#endif
+#include "qapi/error.h"
+
/*
* pixman image formats are defined to be native endian,
* that means host byte order on qemu. So we go define
@@ -73,12 +75,12 @@ PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format);
pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian);
pixman_format_code_t qemu_drm_format_to_pixman(uint32_t drm_format);
uint32_t qemu_pixman_to_drm_format(pixman_format_code_t pixman);
-int qemu_pixman_get_type(int rshift, int gshift, int bshift);
+int qemu_pixman_get_type(int rshift, int gshift, int bshift, int endian);
bool qemu_pixman_check_format(DisplayChangeListener *dcl,
pixman_format_code_t format);
#ifdef CONFIG_PIXMAN
-pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
+pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf, int endian);
pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
int width);
void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
@@ -97,6 +99,28 @@ void qemu_pixman_glyph_render(pixman_image_t *glyph,
void qemu_pixman_image_unref(pixman_image_t *image);
+#ifdef WIN32
+typedef HANDLE qemu_pixman_shareable;
+#define SHAREABLE_NONE (NULL)
+#define SHAREABLE_TO_PTR(handle) (handle)
+#define PTR_TO_SHAREABLE(ptr) (ptr)
+#else
+typedef int qemu_pixman_shareable;
+#define SHAREABLE_NONE (-1)
+#define SHAREABLE_TO_PTR(handle) GINT_TO_POINTER(handle)
+#define PTR_TO_SHAREABLE(ptr) GPOINTER_TO_INT(ptr)
+#endif
+
+bool qemu_pixman_image_new_shareable(
+ pixman_image_t **image,
+ qemu_pixman_shareable *handle,
+ const char *name,
+ pixman_format_code_t format,
+ int width,
+ int height,
+ int rowstride_bytes,
+ Error **errp);
+
G_DEFINE_AUTOPTR_CLEANUP_FUNC(pixman_image_t, qemu_pixman_image_unref)
#endif /* QEMU_PIXMAN_H */
diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index e3acc7c..dbe6e3d 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -42,6 +42,7 @@ struct sdl2_console {
int updates;
int idle_counter;
int ignore_hotkeys;
+ bool gui_keysym;
SDL_GLContext winctx;
QKbdState *kbd;
#ifdef CONFIG_OPENGL
@@ -60,6 +61,7 @@ void sdl2_poll_events(struct sdl2_console *scon);
void sdl2_process_key(struct sdl2_console *scon,
SDL_KeyboardEvent *ev);
+void sdl2_release_modifiers(struct sdl2_console *scon);
void sdl2_2d_update(DisplayChangeListener *dcl,
int x, int y, int w, int h);
diff --git a/include/ui/surface.h b/include/ui/surface.h
index 345b191..f16f7be 100644
--- a/include/ui/surface.h
+++ b/include/ui/surface.h
@@ -23,10 +23,8 @@ typedef struct DisplaySurface {
GLenum gltype;
GLuint texture;
#endif
-#ifdef WIN32
- HANDLE handle;
- uint32_t handle_offset;
-#endif
+ qemu_pixman_shareable share_handle;
+ uint32_t share_handle_offset;
} DisplaySurface;
PixelFormat qemu_default_pixelformat(int bpp);
@@ -37,10 +35,10 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height,
DisplaySurface *qemu_create_displaysurface_pixman(pixman_image_t *image);
DisplaySurface *qemu_create_placeholder_surface(int w, int h,
const char *msg);
-#ifdef WIN32
-void qemu_displaysurface_win32_set_handle(DisplaySurface *surface,
- HANDLE h, uint32_t offset);
-#endif
+
+void qemu_displaysurface_set_share_handle(DisplaySurface *surface,
+ qemu_pixman_shareable handle,
+ uint32_t offset);
DisplaySurface *qemu_create_displaysurface(int width, int height);
void qemu_free_displaysurface(DisplaySurface *surface);
diff --git a/include/user/abitypes.h b/include/user/abitypes.h
index 5c9a955..7528124 100644
--- a/include/user/abitypes.h
+++ b/include/user/abitypes.h
@@ -21,13 +21,6 @@
#define ABI_LLONG_ALIGNMENT 2
#endif
-#ifdef TARGET_CRIS
-#define ABI_SHORT_ALIGNMENT 1
-#define ABI_INT_ALIGNMENT 1
-#define ABI_LONG_ALIGNMENT 1
-#define ABI_LLONG_ALIGNMENT 1
-#endif
-
#if (defined(TARGET_I386) && !defined(TARGET_X86_64)) \
|| defined(TARGET_SH4) \
|| defined(TARGET_OPENRISC) \
diff --git a/include/user/cpu_loop.h b/include/user/cpu_loop.h
new file mode 100644
index 0000000..ad8a1d7
--- /dev/null
+++ b/include/user/cpu_loop.h
@@ -0,0 +1,88 @@
+/*
+ * qemu user cpu loop
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef USER_CPU_LOOP_H
+#define USER_CPU_LOOP_H
+
+#include "exec/vaddr.h"
+#include "exec/mmu-access-type.h"
+
+
+/**
+ * adjust_signal_pc:
+ * @pc: raw pc from the host signal ucontext_t.
+ * @is_write: host memory operation was write, or read-modify-write.
+ *
+ * Alter @pc as required for unwinding. Return the type of the
+ * guest memory access -- host reads may be for guest execution.
+ */
+MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write);
+
+/**
+ * handle_sigsegv_accerr_write:
+ * @cpu: the cpu context
+ * @old_set: the sigset_t from the signal ucontext_t
+ * @host_pc: the host pc, adjusted for the signal
+ * @host_addr: the host address of the fault
+ *
+ * Return true if the write fault has been handled, and should be re-tried.
+ */
+bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set,
+ uintptr_t host_pc, vaddr guest_addr);
+
+/**
+ * cpu_loop_exit_sigsegv:
+ * @cpu: the cpu context
+ * @addr: the guest address of the fault
+ * @access_type: access was read/write/execute
+ * @maperr: true for invalid page, false for permission fault
+ * @ra: host pc for unwinding
+ *
+ * Use the TCGCPUOps hook to record cpu state, do guest operating system
+ * specific things to raise SIGSEGV, and jump to the main cpu loop.
+ */
+G_NORETURN void cpu_loop_exit_sigsegv(CPUState *cpu, vaddr addr,
+ MMUAccessType access_type,
+ bool maperr, uintptr_t ra);
+
+/**
+ * cpu_loop_exit_sigbus:
+ * @cpu: the cpu context
+ * @addr: the guest address of the alignment fault
+ * @access_type: access was read/write/execute
+ * @ra: host pc for unwinding
+ *
+ * Use the TCGCPUOps hook to record cpu state, do guest operating system
+ * specific things to raise SIGBUS, and jump to the main cpu loop.
+ */
+G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, vaddr addr,
+ MMUAccessType access_type,
+ uintptr_t ra);
+
+G_NORETURN void cpu_loop(CPUArchState *env);
+
+void target_exception_dump(CPUArchState *env, const char *fmt, int code);
+#define EXCP_DUMP(env, fmt, code) \
+ target_exception_dump(env, fmt, code)
+
+typedef struct target_pt_regs target_pt_regs;
+
+void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs);
+
+#endif
diff --git a/include/user/guest-host.h b/include/user/guest-host.h
new file mode 100644
index 0000000..8f7ef75
--- /dev/null
+++ b/include/user/guest-host.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * guest <-> host helpers.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ */
+
+#ifndef USER_GUEST_HOST_H
+#define USER_GUEST_HOST_H
+
+#include "exec/vaddr.h"
+#include "user/guest-base.h"
+#include "accel/tcg/cpu-ops.h"
+
+/*
+ * If non-zero, the guest virtual address space is a contiguous subset
+ * of the host virtual address space, i.e. '-R reserved_va' is in effect
+ * either from the command-line or by default. The value is the last
+ * byte of the guest address space e.g. UINT32_MAX.
+ *
+ * If zero, the host and guest virtual address spaces are intermingled.
+ */
+extern unsigned long reserved_va;
+
+/*
+ * The last byte of the guest address space.
+ * If reserved_va is non-zero, guest_addr_max matches.
+ * If reserved_va is zero, guest_addr_max equals the full guest space.
+ */
+extern unsigned long guest_addr_max;
+
+static inline vaddr cpu_untagged_addr(CPUState *cs, vaddr x)
+{
+ const TCGCPUOps *tcg_ops = cs->cc->tcg_ops;
+ if (tcg_ops->untagged_addr) {
+ return tcg_ops->untagged_addr(cs, x);
+ }
+ return x;
+}
+
+/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
+static inline void *g2h_untagged(vaddr x)
+{
+ return (void *)((uintptr_t)(x) + guest_base);
+}
+
+static inline void *g2h(CPUState *cs, vaddr x)
+{
+ return g2h_untagged(cpu_untagged_addr(cs, x));
+}
+
+static inline bool guest_addr_valid_untagged(vaddr x)
+{
+ return x <= guest_addr_max;
+}
+
+static inline bool guest_range_valid_untagged(vaddr start, vaddr len)
+{
+ return len - 1 <= guest_addr_max && start <= guest_addr_max - len + 1;
+}
+
+#define h2g_valid(x) \
+ ((uintptr_t)(x) - guest_base <= guest_addr_max)
+
+#define h2g_nocheck(x) ({ \
+ uintptr_t __ret = (uintptr_t)(x) - guest_base; \
+ (vaddr)__ret; \
+})
+
+#define h2g(x) ({ \
+ /* Check if given address fits target address space */ \
+ assert(h2g_valid(x)); \
+ h2g_nocheck(x); \
+})
+
+#endif
diff --git a/include/user/mmap.h b/include/user/mmap.h
new file mode 100644
index 0000000..4d5e9aa
--- /dev/null
+++ b/include/user/mmap.h
@@ -0,0 +1,32 @@
+/*
+ * MMAP declarations for QEMU user emulation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef USER_MMAP_H
+#define USER_MMAP_H
+
+#include "user/abitypes.h"
+
+/*
+ * mmap_next_start: The base address for the next mmap without hint,
+ * increased after each successful map, starting at task_unmapped_base.
+ * This is an optimization within QEMU and not part of ADDR_COMPAT_LAYOUT.
+ */
+extern abi_ulong mmap_next_start;
+
+int target_mprotect(abi_ulong start, abi_ulong len, int prot);
+
+abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
+ int flags, int fd, off_t offset);
+int target_munmap(abi_ulong start, abi_ulong len);
+abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
+ abi_ulong new_size, unsigned long flags,
+ abi_ulong new_addr);
+
+abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong alignment);
+
+void TSA_NO_TSA mmap_fork_start(void);
+void TSA_NO_TSA mmap_fork_end(int child);
+
+#endif
diff --git a/include/user/page-protection.h b/include/user/page-protection.h
new file mode 100644
index 0000000..4bde664
--- /dev/null
+++ b/include/user/page-protection.h
@@ -0,0 +1,96 @@
+/*
+ * QEMU page protection declarations.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ */
+#ifndef USER_PAGE_PROTECTION_H
+#define USER_PAGE_PROTECTION_H
+
+#ifndef CONFIG_USER_ONLY
+#error Cannot include this header from system emulation
+#endif
+
+#include "exec/vaddr.h"
+#include "exec/translation-block.h"
+
+int page_unprotect(CPUState *cpu, tb_page_addr_t address, uintptr_t pc);
+
+int page_get_flags(vaddr address);
+
+/**
+ * page_set_flags:
+ * @start: first byte of range
+ * @last: last byte of range
+ * @flags: flags to set
+ * Context: holding mmap lock
+ *
+ * Modify the flags of a page and invalidate the code if necessary.
+ * The flag PAGE_WRITE_ORG is positioned automatically depending
+ * on PAGE_WRITE. The mmap_lock should already be held.
+ */
+void page_set_flags(vaddr start, vaddr last, int flags);
+
+void page_reset_target_data(vaddr start, vaddr last);
+
+/**
+ * page_check_range
+ * @start: first byte of range
+ * @len: length of range
+ * @flags: flags required for each page
+ *
+ * Return true if every page in [@start, @start+@len) has @flags set.
+ * Return false if any page is unmapped. Thus testing flags == 0 is
+ * equivalent to testing for flags == PAGE_VALID.
+ */
+bool page_check_range(vaddr start, vaddr last, int flags);
+
+/**
+ * page_check_range_empty:
+ * @start: first byte of range
+ * @last: last byte of range
+ * Context: holding mmap lock
+ *
+ * Return true if the entire range [@start, @last] is unmapped.
+ * The memory lock must be held so that the caller will can ensure
+ * the result stays true until a new mapping can be installed.
+ */
+bool page_check_range_empty(vaddr start, vaddr last);
+
+/**
+ * page_find_range_empty
+ * @min: first byte of search range
+ * @max: last byte of search range
+ * @len: size of the hole required
+ * @align: alignment of the hole required (power of 2)
+ *
+ * If there is a range [x, x+@len) within [@min, @max] such that
+ * x % @align == 0, then return x. Otherwise return -1.
+ * The memory lock must be held, as the caller will want to ensure
+ * the returned range stays empty until a new mapping can be installed.
+ */
+vaddr page_find_range_empty(vaddr min, vaddr max, vaddr len, vaddr align);
+
+/**
+ * page_get_target_data
+ * @address: guest virtual address
+ * @size: per-page size
+ *
+ * Return @size bytes of out-of-band data to associate
+ * with the guest page at @address, allocating it if necessary. The
+ * caller should already have verified that the address is valid.
+ * The value of @size must be the same for every call.
+ *
+ * The memory will be freed when the guest page is deallocated,
+ * e.g. with the munmap system call.
+ */
+__attribute__((returns_nonnull))
+void *page_get_target_data(vaddr address, size_t size);
+
+typedef int (*walk_memory_regions_fn)(void *, vaddr, vaddr, int);
+int walk_memory_regions(void *, walk_memory_regions_fn);
+
+void page_dump(FILE *f);
+
+#endif
diff --git a/include/user/signal.h b/include/user/signal.h
new file mode 100644
index 0000000..7fa33b0
--- /dev/null
+++ b/include/user/signal.h
@@ -0,0 +1,25 @@
+/*
+ * Signal-related declarations.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#ifndef USER_SIGNAL_H
+#define USER_SIGNAL_H
+
+#ifndef CONFIG_USER_ONLY
+#error Cannot include this header from system emulation
+#endif
+
+/**
+ * target_to_host_signal:
+ * @sig: target signal.
+ *
+ * On success, return the host signal between 0 (inclusive) and NSIG
+ * (exclusive) corresponding to the target signal @sig. Return any other value
+ * on failure.
+ */
+int target_to_host_signal(int sig);
+
+extern int host_interrupt_signal;
+
+#endif