diff options
author | Chanho Park <chanho61.park@samsung.com> | 2014-06-26 20:28:10 +0900 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-07-07 16:25:44 +0900 |
commit | a15119db2ff5c2fdfdeb913b297bf8aa3399132e (patch) | |
tree | 7d6f779408bb772b11c029ab88000fc01856b599 /include/hw | |
parent | 340f06c9eaee097e626c251bf7a013350649c091 (diff) | |
download | qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.tar.gz qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.tar.bz2 qemu-a15119db2ff5c2fdfdeb913b297bf8aa3399132e.zip |
Imported Upstream version 2.0.0upstream/2.0.0
Change-Id: I081766c4314e7893f54fec80b920b1638d15021f
Diffstat (limited to 'include/hw')
88 files changed, 2440 insertions, 442 deletions
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index 635be7be1..a9fae9d5c 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -24,6 +24,7 @@ #include "qemu/notify.h" #include "qemu/option.h" #include "exec/memory.h" +#include "hw/irq.h" /* from linux include/acpi/actype.h */ /* Default ACPI register widths */ @@ -69,6 +70,12 @@ #define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400 #define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */ +#define ACPI_BITMASK_PM1_COMMON_ENABLED ( \ + ACPI_BITMASK_RT_CLOCK_ENABLE | \ + ACPI_BITMASK_POWER_BUTTON_ENABLE | \ + ACPI_BITMASK_GLOBAL_LOCK_ENABLE | \ + ACPI_BITMASK_TIMER_ENABLE) + /* PM1x_CNT */ #define ACPI_BITMASK_SCI_ENABLE 0x0001 #define ACPI_BITMASK_BUS_MASTER_RLD 0x0002 @@ -136,7 +143,7 @@ void acpi_pm_tmr_reset(ACPIREGS *ar); #include "qemu/timer.h" static inline int64_t acpi_pm_tmr_get_clock(void) { - return muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY, + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY, get_ticks_per_sec()); } @@ -160,11 +167,17 @@ void acpi_gpe_reset(ACPIREGS *ar); void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val); uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr); +void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq); + /* acpi.c */ extern int acpi_enabled; extern char unsigned *acpi_tables; extern size_t acpi_tables_len; +uint8_t *acpi_table_first(void); +uint8_t *acpi_table_next(uint8_t *current); +unsigned acpi_table_len(void *current); void acpi_table_add(const QemuOpts *opts, Error **errp); +void acpi_table_add_builtin(const QemuOpts *opts, Error **errp); #endif /* !QEMU_HW_ACPI_H */ diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h new file mode 100644 index 000000000..4576400fd --- /dev/null +++ b/include/hw/acpi/cpu_hotplug.h @@ -0,0 +1,27 @@ +/* + * QEMU ACPI hotplug utilities + * + * Copyright (C) 2013 Red Hat Inc + * + * Authors: + * Igor Mammedov <imammedo@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. + */ +#ifndef ACPI_HOTPLUG_H +#define ACPI_HOTPLUG_H + +#include "hw/acpi/acpi.h" +#include "hw/acpi/cpu_hotplug_defs.h" + +typedef struct AcpiCpuHotplug { + MemoryRegion io; + uint8_t sts[ACPI_GPE_PROC_LEN]; +} AcpiCpuHotplug; + +void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu); + +void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base); +#endif diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h new file mode 100644 index 000000000..9f3366351 --- /dev/null +++ b/include/hw/acpi/cpu_hotplug_defs.h @@ -0,0 +1,32 @@ +/* + * QEMU ACPI hotplug utilities shared defines + * + * Copyright (C) 2013 Red Hat Inc + * + * Authors: + * Igor Mammedov <imammedo@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. + */ +#ifndef ACPI_HOTPLUG_DEFS_H +#define ACPI_HOTPLUG_DEFS_H + +/* + * ONLY DEFINEs are permited in this file since it's shared + * between C and ASL code. + */ +#define ACPI_CPU_HOTPLUG_STATUS 4 + +/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should + * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT. + */ +#define ACPI_CPU_HOTPLUG_ID_LIMIT 256 + +/* 256 CPU IDs, 8 bits per entry: */ +#define ACPI_GPE_PROC_LEN 32 + +#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8 +#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00 + +#endif diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index b1fe71faf..104f41985 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -22,6 +22,7 @@ #define HW_ACPI_ICH9_H #include "hw/acpi/acpi.h" +#include "hw/acpi/cpu_hotplug.h" typedef struct ICH9LPCPMRegs { /* @@ -42,6 +43,9 @@ typedef struct ICH9LPCPMRegs { uint32_t pm_io_base; Notifier powerdown_notifier; + + AcpiCpuHotplug gpe_cpu; + Notifier cpu_added_notifier; } ICH9LPCPMRegs; void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, @@ -49,4 +53,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base); extern const VMStateDescription vmstate_ich9_pm; +void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); + #endif /* HW_ACPI_ICH9_H */ diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h new file mode 100644 index 000000000..932383831 --- /dev/null +++ b/include/hw/acpi/pcihp.h @@ -0,0 +1,75 @@ +/* + * QEMU<->ACPI BIOS PCI hotplug interface + * + * QEMU supports PCI hotplug via ACPI. This module + * implements the interface between QEMU and the ACPI BIOS. + * Interface specification - see docs/specs/acpi_pci_hotplug.txt + * + * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (mst@redhat.com) + * Copyright (c) 2006 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 version 2 as published by the Free Software Foundation. + * + * 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/> + * + * 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_ACPI_PCIHP_H +#define HW_ACPI_PCIHP_H + +#include <inttypes.h> +#include <qemu/typedefs.h> +#include "hw/acpi/acpi.h" +#include "migration/vmstate.h" + +typedef struct AcpiPciHpPciStatus { + uint32_t up; + uint32_t down; + uint32_t hotplug_enable; +} AcpiPciHpPciStatus; + +#define ACPI_PCIHP_PROP_BSEL "acpi-pcihp-bsel" +#define ACPI_PCIHP_MAX_HOTPLUG_BUS 256 +#define ACPI_PCIHP_BSEL_DEFAULT 0x0 + +typedef struct AcpiPciHpState { + AcpiPciHpPciStatus acpi_pcihp_pci_status[ACPI_PCIHP_MAX_HOTPLUG_BUS]; + uint32_t hotplug_select; + PCIBus *root; + MemoryRegion io; + bool legacy_piix; +} AcpiPciHpState; + +void acpi_pcihp_init(AcpiPciHpState *, PCIBus *root, + MemoryRegion *address_space_io, bool bridges_enabled); + +void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, + DeviceState *dev, Error **errp); +void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, + DeviceState *dev, Error **errp); + +/* Called on reset */ +void acpi_pcihp_reset(AcpiPciHpState *s); + +extern const VMStateDescription vmstate_acpi_pcihp_pci_status; + +#define VMSTATE_PCI_HOTPLUG(pcihp, state, test_pcihp) \ + VMSTATE_UINT32_TEST(pcihp.hotplug_select, state, \ + test_pcihp), \ + VMSTATE_STRUCT_ARRAY_TEST(pcihp.acpi_pcihp_pci_status, state, \ + ACPI_PCIHP_MAX_HOTPLUG_BUS, \ + test_pcihp, 1, \ + vmstate_acpi_pcihp_pci_status, \ + AcpiPciHpPciStatus) + +#endif diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h new file mode 100644 index 000000000..65e6fd7aa --- /dev/null +++ b/include/hw/acpi/piix4.h @@ -0,0 +1,8 @@ +#ifndef HW_ACPI_PIIX4_H +#define HW_ACPI_PIIX4_H + +#include "qemu/typedefs.h" + +Object *piix4_pm_find(void); + +#endif diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h new file mode 100644 index 000000000..01a189bcd --- /dev/null +++ b/include/hw/arm/allwinner-a10.h @@ -0,0 +1,38 @@ +#ifndef ALLWINNER_H_ + +#include "qemu-common.h" +#include "qemu/error-report.h" +#include "hw/char/serial.h" +#include "hw/arm/arm.h" +#include "hw/timer/allwinner-a10-pit.h" +#include "hw/intc/allwinner-a10-pic.h" +#include "hw/net/allwinner_emac.h" + +#include "sysemu/sysemu.h" +#include "exec/address-spaces.h" + + +#define AW_A10_PIC_REG_BASE 0x01c20400 +#define AW_A10_PIT_REG_BASE 0x01c20c00 +#define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE 0x01c0b000 + +#define AW_A10_SDRAM_BASE 0x40000000 + +#define TYPE_AW_A10 "allwinner-a10" +#define AW_A10(obj) OBJECT_CHECK(AwA10State, (obj), TYPE_AW_A10) + +typedef struct AwA10State { + /*< private >*/ + DeviceState parent_obj; + /*< public >*/ + + ARMCPU cpu; + qemu_irq irq[AW_A10_PIC_INT_NR]; + AwA10PITState timer; + AwA10PICState intc; + AwEmacState emac; +} AwA10State; + +#define ALLWINNER_H_ +#endif diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h index bae87c627..cbbf4ca4c 100644 --- a/include/hw/arm/arm.h +++ b/include/hw/arm/arm.h @@ -14,11 +14,6 @@ #include "exec/memory.h" #include "hw/irq.h" -/* The CPU is also modelled as an interrupt controller. */ -#define ARM_PIC_CPU_IRQ 0 -#define ARM_PIC_CPU_FIQ 1 -qemu_irq *arm_pic_init_cpu(ARMCPU *cpu); - /* armv7m.c */ qemu_irq *armv7m_init(MemoryRegion *address_space_mem, int flash_size, int sram_size, @@ -55,6 +50,13 @@ struct arm_boot_info { const struct arm_boot_info *info); void (*secondary_cpu_reset_hook)(ARMCPU *cpu, const struct arm_boot_info *info); + /* if a board is able to create a dtb without a dtb file then it + * sets get_dtb. This will only be used if no dtb file is provided + * by the user. On success, sets *size to the length of the created + * dtb, and returns a pointer to it. (The caller must free this memory + * with g_free() when it has finished with it.) On failure, returns NULL. + */ + void *(*get_dtb)(const struct arm_boot_info *info, int *size); /* if a board needs to be able to modify a device tree provided by * the user it should implement this hook. */ diff --git a/include/hw/arm/digic.h b/include/hw/arm/digic.h new file mode 100644 index 000000000..a739d6ae6 --- /dev/null +++ b/include/hw/arm/digic.h @@ -0,0 +1,43 @@ +/* + * Misc Canon DIGIC declarations. + * + * Copyright (C) 2013 Antony Pavlov <antonynpavlov@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. + * + */ + +#ifndef HW_ARM_DIGIC_H +#define HW_ARM_DIGIC_H + +#include "cpu.h" + +#include "hw/timer/digic-timer.h" +#include "hw/char/digic-uart.h" + +#define TYPE_DIGIC "digic" + +#define DIGIC(obj) OBJECT_CHECK(DigicState, (obj), TYPE_DIGIC) + +#define DIGIC4_NB_TIMERS 3 + +typedef struct DigicState { + /*< private >*/ + DeviceState parent_obj; + /*< public >*/ + + ARMCPU cpu; + + DigicTimerState timer[DIGIC4_NB_TIMERS]; + DigicUartState uart; +} DigicState; + +#endif /* HW_ARM_DIGIC_H */ diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index bb9a1dddc..5c1820f88 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -97,7 +97,7 @@ typedef struct Exynos4210State { MemoryRegion dram1_mem; MemoryRegion boot_secondary; MemoryRegion bootreg_mem; - i2c_bus *i2c_if[EXYNOS4210_I2C_NUMBER]; + I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER]; } Exynos4210State; void exynos4210_write_secondary(ARMCPU *cpu, diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h index 188cda877..b9655ee39 100644 --- a/include/hw/arm/omap.h +++ b/include/hw/arm/omap.h @@ -765,7 +765,7 @@ 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); /* omap_i2c.c */ -i2c_bus *omap_i2c_bus(DeviceState *omap_i2c); +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) diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h index 668232cea..c5079067b 100644 --- a/include/hw/arm/pxa.h +++ b/include/hw/arm/pxa.h @@ -97,26 +97,26 @@ typedef struct PXA2xxPCMCIAState PXA2xxPCMCIAState; PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem, hwaddr base); int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card); -int pxa2xx_pcmcia_dettach(void *opaque); +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 { - int column; - int row; + 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, struct keymap *map, - int size); +void pxa27x_register_keypad(PXA2xxKeyPadState *kp, + const struct keymap *map, int size); /* pxa2xx.c */ typedef struct PXA2xxI2CState PXA2xxI2CState; PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base, qemu_irq irq, uint32_t page_size); -i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s); +I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s); typedef struct PXA2xxI2SState PXA2xxI2SState; typedef struct PXA2xxFIrState PXA2xxFIrState; diff --git a/include/hw/block/block.h b/include/hw/block/block.h index dd115320c..7c3d6c817 100644 --- a/include/hw/block/block.h +++ b/include/hw/block/block.h @@ -65,12 +65,6 @@ int blkconf_geometry(BlockConf *conf, int *trans, /* Hard disk geometry */ -#define BIOS_ATA_TRANSLATION_AUTO 0 -#define BIOS_ATA_TRANSLATION_NONE 1 -#define BIOS_ATA_TRANSLATION_LBA 2 -#define BIOS_ATA_TRANSLATION_LARGE 3 -#define BIOS_ATA_TRANSLATION_RECHS 4 - void hd_geometry_guess(BlockDriverState *bs, uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs, int *ptrans); diff --git a/include/hw/boards.h b/include/hw/boards.h index fb7c6f124..dd2c70da3 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -5,13 +5,12 @@ #include "sysemu/blockdev.h" #include "hw/qdev.h" - -#define DEFAULT_MACHINE_OPTIONS \ - .boot_order = "cad" +#include "qom/object.h" typedef struct QEMUMachineInitArgs { + const QEMUMachine *machine; ram_addr_t ram_size; - const char *boot_device; + const char *boot_order; const char *kernel_filename; const char *kernel_cmdline; const char *initrd_filename; @@ -24,13 +23,16 @@ typedef void QEMUMachineResetFunc(void); typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp); -typedef struct QEMUMachine { +typedef int QEMUMachineGetKvmtypeFunc(const char *arg); + +struct QEMUMachine { const char *name; const char *alias; const char *desc; QEMUMachineInitFunc *init; QEMUMachineResetFunc *reset; QEMUMachineHotAddCPUFunc *hot_add_cpu; + QEMUMachineGetKvmtypeFunc *kvm_type; BlockInterfaceType block_default_type; int max_cpus; unsigned int no_serial:1, @@ -42,15 +44,66 @@ typedef struct QEMUMachine { no_sdcard:1; int is_default; const char *default_machine_opts; - const char *boot_order; + const char *default_boot_order; GlobalProperty *compat_props; struct QEMUMachine *next; const char *hw_version; -} QEMUMachine; +}; +#define TYPE_MACHINE_SUFFIX "-machine" int qemu_register_machine(QEMUMachine *m); -QEMUMachine *find_default_machine(void); -extern QEMUMachine *current_machine; +#define TYPE_MACHINE "machine" +#undef MACHINE /* BSD defines it and QEMU does not use it */ +#define MACHINE(obj) \ + OBJECT_CHECK(MachineState, (obj), TYPE_MACHINE) +#define MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(MachineClass, (obj), TYPE_MACHINE) +#define MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(MachineClass, (klass), TYPE_MACHINE) + +typedef struct MachineState MachineState; +typedef struct MachineClass MachineClass; + +MachineClass *find_default_machine(void); +extern MachineState *current_machine; + +/** + * MachineClass: + * @qemu_machine: #QEMUMachine + */ +struct MachineClass { + /*< private >*/ + ObjectClass parent_class; + /*< public >*/ + + QEMUMachine *qemu_machine; +}; + +/** + * MachineState: + */ +struct MachineState { + /*< private >*/ + Object parent_obj; + /*< public >*/ + + char *accel; + bool kernel_irqchip; + int kvm_shadow_mem; + char *kernel; + char *initrd; + char *append; + char *dtb; + char *dumpdtb; + int phandle_start; + char *dt_compatible; + bool dump_guest_core; + bool mem_merge; + bool usb; + char *firmware; + + QEMUMachineInitArgs init_args; +}; #endif diff --git a/include/hw/bt.h b/include/hw/bt.h index 830af9473..cb2a7e657 100644 --- a/include/hw/bt.h +++ b/include/hw/bt.h @@ -108,12 +108,15 @@ struct bt_device_s { uint16_t clkoff; /* Note: Always little-endian */ }; +extern struct HCIInfo null_hci; /* bt.c */ void bt_device_init(struct bt_device_s *dev, struct bt_scatternet_s *net); void bt_device_done(struct bt_device_s *dev); +struct bt_scatternet_s *qemu_find_bt_vlan(int id); /* bt-hci.c */ struct HCIInfo *bt_new_hci(struct bt_scatternet_s *net); +struct HCIInfo *hci_init(const char *str); /* bt-vhci.c */ void bt_vhci_init(struct HCIInfo *info); @@ -640,8 +643,8 @@ typedef struct { #define OCF_SETUP_SYNC_CONN 0x0028 typedef struct { uint16_t handle; - uint32_t tx_bandwith; - uint32_t rx_bandwith; + uint32_t tx_bandwidth; + uint32_t rx_bandwidth; uint16_t max_latency; uint16_t voice_setting; uint8_t retrans_effort; @@ -652,8 +655,8 @@ typedef struct { #define OCF_ACCEPT_SYNC_CONN_REQ 0x0029 typedef struct { bdaddr_t bdaddr; - uint32_t tx_bandwith; - uint32_t rx_bandwith; + uint32_t tx_bandwidth; + uint32_t rx_bandwidth; uint16_t max_latency; uint16_t voice_setting; uint8_t retrans_effort; diff --git a/include/hw/char/digic-uart.h b/include/hw/char/digic-uart.h new file mode 100644 index 000000000..ef83a3059 --- /dev/null +++ b/include/hw/char/digic-uart.h @@ -0,0 +1,47 @@ +/* + * Canon DIGIC UART block declarations. + * + * Copyright (C) 2013 Antony Pavlov <antonynpavlov@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. + * + */ + +#ifndef HW_CHAR_DIGIC_UART_H +#define HW_CHAR_DIGIC_UART_H + +#include "hw/sysbus.h" +#include "qemu/typedefs.h" + +#define TYPE_DIGIC_UART "digic-uart" +#define DIGIC_UART(obj) \ + OBJECT_CHECK(DigicUartState, (obj), TYPE_DIGIC_UART) + +enum { + R_TX = 0x00, + R_RX, + R_ST = (0x14 >> 2), + R_MAX +}; + +typedef struct DigicUartState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion regs_region; + CharDriverState *chr; + + uint32_t reg_rx; + uint32_t reg_st; +} DigicUartState; + +#endif /* HW_CHAR_DIGIC_UART_H */ diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 85f58acd5..f431764bf 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -65,13 +65,13 @@ struct SerialState { /* Interrupt trigger level for recv_fifo */ uint8_t recv_fifo_itl; - struct QEMUTimer *fifo_timeout_timer; + QEMUTimer *fifo_timeout_timer; int timeout_ipending; /* timeout interrupt pending state */ uint64_t char_transmit_time; /* time to transmit a char in ticks */ int poll_msl; - struct QEMUTimer *modem_status_poll; + QEMUTimer *modem_status_poll; MemoryRegion io; }; diff --git a/include/hw/cpu/a15mpcore.h b/include/hw/cpu/a15mpcore.h new file mode 100644 index 000000000..b423533d2 --- /dev/null +++ b/include/hw/cpu/a15mpcore.h @@ -0,0 +1,44 @@ +/* + * Cortex-A15MPCore internal peripheral emulation. + * + * Copyright (c) 2012 Linaro Limited. + * Written by Peter Maydell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef HW_CPU_A15MPCORE_H +#define HW_CPU_A15MPCORE_H + +#include "hw/sysbus.h" +#include "hw/intc/arm_gic.h" + +/* A15MP private memory region. */ + +#define TYPE_A15MPCORE_PRIV "a15mpcore_priv" +#define A15MPCORE_PRIV(obj) \ + OBJECT_CHECK(A15MPPrivState, (obj), TYPE_A15MPCORE_PRIV) + +typedef struct A15MPPrivState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + uint32_t num_cpu; + uint32_t num_irq; + MemoryRegion container; + + GICState gic; +} A15MPPrivState; + +#endif diff --git a/include/hw/cpu/a9mpcore.h b/include/hw/cpu/a9mpcore.h new file mode 100644 index 000000000..5d67ca22c --- /dev/null +++ b/include/hw/cpu/a9mpcore.h @@ -0,0 +1,39 @@ +/* + * Cortex-A9MPCore internal peripheral emulation. + * + * Copyright (c) 2009 CodeSourcery. + * Copyright (c) 2011 Linaro Limited. + * Written by Paul Brook, Peter Maydell. + * + * This code is licensed under the GPL. + */ +#ifndef HW_CPU_A9MPCORE_H +#define HW_CPU_A9MPCORE_H + +#include "hw/sysbus.h" +#include "hw/intc/arm_gic.h" +#include "hw/misc/a9scu.h" +#include "hw/timer/arm_mptimer.h" +#include "hw/timer/a9gtimer.h" + +#define TYPE_A9MPCORE_PRIV "a9mpcore_priv" +#define A9MPCORE_PRIV(obj) \ + OBJECT_CHECK(A9MPPrivState, (obj), TYPE_A9MPCORE_PRIV) + +typedef struct A9MPPrivState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + uint32_t num_cpu; + MemoryRegion container; + uint32_t num_irq; + + A9SCUState scu; + GICState gic; + A9GTimerState gtimer; + ARMMPTimerState mptimer; + ARMMPTimerState wdt; +} A9MPPrivState; + +#endif diff --git a/include/hw/cpu/arm11mpcore.h b/include/hw/cpu/arm11mpcore.h new file mode 100644 index 000000000..6196109ca --- /dev/null +++ b/include/hw/cpu/arm11mpcore.h @@ -0,0 +1,35 @@ +/* + * ARM11MPCore internal peripheral emulation. + * + * Copyright (c) 2006-2007 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the GPL. + */ + +#ifndef HW_CPU_ARM11MPCORE_H +#define HW_CPU_ARM11MPCORE_H + +#include "hw/sysbus.h" +#include "hw/misc/arm11scu.h" +#include "hw/intc/arm_gic.h" +#include "hw/timer/arm_mptimer.h" + +#define TYPE_ARM11MPCORE_PRIV "arm11mpcore_priv" +#define ARM11MPCORE_PRIV(obj) \ + OBJECT_CHECK(ARM11MPCorePriveState, (obj), TYPE_ARM11MPCORE_PRIV) + +typedef struct ARM11MPCorePriveState { + SysBusDevice parent_obj; + + uint32_t num_cpu; + MemoryRegion container; + uint32_t num_irq; + + ARM11SCUState scu; + GICState gic; + ARMMPTimerState mptimer; + ARMMPTimerState wdtimer; +} ARM11MPCorePriveState; + +#endif diff --git a/include/hw/cpu/icc_bus.h b/include/hw/cpu/icc_bus.h index b5500708d..98a979fa1 100644 --- a/include/hw/cpu/icc_bus.h +++ b/include/hw/cpu/icc_bus.h @@ -66,7 +66,7 @@ typedef struct ICCDeviceClass { DeviceClass parent_class; /*< public >*/ - int (*init)(ICCDevice *dev); /* TODO replace with QOM realize */ + DeviceRealize realize; } ICCDeviceClass; #define TYPE_ICC_DEVICE "icc-device" diff --git a/include/hw/cris/etraxfs.h b/include/hw/cris/etraxfs.h index ab30559c7..73a6134c1 100644 --- a/include/hw/cris/etraxfs.h +++ b/include/hw/cris/etraxfs.h @@ -28,8 +28,6 @@ #include "net/net.h" #include "hw/cris/etraxfs_dma.h" -qemu_irq *cris_pic_init_cpu(CPUCRISState *env); - /* Instantiate an ETRAXFS Ethernet MAC. */ static inline DeviceState * etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr, diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index acc701e3a..c6b5129ba 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -201,6 +201,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, uint64_t addr, low = (uint64_t)-1, high = 0; uint8_t *data = NULL; char label[128]; + int ret = ELF_LOAD_FAILED; if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) goto fail; @@ -211,22 +212,30 @@ static int glue(load_elf, SZ)(const char *name, int fd, switch (elf_machine) { case EM_PPC64: if (EM_PPC64 != ehdr.e_machine) - if (EM_PPC != ehdr.e_machine) + if (EM_PPC != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } break; case EM_X86_64: if (EM_X86_64 != ehdr.e_machine) - if (EM_386 != ehdr.e_machine) + if (EM_386 != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } break; case EM_MICROBLAZE: if (EM_MICROBLAZE != ehdr.e_machine) - if (EM_MICROBLAZE_OLD != ehdr.e_machine) + if (EM_MICROBLAZE_OLD != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } break; default: - if (elf_machine != ehdr.e_machine) + if (elf_machine != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } } if (pentry) @@ -305,5 +314,5 @@ static int glue(load_elf, SZ)(const char *name, int fd, fail: g_free(data); g_free(phdr); - return -1; + return ret; } diff --git a/include/hw/fw-path-provider.h b/include/hw/fw-path-provider.h new file mode 100644 index 000000000..7afaec0b1 --- /dev/null +++ b/include/hw/fw-path-provider.h @@ -0,0 +1,48 @@ +/* + * Firmware patch provider class and helpers definitions. + * + * 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 FW_PATH_PROVIDER_H +#define FW_PATH_PROVIDER_H 1 + +#include "qemu-common.h" +#include "qom/object.h" + +#define TYPE_FW_PATH_PROVIDER "fw-path-provider" + +#define FW_PATH_PROVIDER_CLASS(klass) \ + OBJECT_CLASS_CHECK(FWPathProviderClass, (klass), TYPE_FW_PATH_PROVIDER) +#define FW_PATH_PROVIDER_GET_CLASS(obj) \ + OBJECT_GET_CLASS(FWPathProviderClass, (obj), TYPE_FW_PATH_PROVIDER) +#define FW_PATH_PROVIDER(obj) \ + INTERFACE_CHECK(FWPathProvider, (obj), TYPE_FW_PATH_PROVIDER) + +typedef struct FWPathProvider { + Object parent_obj; +} FWPathProvider; + +typedef struct FWPathProviderClass { + InterfaceClass parent_class; + + char *(*get_dev_path)(FWPathProvider *p, BusState *bus, DeviceState *dev); +} FWPathProviderClass; + +char *fw_path_provider_get_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev); +char *fw_path_provider_try_get_dev_path(Object *o, BusState *bus, + DeviceState *dev); + +#endif /* FW_PATH_PROVIDER_H */ diff --git a/include/hw/hotplug.h b/include/hw/hotplug.h new file mode 100644 index 000000000..a6533cb0b --- /dev/null +++ b/include/hw/hotplug.h @@ -0,0 +1,78 @@ +/* + * Hotplug handler interface. + * + * Copyright (c) 2014 Red Hat Inc. + * + * Authors: + * Igor Mammedov <imammedo@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. + */ +#ifndef HOTPLUG_H +#define HOTPLUG_H + +#include "qom/object.h" +#include "qemu/typedefs.h" + +#define TYPE_HOTPLUG_HANDLER "hotplug-handler" + +#define HOTPLUG_HANDLER_CLASS(klass) \ + OBJECT_CLASS_CHECK(HotplugHandlerClass, (klass), TYPE_HOTPLUG_HANDLER) +#define HOTPLUG_HANDLER_GET_CLASS(obj) \ + OBJECT_GET_CLASS(HotplugHandlerClass, (obj), TYPE_HOTPLUG_HANDLER) +#define HOTPLUG_HANDLER(obj) \ + INTERFACE_CHECK(HotplugHandler, (obj), TYPE_HOTPLUG_HANDLER) + + +typedef struct HotplugHandler { + /* <private> */ + Object Parent; +} HotplugHandler; + +/** + * hotplug_fn: + * @plug_handler: a device performing plug/uplug action + * @plugged_dev: a device that has been (un)plugged + * @errp: returns an error if this function fails + */ +typedef void (*hotplug_fn)(HotplugHandler *plug_handler, + DeviceState *plugged_dev, Error **errp); + +/** + * HotplugDeviceClass: + * + * Interface to be implemented by a device performing + * hardware (un)plug functions. + * + * @parent: Opaque parent interface. + * @plug: plug callback. + * @unplug: unplug callback. + */ +typedef struct HotplugHandlerClass { + /* <private> */ + InterfaceClass parent; + + /* <public> */ + hotplug_fn plug; + hotplug_fn unplug; +} HotplugHandlerClass; + +/** + * hotplug_handler_plug: + * + * Call #HotplugHandlerClass.plug callback of @plug_handler. + */ +void hotplug_handler_plug(HotplugHandler *plug_handler, + DeviceState *plugged_dev, + Error **errp); + +/** + * hotplug_handler_unplug: + * + * Call #HotplugHandlerClass.unplug callback of @plug_handler. + */ +void hotplug_handler_unplug(HotplugHandler *plug_handler, + DeviceState *plugged_dev, + Error **errp); +#endif diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 461392f37..4986ebc73 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -50,18 +50,16 @@ struct I2CSlave uint8_t address; }; -i2c_bus *i2c_init_bus(DeviceState *parent, const char *name); +I2CBus *i2c_init_bus(DeviceState *parent, const char *name); void i2c_set_slave_address(I2CSlave *dev, uint8_t address); -int i2c_bus_busy(i2c_bus *bus); -int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv); -void i2c_end_transfer(i2c_bus *bus); -void i2c_nack(i2c_bus *bus); -int i2c_send(i2c_bus *bus, uint8_t data); -int i2c_recv(i2c_bus *bus); - -#define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev) - -DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr); +int i2c_bus_busy(I2CBus *bus); +int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv); +void i2c_end_transfer(I2CBus *bus); +void i2c_nack(I2CBus *bus); +int i2c_send(I2CBus *bus, uint8_t data); +int i2c_recv(I2CBus *bus); + +DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr); /* wm8750.c */ void wm8750_data_req_set(DeviceState *dev, diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h index e3069bf7d..926603fdf 100644 --- a/include/hw/i2c/pm_smbus.h +++ b/include/hw/i2c/pm_smbus.h @@ -2,7 +2,7 @@ #define PM_SMBUS_H typedef struct PMSMBus { - i2c_bus *smbus; + I2CBus *smbus; MemoryRegion io; uint8_t smb_stat; diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus.h index d764d759c..63f0cc478 100644 --- a/include/hw/i2c/smbus.h +++ b/include/hw/i2c/smbus.h @@ -66,18 +66,18 @@ struct SMBusDevice { }; /* Master device commands. */ -void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read); -uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr); -void smbus_send_byte(i2c_bus *bus, uint8_t addr, uint8_t data); -uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command); -void smbus_write_byte(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t data); -uint16_t smbus_read_word(i2c_bus *bus, uint8_t addr, uint8_t command); -void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data); -int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data); -void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data, +void smbus_quick_command(I2CBus *bus, uint8_t addr, int read); +uint8_t smbus_receive_byte(I2CBus *bus, uint8_t addr); +void smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data); +uint8_t smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command); +void smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data); +uint16_t smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command); +void smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data); +int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data); +void smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data, int len); -void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom, +void smbus_eeprom_init(I2CBus *smbus, int nb_eeprom, const uint8_t *eeprom_spd, int size); #endif diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h index 1b0a7fbfa..70542a6f4 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -80,7 +80,7 @@ typedef struct APICCommonClass { ICCDeviceClass parent_class; - void (*init)(APICCommonState *s); + DeviceRealize realize; void (*set_base)(APICCommonState *s, uint64_t val); void (*set_tpr)(APICCommonState *s, uint8_t val); uint8_t (*get_tpr)(APICCommonState *s); diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index c5f637bff..e19143555 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -20,7 +20,7 @@ int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx); PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin); void ich9_lpc_pm_init(PCIDevice *pci_lpc); PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus); -i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base); +I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base); #define ICH9_CC_SIZE (16 * 1024) /* 16KB */ @@ -66,6 +66,8 @@ typedef struct ICH9LPCState { qemu_irq *ioapic; } ICH9LPCState; +Object *ich9_lpc_find(void); + #define Q35_MASK(bit, ms_bit, ls_bit) \ ((uint##bit##_t)(((1ULL << ((ms_bit) + 1)) - 1) & ~((1ULL << ls_bit) - 1))) @@ -100,7 +102,7 @@ typedef struct ICH9LPCState { #define ICH9_USB_UHCI1_DEV 29 #define ICH9_USB_UHCI1_FUNC 0 -/* D30:F0 DMI-to-PCI brdige */ +/* D30:F0 DMI-to-PCI bridge */ #define ICH9_D2P_BRIDGE "ICH9 D2P BRIDGE" #define ICH9_D2P_BRIDGE_SAVEVM_VERSION 0 diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h index 25576c819..3be335218 100644 --- a/include/hw/i386/ioapic_internal.h +++ b/include/hw/i386/ioapic_internal.h @@ -83,7 +83,8 @@ typedef struct IOAPICCommonState IOAPICCommonState; typedef struct IOAPICCommonClass { SysBusDeviceClass parent_class; - void (*init)(IOAPICCommonState *s, int instance_no); + + DeviceRealize realize; void (*pre_save)(IOAPICCommonState *s); void (*post_load)(IOAPICCommonState *s); } IOAPICCommonClass; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index f79d4782c..9010246cb 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -9,6 +9,11 @@ #include "hw/i386/ioapic.h" #include "qemu/range.h" +#include "qemu/bitmap.h" +#include "sysemu/sysemu.h" +#include "hw/pci/pci.h" + +#define HPET_INTCAP "hpet-intcap" /* PC-style peripherals (also used by other machines). */ @@ -17,10 +22,27 @@ typedef struct PcPciInfo { Range w64; } PcPciInfo; +#define ACPI_PM_PROP_S3_DISABLED "disable_s3" +#define ACPI_PM_PROP_S4_DISABLED "disable_s4" +#define ACPI_PM_PROP_S4_VAL "s4_val" +#define ACPI_PM_PROP_SCI_INT "sci_int" +#define ACPI_PM_PROP_ACPI_ENABLE_CMD "acpi_enable_cmd" +#define ACPI_PM_PROP_ACPI_DISABLE_CMD "acpi_disable_cmd" +#define ACPI_PM_PROP_PM_IO_BASE "pm_io_base" +#define ACPI_PM_PROP_GPE0_BLK "gpe0_blk" +#define ACPI_PM_PROP_GPE0_BLK_LEN "gpe0_blk_len" + struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; + hwaddr ram_size, ram_size_below_4g; + unsigned apic_id_limit; + bool apic_xrupt_override; + uint64_t numa_nodes; + uint64_t *node_mem; + uint64_t *node_cpu; FWCfgState *fw_cfg; + bool has_acpi_build; }; /* parallel.c */ @@ -106,10 +128,11 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start" #define PCI_HOST_PROP_PCI_HOLE64_END "pci-hole64-end" #define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size" -#define DEFAULT_PCI_HOLE64_SIZE (1ULL << 31) +#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL) + -void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start, - uint64_t pci_hole64_size); +void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory, + MemoryRegion *pci_address_space); FWCfgState *pc_memory_init(MemoryRegion *system_memory, const char *kernel_filename, @@ -125,7 +148,8 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus); void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, - bool no_vmport); + bool no_vmport, + uint32 hpet_irqs); void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd); void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, const char *boot_device, @@ -141,9 +165,9 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name); /* acpi_piix.c */ -i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq, qemu_irq smi_irq, - int kvm_enabled, FWCfgState *fw_cfg); +I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, + qemu_irq sci_irq, qemu_irq smi_irq, + int kvm_enabled, FWCfgState *fw_cfg); void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr); /* hpet.c */ @@ -158,12 +182,12 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, ram_addr_t ram_size, - hwaddr pci_hole_start, - hwaddr pci_hole_size, + ram_addr_t below_4g_mem_size, ram_addr_t above_4g_mem_size, MemoryRegion *pci_memory, MemoryRegion *ram_memory); +PCIBus *find_i440fx(void); /* piix4.c */ extern PCIDevice *piix4_dev; int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn); @@ -205,7 +229,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw); /* pvpanic.c */ -void pvpanic_init(ISABus *bus); +uint16_t pvpanic_port(void); /* e820 types */ #define E820_RAM 1 @@ -216,7 +240,64 @@ void pvpanic_init(ISABus *bus); int e820_add_entry(uint64_t, uint64_t, uint32_t); +#define PC_Q35_COMPAT_1_7 \ + PC_COMPAT_1_7, \ + {\ + .driver = "hpet",\ + .property = HPET_INTCAP,\ + .value = stringify(4),\ + } + +#define PC_Q35_COMPAT_1_6 \ + PC_COMPAT_1_6, \ + PC_Q35_COMPAT_1_7 + +#define PC_Q35_COMPAT_1_5 \ + PC_COMPAT_1_5, \ + PC_Q35_COMPAT_1_6 + +#define PC_Q35_COMPAT_1_4 \ + PC_COMPAT_1_4, \ + PC_Q35_COMPAT_1_5 + +#define PC_COMPAT_1_7 \ + {\ + .driver = TYPE_USB_DEVICE,\ + .property = "msos-desc",\ + .value = "no",\ + },\ + {\ + .driver = "PIIX4_PM",\ + .property = "acpi-pci-hotplug-with-bridge-support",\ + .value = "off",\ + } + +#define PC_COMPAT_1_6 \ + PC_COMPAT_1_7, \ + {\ + .driver = "e1000",\ + .property = "mitigation",\ + .value = "off",\ + },{\ + .driver = "qemu64-" TYPE_X86_CPU,\ + .property = "model",\ + .value = stringify(2),\ + },{\ + .driver = "qemu32-" TYPE_X86_CPU,\ + .property = "model",\ + .value = stringify(3),\ + },{\ + .driver = "i440FX-pcihost",\ + .property = "short_root_bus",\ + .value = stringify(1),\ + },{\ + .driver = "q35-pcihost",\ + .property = "short_root_bus",\ + .value = stringify(1),\ + } + #define PC_COMPAT_1_5 \ + PC_COMPAT_1_6, \ {\ .driver = "Conroe-" TYPE_X86_CPU,\ .property = "model",\ @@ -249,6 +330,14 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); .driver = TYPE_X86_CPU,\ .property = "pmu",\ .value = "on",\ + },{\ + .driver = "i440FX-pcihost",\ + .property = "short_root_bus",\ + .value = stringify(0),\ + },{\ + .driver = "q35-pcihost",\ + .property = "short_root_bus",\ + .value = stringify(0),\ } #define PC_COMPAT_1_4 \ @@ -316,4 +405,12 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); .value = stringify(0),\ } +#define PC_COMMON_MACHINE_OPTIONS \ + .default_boot_order = "cad" + +#define PC_DEFAULT_MACHINE_OPTIONS \ + PC_COMMON_MACHINE_OPTIONS, \ + .hot_add_cpu = pc_hot_add_cpu, \ + .max_cpus = 255 + #endif diff --git a/include/hw/i386/smbios.h b/include/hw/i386/smbios.h index 9babeaf27..18fb97064 100644 --- a/include/hw/i386/smbios.h +++ b/include/hw/i386/smbios.h @@ -13,8 +13,11 @@ * */ -int smbios_entry_add(const char *t); -void smbios_add_field(int type, int offset, const void *data, size_t len); +#include "qemu/option.h" + +void smbios_entry_add(QemuOpts *opts); +void smbios_set_type1_defaults(const char *manufacturer, + const char *product, const char *version); uint8_t *smbios_get_table(size_t *length); /* diff --git a/include/hw/ide.h b/include/hw/ide.h index 507e6d33c..bc8bd321a 100644 --- a/include/hw/ide.h +++ b/include/hw/ide.h @@ -17,6 +17,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); +int pci_piix3_xen_ide_unplug(DeviceState *dev); void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); /* ide-mmio.c */ diff --git a/include/hw/intc/allwinner-a10-pic.h b/include/hw/intc/allwinner-a10-pic.h new file mode 100644 index 000000000..5721b2e6b --- /dev/null +++ b/include/hw/intc/allwinner-a10-pic.h @@ -0,0 +1,40 @@ +#ifndef AW_A10_PIC_H +#define AW_A10_PIC_H + +#define TYPE_AW_A10_PIC "allwinner-a10-pic" +#define AW_A10_PIC(obj) OBJECT_CHECK(AwA10PICState, (obj), TYPE_AW_A10_PIC) + +#define AW_A10_PIC_VECTOR 0 +#define AW_A10_PIC_BASE_ADDR 4 +#define AW_A10_PIC_PROTECT 8 +#define AW_A10_PIC_NMI 0xc +#define AW_A10_PIC_IRQ_PENDING 0x10 +#define AW_A10_PIC_FIQ_PENDING 0x20 +#define AW_A10_PIC_SELECT 0x30 +#define AW_A10_PIC_ENABLE 0x40 +#define AW_A10_PIC_MASK 0x50 + +#define AW_A10_PIC_INT_NR 95 +#define AW_A10_PIC_REG_NUM DIV_ROUND_UP(AW_A10_PIC_INT_NR, 32) + +typedef struct AwA10PICState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + MemoryRegion iomem; + qemu_irq parent_fiq; + qemu_irq parent_irq; + + uint32_t vector; + uint32_t base_addr; + uint32_t protect; + uint32_t nmi; + uint32_t irq_pending[AW_A10_PIC_REG_NUM]; + uint32_t fiq_pending[AW_A10_PIC_REG_NUM]; + uint32_t select[AW_A10_PIC_REG_NUM]; + uint32_t enable[AW_A10_PIC_REG_NUM]; + uint32_t mask[AW_A10_PIC_REG_NUM]; + /*priority setting here*/ +} AwA10PICState; + +#endif diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h new file mode 100644 index 000000000..0971e3771 --- /dev/null +++ b/include/hw/intc/arm_gic.h @@ -0,0 +1,42 @@ +/* + * ARM GIC support + * + * Copyright (c) 2012 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_ARM_GIC_H +#define HW_ARM_GIC_H + +#include "arm_gic_common.h" + +#define TYPE_ARM_GIC "arm_gic" +#define ARM_GIC(obj) \ + OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC) +#define ARM_GIC_CLASS(klass) \ + OBJECT_CLASS_CHECK(ARMGICClass, (klass), TYPE_ARM_GIC) +#define ARM_GIC_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ARMGICClass, (obj), TYPE_ARM_GIC) + +typedef struct ARMGICClass { + /*< private >*/ + ARMGICCommonClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; +} ARMGICClass; + +#endif diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h new file mode 100644 index 000000000..f6887ed92 --- /dev/null +++ b/include/hw/intc/arm_gic_common.h @@ -0,0 +1,127 @@ +/* + * ARM GIC support + * + * Copyright (c) 2012 Linaro Limited + * Written by Peter Maydell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_ARM_GIC_COMMON_H +#define HW_ARM_GIC_COMMON_H + +#include "hw/sysbus.h" + +/* Maximum number of possible interrupts, determined by the GIC architecture */ +#define GIC_MAXIRQ 1020 +/* First 32 are private to each CPU (SGIs and PPIs). */ +#define GIC_INTERNAL 32 +#define GIC_NR_SGIS 16 +/* Maximum number of possible CPU interfaces, determined by GIC architecture */ +#define GIC_NCPU 8 + +#define MAX_NR_GROUP_PRIO 128 +#define GIC_NR_APRS (MAX_NR_GROUP_PRIO / 32) + +typedef struct gic_irq_state { + /* The enable bits are only banked for per-cpu interrupts. */ + uint8_t enabled; + uint8_t pending; + uint8_t active; + uint8_t level; + bool model; /* 0 = N:N, 1 = 1:N */ + bool edge_trigger; /* true: edge-triggered, false: level-triggered */ +} gic_irq_state; + +typedef struct GICState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + qemu_irq parent_irq[GIC_NCPU]; + bool enabled; + bool cpu_enabled[GIC_NCPU]; + + gic_irq_state irq_state[GIC_MAXIRQ]; + uint8_t irq_target[GIC_MAXIRQ]; + uint8_t priority1[GIC_INTERNAL][GIC_NCPU]; + uint8_t priority2[GIC_MAXIRQ - GIC_INTERNAL]; + uint16_t last_active[GIC_MAXIRQ][GIC_NCPU]; + /* For each SGI on the target CPU, we store 8 bits + * indicating which source CPUs have made this SGI + * pending on the target CPU. These correspond to + * the bytes in the GIC_SPENDSGIR* registers as + * read by the target CPU. + */ + uint8_t sgi_pending[GIC_NR_SGIS][GIC_NCPU]; + + uint16_t priority_mask[GIC_NCPU]; + uint16_t running_irq[GIC_NCPU]; + uint16_t running_priority[GIC_NCPU]; + uint16_t current_pending[GIC_NCPU]; + + /* We present the GICv2 without security extensions to a guest and + * therefore the guest can configure the GICC_CTLR to configure group 1 + * binary point in the abpr. + */ + uint8_t bpr[GIC_NCPU]; + uint8_t abpr[GIC_NCPU]; + + /* The APR is implementation defined, so we choose a layout identical to + * the KVM ABI layout for QEMU's implementation of the gic: + * If an interrupt for preemption level X is active, then + * APRn[X mod 32] == 0b1, where n = X / 32 + * otherwise the bit is clear. + * + * TODO: rewrite the interrupt acknowlege/complete routines to use + * the APR registers to track the necessary information to update + * s->running_priority[] on interrupt completion (ie completely remove + * last_active[][] and running_irq[]). This will be necessary if we ever + * want to support TCG<->KVM migration, or TCG guests which can + * do power management involving powering down and restarting + * the GIC. + */ + uint32_t apr[GIC_NR_APRS][GIC_NCPU]; + + uint32_t num_cpu; + + MemoryRegion iomem; /* Distributor */ + /* This is just so we can have an opaque pointer which identifies + * both this GIC and which CPU interface we should be accessing. + */ + struct GICState *backref[GIC_NCPU]; + MemoryRegion cpuiomem[GIC_NCPU + 1]; /* CPU interfaces */ + uint32_t num_irq; + uint32_t revision; + int dev_fd; /* kvm device fd if backed by kvm vgic support */ +} GICState; + +#define TYPE_ARM_GIC_COMMON "arm_gic_common" +#define ARM_GIC_COMMON(obj) \ + OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC_COMMON) +#define ARM_GIC_COMMON_CLASS(klass) \ + OBJECT_CLASS_CHECK(ARMGICCommonClass, (klass), TYPE_ARM_GIC_COMMON) +#define ARM_GIC_COMMON_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ARMGICCommonClass, (obj), TYPE_ARM_GIC_COMMON) + +typedef struct ARMGICCommonClass { + /*< private >*/ + SysBusDeviceClass parent_class; + /*< public >*/ + + void (*pre_save)(GICState *s); + void (*post_load)(GICState *s); +} ARMGICCommonClass; + +#endif diff --git a/include/hw/intc/realview_gic.h b/include/hw/intc/realview_gic.h new file mode 100644 index 000000000..1783ea11b --- /dev/null +++ b/include/hw/intc/realview_gic.h @@ -0,0 +1,28 @@ +/* + * ARM RealView Emulation Baseboard Interrupt Controller + * + * Copyright (c) 2006-2007 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the GPL. + */ + +#ifndef HW_INTC_REALVIEW_GIC_H +#define HW_INTC_REALVIEW_GIC_H + +#include "hw/sysbus.h" +#include "hw/intc/arm_gic.h" + +#define TYPE_REALVIEW_GIC "realview_gic" +#define REALVIEW_GIC(obj) \ + OBJECT_CHECK(RealViewGICState, (obj), TYPE_REALVIEW_GIC) + +typedef struct RealViewGICState { + SysBusDevice parent_obj; + + MemoryRegion container; + + GICState gic; +} RealViewGICState; + +#endif diff --git a/include/hw/ipack/ipack.h b/include/hw/ipack/ipack.h new file mode 100644 index 000000000..e95ffe820 --- /dev/null +++ b/include/hw/ipack/ipack.h @@ -0,0 +1,87 @@ +/* + * QEMU IndustryPack emulation + * + * Copyright (C) 2012 Igalia, S.L. + * Author: Alberto Garcia <agarcia@igalia.com> + * + * This code is licensed under the GNU GPL v2 or (at your option) any + * later version. + */ + +#ifndef QEMU_IPACK_H +#define QEMU_IPACK_H + +#include "hw/qdev.h" + +typedef struct IPackBus IPackBus; + +#define TYPE_IPACK_BUS "IndustryPack" +#define IPACK_BUS(obj) OBJECT_CHECK(IPackBus, (obj), TYPE_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; +}; + +typedef struct IPackDevice IPackDevice; +typedef struct IPackDeviceClass IPackDeviceClass; + +#define TYPE_IPACK_DEVICE "ipack-device" +#define IPACK_DEVICE(obj) \ + OBJECT_CHECK(IPackDevice, (obj), TYPE_IPACK_DEVICE) +#define IPACK_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(IPackDeviceClass, (klass), TYPE_IPACK_DEVICE) +#define IPACK_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(IPackDeviceClass, (obj), TYPE_IPACK_DEVICE) + +struct IPackDeviceClass { + /*< private >*/ + DeviceClass parent_class; + /*< public >*/ + + DeviceRealize realize; + DeviceUnrealize unrealize; + + uint16_t (*io_read)(IPackDevice *dev, uint8_t addr); + void (*io_write)(IPackDevice *dev, uint8_t addr, uint16_t val); + + uint16_t (*id_read)(IPackDevice *dev, uint8_t addr); + void (*id_write)(IPackDevice *dev, uint8_t addr, uint16_t val); + + uint16_t (*int_read)(IPackDevice *dev, uint8_t addr); + void (*int_write)(IPackDevice *dev, uint8_t addr, uint16_t val); + + uint16_t (*mem_read16)(IPackDevice *dev, uint32_t addr); + void (*mem_write16)(IPackDevice *dev, uint32_t addr, uint16_t val); + + uint8_t (*mem_read8)(IPackDevice *dev, uint32_t addr); + void (*mem_write8)(IPackDevice *dev, uint32_t addr, uint8_t val); +}; + +struct IPackDevice { + /*< private >*/ + DeviceState parent_obj; + /*< public >*/ + + int32_t slot; + /* IRQ objects for the IndustryPack INT0# and INT1# */ + qemu_irq *irq; +}; + +extern const VMStateDescription vmstate_ipack_device; + +#define VMSTATE_IPACK_DEVICE(_field, _state) \ + VMSTATE_STRUCT(_field, _state, 1, vmstate_ipack_device, IPackDevice) + +IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot); +void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size, + DeviceState *parent, + const char *name, uint8_t n_slots, + qemu_irq_handler handler); + +#endif diff --git a/include/hw/irq.h b/include/hw/irq.h index 610e6b762..d08bc02a0 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h @@ -30,6 +30,12 @@ static inline void qemu_irq_pulse(qemu_irq irq) */ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n); +/* + * Allocates a single IRQ. The irq is assigned with a handler, an opaque + * data and the interrupt number. + */ +qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n); + /* Extends an Array of IRQs. Old IRQs have their handlers and opaque data * preserved. New IRQs are assigned the argument handler and opaque data. */ @@ -37,6 +43,7 @@ qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler, void *opaque, int n); void qemu_free_irqs(qemu_irq *s); +void qemu_free_irq(qemu_irq irq); /* Returns a new IRQ with opposite polarity. */ qemu_irq qemu_irq_invert(qemu_irq irq); diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index 495bcf3a0..e0c749f9e 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -20,6 +20,13 @@ #define TYPE_ISA_BUS "ISA" #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS) +#define TYPE_APPLE_SMC "isa-applesmc" + +static inline bool applesmc_find(void) +{ + return object_resolve_path_type("", TYPE_APPLE_SMC, NULL); +} + typedef struct ISADeviceClass { DeviceClass parent_class; } ISADeviceClass; @@ -78,7 +85,7 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start); * @dev: the ISADevice against which these are registered; may be NULL. * @start: the base I/O port against which the portio->offset is applied. * @portio: the ports, sorted by offset. - * @opaque: passed into the old_portio callbacks. + * @opaque: passed into the portio callbacks. * @name: passed into memory_region_init_io. */ void isa_register_portio_list(ISADevice *dev, uint16_t start, diff --git a/include/hw/isa/vt82c686.h b/include/hw/isa/vt82c686.h index 6ef876d26..471b5e9e5 100644 --- a/include/hw/isa/vt82c686.h +++ b/include/hw/isa/vt82c686.h @@ -5,7 +5,7 @@ ISABus *vt82c686b_init(PCIBus * bus, int devfn); void vt82c686b_ac97_init(PCIBus *bus, int devfn); void vt82c686b_mc97_init(PCIBus *bus, int devfn); -i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, - qemu_irq sci_irq); +I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, + qemu_irq sci_irq); #endif diff --git a/include/hw/loader.h b/include/hw/loader.h index eb9c9a361..796cbf9b3 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -4,10 +4,23 @@ #include "hw/nvram/fw_cfg.h" /* loader.c */ +/** + * get_image_size: retrieve size of an image file + * @filename: Path to the image file + * + * Returns the size of the image file on success, -1 otherwise. + * On error, errno is also set as appropriate. + */ int get_image_size(const char *filename); int load_image(const char *filename, uint8_t *addr); /* deprecated */ int load_image_targphys(const char *filename, hwaddr, uint64_t max_sz); + +#define ELF_LOAD_FAILED -1 +#define ELF_LOAD_NOT_ELF -2 +#define ELF_LOAD_WRONG_ARCH -3 +#define ELF_LOAD_WRONG_ENDIAN -4 +const char *load_elf_strerror(int error); int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, @@ -36,23 +49,28 @@ void pstrcpy_targphys(const char *name, hwaddr dest, int buf_size, const char *source); +extern bool option_rom_has_mr; +extern bool rom_file_has_mr; int rom_add_file(const char *file, const char *fw_dir, - hwaddr addr, int32_t bootindex); -int rom_add_blob(const char *name, const void *blob, size_t len, - hwaddr addr); + hwaddr addr, int32_t bootindex, + bool option_rom); +void *rom_add_blob(const char *name, const void *blob, size_t len, + hwaddr addr, const char *fw_file_name, + FWCfgReadCallback fw_callback, void *callback_opaque); int rom_add_elf_program(const char *name, void *data, size_t datasize, size_t romsize, hwaddr addr); int rom_load_all(void); +void rom_load_done(void); void rom_set_fw(FWCfgState *f); int rom_copy(uint8_t *dest, hwaddr addr, size_t size); void *rom_ptr(hwaddr addr); void do_info_roms(Monitor *mon, const QDict *qdict); #define rom_add_file_fixed(_f, _a, _i) \ - rom_add_file(_f, NULL, _a, _i) + rom_add_file(_f, NULL, _a, _i, false) #define rom_add_blob_fixed(_f, _b, _l, _a) \ - rom_add_blob(_f, _b, _l, _a) + rom_add_blob(_f, _b, _l, _a, NULL, NULL, NULL) #define PC_ROM_MIN_VGA 0xc0000 #define PC_ROM_MIN_OPTION 0xc8000 diff --git a/include/hw/misc/a9scu.h b/include/hw/misc/a9scu.h new file mode 100644 index 000000000..efb0c305c --- /dev/null +++ b/include/hw/misc/a9scu.h @@ -0,0 +1,31 @@ +/* + * Cortex-A9MPCore Snoop Control Unit (SCU) emulation. + * + * Copyright (c) 2009 CodeSourcery. + * Copyright (c) 2011 Linaro Limited. + * Written by Paul Brook, Peter Maydell. + * + * This code is licensed under the GPL. + */ +#ifndef HW_MISC_A9SCU_H +#define HW_MISC_A9SCU_H + +#include "hw/sysbus.h" + +/* A9MP private memory region. */ + +typedef struct A9SCUState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + uint32_t control; + uint32_t status; + uint32_t num_cpu; +} A9SCUState; + +#define TYPE_A9_SCU "a9-scu" +#define A9_SCU(obj) OBJECT_CHECK(A9SCUState, (obj), TYPE_A9_SCU) + +#endif diff --git a/include/hw/misc/arm11scu.h b/include/hw/misc/arm11scu.h new file mode 100644 index 000000000..5ad0f3d33 --- /dev/null +++ b/include/hw/misc/arm11scu.h @@ -0,0 +1,29 @@ +/* + * ARM11MPCore Snoop Control Unit (SCU) emulation + * + * Copyright (c) 2006-2007 CodeSourcery. + * Copyright (c) 2013 SUSE LINUX Products GmbH + * Written by Paul Brook and Andreas Färber + * + * This code is licensed under the GPL. + */ + +#ifndef HW_MISC_ARM11SCU_H +#define HW_MISC_ARM11SCU_H + +#include "hw/sysbus.h" + +#define TYPE_ARM11_SCU "arm11-scu" +#define ARM11_SCU(obj) OBJECT_CHECK(ARM11SCUState, (obj), TYPE_ARM11_SCU) + +typedef struct ARM11SCUState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + uint32_t control; + uint32_t num_cpu; + MemoryRegion iomem; +} ARM11SCUState; + +#endif diff --git a/include/hw/misc/arm_integrator_debug.h b/include/hw/misc/arm_integrator_debug.h new file mode 100644 index 000000000..37789b69d --- /dev/null +++ b/include/hw/misc/arm_integrator_debug.h @@ -0,0 +1,18 @@ +/* + * ARM Integrator Board Debug, switch and LED section + * + * Browse the data sheet: + * + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0159b/Babbfijf.html + * + * Copyright (c) 2013 Alex Bennée <alex@bennee.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. + */ +#ifndef QEMU_INTEGRATOR_DEBUG_H +#define QEMU_INTEGRATOR_DEBUG_H + +#define TYPE_INTEGRATOR_DEBUG "integrator_debug" + +#endif diff --git a/include/hw/net/allwinner_emac.h b/include/hw/net/allwinner_emac.h new file mode 100644 index 000000000..a5e944af0 --- /dev/null +++ b/include/hw/net/allwinner_emac.h @@ -0,0 +1,210 @@ +/* + * Emulation of Allwinner EMAC Fast Ethernet controller and + * Realtek RTL8201CP PHY + * + * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com> + * + * Allwinner EMAC register definitions from Linux kernel are: + * Copyright 2012 Stefan Roese <sr@denx.de> + * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com> + * Copyright 1997 Sten Wang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 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. + * + */ +#ifndef AW_EMAC_H +#define AW_EMAC_H + +#include "net/net.h" +#include "qemu/fifo8.h" + +#define TYPE_AW_EMAC "allwinner-emac" +#define AW_EMAC(obj) OBJECT_CHECK(AwEmacState, (obj), TYPE_AW_EMAC) + +/* + * Allwinner EMAC register list + */ +#define EMAC_CTL_REG 0x00 + +#define EMAC_TX_MODE_REG 0x04 +#define EMAC_TX_FLOW_REG 0x08 +#define EMAC_TX_CTL0_REG 0x0C +#define EMAC_TX_CTL1_REG 0x10 +#define EMAC_TX_INS_REG 0x14 +#define EMAC_TX_PL0_REG 0x18 +#define EMAC_TX_PL1_REG 0x1C +#define EMAC_TX_STA_REG 0x20 +#define EMAC_TX_IO_DATA_REG 0x24 +#define EMAC_TX_IO_DATA1_REG 0x28 +#define EMAC_TX_TSVL0_REG 0x2C +#define EMAC_TX_TSVH0_REG 0x30 +#define EMAC_TX_TSVL1_REG 0x34 +#define EMAC_TX_TSVH1_REG 0x38 + +#define EMAC_RX_CTL_REG 0x3C +#define EMAC_RX_HASH0_REG 0x40 +#define EMAC_RX_HASH1_REG 0x44 +#define EMAC_RX_STA_REG 0x48 +#define EMAC_RX_IO_DATA_REG 0x4C +#define EMAC_RX_FBC_REG 0x50 + +#define EMAC_INT_CTL_REG 0x54 +#define EMAC_INT_STA_REG 0x58 + +#define EMAC_MAC_CTL0_REG 0x5C +#define EMAC_MAC_CTL1_REG 0x60 +#define EMAC_MAC_IPGT_REG 0x64 +#define EMAC_MAC_IPGR_REG 0x68 +#define EMAC_MAC_CLRT_REG 0x6C +#define EMAC_MAC_MAXF_REG 0x70 +#define EMAC_MAC_SUPP_REG 0x74 +#define EMAC_MAC_TEST_REG 0x78 +#define EMAC_MAC_MCFG_REG 0x7C +#define EMAC_MAC_MCMD_REG 0x80 +#define EMAC_MAC_MADR_REG 0x84 +#define EMAC_MAC_MWTD_REG 0x88 +#define EMAC_MAC_MRDD_REG 0x8C +#define EMAC_MAC_MIND_REG 0x90 +#define EMAC_MAC_SSRR_REG 0x94 +#define EMAC_MAC_A0_REG 0x98 +#define EMAC_MAC_A1_REG 0x9C +#define EMAC_MAC_A2_REG 0xA0 + +#define EMAC_SAFX_L_REG0 0xA4 +#define EMAC_SAFX_H_REG0 0xA8 +#define EMAC_SAFX_L_REG1 0xAC +#define EMAC_SAFX_H_REG1 0xB0 +#define EMAC_SAFX_L_REG2 0xB4 +#define EMAC_SAFX_H_REG2 0xB8 +#define EMAC_SAFX_L_REG3 0xBC +#define EMAC_SAFX_H_REG3 0xC0 + +/* CTL register fields */ +#define EMAC_CTL_RESET (1 << 0) +#define EMAC_CTL_TX_EN (1 << 1) +#define EMAC_CTL_RX_EN (1 << 2) + +/* TX MODE register fields */ +#define EMAC_TX_MODE_ABORTED_FRAME_EN (1 << 0) +#define EMAC_TX_MODE_DMA_EN (1 << 1) + +/* RX CTL register fields */ +#define EMAC_RX_CTL_AUTO_DRQ_EN (1 << 1) +#define EMAC_RX_CTL_DMA_EN (1 << 2) +#define EMAC_RX_CTL_PASS_ALL_EN (1 << 4) +#define EMAC_RX_CTL_PASS_CTL_EN (1 << 5) +#define EMAC_RX_CTL_PASS_CRC_ERR_EN (1 << 6) +#define EMAC_RX_CTL_PASS_LEN_ERR_EN (1 << 7) +#define EMAC_RX_CTL_PASS_LEN_OOR_EN (1 << 8) +#define EMAC_RX_CTL_ACCEPT_UNICAST_EN (1 << 16) +#define EMAC_RX_CTL_DA_FILTER_EN (1 << 17) +#define EMAC_RX_CTL_ACCEPT_MULTICAST_EN (1 << 20) +#define EMAC_RX_CTL_HASH_FILTER_EN (1 << 21) +#define EMAC_RX_CTL_ACCEPT_BROADCAST_EN (1 << 22) +#define EMAC_RX_CTL_SA_FILTER_EN (1 << 24) +#define EMAC_RX_CTL_SA_FILTER_INVERT_EN (1 << 25) + +/* RX IO DATA register fields */ +#define EMAC_RX_HEADER(len, status) (((len) & 0xffff) | ((status) << 16)) +#define EMAC_RX_IO_DATA_STATUS_CRC_ERR (1 << 4) +#define EMAC_RX_IO_DATA_STATUS_LEN_ERR (3 << 5) +#define EMAC_RX_IO_DATA_STATUS_OK (1 << 7) +#define EMAC_UNDOCUMENTED_MAGIC 0x0143414d /* header for RX frames */ + +/* PHY registers */ +#define MII_BMCR 0 +#define MII_BMSR 1 +#define MII_PHYID1 2 +#define MII_PHYID2 3 +#define MII_ANAR 4 +#define MII_ANLPAR 5 +#define MII_ANER 6 +#define MII_NSR 16 +#define MII_LBREMR 17 +#define MII_REC 18 +#define MII_SNRDR 19 +#define MII_TEST 25 + +/* PHY registers fields */ +#define MII_BMCR_RESET (1 << 15) +#define MII_BMCR_LOOPBACK (1 << 14) +#define MII_BMCR_SPEED (1 << 13) +#define MII_BMCR_AUTOEN (1 << 12) +#define MII_BMCR_FD (1 << 8) + +#define MII_BMSR_100TX_FD (1 << 14) +#define MII_BMSR_100TX_HD (1 << 13) +#define MII_BMSR_10T_FD (1 << 12) +#define MII_BMSR_10T_HD (1 << 11) +#define MII_BMSR_MFPS (1 << 6) +#define MII_BMSR_AUTONEG (1 << 3) +#define MII_BMSR_LINK_ST (1 << 2) + +#define MII_ANAR_TXFD (1 << 8) +#define MII_ANAR_TX (1 << 7) +#define MII_ANAR_10FD (1 << 6) +#define MII_ANAR_10 (1 << 5) +#define MII_ANAR_CSMACD (1 << 0) + +#define RTL8201CP_PHYID1 0x0000 +#define RTL8201CP_PHYID2 0x8201 + +/* INT CTL and INT STA registers fields */ +#define EMAC_INT_TX_CHAN(x) (1 << (x)) +#define EMAC_INT_RX (1 << 8) + +/* Due to lack of specifications, size of fifos is chosen arbitrarily */ +#define TX_FIFO_SIZE (4 * 1024) +#define RX_FIFO_SIZE (32 * 1024) + +#define NUM_TX_FIFOS 2 +#define RX_HDR_SIZE 8 +#define CRC_SIZE 4 + +#define PHY_REG_SHIFT 0 +#define PHY_ADDR_SHIFT 8 + +typedef struct RTL8201CPState { + uint16_t bmcr; + uint16_t bmsr; + uint16_t anar; + uint16_t anlpar; +} RTL8201CPState; + +typedef struct AwEmacState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + qemu_irq irq; + NICState *nic; + NICConf conf; + RTL8201CPState mii; + uint8_t phy_addr; + + uint32_t ctl; + uint32_t tx_mode; + uint32_t rx_ctl; + uint32_t int_ctl; + uint32_t int_sta; + uint32_t phy_target; + + Fifo8 rx_fifo; + uint32_t rx_num_packets; + uint32_t rx_packet_size; + uint32_t rx_packet_pos; + + Fifo8 tx_fifo[NUM_TX_FIFOS]; + uint32_t tx_length[NUM_TX_FIFOS]; + uint32_t tx_channel; +} AwEmacState; + +#endif diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index f60dd676c..72b1549dc 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -46,12 +46,14 @@ #define FW_CFG_INVALID 0xffff +#define FW_CFG_MAX_FILE_PATH 56 + #ifndef NO_QEMU_PROTOS typedef struct FWCfgFile { uint32_t size; /* file size */ uint16_t select; /* write this to 0x510 to read it */ uint16_t reserved; - char name[56]; + char name[FW_CFG_MAX_FILE_PATH]; } FWCfgFile; typedef struct FWCfgFiles { @@ -60,6 +62,7 @@ typedef struct FWCfgFiles { } FWCfgFiles; typedef void (*FWCfgCallback)(void *opaque, uint8_t *data); +typedef void (*FWCfgReadCallback)(void *opaque, uint32_t offset); void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len); void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value); @@ -70,6 +73,9 @@ void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback, void *callback_opaque, void *data, size_t len); void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data, size_t len); +void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, + FWCfgReadCallback callback, void *callback_opaque, + void *data, size_t len); FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, hwaddr crl_addr, hwaddr data_addr); diff --git a/include/hw/nvram/openbios_firmware_abi.h b/include/hw/nvram/openbios_firmware_abi.h index 5e6e5d4d3..c66ee2268 100644 --- a/include/hw/nvram/openbios_firmware_abi.h +++ b/include/hw/nvram/openbios_firmware_abi.h @@ -62,6 +62,8 @@ Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id header->type = 1; header->machine_id = machine_id & 0xff; memcpy(&header->macaddr, macaddr, 6); + memcpy(&header->hostid , &macaddr[3], 3); + /* Calculate checksum */ tmp = 0; tmpptr = (uint8_t *)header; diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 6eb7ab676..d9ee97845 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -53,14 +53,13 @@ typedef struct MCHPCIState { MemoryRegion *address_space_io; PAMMemoryRegion pam_regions[13]; MemoryRegion smram_region; - MemoryRegion pci_hole; - MemoryRegion pci_hole_64bit; PcPciInfo pci_info; uint8_t smm_enabled; ram_addr_t below_4g_mem_size; ram_addr_t above_4g_mem_size; uint64_t pci_hole64_size; PcGuestInfo *guest_info; + uint32_t short_root_bus; } MCHPCIState; typedef struct Q35PCIHost { @@ -85,7 +84,7 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_CONFIG_DATA 0xcfc /* D0:F0 configuration space */ -#define MCH_HOST_BRIDGE_REVISION_DEFUALT 0x0 +#define MCH_HOST_BRIDGE_REVISION_DEFAULT 0x0 #define MCH_HOST_BRIDGE_PCIEXBAR 0x60 /* 64bit register */ #define MCH_HOST_BRIDGE_PCIEXBAR_SIZE 8 /* 64bit register */ @@ -126,8 +125,8 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_PAM_RE ((uint8_t)0x1) #define MCH_HOST_BRIDGE_PAM_MASK ((uint8_t)0x3) -#define MCH_HOST_BRDIGE_SMRAM 0x9d -#define MCH_HOST_BRDIGE_SMRAM_SIZE 1 +#define MCH_HOST_BRIDGE_SMRAM 0x9d +#define MCH_HOST_BRIDGE_SMRAM_SIZE 1 #define MCH_HOST_BRIDGE_SMRAM_DEFAULT ((uint8_t)0x2) #define MCH_HOST_BRIDGE_SMRAM_D_OPEN ((uint8_t)(1 << 6)) #define MCH_HOST_BRIDGE_SMRAM_D_CLS ((uint8_t)(1 << 5)) @@ -141,19 +140,21 @@ typedef struct Q35PCIHost { #define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END 0x100000 #define MCH_HOST_BRIDGE_ESMRAMC 0x9e -#define MCH_HOST_BRDIGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6)) -#define MCH_HOST_BRDIGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5)) -#define MCH_HOST_BRDIGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4)) -#define MCH_HOST_BRDIGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3)) -#define MCH_HOST_BRDIGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2)) -#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1)) -#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1)) -#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1)) -#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1)) -#define MCH_HOST_BRDIGE_ESMRAMC_T_EN ((uint8_t)1) +#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6)) +#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5)) +#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4)) +#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3)) +#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2)) +#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1)) +#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1)) +#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1)) +#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1)) +#define MCH_HOST_BRIDGE_ESMRAMC_T_EN ((uint8_t)1) /* D1:F0 PCIE* port*/ #define MCH_PCIE_DEV 1 #define MCH_PCIE_FUNC 0 +uint64_t mch_mcfg_base(void); + #endif /* HW_Q35_H */ diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 93f951132..970b4a9e4 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -43,8 +43,7 @@ typedef struct sPAPRPHBState { MemoryRegion memspace, iospace; hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size; - hwaddr msi_win_addr; - MemoryRegion memwindow, iowindow, msiwindow; + MemoryRegion memwindow, iowindow; uint32_t dma_liobn; uint64_t dma_window_start; @@ -73,7 +72,8 @@ typedef struct sPAPRPHBState { #define SPAPR_PCI_MMIO_WIN_SIZE 0x20000000 #define SPAPR_PCI_IO_WIN_OFF 0x80000000 #define SPAPR_PCI_IO_WIN_SIZE 0x10000 -#define SPAPR_PCI_MSI_WIN_OFF 0x90000000 + +#define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL #define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL @@ -88,6 +88,8 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt); +void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr); + void spapr_pci_rtas_init(void); #endif /* __HW_SPAPR_PCI_H__ */ diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index ccec2bac3..693dd6b65 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -201,9 +201,6 @@ typedef struct PCIDeviceClass { /* pcie stuff */ int is_express; /* is this device pci express? */ - /* device isn't hot-pluggable */ - int no_hotplug; - /* rom bar */ const char *romfile; } PCIDeviceClass; @@ -247,9 +244,6 @@ struct PCIDevice { PCIConfigReadFunc *config_read; PCIConfigWriteFunc *config_write; - /* IRQ objects for the INTA-INTD pins. */ - qemu_irq *irq; - /* Legacy PCI VGA regions */ MemoryRegion *vga_regions[QEMU_PCI_VGA_NUM_REGIONS]; bool has_vga; @@ -333,22 +327,13 @@ typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin); -typedef enum { - PCI_HOTPLUG_DISABLED, - PCI_HOTPLUG_ENABLED, - PCI_COLDPLUG_ENABLED, -} PCIHotplugState; - -typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev, - PCIHotplugState state); - #define TYPE_PCI_BUS "PCI" #define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS) #define TYPE_PCIE_BUS "PCIE" bool pci_bus_is_express(PCIBus *bus); bool pci_bus_is_root(PCIBus *bus); -void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent, +void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent, const char *name, MemoryRegion *address_space_mem, MemoryRegion *address_space_io, @@ -360,7 +345,6 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name, void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, void *irq_opaque, int nirq); int pci_bus_get_irq_level(PCIBus *bus, int irq_num); -void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev); /* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */ int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin); PCIBus *pci_register_bus(DeviceState *parent, const char *name, @@ -376,7 +360,6 @@ void pci_bus_fire_intx_routing_notifier(PCIBus *bus); void pci_device_set_intx_routing_notifier(PCIDevice *dev, PCIINTxRoutingNotifier notifier); void pci_device_reset(PCIDevice *dev); -void pci_bus_reset(PCIBus *bus); PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus, const char *default_model, @@ -391,12 +374,27 @@ int pci_bus_num(PCIBus *s); void pci_for_each_device(PCIBus *bus, int bus_num, void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque), void *opaque); +void pci_for_each_bus_depth_first(PCIBus *bus, + void *(*begin)(PCIBus *bus, void *parent_state), + void (*end)(PCIBus *bus, void *state), + void *parent_state); + +/* Use this wrapper when specific scan order is not required. */ +static inline +void pci_for_each_bus(PCIBus *bus, + void (*fn)(PCIBus *bus, void *opaque), + void *opaque) +{ + pci_for_each_bus_depth_first(bus, NULL, fn, opaque); +} + PCIBus *pci_find_primary_bus(void); PCIBus *pci_device_root_bus(const PCIDevice *d); const char *pci_root_bus_path(PCIDevice *dev); PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn); int pci_qdev_find_device(const char *id, PCIDevice **pdev); PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root, const char *devaddr); +void pci_bus_get_w64_range(PCIBus *bus, Range *range); int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned int *slotp, unsigned int *funcp); @@ -405,6 +403,7 @@ void pci_device_deassert_intx(PCIDevice *dev); typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int); +AddressSpace *pci_device_iommu_address_space(PCIDevice *dev); void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque); static inline void @@ -422,25 +421,25 @@ pci_get_byte(const uint8_t *config) static inline void pci_set_word(uint8_t *config, uint16_t val) { - cpu_to_le16wu((uint16_t *)config, val); + stw_le_p(config, val); } static inline uint16_t pci_get_word(const uint8_t *config) { - return le16_to_cpupu((const uint16_t *)config); + return lduw_le_p(config); } static inline void pci_set_long(uint8_t *config, uint32_t val) { - cpu_to_le32wu((uint32_t *)config, val); + stl_le_p(config, val); } static inline uint32_t pci_get_long(const uint8_t *config) { - return le32_to_cpupu((const uint32_t *)config); + return ldl_le_p(config); } static inline void @@ -630,6 +629,29 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); +qemu_irq pci_allocate_irq(PCIDevice *pci_dev); +void pci_set_irq(PCIDevice *pci_dev, int level); + +static inline void pci_irq_assert(PCIDevice *pci_dev) +{ + pci_set_irq(pci_dev, 1); +} + +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); +} + static inline int pci_is_express(const PCIDevice *d) { return d->cap_present & QEMU_PCI_CAP_EXPRESS; diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index 9df17885e..fabaeee86 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -16,8 +16,6 @@ struct PCIBus { pci_set_irq_fn set_irq; pci_map_irq_fn map_irq; pci_route_irq_fn route_intx_to_irq; - pci_hotplug_fn hotplug; - DeviceState *hotplug_qdev; void *irq_opaque; PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX]; PCIDevice *parent_dev; diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index 3ddaf6aad..e597070ab 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -53,6 +53,7 @@ /* Vendors and devices. Sort key: vendor first, device next. */ #define PCI_VENDOR_ID_LSI_LOGIC 0x1000 +#define PCI_DEVICE_ID_LSI_53C810 0x0001 #define PCI_DEVICE_ID_LSI_53C895A 0x0012 #define PCI_DEVICE_ID_LSI_SAS1078 0x0060 @@ -145,7 +146,6 @@ #define PCI_VENDOR_ID_XEN 0x5853 #define PCI_DEVICE_ID_XEN_PLATFORM 0x0001 -#define PCI_DEVICE_ID_XEN_PVDEVICE 0x0002 #define PCI_VENDOR_ID_NEC 0x1033 #define PCI_DEVICE_ID_NEC_UPD720200 0x0194 diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index c010007c5..b0bf7e3ce 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -25,6 +25,7 @@ #include "hw/pci/pci_regs.h" #include "hw/pci/pcie_regs.h" #include "hw/pci/pcie_aer.h" +#include "hw/hotplug.h" typedef enum { /* for attention and power indicator */ @@ -64,15 +65,6 @@ struct PCIExpressDevice { uint8_t exp_cap; /* SLOT */ - unsigned int hpev_intx; /* INTx for hot plug event (0-3:INT[A-D]#) - * default is 0 = INTA# - * If the chip wants to use other interrupt - * line, initialize this member with the - * desired number. - * If the chip dynamically changes this member, - * also initialize it when loaded as - * appropreately. - */ bool hpev_notified; /* Logical AND of conditions for hot plug event. Following 6.7.3.4: Software Notification of Hot-Plug Events, an interrupt @@ -82,15 +74,6 @@ struct PCIExpressDevice { /* AER */ uint16_t aer_cap; PCIEAERLog aer_log; - unsigned int aer_intx; /* INTx for error reporting - * default is 0 = INTA# - * If the chip wants to use other interrupt - * line, initialize this member with the - * desired number. - * If the chip dynamically changes this member, - * also initialize it when loaded as - * appropreately. - */ }; /* PCI express capability helper functions */ @@ -140,4 +123,8 @@ extern const VMStateDescription vmstate_pcie_device; .offset = vmstate_offset_value(_state, _field, PCIDevice), \ } +void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp); +void pcie_cap_slot_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp); #endif /* QEMU_PCIE_H */ diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index 1228e36cb..acca45ed5 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -28,6 +28,12 @@ #define PCIE_HOST_BRIDGE(obj) \ OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE) +#define PCIE_HOST_MCFG_BASE "MCFG" +#define PCIE_HOST_MCFG_SIZE "mcfg_size" + +/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ +#define PCIE_BASE_ADDR_UNMAPPED ((hwaddr)-1ULL) + struct PCIExpressHost { PCIHostState pci; @@ -51,4 +57,25 @@ void pcie_host_mmcfg_update(PCIExpressHost *e, hwaddr addr, uint32_t size); +/* + * PCI express ECAM (Enhanced Configuration Address Mapping) format. + * AKA mmcfg address + * bit 20 - 28: bus number + * bit 15 - 19: device number + * bit 12 - 14: function number + * bit 0 - 11: offset in configuration space of a given device + */ +#define PCIE_MMCFG_SIZE_MAX (1ULL << 28) +#define PCIE_MMCFG_SIZE_MIN (1ULL << 20) +#define PCIE_MMCFG_BUS_BIT 20 +#define PCIE_MMCFG_BUS_MASK 0x1ff +#define PCIE_MMCFG_DEVFN_BIT 12 +#define PCIE_MMCFG_DEVFN_MASK 0xff +#define PCIE_MMCFG_CONFOFFSET_MASK 0xfff +#define PCIE_MMCFG_BUS(addr) (((addr) >> PCIE_MMCFG_BUS_BIT) & \ + PCIE_MMCFG_BUS_MASK) +#define PCIE_MMCFG_DEVFN(addr) (((addr) >> PCIE_MMCFG_DEVFN_BIT) & \ + PCIE_MMCFG_DEVFN_MASK) +#define PCIE_MMCFG_CONFOFFSET(addr) ((addr) & PCIE_MMCFG_CONFOFFSET_MASK) + #endif /* PCIE_HOST_H */ diff --git a/include/hw/pci/shpc.h b/include/hw/pci/shpc.h index 467911a55..eef1a1ad6 100644 --- a/include/hw/pci/shpc.h +++ b/include/hw/pci/shpc.h @@ -4,6 +4,8 @@ #include "qemu-common.h" #include "exec/memory.h" #include "migration/vmstate.h" +#include "qapi/error.h" +#include "hw/hotplug.h" struct SHPCDevice { /* Capability offset in device's config space */ @@ -41,6 +43,12 @@ int shpc_init(PCIDevice *dev, PCIBus *sec_bus, MemoryRegion *bar, unsigned off); void shpc_cleanup(PCIDevice *dev, MemoryRegion *bar); void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len); + +void shpc_device_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp); +void shpc_device_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp); + extern VMStateInfo shpc_vmstate_info; #define SHPC_VMSTATE(_field, _type) \ VMSTATE_BUFFER_UNSAFE_INFO(_field, _type, 0, shpc_vmstate_info, 0) diff --git a/include/hw/pcmcia.h b/include/hw/pcmcia.h index f91669305..2695d3cba 100644 --- a/include/hw/pcmcia.h +++ b/include/hw/pcmcia.h @@ -3,11 +3,11 @@ /* PCMCIA/Cardbus */ -#include "qemu-common.h" +#include "hw/qdev.h" -typedef struct { +typedef struct PCMCIASocket { qemu_irq irq; - int attached; + bool attached; const char *slot_string; const char *card_string; } PCMCIASocket; @@ -16,22 +16,42 @@ void pcmcia_socket_register(PCMCIASocket *socket); void pcmcia_socket_unregister(PCMCIASocket *socket); void pcmcia_info(Monitor *mon, const QDict *qdict); +#define TYPE_PCMCIA_CARD "pcmcia-card" +#define PCMCIA_CARD(obj) \ + OBJECT_CHECK(PCMCIACardState, (obj), TYPE_PCMCIA_CARD) +#define PCMCIA_CARD_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PCMCIACardClass, obj, TYPE_PCMCIA_CARD) +#define PCMCIA_CARD_CLASS(cls) \ + OBJECT_CLASS_CHECK(PCMCIACardClass, cls, TYPE_PCMCIA_CARD) + struct PCMCIACardState { - void *state; + /*< private >*/ + DeviceState parent_obj; + /*< public >*/ + PCMCIASocket *slot; - int (*attach)(void *state); - int (*detach)(void *state); +}; + +typedef 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)(void *state, uint32_t address); - void (*attr_write)(void *state, uint32_t address, uint8_t value); - uint16_t (*common_read)(void *state, uint32_t address); - void (*common_write)(void *state, uint32_t address, uint16_t value); - uint16_t (*io_read)(void *state, uint32_t address); - void (*io_write)(void *state, uint32_t address, uint16_t value); -}; + 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); +} PCMCIACardClass; #define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */ #define CISTPL_NO_LINK 0x14 /* No Link Tuple */ diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h index 132ab97b5..d71bd0749 100644 --- a/include/hw/ppc/ppc.h +++ b/include/hw/ppc/ppc.h @@ -24,10 +24,10 @@ struct ppc_tb_t { /* Decrementer management */ uint64_t decr_next; /* Tick for next decr interrupt */ uint32_t decr_freq; /* decrementer frequency */ - struct QEMUTimer *decr_timer; + QEMUTimer *decr_timer; /* Hypervisor decrementer management */ uint64_t hdecr_next; /* Tick for next hdecr interrupt */ - struct QEMUTimer *hdecr_timer; + QEMUTimer *hdecr_timer; uint64_t purr_load; uint64_t purr_start; void *opaque; @@ -44,6 +44,9 @@ struct ppc_tb_t { #define PPC_DECR_ZERO_TRIGGERED (1 << 3) /* Decr interrupt triggered when * the decrementer reaches zero. */ +#define PPC_DECR_UNDERFLOW_LEVEL (1 << 4) /* Decr interrupt active when + * the most significant bit is 1. + */ uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset); clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9fc197286..5fdac1e00 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -13,6 +13,8 @@ struct sPAPRNVRAM; typedef struct sPAPREnvironment { struct VIOsPAPRBus *vio_bus; QLIST_HEAD(, sPAPRPHBState) phbs; + hwaddr msi_win_addr; + MemoryRegion msiwindow; struct sPAPRNVRAM *nvram; XICSState *icp; @@ -27,7 +29,6 @@ typedef struct sPAPREnvironment { target_ulong entry_point; uint32_t next_irq; uint64_t rtc_offset; - char *cpu_model; bool has_graphics; uint32_t epow_irq; @@ -109,6 +110,15 @@ typedef struct sPAPREnvironment { #define H_NOT_ENOUGH_RESOURCES -44 #define H_R_STATE -45 #define H_RESCINDEND -46 +#define H_P2 -55 +#define H_P3 -56 +#define H_P4 -57 +#define H_P5 -58 +#define H_P6 -59 +#define H_P7 -60 +#define H_P8 -61 +#define H_P9 -62 +#define H_UNSUPPORTED_FLAG -256 #define H_MULTI_THREADS_ACTIVE -9005 @@ -143,6 +153,16 @@ typedef struct sPAPREnvironment { #define H_PP1 (1ULL<<(63-62)) #define H_PP2 (1ULL<<(63-63)) +/* Values for 2nd argument to H_SET_MODE */ +#define H_SET_MODE_RESOURCE_SET_CIABR 1 +#define H_SET_MODE_RESOURCE_SET_DAWR 2 +#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 +#define H_SET_MODE_RESOURCE_LE 4 + +/* Flags for H_SET_MODE_RESOURCE_LE */ +#define H_SET_MODE_ENDIAN_BIG 0 +#define H_SET_MODE_ENDIAN_LITTLE 1 + /* VASI States */ #define H_VASI_INVALID 0 #define H_VASI_ENABLED 1 @@ -267,7 +287,9 @@ typedef struct sPAPREnvironment { #define H_GET_EM_PARMS 0x2B8 #define H_SET_MPP 0x2D0 #define H_GET_MPP 0x2D4 -#define MAX_HCALL_OPCODE H_GET_MPP +#define H_XIRR_X 0x2FC +#define H_SET_MODE 0x31C +#define MAX_HCALL_OPCODE H_SET_MODE /* The hcalls above are standardized in PAPR and implemented by pHyp * as well. @@ -303,7 +325,7 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, target_ulong *args); int spapr_allocate_irq(int hint, bool lsi); -int spapr_allocate_irq_block(int num, bool lsi); +int spapr_allocate_irq_block(int num, bool lsi, bool msi); static inline int spapr_allocate_msi(int hint) { @@ -315,14 +337,28 @@ static inline int spapr_allocate_lsi(int hint) return spapr_allocate_irq(hint, true); } +/* RTAS return codes */ +#define RTAS_OUT_SUCCESS 0 +#define RTAS_OUT_NO_ERRORS_FOUND 1 +#define RTAS_OUT_HW_ERROR -1 +#define RTAS_OUT_BUSY -2 +#define RTAS_OUT_PARAM_ERROR -3 +#define RTAS_OUT_NOT_SUPPORTED -3 +#define RTAS_OUT_NOT_AUTHORIZED -9002 + +static inline uint64_t ppc64_phys_to_real(uint64_t addr) +{ + return addr & ~0xF000000000000000ULL; +} + static inline uint32_t rtas_ld(target_ulong phys, int n) { - return ldl_be_phys(phys + 4*n); + return ldl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n)); } static inline void rtas_st(target_ulong phys, int n, uint32_t val) { - stl_be_phys(phys + 4*n, val); + stl_be_phys(&address_space_memory, ppc64_phys_to_real(phys + 4*n), val); } typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPREnvironment *spapr, diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 66364c5fa..0d7673de9 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -29,9 +29,24 @@ #include "hw/sysbus.h" +#define TYPE_XICS_COMMON "xics-common" +#define XICS_COMMON(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS_COMMON) + #define TYPE_XICS "xics" #define XICS(obj) OBJECT_CHECK(XICSState, (obj), TYPE_XICS) +#define TYPE_KVM_XICS "xics-kvm" +#define KVM_XICS(obj) OBJECT_CHECK(KVMXICSState, (obj), TYPE_KVM_XICS) + +#define XICS_COMMON_CLASS(klass) \ + OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS_COMMON) +#define XICS_CLASS(klass) \ + OBJECT_CLASS_CHECK(XICSStateClass, (klass), TYPE_XICS) +#define XICS_COMMON_GET_CLASS(obj) \ + OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS_COMMON) +#define XICS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(XICSStateClass, (obj), TYPE_XICS) + #define XICS_IPI 0x2 #define XICS_BUID 0x1 #define XICS_IRQ_BASE (XICS_BUID << 12) @@ -41,11 +56,22 @@ * (the kernel implementation supports more but we don't exploit * that yet) */ +typedef struct XICSStateClass XICSStateClass; typedef struct XICSState XICSState; +typedef struct ICPStateClass ICPStateClass; typedef struct ICPState ICPState; +typedef struct ICSStateClass ICSStateClass; typedef struct ICSState ICSState; typedef struct ICSIRQState ICSIRQState; +struct XICSStateClass { + DeviceClass parent_class; + + void (*cpu_setup)(XICSState *icp, PowerPCCPU *cpu); + void (*set_nr_irqs)(XICSState *icp, uint32_t nr_irqs, Error **errp); + void (*set_nr_servers)(XICSState *icp, uint32_t nr_servers, Error **errp); +}; + struct XICSState { /*< private >*/ SysBusDevice parent_obj; @@ -59,10 +85,26 @@ struct XICSState { #define TYPE_ICP "icp" #define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP) +#define TYPE_KVM_ICP "icp-kvm" +#define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP) + +#define ICP_CLASS(klass) \ + OBJECT_CLASS_CHECK(ICPStateClass, (klass), TYPE_ICP) +#define ICP_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ICPStateClass, (obj), TYPE_ICP) + +struct ICPStateClass { + DeviceClass parent_class; + + void (*pre_save)(ICPState *s); + int (*post_load)(ICPState *s, int version_id); +}; + struct ICPState { /*< private >*/ DeviceState parent_obj; /*< public >*/ + CPUState *cs; uint32_t xirr; uint8_t pending_priority; uint8_t mfrr; @@ -72,6 +114,21 @@ struct ICPState { #define TYPE_ICS "ics" #define ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS) +#define TYPE_KVM_ICS "icskvm" +#define KVM_ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_KVM_ICS) + +#define ICS_CLASS(klass) \ + OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS) +#define ICS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS) + +struct ICSStateClass { + DeviceClass parent_class; + + void (*pre_save)(ICSState *s); + int (*post_load)(ICSState *s, int version_id); +}; + struct ICSState { /*< private >*/ DeviceState parent_obj; diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h index 28fcaf17f..8ebacbbda 100644 --- a/include/hw/ptimer.h +++ b/include/hw/ptimer.h @@ -27,13 +27,11 @@ void ptimer_stop(ptimer_state *s); extern const VMStateDescription vmstate_ptimer; -#define VMSTATE_PTIMER(_field, _state) { \ - .name = (stringify(_field)), \ - .version_id = (1), \ - .vmsd = &vmstate_ptimer, \ - .size = sizeof(ptimer_state *), \ - .flags = VMS_STRUCT|VMS_POINTER, \ - .offset = vmstate_offset_pointer(_state, _field, ptimer_state), \ -} +#define VMSTATE_PTIMER(_field, _state) \ + VMSTATE_STRUCT_POINTER_V(_field, _state, 1, vmstate_ptimer, ptimer_state) + +#define VMSTATE_PTIMER_ARRAY(_f, _s, _n) \ + VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(_f, _s, _n, 0, \ + vmstate_ptimer, ptimer_state) #endif diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 46972f496..dbe473c34 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -8,6 +8,7 @@ #include "qom/object.h" #include "hw/irq.h" #include "qapi/error.h" +#include "hw/hotplug.h" enum { DEV_NVECTORS_UNSPECIFIED = -1, @@ -30,27 +31,13 @@ typedef enum DeviceCategory { DEVICE_CATEGORY_MAX } DeviceCategory; -static inline const char *qdev_category_get_name(DeviceCategory category) -{ - static const char *category_names[DEVICE_CATEGORY_MAX] = { - [DEVICE_CATEGORY_BRIDGE] = "Controller/Bridge/Hub", - [DEVICE_CATEGORY_USB] = "USB", - [DEVICE_CATEGORY_STORAGE] = "Storage", - [DEVICE_CATEGORY_NETWORK] = "Network", - [DEVICE_CATEGORY_INPUT] = "Input", - [DEVICE_CATEGORY_DISPLAY] = "Display", - [DEVICE_CATEGORY_SOUND] = "Sound", - [DEVICE_CATEGORY_MISC] = "Misc", - }; - - return category_names[category]; -}; - typedef int (*qdev_initfn)(DeviceState *dev); typedef int (*qdev_event)(DeviceState *dev); typedef void (*qdev_resetfn)(DeviceState *dev); typedef void (*DeviceRealize)(DeviceState *dev, Error **errp); typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp); +typedef void (*BusRealize)(BusState *bus, Error **errp); +typedef void (*BusUnrealize)(BusState *bus, Error **errp); struct VMStateDescription; @@ -65,6 +52,8 @@ struct VMStateDescription; * is changed to %true. Deprecated, new types inheriting directly from * TYPE_DEVICE should use @realize instead, new leaf types should consult * their respective parent type. + * @hotpluggable: indicates if #DeviceClass is hotpluggable, available + * as readonly "hotpluggable" property of #DeviceState instance * * # Realization # * Devices are constructed in two stages, @@ -113,7 +102,19 @@ typedef struct DeviceClass { const char *fw_name; const char *desc; Property *props; - int no_user; + + /* + * Shall we hide this device model from -device / device_add? + * All devices should support instantiation with device_add, and + * this flag should not exist. But we're not there, yet. Some + * devices fail to instantiate with cryptic error messages. + * Others instantiate, but don't work. Exposing users to such + * behavior would be cruel; this flag serves to protect them. It + * should never be set without a comment explaining why it is set. + * TODO remove once we're there + */ + bool cannot_instantiate_with_device_add_yet; + bool hotpluggable; /* callbacks */ void (*reset)(DeviceState *dev); @@ -174,9 +175,14 @@ struct BusClass { * bindings can be found at http://playground.sun.com/1275/bindings/. */ char *(*get_fw_dev_path)(DeviceState *dev); - int (*reset)(BusState *bus); + void (*reset)(BusState *bus); + BusRealize realize; + BusUnrealize unrealize; + /* maximum devices allowed on the bus, 0: no limit. */ int max_dev; + /* number of automatically allocated bus ids (e.g. ide.0) */ + int automatic_ids; }; typedef struct BusChild { @@ -185,15 +191,20 @@ typedef struct BusChild { QTAILQ_ENTRY(BusChild) sibling; } BusChild; +#define QDEV_HOTPLUG_HANDLER_PROPERTY "hotplug-handler" + /** * BusState: + * @hotplug_device: link to a hotplug device associated with bus. */ struct BusState { Object obj; DeviceState *parent; const char *name; int allow_hotplug; + HotplugHandler *hotplug_handler; int max_index; + bool realized; QTAILQ_HEAD(ChildrenHead, BusChild) children; QLIST_ENTRY(BusState) sibling; }; @@ -214,7 +225,6 @@ struct PropertyInfo { const char *name; const char *legacy_name; const char **enum_table; - int (*parse)(DeviceState *dev, Property *prop, const char *str); int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); ObjectPropertyAccessor *get; ObjectPropertyAccessor *set; @@ -237,7 +247,6 @@ void qdev_init_nofail(DeviceState *dev); void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id, int required_for_version); void qdev_unplug(DeviceState *dev, Error **errp); -void qdev_free(DeviceState *dev); int qdev_simple_unplug_cb(DeviceState *dev); void qdev_machine_creation_done(void); bool qdev_machine_modified(void); @@ -264,16 +273,21 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id); typedef int (qbus_walkerfn)(BusState *bus, void *opaque); typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque); -void qbus_create_inplace(void *bus, const char *typename, +void qbus_create_inplace(void *bus, size_t size, const char *typename, DeviceState *parent, const char *name); BusState *qbus_create(const char *typename, DeviceState *parent, const char *name); /* Returns > 0 if either devfn or busfn skip walk somewhere in cursion, * < 0 if either devfn or busfn terminate walk somewhere in cursion, * 0 otherwise. */ -int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque); -int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, - qbus_walkerfn *busfn, void *opaque); +int qbus_walk_children(BusState *bus, + qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn, + qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn, + void *opaque); +int qdev_walk_children(DeviceState *dev, + qdev_walkerfn *pre_devfn, qbus_walkerfn *pre_busfn, + qdev_walkerfn *post_devfn, qbus_walkerfn *post_busfn, + void *opaque); + void qdev_reset_all(DeviceState *dev); /** @@ -289,8 +303,6 @@ void qdev_reset_all(DeviceState *dev); void qbus_reset_all(BusState *bus); void qbus_reset_all_fn(void *opaque); -void qbus_free(BusState *bus); - /* This should go away once we get rid of the NULL bus hack */ BusState *sysbus_get_default(void); @@ -324,4 +336,11 @@ extern int qdev_hotplug; char *qdev_get_dev_path(DeviceState *dev); +static inline void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, + Error **errp) +{ + object_property_set_link(OBJECT(bus), OBJECT(handler), + QDEV_HOTPLUG_HANDLER_PROPERTY, errp); + bus->allow_hotplug = 1; +} #endif diff --git a/include/hw/qdev-dma.h b/include/hw/qdev-dma.h index 6812735e3..8cfb0f348 100644 --- a/include/hw/qdev-dma.h +++ b/include/hw/qdev-dma.h @@ -7,4 +7,4 @@ * See the COPYING file in the top-level directory. */ #define DEFINE_PROP_DMAADDR(_n, _s, _f, _d) \ - DEFINE_PROP_HEX64(_n, _s, _f, _d) + DEFINE_PROP_UINT64(_n, _s, _f, _d) diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 692f82e93..c46e908d7 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -12,9 +12,6 @@ extern PropertyInfo qdev_prop_uint16; extern PropertyInfo qdev_prop_uint32; extern PropertyInfo qdev_prop_int32; extern PropertyInfo qdev_prop_uint64; -extern PropertyInfo qdev_prop_hex8; -extern PropertyInfo qdev_prop_hex32; -extern PropertyInfo qdev_prop_hex64; extern PropertyInfo qdev_prop_size; extern PropertyInfo qdev_prop_string; extern PropertyInfo qdev_prop_chr; @@ -25,6 +22,7 @@ extern PropertyInfo qdev_prop_bios_chs_trans; extern PropertyInfo qdev_prop_drive; extern PropertyInfo qdev_prop_netdev; extern PropertyInfo qdev_prop_vlan; +extern PropertyInfo qdev_prop_iothread; extern PropertyInfo qdev_prop_pci_devfn; extern PropertyInfo qdev_prop_blocksize; extern PropertyInfo qdev_prop_pci_host_devaddr; @@ -111,19 +109,30 @@ extern PropertyInfo qdev_prop_arraylen; DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t) #define DEFINE_PROP_UINT64(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t) -#define DEFINE_PROP_HEX8(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t) -#define DEFINE_PROP_HEX32(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t) -#define DEFINE_PROP_HEX64(_n, _s, _f, _d) \ - DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t) #define DEFINE_PROP_SIZE(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_size, uint64_t) #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) +/* + * Please avoid pointer properties. If you must use them, you must + * cover them in their device's class init function as follows: + * + * - If the property must be set, the device cannot be used with + * device_add, so add code like this: + * |* Reason: pointer property "NAME-OF-YOUR-PROP" *| + * DeviceClass *dc = DEVICE_CLASS(class); + * dc->cannot_instantiate_with_device_add_yet = true; + * + * - If the property may safely remain null, document it like this: + * |* + * * Note: pointer property "interrupt_vector" may remain null, thus + * * no need for dc->cannot_instantiate_with_device_add_yet = true; + * *| + */ #define DEFINE_PROP_PTR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) + #define DEFINE_PROP_CHR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*) #define DEFINE_PROP_STRING(_n, _s, _f) \ @@ -134,6 +143,8 @@ extern PropertyInfo qdev_prop_arraylen; DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NICPeers) #define DEFINE_PROP_DRIVE(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *) +#define DEFINE_PROP_IOTHREAD(_n, _s, _f) \ + DEFINE_PROP(_n, _s, _f, qdev_prop_iothread, IOThread *) #define DEFINE_PROP_MACADDR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr) #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \ @@ -151,8 +162,6 @@ extern PropertyInfo qdev_prop_arraylen; /* Set properties between creation and init. */ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); -void qdev_prop_parse(DeviceState *dev, const char *name, const char *value, - Error **errp); void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value); void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value); void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value); @@ -195,4 +204,15 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp); */ void qdev_prop_set_after_realize(DeviceState *dev, const char *name, Error **errp); + +/** + * qdev_prop_allow_set_link_before_realize: + * + * Set the #Error object if an attempt is made to set the link after realize. + * This function should be used as the check() argument to + * object_property_add_link(). + */ +void qdev_prop_allow_set_link_before_realize(Object *obj, const char *name, + Object *val, Error **errp); + #endif diff --git a/include/hw/s390x/ebcdic.h b/include/hw/s390x/ebcdic.h new file mode 100644 index 000000000..1d6fde9c1 --- /dev/null +++ b/include/hw/s390x/ebcdic.h @@ -0,0 +1,104 @@ +/* + * EBCDIC/ASCII conversion Support + * + * Copyright (c) 2011 Alexander Graf + * Copyright IBM, Corp. 2013 + * + * 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 EBCDIC_H_ +#define EBCDIC_H_ + +/* EBCDIC handling */ +static const uint8_t ebcdic2ascii[] = { + 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, + 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, + 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, + 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, + 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, + 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, + 0x87, 0xA4, 0x5B, 0x2E, 0x3C, 0x28, 0x2B, 0x21, + 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, + 0x8D, 0xE1, 0x5D, 0x24, 0x2A, 0x29, 0x3B, 0x5E, + 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, + 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, + 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, + 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, + 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, + 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, + 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, + 0x9B, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, + 0xAB, 0x07, 0xAA, 0x7C, 0x07, 0x07, 0x07, 0x07, + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, + 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07, +}; + +static const uint8_t ascii2ebcdic[] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, + 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, + 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F, + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, + 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF +}; + +static inline void ebcdic_put(uint8_t *p, const char *ascii, int len) +{ + int i; + + for (i = 0; i < len; i++) { + p[i] = ascii2ebcdic[(uint8_t)ascii[i]]; + } +} + +static inline void ascii_put(uint8_t *p, const char *ebcdic, int len) +{ + int i; + + for (i = 0; i < len; i++) { + p[i] = ebcdic2ascii[(uint8_t)ebcdic[i]]; + } +} + +#endif /* EBCDIC_H_ */ diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h index 791ab2a6d..6a062b668 100644 --- a/include/hw/s390x/event-facility.h +++ b/include/hw/s390x/event-facility.h @@ -17,14 +17,23 @@ #include <hw/qdev.h> #include "qemu/thread.h" +#include "hw/s390x/sclp.h" /* SCLP event types */ +#define SCLP_EVENT_OPRTNS_COMMAND 0x01 +#define SCLP_EVENT_MESSAGE 0x02 +#define SCLP_EVENT_CONFIG_MGT_DATA 0x04 +#define SCLP_EVENT_PMSGCMD 0x09 #define SCLP_EVENT_ASCII_CONSOLE_DATA 0x1a #define SCLP_EVENT_SIGNAL_QUIESCE 0x1d /* SCLP event masks */ #define SCLP_EVENT_MASK_SIGNAL_QUIESCE 0x00000008 #define SCLP_EVENT_MASK_MSG_ASCII 0x00000040 +#define SCLP_EVENT_MASK_CONFIG_MGT_DATA 0x10000000 +#define SCLP_EVENT_MASK_OP_CMD 0x80000000 +#define SCLP_EVENT_MASK_MSG 0x40000000 +#define SCLP_EVENT_MASK_PMSGCMD 0x00800000 #define SCLP_UNCONDITIONAL_READ 0x00 #define SCLP_SELECTIVE_READ 0x01 @@ -37,14 +46,16 @@ #define SCLP_EVENT_GET_CLASS(obj) \ OBJECT_GET_CLASS(SCLPEventClass, (obj), TYPE_SCLP_EVENT) +#define TYPE_SCLP_CPU_HOTPLUG "sclp-cpu-hotplug" + typedef struct WriteEventMask { SCCBHeader h; uint16_t _reserved; uint16_t mask_length; uint32_t cp_receive_mask; uint32_t cp_send_mask; - uint32_t send_mask; uint32_t receive_mask; + uint32_t send_mask; } QEMU_PACKED WriteEventMask; typedef struct EventBufferHeader { @@ -54,6 +65,80 @@ typedef struct EventBufferHeader { uint16_t _reserved; } QEMU_PACKED EventBufferHeader; +typedef struct MdbHeader { + uint16_t length; + uint16_t type; + uint32_t tag; + uint32_t revision_code; +} QEMU_PACKED MdbHeader; + +typedef struct MTO { + uint16_t line_type_flags; + uint8_t alarm_control; + uint8_t _reserved[3]; + char message[]; +} QEMU_PACKED MTO; + +typedef struct GO { + uint32_t domid; + uint8_t hhmmss_time[8]; + uint8_t th_time[3]; + uint8_t _reserved_0; + uint8_t dddyyyy_date[7]; + uint8_t _reserved_1; + uint16_t general_msg_flags; + uint8_t _reserved_2[10]; + uint8_t originating_system_name[8]; + uint8_t job_guest_name[8]; +} QEMU_PACKED GO; + +#define MESSAGE_TEXT 0x0004 + +typedef struct MDBO { + uint16_t length; + uint16_t type; + union { + GO go; + MTO mto; + }; +} QEMU_PACKED MDBO; + +typedef struct MDB { + MdbHeader header; + MDBO mdbo[0]; +} QEMU_PACKED MDB; + +typedef struct SclpMsg { + EventBufferHeader header; + MDB mdb; +} QEMU_PACKED SclpMsg; + +#define GDS_ID_MDSMU 0x1310 +#define GDS_ID_CPMSU 0x1212 +#define GDS_ID_TEXTCMD 0x1320 + +typedef struct GdsVector { + uint16_t length; + uint16_t gds_id; +} QEMU_PACKED GdsVector; + +#define GDS_KEY_SELFDEFTEXTMSG 0x31 +#define GDS_KEY_TEXTMSG 0x30 + +typedef struct GdsSubvector { + uint8_t length; + uint8_t key; +} QEMU_PACKED GdsSubvector; + +/* MDS Message Unit */ +typedef struct MDMSU { + GdsVector mdmsu; + GdsVector cpmsu; + GdsVector text_command; + GdsSubvector self_def_text_message; + GdsSubvector text_message; +} QEMU_PACKED MDMSU; + typedef struct WriteEventData { SCCBHeader h; EventBufferHeader ebh; @@ -68,7 +153,6 @@ typedef struct ReadEventData { typedef struct SCLPEvent { DeviceState qdev; bool event_pending; - uint32_t event_type; char *name; } SCLPEvent; @@ -88,9 +172,27 @@ typedef struct SCLPEventClass { int (*write_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr); - /* returns the supported event type */ - int (*event_type)(void); - + /* can we handle this event type? */ + bool (*can_handle_event)(uint8_t type); } SCLPEventClass; +#define TYPE_SCLP_EVENT_FACILITY "s390-sclp-event-facility" +#define EVENT_FACILITY(obj) \ + OBJECT_CHECK(SCLPEventFacility, (obj), TYPE_SCLP_EVENT_FACILITY) +#define EVENT_FACILITY_CLASS(klass) \ + OBJECT_CLASS_CHECK(SCLPEventFacilityClass, (klass), \ + TYPE_SCLP_EVENT_FACILITY) +#define EVENT_FACILITY_GET_CLASS(obj) \ + OBJECT_GET_CLASS(SCLPEventFacilityClass, (obj), \ + TYPE_SCLP_EVENT_FACILITY) + +typedef struct SCLPEventFacility SCLPEventFacility; + +typedef struct SCLPEventFacilityClass { + DeviceClass parent_class; + int (*init)(SCLPEventFacility *ef); + void (*command_handler)(SCLPEventFacility *ef, SCCB *sccb, uint64_t code); + bool (*event_pending)(SCLPEventFacility *ef); +} SCLPEventFacilityClass; + #endif diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h new file mode 100644 index 000000000..497b219e3 --- /dev/null +++ b/include/hw/s390x/s390_flic.h @@ -0,0 +1,33 @@ +/* + * QEMU S390x KVM floating interrupt controller (flic) + * + * Copyright 2014 IBM Corp. + * Author(s): Jens Freimann <jfrei@linux.vnet.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 __KVM_S390_FLIC_H +#define __KVM_S390_FLIC_H + +#include "hw/sysbus.h" + +#define TYPE_KVM_S390_FLIC "s390-flic" +#define KVM_S390_FLIC(obj) \ + OBJECT_CHECK(KVMS390FLICState, (obj), TYPE_KVM_S390_FLIC) + +typedef struct KVMS390FLICState { + SysBusDevice parent_obj; + + uint32_t fd; +} KVMS390FLICState; + +#ifdef CONFIG_KVM +void s390_flic_init(void); +#else +static inline void s390_flic_init(void) { } +#endif + +#endif /* __KVM_S390_FLIC_H */ diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h index 231a38aa0..7ef16226d 100644 --- a/include/hw/s390x/sclp.h +++ b/include/hw/s390x/sclp.h @@ -17,21 +17,41 @@ #include <hw/sysbus.h> #include <hw/qdev.h> +#define SCLP_CMD_CODE_MASK 0xffff00ff + /* SCLP command codes */ #define SCLP_CMDW_READ_SCP_INFO 0x00020001 #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 +#define SCLP_READ_STORAGE_ELEMENT_INFO 0x00040001 +#define SCLP_ATTACH_STORAGE_ELEMENT 0x00080001 +#define SCLP_ASSIGN_STORAGE 0x000D0001 +#define SCLP_UNASSIGN_STORAGE 0x000C0001 #define SCLP_CMD_READ_EVENT_DATA 0x00770005 #define SCLP_CMD_WRITE_EVENT_DATA 0x00760005 #define SCLP_CMD_READ_EVENT_DATA 0x00770005 #define SCLP_CMD_WRITE_EVENT_DATA 0x00760005 #define SCLP_CMD_WRITE_EVENT_MASK 0x00780005 +/* SCLP Memory hotplug codes */ +#define SCLP_FC_ASSIGN_ATTACH_READ_STOR 0xE00000000000ULL +#define SCLP_STARTING_SUBINCREMENT_ID 0x10001 +#define SCLP_INCREMENT_UNIT 0x10000 +#define MAX_AVAIL_SLOTS 32 + +/* CPU hotplug SCLP codes */ +#define SCLP_HAS_CPU_INFO 0x0C00000000000000ULL +#define SCLP_CMDW_READ_CPU_INFO 0x00010001 +#define SCLP_CMDW_CONFIGURE_CPU 0x00110001 +#define SCLP_CMDW_DECONFIGURE_CPU 0x00100001 + /* SCLP response codes */ #define SCLP_RC_NORMAL_READ_COMPLETION 0x0010 #define SCLP_RC_NORMAL_COMPLETION 0x0020 +#define SCLP_RC_SCCB_BOUNDARY_VIOLATION 0x0100 #define SCLP_RC_INVALID_SCLP_COMMAND 0x01f0 #define SCLP_RC_CONTAINED_EQUIPMENT_CHECK 0x0340 #define SCLP_RC_INSUFFICIENT_SCCB_LENGTH 0x0300 +#define SCLP_RC_STANDBY_READ_COMPLETION 0x0410 #define SCLP_RC_INVALID_FUNCTION 0x40f0 #define SCLP_RC_NO_EVENT_BUFFERS_STORED 0x60f0 #define SCLP_RC_INVALID_SELECTION_MASK 0x70f0 @@ -71,12 +91,66 @@ typedef struct SCCBHeader { #define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader)) +/* CPU information */ +typedef struct CPUEntry { + uint8_t address; + uint8_t reserved0[13]; + uint8_t type; + uint8_t reserved1; +} QEMU_PACKED CPUEntry; + typedef struct ReadInfo { SCCBHeader h; uint16_t rnmax; uint8_t rnsize; + uint8_t _reserved1[16 - 11]; /* 11-15 */ + uint16_t entries_cpu; /* 16-17 */ + uint16_t offset_cpu; /* 18-19 */ + uint8_t _reserved2[24 - 20]; /* 20-23 */ + uint8_t loadparm[8]; /* 24-31 */ + uint8_t _reserved3[48 - 32]; /* 32-47 */ + uint64_t facilities; /* 48-55 */ + uint8_t _reserved0[100 - 56]; + uint32_t rnsize2; + uint64_t rnmax2; + uint8_t _reserved4[120-112]; /* 112-119 */ + uint16_t highest_cpu; + uint8_t _reserved5[128 - 122]; /* 122-127 */ + struct CPUEntry entries[0]; } QEMU_PACKED ReadInfo; +typedef struct ReadCpuInfo { + SCCBHeader h; + uint16_t nr_configured; /* 8-9 */ + uint16_t offset_configured; /* 10-11 */ + uint16_t nr_standby; /* 12-13 */ + uint16_t offset_standby; /* 14-15 */ + uint8_t reserved0[24-16]; /* 16-23 */ + struct CPUEntry entries[0]; +} QEMU_PACKED ReadCpuInfo; + +typedef struct ReadStorageElementInfo { + SCCBHeader h; + uint16_t max_id; + uint16_t assigned; + uint16_t standby; + uint8_t _reserved0[16 - 14]; /* 14-15 */ + uint32_t entries[0]; +} QEMU_PACKED ReadStorageElementInfo; + +typedef struct AttachStorageElement { + SCCBHeader h; + uint8_t _reserved0[10 - 8]; /* 8-9 */ + uint16_t assigned; + uint8_t _reserved1[16 - 12]; /* 12-15 */ + uint32_t entries[0]; +} QEMU_PACKED AttachStorageElement; + +typedef struct AssignStorage { + SCCBHeader h; + uint16_t rn; +} QEMU_PACKED AssignStorage; + typedef struct SCCB { SCCBHeader h; char data[SCCB_DATA_LEN]; @@ -87,32 +161,9 @@ static inline int sccb_data_len(SCCB *sccb) return be16_to_cpu(sccb->h.length) - sizeof(sccb->h); } -#define TYPE_DEVICE_S390_SCLP "s390-sclp-device" -#define SCLP_S390_DEVICE(obj) \ - OBJECT_CHECK(S390SCLPDevice, (obj), TYPE_DEVICE_S390_SCLP) -#define SCLP_S390_DEVICE_CLASS(klass) \ - OBJECT_CLASS_CHECK(S390SCLPDeviceClass, (klass), \ - TYPE_DEVICE_S390_SCLP) -#define SCLP_S390_DEVICE_GET_CLASS(obj) \ - OBJECT_GET_CLASS(S390SCLPDeviceClass, (obj), \ - TYPE_DEVICE_S390_SCLP) - -typedef struct SCLPEventFacility SCLPEventFacility; - -typedef struct S390SCLPDevice { - SysBusDevice busdev; - SCLPEventFacility *ef; - void (*sclp_command_handler)(SCLPEventFacility *ef, SCCB *sccb, - uint64_t code); - bool (*event_pending)(SCLPEventFacility *ef); -} S390SCLPDevice; - -typedef struct S390SCLPDeviceClass { - DeviceClass qdev; - int (*init)(S390SCLPDevice *sdev); -} S390SCLPDeviceClass; void s390_sclp_init(void); void sclp_service_interrupt(uint32_t sccb); +void raise_irq_cpu_hotplug(void); #endif diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 87865313e..1adb54906 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -9,6 +9,8 @@ #define MAX_SCSI_DEVS 255 #define SCSI_CMD_BUF_SIZE 16 +#define SCSI_SENSE_LEN 18 +#define SCSI_INQUIRY_LEN 36 typedef struct SCSIBus SCSIBus; typedef struct SCSIBusInfo SCSIBusInfo; @@ -29,7 +31,8 @@ typedef struct SCSISense { uint8_t ascq; } SCSISense; -#define SCSI_SENSE_BUF_SIZE 96 +#define SCSI_SENSE_BUF_SIZE_OLD 96 +#define SCSI_SENSE_BUF_SIZE 252 struct SCSICommand { uint8_t buf[SCSI_CMD_BUF_SIZE]; @@ -152,8 +155,8 @@ struct SCSIBus { const SCSIBusInfo *info; }; -void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info, - const char *bus_name); +void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host, + const SCSIBusInfo *info, const char *bus_name); static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d) { @@ -197,12 +200,16 @@ extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED; extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT; /* Illegal request, medium removal prevented */ extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED; +/* Illegal request, Invalid Transfer Tag */ +extern const struct SCSISense sense_code_INVALID_TAG; /* Command aborted, I/O process terminated */ extern const struct SCSISense sense_code_IO_ERROR; /* Command aborted, I_T Nexus loss occurred */ extern const struct SCSISense sense_code_I_T_NEXUS_LOSS; /* Command aborted, Logical Unit failure */ extern const struct SCSISense sense_code_LUN_FAILURE; +/* Command aborted, Overlapped Commands Attempted */ +extern const struct SCSISense sense_code_OVERLAPPED_COMMANDS; /* LUN not ready, Capacity data has changed */ extern const struct SCSISense sense_code_CAPACITY_CHANGED; /* LUN not ready, Medium not present */ @@ -217,6 +224,8 @@ extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED; extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET; /* Data Protection, Write Protected */ extern const struct SCSISense sense_code_WRITE_PROTECTED; +/* Data Protection, Space Allocation Failed Write Protect */ +extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED; #define SENSE_CODE(x) sense_code_ ## x diff --git a/include/hw/ssi.h b/include/hw/ssi.h index fdae31729..6c13fb2e4 100644 --- a/include/hw/ssi.h +++ b/include/hw/ssi.h @@ -56,13 +56,12 @@ typedef struct SSISlaveClass { } SSISlaveClass; struct SSISlave { - DeviceState qdev; + DeviceState parent_obj; /* Chip select state */ bool cs; }; -#define SSI_SLAVE_FROM_QDEV(dev) DO_UPCAST(SSISlave, qdev, dev) #define FROM_SSI_SLAVE(type, dev) DO_UPCAST(type, ssidev, dev) extern const VMStateDescription vmstate_ssi_slave; diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index bb50a877c..f5aaa05ee 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -68,7 +68,7 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq); void sysbus_mmio_map(SysBusDevice *dev, int n, hwaddr addr); void sysbus_mmio_map_overlap(SysBusDevice *dev, int n, hwaddr addr, - unsigned priority); + int priority); void sysbus_add_io(SysBusDevice *dev, hwaddr addr, MemoryRegion *mem); void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem); diff --git a/include/hw/timer/a9gtimer.h b/include/hw/timer/a9gtimer.h new file mode 100644 index 000000000..b88c02a6e --- /dev/null +++ b/include/hw/timer/a9gtimer.h @@ -0,0 +1,97 @@ +/* + * Global peripheral timer block for ARM A9MP + * + * (C) 2013 Xilinx Inc. + * + * Written by François LEGAL + * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.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/>. + */ + +#ifndef HW_TIMER_A9_GTIMER_H_H +#define HW_TIMER_A9_GTIMER_H_H + +#include "hw/sysbus.h" + +#define A9_GTIMER_MAX_CPUS 4 + +#define TYPE_A9_GTIMER "arm.cortex-a9-global-timer" +#define A9_GTIMER(obj) OBJECT_CHECK(A9GTimerState, (obj), TYPE_A9_GTIMER) + +#define R_COUNTER_LO 0x00 +#define R_COUNTER_HI 0x04 + +#define R_CONTROL 0x08 +#define R_CONTROL_TIMER_ENABLE (1 << 0) +#define R_CONTROL_COMP_ENABLE (1 << 1) +#define R_CONTROL_IRQ_ENABLE (1 << 2) +#define R_CONTROL_AUTO_INCREMENT (1 << 2) +#define R_CONTROL_PRESCALER_SHIFT 8 +#define R_CONTROL_PRESCALER_LEN 8 +#define R_CONTROL_PRESCALER_MASK (((1 << R_CONTROL_PRESCALER_LEN) - 1) << \ + R_CONTROL_PRESCALER_SHIFT) + +#define R_CONTROL_BANKED (R_CONTROL_COMP_ENABLE | \ + R_CONTROL_IRQ_ENABLE | \ + R_CONTROL_AUTO_INCREMENT) +#define R_CONTROL_NEEDS_SYNC (R_CONTROL_TIMER_ENABLE | \ + R_CONTROL_PRESCALER_MASK) + +#define R_INTERRUPT_STATUS 0x0C +#define R_COMPARATOR_LO 0x10 +#define R_COMPARATOR_HI 0x14 +#define R_AUTO_INCREMENT 0x18 + +typedef struct A9GTimerPerCPU A9GTimerPerCPU; +typedef struct A9GTimerState A9GTimerState; + +struct A9GTimerPerCPU { + A9GTimerState *parent; + + uint32_t control; /* only per cpu banked bits valid */ + uint64_t compare; + uint32_t status; + uint32_t inc; + + MemoryRegion iomem; + qemu_irq irq; /* PPI interrupts */ +}; + +struct A9GTimerState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + /* static props */ + uint32_t num_cpu; + + QEMUTimer *timer; + + uint64_t counter; /* current timer value */ + + uint64_t ref_counter; + uint64_t cpu_ref_time; /* the cpu time as of last update of ref_counter */ + uint32_t control; /* only non per cpu banked bits valid */ + + A9GTimerPerCPU per_cpu[A9_GTIMER_MAX_CPUS]; +}; + +typedef struct A9GTimerUpdate { + uint64_t now; + uint64_t new; +} A9GTimerUpdate; + +#endif /* #ifdef HW_TIMER_A9_GTIMER_H_H */ diff --git a/include/hw/timer/allwinner-a10-pit.h b/include/hw/timer/allwinner-a10-pit.h new file mode 100644 index 000000000..15efab8b5 --- /dev/null +++ b/include/hw/timer/allwinner-a10-pit.h @@ -0,0 +1,58 @@ +#ifndef AW_A10_PIT_H +#define AW_A10_PIT_H + +#include "hw/ptimer.h" + +#define TYPE_AW_A10_PIT "allwinner-A10-timer" +#define AW_A10_PIT(obj) OBJECT_CHECK(AwA10PITState, (obj), TYPE_AW_A10_PIT) + +#define AW_A10_PIT_TIMER_NR 6 +#define AW_A10_PIT_TIMER_IRQ 0x1 +#define AW_A10_PIT_WDOG_IRQ 0x100 + +#define AW_A10_PIT_TIMER_IRQ_EN 0 +#define AW_A10_PIT_TIMER_IRQ_ST 0x4 + +#define AW_A10_PIT_TIMER_CONTROL 0x0 +#define AW_A10_PIT_TIMER_EN 0x1 +#define AW_A10_PIT_TIMER_RELOAD 0x2 +#define AW_A10_PIT_TIMER_MODE 0x80 + +#define AW_A10_PIT_TIMER_INTERVAL 0x4 +#define AW_A10_PIT_TIMER_COUNT 0x8 +#define AW_A10_PIT_WDOG_CONTROL 0x90 +#define AW_A10_PIT_WDOG_MODE 0x94 + +#define AW_A10_PIT_COUNT_CTL 0xa0 +#define AW_A10_PIT_COUNT_RL_EN 0x2 +#define AW_A10_PIT_COUNT_CLR_EN 0x1 +#define AW_A10_PIT_COUNT_LO 0xa4 +#define AW_A10_PIT_COUNT_HI 0xa8 + +#define AW_A10_PIT_TIMER_BASE 0x10 +#define AW_A10_PIT_TIMER_BASE_END \ + (AW_A10_PIT_TIMER_BASE * 6 + AW_A10_PIT_TIMER_COUNT) + +#define AW_A10_PIT_DEFAULT_CLOCK 0x4 + +typedef struct AwA10PITState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + qemu_irq irq[AW_A10_PIT_TIMER_NR]; + ptimer_state * timer[AW_A10_PIT_TIMER_NR]; + MemoryRegion iomem; + + uint32_t irq_enable; + uint32_t irq_status; + uint32_t control[AW_A10_PIT_TIMER_NR]; + uint32_t interval[AW_A10_PIT_TIMER_NR]; + uint32_t count[AW_A10_PIT_TIMER_NR]; + uint32_t watch_dog_mode; + uint32_t watch_dog_control; + uint32_t count_lo; + uint32_t count_hi; + uint32_t count_ctl; +} AwA10PITState; + +#endif diff --git a/include/hw/timer/arm_mptimer.h b/include/hw/timer/arm_mptimer.h new file mode 100644 index 000000000..b34cba00c --- /dev/null +++ b/include/hw/timer/arm_mptimer.h @@ -0,0 +1,54 @@ +/* + * Private peripheral timer/watchdog blocks for ARM 11MPCore and A9MP + * + * Copyright (c) 2006-2007 CodeSourcery. + * Copyright (c) 2011 Linaro Limited + * Written by Paul Brook, Peter Maydell + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef HW_TIMER_ARM_MPTIMER_H +#define HW_TIMER_ARM_MPTIMER_H + +#include "hw/sysbus.h" + +#define ARM_MPTIMER_MAX_CPUS 4 + +/* State of a single timer or watchdog block */ +typedef struct { + uint32_t count; + uint32_t load; + uint32_t control; + uint32_t status; + int64_t tick; + QEMUTimer *timer; + qemu_irq irq; + MemoryRegion iomem; +} TimerBlock; + +#define TYPE_ARM_MPTIMER "arm_mptimer" +#define ARM_MPTIMER(obj) \ + OBJECT_CHECK(ARMMPTimerState, (obj), TYPE_ARM_MPTIMER) + +typedef struct { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + uint32_t num_cpu; + TimerBlock timerblock[ARM_MPTIMER_MAX_CPUS]; + MemoryRegion iomem; +} ARMMPTimerState; + +#endif diff --git a/include/hw/timer/digic-timer.h b/include/hw/timer/digic-timer.h new file mode 100644 index 000000000..ae913482c --- /dev/null +++ b/include/hw/timer/digic-timer.h @@ -0,0 +1,46 @@ +/* + * Canon DIGIC timer block declarations. + * + * Copyright (C) 2013 Antony Pavlov <antonynpavlov@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. + * + */ + +#ifndef HW_TIMER_DIGIC_TIMER_H +#define HW_TIMER_DIGIC_TIMER_H + +#include "hw/sysbus.h" +#include "qemu/typedefs.h" +#include "hw/ptimer.h" + +#define TYPE_DIGIC_TIMER "digic-timer" +#define DIGIC_TIMER(obj) OBJECT_CHECK(DigicTimerState, (obj), TYPE_DIGIC_TIMER) + +#define DIGIC_TIMER_CONTROL 0x00 +#define DIGIC_TIMER_CONTROL_RST 0x80000000 +#define DIGIC_TIMER_CONTROL_EN 0x00000001 +#define DIGIC_TIMER_RELVALUE 0x08 +#define DIGIC_TIMER_VALUE 0x0c + +typedef struct DigicTimerState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + ptimer_state *ptimer; + + uint32_t control; + uint32_t relvalue; +} DigicTimerState; + +#endif /* HW_TIMER_DIGIC_TIMER_H */ diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h index 757f79fdd..773953be7 100644 --- a/include/hw/timer/hpet.h +++ b/include/hw/timer/hpet.h @@ -13,6 +13,8 @@ #ifndef QEMU_HPET_EMUL_H #define QEMU_HPET_EMUL_H +#include "qom/object.h" + #define HPET_BASE 0xfed00000 #define HPET_CLK_PERIOD 10000000ULL /* 10000000 femtoseconds == 10ns*/ @@ -71,4 +73,12 @@ struct hpet_fw_config } QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; + +#define TYPE_HPET "hpet" + +static inline bool hpet_find(void) +{ + return object_resolve_path_type("", TYPE_HPET, NULL); +} + #endif diff --git a/include/hw/usb.h b/include/hw/usb.h index 901b0da8b..1919bdc09 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -102,17 +102,26 @@ #define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) #define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) -#define InterfaceRequest \ +#define VendorDeviceRequest ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) +#define VendorDeviceOutRequest \ + ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE)<<8) + +#define InterfaceRequest \ ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) #define InterfaceOutRequest \ ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) -#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) -#define EndpointOutRequest \ - ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) #define ClassInterfaceRequest \ ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) #define ClassInterfaceOutRequest \ ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) +#define VendorInterfaceRequest \ + ((USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8) +#define VendorInterfaceOutRequest \ + ((USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE)<<8) + +#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) +#define EndpointOutRequest \ + ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) #define USB_REQ_GET_STATUS 0x00 #define USB_REQ_CLEAR_FEATURE 0x01 @@ -148,6 +157,11 @@ #define USB_DEV_CAP_USB2_EXT 0x02 #define USB_DEV_CAP_SUPERSPEED 0x03 +#define USB_CFG_ATT_ONE (1 << 7) /* should always be set */ +#define USB_CFG_ATT_SELFPOWER (1 << 6) +#define USB_CFG_ATT_WAKEUP (1 << 5) +#define USB_CFG_ATT_BATTERY (1 << 4) + #define USB_ENDPOINT_XFER_CONTROL 0 #define USB_ENDPOINT_XFER_ISOC 1 #define USB_ENDPOINT_XFER_BULK 2 @@ -173,6 +187,7 @@ typedef struct USBDescIface USBDescIface; typedef struct USBDescEndpoint USBDescEndpoint; typedef struct USBDescOther USBDescOther; typedef struct USBDescString USBDescString; +typedef struct USBDescMSOS USBDescMSOS; struct USBDescString { uint8_t index; @@ -189,6 +204,7 @@ struct USBEndpoint { uint8_t type; uint8_t ifnum; int max_packet_size; + int max_streams; bool pipeline; bool halted; USBDevice *dev; @@ -198,6 +214,8 @@ struct USBEndpoint { enum USBDeviceFlags { USB_DEV_FLAG_FULL_PATH, USB_DEV_FLAG_IS_HOST, + USB_DEV_FLAG_MSOS_DESC_ENABLE, + USB_DEV_FLAG_MSOS_DESC_IN_USE, }; /* definition of a USB device */ @@ -314,6 +332,14 @@ typedef struct USBDeviceClass { */ void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep); + /* + * Called by the hcd to alloc / free streams on a bulk endpoint. + * Optional may be NULL. + */ + int (*alloc_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps, + int streams); + void (*free_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps); + const char *product_desc; const USBDesc *usb_desc; } USBDeviceClass; @@ -421,6 +447,8 @@ void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum); void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep, uint16_t raw); int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep); +void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw); +int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep); void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled); void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted); USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep, @@ -442,9 +470,6 @@ int set_usb_string(uint8_t *buf, const char *str); USBDevice *usb_host_device_open(USBBus *bus, const char *devname); void usb_host_info(Monitor *mon, const QDict *qdict); -/* usb-bt.c */ -USBDevice *usb_bt_init(USBBus *bus, HCIInfo *hci); - /* usb ports of the VM */ #define VM_USB_HUB_SIZE 8 @@ -496,7 +521,8 @@ struct USBBusOps { void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream); }; -void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host); +void usb_bus_new(USBBus *bus, size_t bus_size, + USBBusOps *ops, DeviceState *host); USBBus *usb_bus_find(int busnr); void usb_legacy_register(const char *typename, const char *usbdevice_name, USBDevice *(*usbdevice_init)(USBBus *bus, @@ -552,6 +578,10 @@ void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep); void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep); +int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps, + int streams); +void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps); + const char *usb_device_get_product_desc(USBDevice *dev); const USBDesc *usb_device_get_usb_desc(USBDevice *dev); diff --git a/include/hw/virtio/dataplane/hostmem.h b/include/hw/virtio/dataplane/hostmem.h deleted file mode 100644 index 2810f4b44..000000000 --- a/include/hw/virtio/dataplane/hostmem.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Thread-safe guest to host memory mapping - * - * Copyright 2012 Red Hat, Inc. and/or its affiliates - * - * Authors: - * Stefan Hajnoczi <stefanha@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. - * - */ - -#ifndef HOSTMEM_H -#define HOSTMEM_H - -#include "exec/memory.h" -#include "qemu/thread.h" - -typedef struct { - MemoryRegion *mr; - void *host_addr; - hwaddr guest_addr; - uint64_t size; - bool readonly; -} HostMemRegion; - -typedef struct { - /* The listener is invoked when regions change and a new list of regions is - * built up completely before they are installed. - */ - MemoryListener listener; - HostMemRegion *new_regions; - size_t num_new_regions; - - /* Current regions are accessed from multiple threads either to lookup - * addresses or to install a new list of regions. The lock protects the - * pointer and the regions. - */ - QemuMutex current_regions_lock; - HostMemRegion *current_regions; - size_t num_current_regions; -} HostMem; - -void hostmem_init(HostMem *hostmem); -void hostmem_finalize(HostMem *hostmem); - -/** - * Map a guest physical address to a pointer - * - * Note that there is map/unmap mechanism here. The caller must ensure that - * mapped memory is no longer used across events like hot memory unplug. This - * can be done with other mechanisms like bdrv_drain_all() that quiesce - * in-flight I/O. - */ -void *hostmem_lookup(HostMem *hostmem, hwaddr phys, hwaddr len, bool is_write); - -#endif /* HOSTMEM_H */ diff --git a/include/hw/virtio/dataplane/vring.h b/include/hw/virtio/dataplane/vring.h index c0b69ff18..63e7bf425 100644 --- a/include/hw/virtio/dataplane/vring.h +++ b/include/hw/virtio/dataplane/vring.h @@ -19,11 +19,10 @@ #include <linux/virtio_ring.h> #include "qemu-common.h" -#include "hostmem.h" #include "hw/virtio/virtio.h" typedef struct { - HostMem hostmem; /* guest memory mapper */ + MemoryRegion *mr; /* memory region containing the vring */ struct vring vr; /* virtqueue vring mapped to host memory */ uint16_t last_avail_idx; /* last processed avail ring index */ uint16_t last_used_idx; /* last processed used ring index */ @@ -54,9 +53,8 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n); void vring_disable_notification(VirtIODevice *vdev, Vring *vring); bool vring_enable_notification(VirtIODevice *vdev, Vring *vring); bool vring_should_notify(VirtIODevice *vdev, Vring *vring); -int vring_pop(VirtIODevice *vdev, Vring *vring, - struct iovec iov[], struct iovec *iov_end, - unsigned int *out_num, unsigned int *in_num); -void vring_push(Vring *vring, unsigned int head, int len); +int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement **elem); +void vring_push(Vring *vring, VirtQueueElement *elem, int len); +void vring_free_element(VirtQueueElement *elem); #endif /* VRING_H */ diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index b87cf490b..e4c41ff2e 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -16,6 +16,7 @@ #include "hw/virtio/virtio.h" #include "hw/block/block.h" +#include "sysemu/iothread.h" #define TYPE_VIRTIO_BLK "virtio-blk-device" #define VIRTIO_BLK(obj) \ @@ -106,6 +107,7 @@ struct virtio_scsi_inhdr struct VirtIOBlkConf { BlockConf conf; + IOThread *iothread; char *serial; uint32_t scsi; uint32_t config_wce; @@ -123,6 +125,7 @@ typedef struct VirtIOBlock { BlockConf *conf; VirtIOBlkConf blk; unsigned short sector_mask; + bool original_wce; VMChangeStateEntry *change; #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE Notifier migration_state_notifier; @@ -139,13 +142,15 @@ typedef struct VirtIOBlock { DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \ DEFINE_PROP_STRING("serial", _state, _field.serial), \ DEFINE_PROP_BIT("config-wce", _state, _field.config_wce, 0, true), \ - DEFINE_PROP_BIT("scsi", _state, _field.scsi, 0, true) + DEFINE_PROP_BIT("scsi", _state, _field.scsi, 0, true), \ + DEFINE_PROP_IOTHREAD("x-iothread", _state, _field.iothread) #else #define DEFINE_VIRTIO_BLK_PROPERTIES(_state, _field) \ DEFINE_BLOCK_PROPERTIES(_state, _field.conf), \ DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \ DEFINE_PROP_STRING("serial", _state, _field.serial), \ - DEFINE_PROP_BIT("config-wce", _state, _field.config_wce, 0, true) + DEFINE_PROP_BIT("config-wce", _state, _field.config_wce, 0, true), \ + DEFINE_PROP_IOTHREAD("x-iothread", _state, _field.iothread) #endif /* __linux__ */ void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk); diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h index 9217f85ab..0756545d4 100644 --- a/include/hw/virtio/virtio-bus.h +++ b/include/hw/virtio/virtio-bus.h @@ -61,7 +61,7 @@ typedef struct VirtioBusClass { * transport independent exit function. * This is called by virtio-bus just before the device is unplugged. */ - void (*device_unplug)(DeviceState *d); + void (*device_unplugged)(DeviceState *d); /* * Does the transport have variable vring alignment? * (ie can it ever call virtio_queue_set_align()?) @@ -72,15 +72,11 @@ typedef struct VirtioBusClass { struct VirtioBusState { BusState parent_obj; - /* - * Only one VirtIODevice can be plugged on the bus. - */ - VirtIODevice *vdev; }; -int virtio_bus_plug_device(VirtIODevice *vdev); +int virtio_bus_device_plugged(VirtIODevice *vdev); void virtio_bus_reset(VirtioBusState *bus); -void virtio_bus_destroy_device(VirtioBusState *bus); +void virtio_bus_device_unplugged(VirtIODevice *bus); /* Get the device id of the plugged device. */ uint16_t virtio_bus_get_vdev_id(VirtioBusState *bus); /* Get the config_len field of the plugged device. */ @@ -98,4 +94,16 @@ void virtio_bus_get_vdev_config(VirtioBusState *bus, uint8_t *config); /* Set config of the plugged device. */ void virtio_bus_set_vdev_config(VirtioBusState *bus, uint8_t *config); +static inline VirtIODevice *virtio_bus_get_device(VirtioBusState *bus) +{ + BusState *qbus = &bus->parent_obj; + BusChild *kid = QTAILQ_FIRST(&qbus->children); + DeviceState *qdev = kid ? kid->child : NULL; + + /* This is used on the data path, the cast is guaranteed + * to succeed by the qdev machinery. + */ + return (VirtIODevice *)qdev; +} + #endif /* VIRTIO_BUS_H */ diff --git a/include/hw/virtio/virtio-rng.h b/include/hw/virtio/virtio-rng.h index debaa15d5..14e85a5a3 100644 --- a/include/hw/virtio/virtio-rng.h +++ b/include/hw/virtio/virtio-rng.h @@ -18,6 +18,8 @@ #define TYPE_VIRTIO_RNG "virtio-rng-device" #define VIRTIO_RNG(obj) \ OBJECT_CHECK(VirtIORNG, (obj), TYPE_VIRTIO_RNG) +#define VIRTIO_RNG_GET_PARENT_CLASS(obj) \ + OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_RNG) /* The Virtio ID for the virtio rng device */ #define VIRTIO_ID_RNG 4 diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 9a985403c..42b102487 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -186,7 +186,7 @@ typedef struct { DEFINE_PROP_BIT("param_change", _state, _feature_field, \ VIRTIO_SCSI_F_CHANGE, true) -int virtio_scsi_common_init(VirtIOSCSICommon *vs); -int virtio_scsi_common_exit(VirtIOSCSICommon *vs); +void virtio_scsi_common_realize(DeviceState *dev, Error **errp); +void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp); #endif /* _QEMU_VIRTIO_SCSI_H */ diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index 1d2040b24..4746312a8 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -81,15 +81,15 @@ typedef struct VirtIOSerialPortClass { bool is_console; /* - * The per-port (or per-app) init function that's called when a + * The per-port (or per-app) realize function that's called when a * new device is found on the bus. */ - int (*init)(VirtIOSerialPort *port); + DeviceRealize realize; /* - * Per-port exit function that's called when a port gets + * Per-port unrealize function that's called when a port gets * hot-unplugged or removed. */ - int (*exit)(VirtIOSerialPort *port); + DeviceUnrealize unrealize; /* Callbacks for guest events */ /* Guest opened/closed device. */ diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index a90522d6d..3e54e90aa 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -124,9 +124,13 @@ struct VirtIODevice }; typedef struct VirtioDeviceClass { - /* This is what a VirtioDevice must implement */ + /*< private >*/ DeviceClass parent; - int (*init)(VirtIODevice *vdev); + /*< public >*/ + + /* This is what a VirtioDevice must implement */ + DeviceRealize realize; + DeviceUnrealize unrealize; uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features); uint32_t (*bad_features)(VirtIODevice *vdev); void (*set_features)(VirtIODevice *vdev, uint32_t val); diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 6d42dd1bd..9d549fc83 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -36,18 +36,16 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level); qemu_irq *xen_interrupt_controller_init(void); -int xen_init(void); -int xen_hvm_init(void); +int xen_init(QEMUMachine *machine); +int xen_hvm_init(MemoryRegion **ram_memory); void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) -struct MemoryRegion; void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, struct MemoryRegion *mr); void xen_modified_memory(ram_addr_t start, ram_addr_t length); #endif -struct MemoryRegion; void xen_register_framebuffer(struct MemoryRegion *mr); #if defined(CONFIG_XEN) && CONFIG_XEN_CTRL_INTERFACE_VERSION < 400 diff --git a/include/hw/xilinx.h b/include/hw/xilinx.h deleted file mode 100644 index 0c0251a2e..000000000 --- a/include/hw/xilinx.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef HW_XILINX_H -#define HW_XILINX_H 1 - - -#include "qemu-common.h" -#include "qapi/qmp/qerror.h" -#include "hw/stream.h" -#include "net/net.h" - -static inline DeviceState * -xilinx_intc_create(hwaddr base, qemu_irq irq, int kind_of_intr) -{ - DeviceState *dev; - - dev = qdev_create(NULL, "xlnx.xps-intc"); - qdev_prop_set_uint32(dev, "kind-of-intr", kind_of_intr); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - return dev; -} - -/* OPB Timer/Counter. */ -static inline DeviceState * -xilinx_timer_create(hwaddr base, qemu_irq irq, int oto, int freq) -{ - DeviceState *dev; - - dev = qdev_create(NULL, "xlnx.xps-timer"); - qdev_prop_set_uint32(dev, "one-timer-only", oto); - qdev_prop_set_uint32(dev, "clock-frequency", freq); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - return dev; -} - -/* XPS Ethernet Lite MAC. */ -static inline DeviceState * -xilinx_ethlite_create(NICInfo *nd, hwaddr base, qemu_irq irq, - int txpingpong, int rxpingpong) -{ - DeviceState *dev; - - qemu_check_nic_model(nd, "xlnx.xps-ethernetlite"); - - dev = qdev_create(NULL, "xlnx.xps-ethernetlite"); - qdev_set_nic_properties(dev, nd); - qdev_prop_set_uint32(dev, "tx-ping-pong", txpingpong); - qdev_prop_set_uint32(dev, "rx-ping-pong", rxpingpong); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - return dev; -} - -static inline void -xilinx_axiethernet_init(DeviceState *dev, NICInfo *nd, StreamSlave *ds, - StreamSlave *cs, hwaddr base, qemu_irq irq, int txmem, - int rxmem) -{ - Error *errp = NULL; - - qdev_set_nic_properties(dev, nd); - qdev_prop_set_uint32(dev, "rxmem", rxmem); - qdev_prop_set_uint32(dev, "txmem", txmem); - object_property_set_link(OBJECT(dev), OBJECT(ds), - "axistream-connected", &errp); - object_property_set_link(OBJECT(dev), OBJECT(cs), - "axistream-control-connected", &errp); - assert_no_error(errp); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); -} - -static inline void -xilinx_axidma_init(DeviceState *dev, StreamSlave *ds, StreamSlave *cs, - hwaddr base, qemu_irq irq, qemu_irq irq2, int freqhz) -{ - Error *errp = NULL; - - qdev_prop_set_uint32(dev, "freqhz", freqhz); - object_property_set_link(OBJECT(dev), OBJECT(ds), - "axistream-connected", &errp); - object_property_set_link(OBJECT(dev), OBJECT(cs), - "axistream-control-connected", &errp); - assert_no_error(errp); - qdev_init_nofail(dev); - - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, irq2); -} - -#endif |