[Qemu-devel] [PATCH v8 05/26] fw_cfg: interface to trigger callback on read
Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/nvram/fw_cfg.h | 4 hw/nvram/fw_cfg.c | 33 - 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index f60dd67..2ab0fc2 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -60,6 +60,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 +71,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/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index d0820e5..f5dc3ea 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -42,6 +42,7 @@ typedef struct FWCfgEntry { uint8_t *data; void *callback_opaque; FWCfgCallback callback; +FWCfgReadCallback read_callback; } FWCfgEntry; struct FWCfgState { @@ -249,8 +250,12 @@ static uint8_t fw_cfg_read(FWCfgState *s) if (s-cur_entry == FW_CFG_INVALID || !e-data || s-cur_offset = e-len) ret = 0; -else +else { +if (e-read_callback) { +e-read_callback(e-callback_opaque, s-cur_offset); +} ret = e-data[s-cur_offset++]; +} trace_fw_cfg_read(s, ret); return ret; @@ -381,7 +386,10 @@ static const VMStateDescription vmstate_fw_cfg = { } }; -void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) +static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key, + FWCfgReadCallback callback, + void *callback_opaque, + void *data, size_t len) { int arch = !!(key FW_CFG_ARCH_LOCAL); @@ -391,6 +399,13 @@ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) s-entries[arch][key].data = data; s-entries[arch][key].len = (uint32_t)len; +s-entries[arch][key].read_callback = callback; +s-entries[arch][key].callback_opaque = callback_opaque; +} + +void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) +{ +fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len); } void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value) @@ -444,8 +459,9 @@ void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback, s-entries[arch][key].callback = callback; } -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) { int i, index; size_t dsize; @@ -459,7 +475,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, index = be32_to_cpu(s-files-count); assert(index FW_CFG_FILE_SLOTS); -fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len); +fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index, + callback, callback_opaque, data, len); pstrcpy(s-files-f[index].name, sizeof(s-files-f[index].name), filename); @@ -477,6 +494,12 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, s-files-count = cpu_to_be32(index+1); } +void fw_cfg_add_file(FWCfgState *s, const char *filename, + void *data, size_t len) +{ +fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len); +} + static void fw_cfg_machine_ready(struct Notifier *n, void *data) { size_t len; -- MST
[Qemu-devel] [PATCH v8 14/26] acpi: ssdt pcihp: updat generated file
update generated file, not sure what changed Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/ssdt-pcihp.hex.generated | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated index 0d32a27..b3c2cd5 100644 --- a/hw/i386/ssdt-pcihp.hex.generated +++ b/hw/i386/ssdt-pcihp.hex.generated @@ -17,7 +17,7 @@ static unsigned char ssdp_pcihp_aml[] = { 0x0, 0x0, 0x1, -0x77, +0x76, 0x42, 0x58, 0x50, @@ -40,9 +40,9 @@ static unsigned char ssdp_pcihp_aml[] = { 0x4e, 0x54, 0x4c, -0x28, -0x5, -0x10, +0x23, +0x8, +0x13, 0x20, 0x10, 0x33, -- MST
[Qemu-devel] [PATCH v8 06/26] loader: support for unmapped ROM blobs
Support ROM blobs not mapped into guest memory: same as ROM files really but use caller's buffer. Support incoking callback on access and return memory pointer making it easier for caller to update memory if necessary. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Reviewed-by: Laszlo Ersek ler...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/lm32/lm32_hwsetup.h | 2 +- include/hw/loader.h| 7 --- hw/core/loader.c | 23 --- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/hw/lm32/lm32_hwsetup.h b/hw/lm32/lm32_hwsetup.h index 3449bd8..9fd5e69 100644 --- a/hw/lm32/lm32_hwsetup.h +++ b/hw/lm32/lm32_hwsetup.h @@ -73,7 +73,7 @@ static inline void hwsetup_free(HWSetup *hw) static inline void hwsetup_create_rom(HWSetup *hw, hwaddr base) { -rom_add_blob(hwsetup, hw-data, TARGET_PAGE_SIZE, base); +rom_add_blob(hwsetup, hw-data, TARGET_PAGE_SIZE, base, NULL, NULL, NULL); } static inline void hwsetup_add_u8(HWSetup *hw, uint8_t u) diff --git a/include/hw/loader.h b/include/hw/loader.h index 6145736..e0c576b 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -40,8 +40,9 @@ extern bool rom_file_in_ram; 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); +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); @@ -53,7 +54,7 @@ void do_info_roms(Monitor *mon, const QDict *qdict); #define rom_add_file_fixed(_f, _a, _i) \ rom_add_file(_f, NULL, _a, _i) #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) ? 0 : -1) #define PC_ROM_MIN_VGA 0xc #define PC_ROM_MIN_OPTION 0xc8000 diff --git a/hw/core/loader.c b/hw/core/loader.c index 7b3d3ee..449bd4c 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -700,10 +700,12 @@ err: return -1; } -int rom_add_blob(const char *name, const void *blob, size_t len, - hwaddr addr) +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) { Rom *rom; +void *data = NULL; rom = g_malloc0(sizeof(*rom)); rom-name = g_strdup(name); @@ -713,7 +715,22 @@ int rom_add_blob(const char *name, const void *blob, size_t len, rom-data = g_malloc0(rom-datasize); memcpy(rom-data, blob, len); rom_insert(rom); -return 0; +if (fw_file_name fw_cfg) { +char devpath[100]; + +snprintf(devpath, sizeof(devpath), /rom@%s, fw_file_name); + +if (rom_file_in_ram) { +data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); +} else { +data = rom-data; +} + +fw_cfg_add_file_callback(fw_cfg, fw_file_name, + fw_callback, callback_opaque, + data, rom-romsize); +} +return data; } /* This function is specific for elf program because we don't need to allocate -- MST
[Qemu-devel] [PATCH v8 15/26] loader: use file path size from fw_cfg.h
Avoid a bit of code duplication, make max file path constant reusable. Suggested-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/nvram/fw_cfg.h | 4 +++- hw/core/loader.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 2ab0fc2..72b1549 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -46,12 +46,14 @@ #define FW_CFG_INVALID 0x +#define FW_CFG_MAX_FILE_PATH56 + #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 { diff --git a/hw/core/loader.c b/hw/core/loader.c index 449bd4c..060729f 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -663,7 +663,7 @@ int rom_add_file(const char *file, const char *fw_dir, rom_insert(rom); if (rom-fw_file fw_cfg) { const char *basename; -char fw_file_name[56]; +char fw_file_name[FW_CFG_MAX_FILE_PATH]; void *data; basename = strrchr(rom-fw_file, '/'); -- MST
[Qemu-devel] [PATCH v8 07/26] pcie_host: expose UNMAPPED macro
Make it possible to test unmapped status through QMP. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 3 +++ hw/pci/pcie_host.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index 1228e36..bac3c67 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -28,6 +28,9 @@ #define PCIE_HOST_BRIDGE(obj) \ OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE) +/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ +#define PCIE_BASE_ADDR_UNMAPPED ((hwaddr)-1ULL) + struct PCIExpressHost { PCIHostState pci; diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c index b70e5ad..410ac08 100644 --- a/hw/pci/pcie_host.c +++ b/hw/pci/pcie_host.c @@ -104,9 +104,6 @@ static const MemoryRegionOps pcie_mmcfg_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ -#define PCIE_BASE_ADDR_UNMAPPED ((hwaddr)-1ULL) - int pcie_host_init(PCIExpressHost *e) { e-base_addr = PCIE_BASE_ADDR_UNMAPPED; -- MST
[Qemu-devel] [PATCH v8 08/26] pcie_host: expose address format
Callers pass in the address so it's helpful for them to be able to decode it. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 21 + hw/pci/pcie_host.c | 21 - 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index bac3c67..da0f275 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -54,4 +54,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_BIT12 +#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/hw/pci/pcie_host.c b/hw/pci/pcie_host.c index 410ac08..c6e1b57 100644 --- a/hw/pci/pcie_host.c +++ b/hw/pci/pcie_host.c @@ -24,27 +24,6 @@ #include hw/pci/pcie_host.h #include exec/address-spaces.h -/* - * PCI express mmcfig 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_BIT12 -#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) - - /* a helper function to get a PCIDevice for a given mmconfig address */ static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus *s, uint32_t mmcfg_addr) -- MST
[Qemu-devel] [PATCH v8 16/26] i386: add bios linker/loader
This adds a dynamic bios linker/loader. This will be used by acpi table generation code to: - load each table in the appropriate memory segment - link tables to each other - fix up checksums after said linking Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/bios-linker-loader.h | 27 hw/i386/bios-linker-loader.c | 158 +++ hw/i386/Makefile.objs| 1 + 3 files changed, 186 insertions(+) create mode 100644 hw/i386/bios-linker-loader.h create mode 100644 hw/i386/bios-linker-loader.c diff --git a/hw/i386/bios-linker-loader.h b/hw/i386/bios-linker-loader.h new file mode 100644 index 000..498c0af --- /dev/null +++ b/hw/i386/bios-linker-loader.h @@ -0,0 +1,27 @@ +#ifndef BIOS_LINKER_LOADER_H +#define BIOS_LINKER_LOADER_H + +#include glib.h +#include stdbool.h +#include inttypes.h + +GArray *bios_linker_loader_init(void); + +void bios_linker_loader_alloc(GArray *linker, + const char *file, + uint32_t alloc_align, + bool alloc_fseg); + +void bios_linker_loader_add_checksum(GArray *linker, const char *file, + void *table, + void *start, unsigned size, + uint8_t *checksum); + +void bios_linker_loader_add_pointer(GArray *linker, +const char *dest_file, +const char *src_file, +GArray *table, void *pointer, +uint8_t pointer_size); + +void *bios_linker_loader_cleanup(GArray *linker); +#endif diff --git a/hw/i386/bios-linker-loader.c b/hw/i386/bios-linker-loader.c new file mode 100644 index 000..0833853 --- /dev/null +++ b/hw/i386/bios-linker-loader.c @@ -0,0 +1,158 @@ +/* Dynamic linker/loader of ACPI tables + * + * Copyright (C) 2013 Red Hat Inc + * + * Author: Michael S. Tsirkin m...@redhat.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/. + */ + +#include bios-linker-loader.h +#include hw/nvram/fw_cfg.h + +#include string.h +#include assert.h +#include qemu/bswap.h + +#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH + +struct BiosLinkerLoaderEntry { +uint32_t command; +union { +/* + * COMMAND_ALLOCATE - allocate a table from @alloc.file + * subject to @alloc.align alignment (must be power of 2) + * and @alloc.zone (can be HIGH or FSEG) requirements. + * + * Must appear exactly once for each file, and before + * this file is referenced by any other command. + */ +struct { +char file[BIOS_LINKER_LOADER_FILESZ]; +uint32_t align; +uint8_t zone; +} alloc; + +/* + * COMMAND_ADD_POINTER - patch the table (originating from + * @dest_file) at @pointer.offset, by adding a pointer to the table + * originating from @src_file. 1,2,4 or 8 byte unsigned + * addition is used depending on @pointer.size. + */ +struct { +char dest_file[BIOS_LINKER_LOADER_FILESZ]; +char src_file[BIOS_LINKER_LOADER_FILESZ]; +uint32_t offset; +uint8_t size; +} pointer; + +/* + * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by + * @cksum_start and @cksum_length fields, + * and then add the value at @cksum.offset. + * Checksum simply sums -X for each byte X in the range + * using 8-bit math. + */ +struct { +char file[BIOS_LINKER_LOADER_FILESZ]; +uint32_t offset; +uint32_t start; +uint32_t length; +} cksum; + +/* padding */ +char pad[124]; +}; +} QEMU_PACKED; +typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry; + +enum { +BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1, +BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2, +BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3, +}; + +enum { +BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1, +BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2, +}; + +GArray *bios_linker_loader_init(void) +{ +return
[Qemu-devel] [PATCH v8 09/26] q35: use macro for MCFG property name
Useful to make it accessible through QOM. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 2 ++ hw/pci-host/q35.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index da0f275..33d75bd 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -28,6 +28,8 @@ #define PCIE_HOST_BRIDGE(obj) \ OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE) +#define PCIE_HOST_MCFG_BASE MCFG + /* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ #define PCIE_BASE_ADDR_UNMAPPED ((hwaddr)-1ULL) diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 23dbeea..e46f286 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -110,7 +110,7 @@ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v, } static Property mch_props[] = { -DEFINE_PROP_UINT64(MCFG, Q35PCIHost, parent_obj.base_addr, +DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr, MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT), DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost, mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE), -- MST
[Qemu-devel] [PATCH v8 23/26] hpet: add API to find it
Add API to find HPET using QOM. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/timer/hpet.h | 2 ++ hw/timer/hpet.c | 5 + 2 files changed, 7 insertions(+) diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h index 757f79f..ab44bd3 100644 --- a/include/hw/timer/hpet.h +++ b/include/hw/timer/hpet.h @@ -71,4 +71,6 @@ struct hpet_fw_config } QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; + +bool hpet_find(void); #endif diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index fcd22ae..2eb75ea 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -757,6 +757,11 @@ static void hpet_device_class_init(ObjectClass *klass, void *data) dc-props = hpet_device_properties; } +bool hpet_find(void) +{ +return object_resolve_path_type(, TYPE_HPET, NULL); +} + static const TypeInfo hpet_device_info = { .name = TYPE_HPET, .parent= TYPE_SYS_BUS_DEVICE, -- MST
[Qemu-devel] [PATCH v8 18/26] i386: define pc guest info
This defines a structure that will be used to fill in acpi tables where relevant properties are not yet available using QOM. Reviewed-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 9 + hw/i386/pc.c | 31 +++ 2 files changed, 40 insertions(+) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9b2ddc4..085a621 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -9,6 +9,9 @@ #include hw/i386/ioapic.h #include qemu/range.h +#include qemu/bitmap.h +#include sysemu/sysemu.h +#include hw/pci/pci.h /* PC-style peripherals (also used by other machines). */ @@ -20,6 +23,12 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; +hwaddr ram_size; +unsigned apic_id_limit; +bool apic_xrupt_override; +uint64_t numa_nodes; +uint64_t *node_mem; +uint64_t *node_cpu; FWCfgState *fw_cfg; }; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..dbae9da 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1028,6 +1028,23 @@ static void pc_fw_cfg_guest_info(PcGuestInfo *guest_info) fw_cfg_add_file(guest_info-fw_cfg, etc/pci-info, info, sizeof *info); } +static void pc_set_cpu_guest_info(CPUState *cpu, PcGuestInfo *guest_info) +{ +CPUClass *klass = CPU_GET_CLASS(cpu); +uint64_t apic_id = klass-get_arch_id(cpu); +int j; + +assert(apic_id guest_info-apic_id_limit); + +for (j = 0; j guest_info-numa_nodes; j++) { +assert(cpu-cpu_index max_cpus); +if (test_bit(cpu-cpu_index, node_cpumask[j])) { +guest_info-node_cpu[apic_id] = cpu_to_le64(j); +break; +} +} +} + typedef struct PcGuestInfoState { PcGuestInfo info; Notifier machine_done; @@ -1047,6 +1064,20 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, { PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state); PcGuestInfo *guest_info = guest_info_state-info; +CPUState *cpu; + +guest_info-ram_size = below_4g_mem_size + above_4g_mem_size; +guest_info-apic_id_limit = pc_apic_id_limit(max_cpus); +guest_info-apic_xrupt_override = kvm_allows_irq0_override(); +guest_info-numa_nodes = nb_numa_nodes; +guest_info-node_mem = g_memdup(node_mem, guest_info-numa_nodes * +sizeof *guest_info-node_mem); +guest_info-node_cpu = g_malloc0(guest_info-apic_id_limit * + sizeof *guest_info-node_cpu); + +CPU_FOREACH(cpu) { +pc_set_cpu_guest_info(cpu, guest_info); +} guest_info_state-machine_done.notify = pc_guest_info_machine_done; qemu_add_machine_init_done_notifier(guest_info_state-machine_done); -- MST
[Qemu-devel] [PATCH v8 25/26] ssdt: fix PBLK length
We don't really support CPU throttling, so supply 0 PBLK length. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/ssdt-proc.dsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/ssdt-proc.dsl b/hw/i386/ssdt-proc.dsl index 58333c7..8229bfd 100644 --- a/hw/i386/ssdt-proc.dsl +++ b/hw/i386/ssdt-proc.dsl @@ -37,7 +37,7 @@ DefinitionBlock (ssdt-proc.aml, SSDT, 0x01, BXPC, BXSSDT, 0x1) ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name -Processor(CPAA, 0xAA, 0xb010, 0x06) { +Processor(CPAA, 0xAA, 0x, 0x0) { ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id Name(ID, 0xAA) /* -- MST
[Qemu-devel] [PATCH v8 19/26] acpi/piix: add macros for acpi property names
Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 10 ++ hw/acpi/piix4.c | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 085a621..5aefc5b 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -20,6 +20,16 @@ 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; diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index b46bd5e..4b8c1da 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -489,9 +489,9 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, static Property piix4_pm_properties[] = { DEFINE_PROP_UINT32(smb_io_base, PIIX4PMState, smb_io_base, 0), -DEFINE_PROP_UINT8(disable_s3, PIIX4PMState, disable_s3, 0), -DEFINE_PROP_UINT8(disable_s4, PIIX4PMState, disable_s4, 0), -DEFINE_PROP_UINT8(s4_val, PIIX4PMState, s4_val, 2), +DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), +DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), +DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), DEFINE_PROP_END_OF_LIST(), }; -- MST
[Qemu-devel] [PATCH v8 20/26] piix: APIs for pc guest info
This adds APIs that will be used to fill in guest acpi tables. Some required information is still lacking in QOM, so we fall back on lookups by type and returning explicit types. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/piix4.h | 8 include/hw/i386/pc.h| 1 + hw/acpi/piix4.c | 44 hw/pci-host/piix.c | 8 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 include/hw/acpi/piix4.h diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h new file mode 100644 index 000..65e6fd7 --- /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/i386/pc.h b/include/hw/i386/pc.h index 5aefc5b..95857be 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -192,6 +192,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, 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); diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 4b8c1da..3bcd890 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -29,6 +29,7 @@ #include exec/ioport.h #include hw/nvram/fw_cfg.h #include exec/address-spaces.h +#include hw/acpi/piix4.h //#define DEBUG @@ -69,6 +70,8 @@ typedef struct PIIX4PMState { /* public */ MemoryRegion io; +uint32_t io_base; + MemoryRegion io_gpe; MemoryRegion io_pci; MemoryRegion io_cpu; @@ -152,14 +155,13 @@ static void apm_ctrl_changed(uint32_t val, void *arg) static void pm_io_space_update(PIIX4PMState *s) { PCIDevice *d = PCI_DEVICE(s); -uint32_t pm_io_base; -pm_io_base = le32_to_cpu(*(uint32_t *)(d-config + 0x40)); -pm_io_base = 0xffc0; +s-io_base = le32_to_cpu(*(uint32_t *)(d-config + 0x40)); +s-io_base = 0xffc0; memory_region_transaction_begin(); memory_region_set_enabled(s-io, d-config[0x80] 1); -memory_region_set_address(s-io, pm_io_base); +memory_region_set_address(s-io, s-io_base); memory_region_transaction_commit(); } @@ -407,6 +409,28 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); } +static void piix4_pm_add_propeties(PIIX4PMState *s) +{ +static const uint8_t acpi_enable_cmd = ACPI_ENABLE; +static const uint8_t acpi_disable_cmd = ACPI_DISABLE; +static const uint32_t gpe0_blk = GPE_BASE; +static const uint32_t gpe0_blk_len = GPE_LEN; +static const uint16_t sci_int = 9; + +object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD, + acpi_enable_cmd, NULL); +object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD, + acpi_disable_cmd, NULL); +object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK, + gpe0_blk, NULL); +object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN, + gpe0_blk_len, NULL); +object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT, + sci_int, NULL); +object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE, + s-io_base, NULL); +} + static int piix4_pm_initfn(PCIDevice *dev) { PIIX4PMState *s = PIIX4_PM(dev); @@ -456,9 +480,21 @@ static int piix4_pm_initfn(PCIDevice *dev) piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev-bus, s); +piix4_pm_add_propeties(s); return 0; } +Object *piix4_pm_find(void) +{ +bool ambig; +Object *o = object_resolve_path_type(, TYPE_PIIX4_PM, ambig); + +if (ambig || !o) { +return NULL; +} +return o; +} + 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) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index c041149..bad3953 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -416,6 +416,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, return b; } +PCIBus *find_i440fx(void) +{ +PCIHostState *s = OBJECT_CHECK(PCIHostState, + object_resolve_path(/machine/i440fx, NULL), + TYPE_PCI_HOST_BRIDGE); +return s ? s-bus : NULL; +} + /* PIIX3 PCI to ISA bridge */ static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq) { -- MST
[Qemu-devel] [PATCH v8 21/26] ich9: APIs for pc guest info
This adds APIs that will be used to fill in acpi tables, implemented using QOM, to various ich9 components. Some information is still missing in QOM, so we fall back on lookups by type instead. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/ich9.h| 2 ++ include/hw/i386/ich9.h| 2 ++ include/hw/pci-host/q35.h | 2 ++ hw/acpi/ich9.c| 24 hw/isa/lpc_ich9.c | 40 hw/pci-host/q35.c | 10 ++ 6 files changed, 80 insertions(+) diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index b1fe71f..82fcf9f 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -49,4 +49,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/i386/ich9.h b/include/hw/i386/ich9.h index c5f637b..4a68b35 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -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))) diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 6eb7ab6..f9db770 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -156,4 +156,6 @@ typedef struct Q35PCIHost { #define MCH_PCIE_DEV 1 #define MCH_PCIE_FUNC 0 +uint64_t mch_mcfg_base(void); + #endif /* HW_Q35_H */ diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 3fb443d..7e0429e 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -24,6 +24,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include hw/hw.h +#include qapi/visitor.h #include hw/i386/pc.h #include hw/pci/pci.h #include qemu/timer.h @@ -228,3 +229,26 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, pm-powerdown_notifier.notify = pm_powerdown_req; qemu_register_powerdown_notifier(pm-powerdown_notifier); } + +static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +ICH9LPCPMRegs *pm = opaque; +uint32_t value = pm-pm_io_base + ICH9_PMIO_GPE0_STS; + +visit_type_uint32(v, value, name, errp); +} + +void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) +{ +static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN; + +object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, + pm-pm_io_base, errp); +object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, uint32, +ich9_pm_get_gpe0_blk, +NULL, NULL, pm, NULL); +object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, + gpe0_len, errp); +} diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 5633d08..19b2198 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -29,6 +29,7 @@ */ #include qemu-common.h #include hw/hw.h +#include qapi/visitor.h #include qemu/range.h #include hw/isa/isa.h #include hw/sysbus.h @@ -525,6 +526,43 @@ static const MemoryRegionOps ich9_rst_cnt_ops = { .endianness = DEVICE_LITTLE_ENDIAN }; +Object *ich9_lpc_find(void) +{ +bool ambig; +Object *o = object_resolve_path_type(, TYPE_ICH9_LPC_DEVICE, ambig); + +if (ambig) { +return NULL; +} +return o; +} + +static void ich9_lpc_get_sci_int(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj); +uint32_t value = ich9_lpc_sci_irq(lpc); + +visit_type_uint32(v, value, name, errp); +} + +static void ich9_lpc_add_properties(ICH9LPCState *lpc) +{ +static const uint8_t acpi_enable_cmd = ICH9_APM_ACPI_ENABLE; +static const uint8_t acpi_disable_cmd = ICH9_APM_ACPI_DISABLE; + +object_property_add(OBJECT(lpc), ACPI_PM_PROP_SCI_INT, uint32, +ich9_lpc_get_sci_int, +NULL, NULL, NULL, NULL); +object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_ENABLE_CMD, + acpi_enable_cmd, NULL); +object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_DISABLE_CMD, + acpi_disable_cmd, NULL); + +ich9_pm_add_properties(OBJECT(lpc), lpc-pm, NULL); +} + static int ich9_lpc_initfn(PCIDevice *d) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(d); @@ -552,6 +590,8 @@ static int ich9_lpc_initfn(PCIDevice *d
[Qemu-devel] [PATCH v8 22/26] pvpanic: add API to access io port
Add API to find pvpanic device and get its io port. Will be used to fill in guest info structure. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 1 + hw/misc/pvpanic.c| 13 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 95857be..e3ee0a8 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -235,6 +235,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory, /* pvpanic.c */ void pvpanic_init(ISABus *bus); +uint16_t pvpanic_port(void); /* e820 types */ #define E820_RAM1 diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c index b64e3bb..226e298 100644 --- a/hw/misc/pvpanic.c +++ b/hw/misc/pvpanic.c @@ -117,8 +117,19 @@ void pvpanic_init(ISABus *bus) isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE); } +#define PVPANIC_IOPORT_PROP ioport + +uint16_t pvpanic_port(void) +{ +Object *o = object_resolve_path_type(, TYPE_ISA_PVPANIC_DEVICE, NULL); +if (!o) { +return 0; +} +return object_property_get_int(o, PVPANIC_IOPORT_PROP, NULL); +} + static Property pvpanic_isa_properties[] = { -DEFINE_PROP_UINT16(ioport, PVPanicState, ioport, 0x505), +DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505), DEFINE_PROP_END_OF_LIST(), }; -- MST
[Qemu-devel] [PATCH v8 26/26] ssdt-proc: update generated file
Update generated ssdt proc hex file (used for systems lacking IASL) after P_BLK length change. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/ssdt-proc.hex.generated | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/i386/ssdt-proc.hex.generated b/hw/i386/ssdt-proc.hex.generated index a28172e..bb9920d 100644 --- a/hw/i386/ssdt-proc.hex.generated +++ b/hw/i386/ssdt-proc.hex.generated @@ -11,7 +11,7 @@ static unsigned char ssdp_proc_aml[] = { 0x0, 0x0, 0x1, -0xb3, +0xb8, 0x42, 0x58, 0x50, @@ -34,9 +34,9 @@ static unsigned char ssdp_proc_aml[] = { 0x4e, 0x54, 0x4c, -0x28, -0x5, -0x10, +0x23, +0x8, +0x13, 0x20, 0x5b, 0x83, @@ -51,7 +51,7 @@ static unsigned char ssdp_proc_aml[] = { 0xb0, 0x0, 0x0, -0x6, +0x0, 0x8, 0x49, 0x44, -- MST
[Qemu-devel] [PATCH v8 17/26] loader: allow adding ROMs in done callbacks
Don't abort if machine done callbacks add ROMs. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/loader.h | 1 + hw/core/loader.c| 6 +- vl.c| 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/hw/loader.h b/include/hw/loader.h index e0c576b..58eca98 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -46,6 +46,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len, 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); diff --git a/hw/core/loader.c b/hw/core/loader.c index 060729f..60d2ebd 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -812,10 +812,14 @@ int rom_load_all(void) memory_region_unref(section.mr); } qemu_register_reset(rom_reset, NULL); -roms_loaded = 1; return 0; } +void rom_load_done(void) +{ +roms_loaded = 1; +} + void rom_set_fw(FWCfgState *f) { fw_cfg = f; diff --git a/vl.c b/vl.c index fb8006e..46c29c4 100644 --- a/vl.c +++ b/vl.c @@ -4339,6 +4339,9 @@ int main(int argc, char **argv, char **envp) qemu_register_reset(qbus_reset_all_fn, sysbus_get_default()); qemu_run_machine_init_done_notifiers(); +/* Done notifiers can load ROMs */ +rom_load_done(); + qemu_system_reset(VMRESET_SILENT); if (loadvm) { if (load_vmstate(loadvm) 0) { -- MST
[Qemu-devel] [PATCH v8 03/26] qom: add pointer to int property helpers
Make it easy to add read-only helpers for simple integer properties in memory. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/qom/object.h | 21 ++ qom/object.c | 60 2 files changed, 81 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index 6c1e7d3..d02172a 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -795,6 +795,27 @@ void object_property_add(Object *obj, const char *name, const char *type, void object_property_del(Object *obj, const char *name, Error **errp); /** + * object_property_add_uint8_ptr: + * object_property_add_uint16_ptr: + * object_property_add_uint32_ptr: + * object_property_add_uint64_ptr: + * @obj: the object to add a property to + * @name: the name of the property + * @v: pointer to value + * + * Add an integer property in memory. This function will add a + * property of the appropriate type. + */ +void object_property_add_uint8_ptr(Object *obj, const char *name, + const uint8_t *v, Error **errp); +void object_property_add_uint16_ptr(Object *obj, const char *name, +const uint16_t *v, Error **errp); +void object_property_add_uint32_ptr(Object *obj, const char *name, +const uint32_t *v, Error **errp); +void object_property_add_uint64_ptr(Object *obj, const char *name, +const uint64_t *v, Error **Errp); + +/** * object_property_find: * @obj: the object * @name: the name of the property diff --git a/qom/object.c b/qom/object.c index e90e382..b617f26 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1344,6 +1344,66 @@ static char *qdev_get_type(Object *obj, Error **errp) return g_strdup(object_get_typename(obj)); } +static void property_get_uint8_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint8_t value = *(uint8_t *)opaque; +visit_type_uint8(v, value, name, errp); +} + +static void property_get_uint16_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint16_t value = *(uint16_t *)opaque; +visit_type_uint16(v, value, name, errp); +} + +static void property_get_uint32_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint32_t value = *(uint32_t *)opaque; +visit_type_uint32(v, value, name, errp); +} + +static void property_get_uint64_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint64_t value = *(uint64_t *)opaque; +visit_type_uint64(v, value, name, errp); +} + +void object_property_add_uint8_ptr(Object *obj, const char *name, + const uint8_t *v, Error **errp) +{ +object_property_add(obj, name, uint8, property_get_uint8_ptr, +NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint16_ptr(Object *obj, const char *name, +const uint16_t *v, Error **errp) +{ +object_property_add(obj, name, uint16, property_get_uint16_ptr, +NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint32_ptr(Object *obj, const char *name, +const uint32_t *v, Error **errp) +{ +object_property_add(obj, name, uint32, property_get_uint32_ptr, +NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint64_ptr(Object *obj, const char *name, +const uint64_t *v, Error **errp) +{ +object_property_add(obj, name, uint64, property_get_uint64_ptr, +NULL, NULL, (void *)v, errp); +} + static void object_instance_init(Object *obj) { object_property_add_str(obj, type, qdev_get_type, NULL, NULL); -- MST
[Qemu-devel] [PATCH v8 12/26] acpi: add rules to compile ASL source
Detect presence of IASL compiler and use it to process ASL source. If not there, use pre-compiled files in-tree. Add script to update the in-tree files. Note: distros are known to silently update iasl so detect correct iasl flags for the installed version on each run as opposed to at configure time. Reviewed-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- configure | 9 - hw/i386/Makefile.objs | 22 ++ scripts/update-acpi.sh | 4 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 scripts/update-acpi.sh diff --git a/configure b/configure index 2b83936..15405e1 100755 --- a/configure +++ b/configure @@ -119,6 +119,7 @@ path_of() { # default parameters source_path=`dirname $0` cpu= +iasl=iasl interp_prefix=/usr/gnemul/qemu-%M static=no cross_prefix= @@ -257,6 +258,8 @@ for opt do ;; --cxx=*) CXX=$optarg ;; + --iasl=*) iasl=$optarg + ;; --source-path=*) source_path=$optarg ;; --cpu=*) cpu=$optarg @@ -1055,6 +1058,7 @@ echo Advanced options (experts only): echo --source-path=PATH path of source code [$source_path] echo --cross-prefix=PREFIXuse PREFIX for compile tools [$cross_prefix] echo --cc=CC use C compiler CC [$cc] +echo --iasl=IASL use ACPI compiler IASL [$iasl] echo --host-cc=CC use C compiler CC [$host_cc] for code run at echobuild time echo --cxx=CXXuse C++ compiler CXX [$cxx] @@ -4239,6 +4243,9 @@ else fi echo PYTHON=$python $config_host_mak echo CC=$cc $config_host_mak +if $iasl -h /dev/null 21; then + echo IASL=$iasl $config_host_mak +fi echo CC_I386=$cc_i386 $config_host_mak echo HOST_CC=$host_cc $config_host_mak echo CXX=$cxx $config_host_mak @@ -4691,7 +4698,7 @@ for rom in seabios vgabios ; do echo BCC=bcc $config_mak echo CPP=$cpp $config_mak echo OBJCOPY=objcopy $config_mak -echo IASL=iasl $config_mak +echo IASL=$iasl $config_mak echo LD=$ld $config_mak done diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 45e6165..f950707 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -5,3 +5,25 @@ obj-y += pc_sysfw.o obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o obj-y += kvmvapic.o + +iasl-option=$(shell if test -z `$(1) $(2) 21 /dev/null` \ +; then echo $(2); else echo $(3); fi ;) + +ifdef IASL +#IASL Present. Generate hex files from .dsl +hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.dsl $(SRC_PATH)/scripts/acpi_extract_preprocess.py $(SRC_PATH)/scripts/acpi_extract.py + $(call quiet-command, cpp -P $ -o $*.dsl.i.orig, CPP $(TARGET_DIR)$*.dsl.i.orig) + $(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract_preprocess.py $*.dsl.i.orig $*.dsl.i, ACPI_PREPROCESS $(TARGET_DIR)$*.dsl.i) + $(call quiet-command, $(IASL) $(call iasl-option,$(IASL),-Pn,) -vs -l -tc -p $* $*.dsl.i $(if $(V), , /dev/null) 21 , IASL $(TARGET_DIR)$*.dsl.i) + $(call quiet-command, $(SRC_PATH)/scripts/acpi_extract.py $*.lst $*.off, ACPI_EXTRACT $(TARGET_DIR)$*.off) + $(call quiet-command, cat $*.off $@, CAT $(TARGET_DIR)$@) +else +#IASL Not present. Restore pre-generated hex files. +hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.hex.generated + $(call quiet-command, cp -f $ $@, CP $(TARGET_DIR)$@) +endif + +.PHONY: cleanhex +cleanhex: + rm -f hw/i386/*hex +clean: cleanhex diff --git a/scripts/update-acpi.sh b/scripts/update-acpi.sh new file mode 100644 index 000..b5f05ff --- /dev/null +++ b/scripts/update-acpi.sh @@ -0,0 +1,4 @@ +cd x86_64-softmmu +for file in hw/i386/*.hex; do +cp -f $file ../$file.generated +done -- MST
Re: [Qemu-devel] [PATCH 0/4] qdev: switch reset to post-order, clean up PCI reset
On Thu, Oct 03, 2013 at 05:58:30PM +0200, Paolo Bonzini wrote: Il 03/10/2013 15:54, Michael S. Tsirkin ha scritto: On Thu, Oct 03, 2013 at 03:46:11PM +0200, Paolo Bonzini wrote: PCI is handling resetting of its devices before the bus is reset, but this is only necessary because qdev is broken and usually does pre-order reset. Post-order is a much better definition. Drop the unnecessary flexibility that lets bus decide the reset order, convert to post-order, and make PCI use common code for reset. Need to go carefully here. I remember a bunch of targets were relying on reset in this order, though don't have the detail right now. The main change is that sub-devices, which basically exist only for USB, virtio, and SCSI, are reset _before_ the corresponding parent device (the USB host controller, virtio proxy device, or SCSI HBA). For SCSI, this patch fixes bugs that I'm currently working around in virtio-scsi (see the manual reset in virtio_scsi_reset, that manually resets the subdevices). USB and virtio are not using qdev reset at all, so they are unaffected by the patches. They rely on the parent device's own reset method to propagate the reset. virtio already uses post-order, so it could be changed to use qdev reset, but I don't plan to do it unless it fixes bugs. USB is more complicated and I don't really understand it. For PCI, the change is that all devices are reset first, and then the interrupts state and config space are reset for all devices. What kind of testing did this patchset go through? For each PCI device I tried creating a VM with an instance of it (a few devices at a time), and did VM resets. Earlier versions were tested by the guy who reported the SCSI problems. Paolo x86 kvm only? Paolo Bonzini (4): pci: do not export pci_bus_reset pci: clean up resetting of IRQs qdev: allow both pre- and post-order vists in qdev walking functions qdev: switch reset to post-order hw/core/qdev.c | 47 ++- hw/pci/pci.c | 42 -- hw/pci/pci_bridge.c|2 +- include/hw/pci/pci.h |1 - include/hw/qdev-core.h | 15 ++- 5 files changed, 65 insertions(+), 42 deletions(-)
Re: [Qemu-devel] [PATCH 0/4] qdev: switch reset to post-order, clean up PCI reset
On Thu, Oct 03, 2013 at 06:53:10PM +0200, Paolo Bonzini wrote: Il 03/10/2013 18:54, Michael S. Tsirkin ha scritto: For each PCI device I tried creating a VM with an instance of it (a few devices at a time), and did VM resets. Earlier versions were tested by the guy who reported the SCSI problems. x86 kvm only? Yes. Paolo Hmm, I'm not sure that's enough for this kind of change.
Re: [Qemu-devel] [PATCH v8 18/26] i386: define pc guest info
On Fri, Oct 04, 2013 at 06:18:42PM +0200, Igor Mammedov wrote: On Thu, 3 Oct 2013 18:05:35 +0300 Michael S. Tsirkin m...@redhat.com wrote: This defines a structure that will be used to fill in acpi tables where relevant properties are not yet available using QOM. Reviewed-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 9 + hw/i386/pc.c | 31 +++ 2 files changed, 40 insertions(+) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9b2ddc4..085a621 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -9,6 +9,9 @@ #include hw/i386/ioapic.h #include qemu/range.h +#include qemu/bitmap.h +#include sysemu/sysemu.h +#include hw/pci/pci.h /* PC-style peripherals (also used by other machines). */ @@ -20,6 +23,12 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; +hwaddr ram_size; +unsigned apic_id_limit; +bool apic_xrupt_override; +uint64_t numa_nodes; +uint64_t *node_mem; +uint64_t *node_cpu; FWCfgState *fw_cfg; }; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..dbae9da 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1028,6 +1028,23 @@ static void pc_fw_cfg_guest_info(PcGuestInfo *guest_info) fw_cfg_add_file(guest_info-fw_cfg, etc/pci-info, info, sizeof *info); } +static void pc_set_cpu_guest_info(CPUState *cpu, PcGuestInfo *guest_info) +{ +CPUClass *klass = CPU_GET_CLASS(cpu); +uint64_t apic_id = klass-get_arch_id(cpu); +int j; + +assert(apic_id guest_info-apic_id_limit); + +for (j = 0; j guest_info-numa_nodes; j++) { +assert(cpu-cpu_index max_cpus); +if (test_bit(cpu-cpu_index, node_cpumask[j])) { +guest_info-node_cpu[apic_id] = cpu_to_le64(j); +break; +} +} +} + typedef struct PcGuestInfoState { PcGuestInfo info; Notifier machine_done; @@ -1047,6 +1064,20 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, { PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state); PcGuestInfo *guest_info = guest_info_state-info; +CPUState *cpu; + +guest_info-ram_size = below_4g_mem_size + above_4g_mem_size; +guest_info-apic_id_limit = pc_apic_id_limit(max_cpus); +guest_info-apic_xrupt_override = kvm_allows_irq0_override(); +guest_info-numa_nodes = nb_numa_nodes; +guest_info-node_mem = g_memdup(node_mem, guest_info-numa_nodes * +sizeof *guest_info-node_mem); +guest_info-node_cpu = g_malloc0(guest_info-apic_id_limit * + sizeof *guest_info-node_cpu); + +CPU_FOREACH(cpu) { +pc_set_cpu_guest_info(cpu, guest_info); +} pc_guest_info_init() is called only once, now lets suppose we hotplug CPUs and then reboot guest. Hotadded CPUs won't be accounted in guest_info.node_cpu since it's initialized only once and is never updated. As result guest will get stale SRAT table. Using a callback in acpi_setup/update could allow to get an updated guest_info. While I agree it's a bug, it's also exactly what happens at the moment with ACPI in BIOS: BIOS gets the info from FW CFG file which is only updated once during qemu initialization. So I'll take a look at fixing this, but I don't think it's a blocker for merging this patchset. Makes sense? guest_info_state-machine_done.notify = pc_guest_info_machine_done; qemu_add_machine_init_done_notifier(guest_info_state-machine_done);
Re: [Qemu-devel] [PATCH v8 18/26] i386: define pc guest info
On Fri, Oct 04, 2013 at 06:18:42PM +0200, Igor Mammedov wrote: On Thu, 3 Oct 2013 18:05:35 +0300 Michael S. Tsirkin m...@redhat.com wrote: This defines a structure that will be used to fill in acpi tables where relevant properties are not yet available using QOM. Reviewed-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 9 + hw/i386/pc.c | 31 +++ 2 files changed, 40 insertions(+) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9b2ddc4..085a621 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -9,6 +9,9 @@ #include hw/i386/ioapic.h #include qemu/range.h +#include qemu/bitmap.h +#include sysemu/sysemu.h +#include hw/pci/pci.h /* PC-style peripherals (also used by other machines). */ @@ -20,6 +23,12 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; +hwaddr ram_size; +unsigned apic_id_limit; +bool apic_xrupt_override; +uint64_t numa_nodes; +uint64_t *node_mem; +uint64_t *node_cpu; FWCfgState *fw_cfg; }; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..dbae9da 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1028,6 +1028,23 @@ static void pc_fw_cfg_guest_info(PcGuestInfo *guest_info) fw_cfg_add_file(guest_info-fw_cfg, etc/pci-info, info, sizeof *info); } +static void pc_set_cpu_guest_info(CPUState *cpu, PcGuestInfo *guest_info) +{ +CPUClass *klass = CPU_GET_CLASS(cpu); +uint64_t apic_id = klass-get_arch_id(cpu); +int j; + +assert(apic_id guest_info-apic_id_limit); + +for (j = 0; j guest_info-numa_nodes; j++) { +assert(cpu-cpu_index max_cpus); +if (test_bit(cpu-cpu_index, node_cpumask[j])) { +guest_info-node_cpu[apic_id] = cpu_to_le64(j); +break; +} +} +} + typedef struct PcGuestInfoState { PcGuestInfo info; Notifier machine_done; @@ -1047,6 +1064,20 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, { PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state); PcGuestInfo *guest_info = guest_info_state-info; +CPUState *cpu; + +guest_info-ram_size = below_4g_mem_size + above_4g_mem_size; +guest_info-apic_id_limit = pc_apic_id_limit(max_cpus); +guest_info-apic_xrupt_override = kvm_allows_irq0_override(); +guest_info-numa_nodes = nb_numa_nodes; +guest_info-node_mem = g_memdup(node_mem, guest_info-numa_nodes * +sizeof *guest_info-node_mem); +guest_info-node_cpu = g_malloc0(guest_info-apic_id_limit * + sizeof *guest_info-node_cpu); + +CPU_FOREACH(cpu) { +pc_set_cpu_guest_info(cpu, guest_info); +} pc_guest_info_init() is called only once, now lets suppose we hotplug CPUs and then reboot guest. Hotadded CPUs won't be accounted in guest_info.node_cpu since it's initialized only once and is never updated. As result guest will get stale SRAT table. Using a callback in acpi_setup/update could allow to get an updated guest_info. Actually we can fix this simpler just by filling in all numa info ahead of the time. Something like the following should fix this, right? diff --git a/hw/i386/pc.c b/hw/i386/pc.c index bbf11ed..a7fcbf9 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1029,23 +1029,6 @@ static void pc_fw_cfg_guest_info(PcGuestInfo *guest_info) fw_cfg_add_file(guest_info-fw_cfg, etc/pci-info, info, sizeof *info); } -static void pc_set_cpu_guest_info(CPUState *cpu, PcGuestInfo *guest_info) -{ -CPUClass *klass = CPU_GET_CLASS(cpu); -uint64_t apic_id = klass-get_arch_id(cpu); -int j; - -assert(apic_id guest_info-apic_id_limit); - -for (j = 0; j guest_info-numa_nodes; j++) { -assert(cpu-cpu_index max_cpus); -if (test_bit(cpu-cpu_index, node_cpumask[j])) { -guest_info-node_cpu[apic_id] = cpu_to_le64(j); -break; -} -} -} - typedef struct PcGuestInfoState { PcGuestInfo info; Notifier machine_done; @@ -1066,7 +1049,7 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, { PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state); PcGuestInfo *guest_info = guest_info_state-info; -CPUState *cpu; +int i, j; guest_info-ram_size = below_4g_mem_size + above_4g_mem_size; guest_info-apic_id_limit = pc_apic_id_limit(max_cpus); @@ -1077,8 +1060,15 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, guest_info-node_cpu = g_malloc0(guest_info-apic_id_limit * sizeof
Re: [Qemu-devel] [PATCH v3 6/8] hw: set interrupts using pci irq wrappers
On Mon, Oct 07, 2013 at 10:36:39AM +0300, Marcel Apfelbaum wrote: pci_set_irq and the other pci irq wrappers use PCI_INTERRUPT_PIN config register to compute device INTx pin to assert/deassert. An irq is allocated using pci_allocate_irq wrapper only if is needed by non pci devices. Removed irq related fields from state if not used anymore. Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- Changes from v2: - Addressed Alex Williamson's comments - replaced calls to pci_set_irq with pci_irq_assert/deassert when possible - Addressed Gerd Hoffmann's comment - removed irq_pin from UHCIState state because it is not used anymore hw/audio/ac97.c| 4 ++-- hw/audio/es1370.c | 4 ++-- hw/audio/intel-hda.c | 2 +- hw/block/nvme.c| 2 +- hw/char/serial-pci.c | 5 +++-- hw/char/tpci200.c | 8 hw/display/qxl.c | 2 +- hw/ide/cmd646.c| 2 +- hw/ide/ich.c | 3 ++- hw/isa/vt82c686.c | 2 +- hw/misc/ivshmem.c | 2 +- hw/net/e1000.c | 2 +- hw/net/eepro100.c | 4 ++-- hw/net/ne2000.c| 3 ++- hw/net/pcnet-pci.c | 3 ++- hw/net/rtl8139.c | 2 +- hw/pci/shpc.c | 2 +- hw/scsi/esp-pci.c | 3 ++- hw/scsi/lsi53c895a.c | 2 +- hw/scsi/megasas.c | 6 +++--- hw/scsi/vmw_pvscsi.c | 2 +- hw/usb/hcd-ehci-pci.c | 2 +- hw/usb/hcd-ohci.c | 2 +- hw/usb/hcd-uhci.c | 6 ++ hw/usb/hcd-xhci.c | 7 ++- hw/virtio/virtio-pci.c | 4 ++-- 26 files changed, 43 insertions(+), 43 deletions(-) diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index 01b4dfb..03f4846 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -280,12 +280,12 @@ static void update_sr (AC97LinkState *s, AC97BusMasterRegs *r, uint32_t new_sr) if (level) { s-glob_sta |= masks[r - s-bm_regs]; dolog (set irq level=1\n); -qemu_set_irq (s-dev.irq[0], 1); +pci_irq_assert(s-dev); } else { s-glob_sta = ~masks[r - s-bm_regs]; dolog (set irq level=0\n); -qemu_set_irq (s-dev.irq[0], 0); +pci_irq_deassert(s-dev); } } diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index adb66ce..1ec7ace 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -323,7 +323,7 @@ static void es1370_update_status (ES1370State *s, uint32_t new_status) else { s-status = new_status ~STAT_INTR; } -qemu_set_irq (s-dev.irq[0], !!level); +pci_set_irq(s-dev, !!level); } static void es1370_reset (ES1370State *s) @@ -349,7 +349,7 @@ static void es1370_reset (ES1370State *s) s-dac_voice[i] = NULL; } } -qemu_irq_lower (s-dev.irq[0]); +pci_irq_deassert(s-dev); } static void es1370_maybe_lower_irq (ES1370State *s, uint32_t sctl) diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index ac6..4327264 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -269,7 +269,7 @@ static void intel_hda_update_irq(IntelHDAState *d) msi_notify(d-pci, 0); } } else { -qemu_set_irq(d-pci.irq[0], level); +pci_set_irq(d-pci, level); } } diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 5dee229..2882ffe 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -69,7 +69,7 @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq) if (msix_enabled((n-parent_obj))) { msix_notify((n-parent_obj), cq-vector); } else { -qemu_irq_pulse(n-parent_obj.irq[0]); +pci_irq_pulse(n-parent_obj); } } } diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index aec6705..991c99f 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -61,7 +61,7 @@ static int serial_pci_init(PCIDevice *dev) } pci-dev.config[PCI_INTERRUPT_PIN] = 0x01; -s-irq = pci-dev.irq[0]; +s-irq = pci_allocate_irq(pci-dev); memory_region_init_io(s-io, OBJECT(pci), serial_io_ops, s, serial, 8); pci_register_bar(pci-dev, 0, PCI_BASE_ADDRESS_SPACE_IO, s-io); @@ -79,7 +79,7 @@ static void multi_serial_irq_mux(void *opaque, int n, int level) pending = 1; } } -qemu_set_irq(pci-dev.irq[0], pending); +pci_set_irq(pci-dev, pending); } static int multi_serial_pci_init(PCIDevice *dev) @@ -132,6 +132,7 @@ static void serial_pci_exit(PCIDevice *dev) serial_exit_core(s); memory_region_destroy(s-io); +qemu_free_irq(s-irq); } static void multi_serial_pci_exit(PCIDevice *dev) diff --git a/hw/char/tpci200.c b/hw/char/tpci200.c index e04ff26..a49d2ed 100644 --- a/hw/char/tpci200.c +++ b/hw/char/tpci200.c @@ -134,8 +134,8 @@ static void tpci200_set_irq(void *opaque, int intno, int level) /* Check if the interrupt is edge sensitive */ if (dev-ctrl[ip_n]
Re: [Qemu-devel] [PATCH v3 6/8] hw: set interrupts using pci irq wrappers
On Mon, Oct 07, 2013 at 11:03:47AM +0300, Michael S. Tsirkin wrote: On Mon, Oct 07, 2013 at 10:36:39AM +0300, Marcel Apfelbaum wrote: pci_set_irq and the other pci irq wrappers use PCI_INTERRUPT_PIN config register to compute device INTx pin to assert/deassert. An irq is allocated using pci_allocate_irq wrapper only if is needed by non pci devices. Removed irq related fields from state if not used anymore. Signed-off-by: Marcel Apfelbaum marce...@redhat.com --- Changes from v2: - Addressed Alex Williamson's comments - replaced calls to pci_set_irq with pci_irq_assert/deassert when possible - Addressed Gerd Hoffmann's comment - removed irq_pin from UHCIState state because it is not used anymore hw/audio/ac97.c| 4 ++-- hw/audio/es1370.c | 4 ++-- hw/audio/intel-hda.c | 2 +- hw/block/nvme.c| 2 +- hw/char/serial-pci.c | 5 +++-- hw/char/tpci200.c | 8 hw/display/qxl.c | 2 +- hw/ide/cmd646.c| 2 +- hw/ide/ich.c | 3 ++- hw/isa/vt82c686.c | 2 +- hw/misc/ivshmem.c | 2 +- hw/net/e1000.c | 2 +- hw/net/eepro100.c | 4 ++-- hw/net/ne2000.c| 3 ++- hw/net/pcnet-pci.c | 3 ++- hw/net/rtl8139.c | 2 +- hw/pci/shpc.c | 2 +- hw/scsi/esp-pci.c | 3 ++- hw/scsi/lsi53c895a.c | 2 +- hw/scsi/megasas.c | 6 +++--- hw/scsi/vmw_pvscsi.c | 2 +- hw/usb/hcd-ehci-pci.c | 2 +- hw/usb/hcd-ohci.c | 2 +- hw/usb/hcd-uhci.c | 6 ++ hw/usb/hcd-xhci.c | 7 ++- hw/virtio/virtio-pci.c | 4 ++-- 26 files changed, 43 insertions(+), 43 deletions(-) diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index 01b4dfb..03f4846 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -280,12 +280,12 @@ static void update_sr (AC97LinkState *s, AC97BusMasterRegs *r, uint32_t new_sr) if (level) { s-glob_sta |= masks[r - s-bm_regs]; dolog (set irq level=1\n); -qemu_set_irq (s-dev.irq[0], 1); +pci_irq_assert(s-dev); } else { s-glob_sta = ~masks[r - s-bm_regs]; dolog (set irq level=0\n); -qemu_set_irq (s-dev.irq[0], 0); +pci_irq_deassert(s-dev); } } diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index adb66ce..1ec7ace 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -323,7 +323,7 @@ static void es1370_update_status (ES1370State *s, uint32_t new_status) else { s-status = new_status ~STAT_INTR; } -qemu_set_irq (s-dev.irq[0], !!level); +pci_set_irq(s-dev, !!level); } static void es1370_reset (ES1370State *s) @@ -349,7 +349,7 @@ static void es1370_reset (ES1370State *s) s-dac_voice[i] = NULL; } } -qemu_irq_lower (s-dev.irq[0]); +pci_irq_deassert(s-dev); } static void es1370_maybe_lower_irq (ES1370State *s, uint32_t sctl) diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index ac6..4327264 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -269,7 +269,7 @@ static void intel_hda_update_irq(IntelHDAState *d) msi_notify(d-pci, 0); } } else { -qemu_set_irq(d-pci.irq[0], level); +pci_set_irq(d-pci, level); } } diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 5dee229..2882ffe 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -69,7 +69,7 @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq) if (msix_enabled((n-parent_obj))) { msix_notify((n-parent_obj), cq-vector); } else { -qemu_irq_pulse(n-parent_obj.irq[0]); +pci_irq_pulse(n-parent_obj); } } } diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index aec6705..991c99f 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -61,7 +61,7 @@ static int serial_pci_init(PCIDevice *dev) } pci-dev.config[PCI_INTERRUPT_PIN] = 0x01; -s-irq = pci-dev.irq[0]; +s-irq = pci_allocate_irq(pci-dev); memory_region_init_io(s-io, OBJECT(pci), serial_io_ops, s, serial, 8); pci_register_bar(pci-dev, 0, PCI_BASE_ADDRESS_SPACE_IO, s-io); @@ -79,7 +79,7 @@ static void multi_serial_irq_mux(void *opaque, int n, int level) pending = 1; } } -qemu_set_irq(pci-dev.irq[0], pending); +pci_set_irq(pci-dev, pending); } static int multi_serial_pci_init(PCIDevice *dev) @@ -132,6 +132,7 @@ static void serial_pci_exit(PCIDevice *dev) serial_exit_core(s); memory_region_destroy(s-io); +qemu_free_irq(s-irq); } static void multi_serial_pci_exit(PCIDevice *dev) diff --git a/hw/char/tpci200.c b/hw/char/tpci200.c index e04ff26..a49d2ed 100644 --- a/hw
[Qemu-devel] [PATCH v3 1/4] pci: add pci_for_each_bus_depth_first
Add a method to scan pci buses in a predictable order. Useful for ACPI hotplug. Document that order is not guaranteed for pci_for_each_device, and re-implement using that. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pci.h | 14 ++ hw/pci/pci.c | 28 2 files changed, 42 insertions(+) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 4b90e5d..6259e23 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -391,6 +391,20 @@ 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); diff --git a/hw/pci/pci.c b/hw/pci/pci.c index c3fdff4..728f7b9 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1682,6 +1682,34 @@ static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num) return NULL; } +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) +{ +PCIBus *sec; +void *state; + +if (!bus) { +return; +} + +if (begin) { +state = begin(bus, parent_state); +} else { +state = parent_state; +} + +QLIST_FOREACH(sec, bus-child, sibling) { +pci_for_each_bus_depth_first(sec, begin, end, state); +} + +if (end) { +end(bus, state); +} +} + + PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn) { bus = pci_find_bus_nr(bus, bus_num); -- MST
[Qemu-devel] [PATCH v3 0/4] acpi hotplug of devices behind a pci bridge
This is on top of patchset generating ACPI tables in qemu. Please review and consider for 1.7. Changes from v2: - split new code out to a separate file: acpi/pcihp.c this way we can reuse it for q35 later - rebased on top of the latest acpi-build patchset Changes from v1: - fixed some bugs - fixed migration and cross version compatibility - rebased to latest bits This adds support for device hotplug behind pci bridges, by generating ACPI tables describing the current hierarchy. Bridge devices themselves need to be pre-configured on qemu command line. How to use: Describe buses on command line. E.g.: -device pci-bridge,id=bar,chassis_nr=1 -device virtio-net,netdev=bur,addr=0x1,id=far,bus=bar use monitor command for hotplug: device_del far We don't currently use QOM properties to generate this info since: - info about hotpluggability of devices is lacking - we need to list all devices and buses in a predictable order For now, add a pci core function to do the above predictable order walk. This is on top of acpi patchset posted previously. with a small patch adding a core function to walk all pci buses, on top. Can also be found in my git tree git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git acpi-bridges Portability: - Non x86 (or any Linux) platforms don't need any of this code. They can keep happily using SHPC the way they always did. Things to note: - Extensive use of glib completely removes pointer math: we use g_array_append_vals exclusively. - As was the case previously, systems that lack working iasl are detected at configure time, pre-generated hex files in source tree are used in this case. This addresses the concern with iasl/big-endian systems. - Cross version migration: when running with -M 1.6 and older, new hotplug functionality is unavailable. All ACPI table generation is disabled. We present FW_CFG interface compatible with 1.6. Michael S. Tsirkin (4): pci: add pci_for_each_bus_depth_first pcihp: generalization of piix4 acpi piix4: add acpi pci hotplug support acpi-build: enable hotplug for PCI bridges include/hw/acpi/pcihp.h | 72 ++ include/hw/i386/pc.h| 5 + include/hw/pci/pci.h| 14 ++ hw/acpi/pcihp.c | 312 +++ hw/acpi/piix4.c | 75 +-- hw/i386/acpi-build.c| 346 ++-- hw/pci/pci.c| 28 hw/acpi/Makefile.objs | 2 +- hw/i386/acpi-dsdt.dsl | 34 +++-- hw/i386/ssdt-pcihp.dsl | 11 +- 10 files changed, 794 insertions(+), 105 deletions(-) create mode 100644 include/hw/acpi/pcihp.h create mode 100644 hw/acpi/pcihp.c -- MST
[Qemu-devel] [PATCH v3 3/4] piix4: add acpi pci hotplug support
Add support for acpi pci hotplug using the new infrastructure. PIIX4 legacy interface is maintained as is for machine types 1.6 and older. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 5 hw/acpi/piix4.c | 75 +--- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 39db8cb..6865972 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -249,6 +249,11 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); #define PC_COMPAT_1_6 \ {\ +.driver = PIIX4_PM,\ +.property = acpi-pci-hotplug-with-bridge-support,\ +.value= off,\ +}, \ +{\ .driver = e1000,\ .property = mitigation,\ .value= off,\ diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 3bcd890..d516033 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -30,6 +30,7 @@ #include hw/nvram/fw_cfg.h #include exec/address-spaces.h #include hw/acpi/piix4.h +#include hw/acpi/pcihp.h //#define DEBUG @@ -73,7 +74,6 @@ typedef struct PIIX4PMState { uint32_t io_base; MemoryRegion io_gpe; -MemoryRegion io_pci; MemoryRegion io_cpu; ACPIREGS ar; @@ -88,11 +88,16 @@ typedef struct PIIX4PMState { Notifier machine_ready; Notifier powerdown_notifier; -/* for pci hotplug */ +/* for legacy pci hotplug (compatible with qemu 1.6 and older) */ +MemoryRegion io_pci; struct pci_status pci0_status; uint32_t pci0_hotplug_enable; uint32_t pci0_slot_device_present; +/* for new pci hotplug (with PCI2PCI bridge support) */ +AcpiPciHpState acpi_pci_hotplug; +bool use_acpi_pci_hotplug; + uint8_t disable_s3; uint8_t disable_s4; uint8_t s4_val; @@ -282,6 +287,18 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) return ret; } +static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id) +{ +PIIX4PMState *s = opaque; +return s-use_acpi_pci_hotplug; +} + +static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id) +{ +PIIX4PMState *s = opaque; +return !s-use_acpi_pci_hotplug; +} + /* qemu-kvm 1.2 uses version 3 but advertised as 2 * To support incoming qemu-kvm 1.2 migration, change version_id * and minimum_version_id to 2 below (which breaks migration from @@ -304,8 +321,12 @@ static const VMStateDescription vmstate_acpi = { VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), -VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status, - struct pci_status), +VMSTATE_STRUCT_TEST(pci0_status, PIIX4PMState, +vmstate_test_no_use_acpi_pci_hotplug, +2, vmstate_pci_status, +struct pci_status), +VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, +vmstate_test_use_acpi_pci_hotplug), VMSTATE_END_OF_LIST() } }; @@ -383,7 +404,11 @@ static void piix4_reset(void *opaque) pci_conf[0x5B] = 0x02; } pm_io_space_update(s); -piix4_update_hotplug(s); +if (s-use_acpi_pci_hotplug) { +acpi_pcihp_reset(s-acpi_pci_hotplug); +} else { +piix4_update_hotplug(s); +} } static void piix4_pm_powerdown_req(Notifier *n, void *opaque) @@ -394,6 +419,26 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque) acpi_pm1_evt_power_down(s-ar); } +static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev, + PCIHotplugState state) +{ +PIIX4PMState *s = PIIX4_PM(qdev); +int ret = acpi_pcihp_device_hotplug(s-acpi_pci_hotplug, dev, state); +if (ret 0) { +return ret; +} +s-ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; + +pm_update_sci(s); +return 0; +} + +static void piix4_update_bus_hotplug(PCIBus *bus, void *opaque) +{ +PIIX4PMState *s = opaque; +pci_bus_hotplug(bus, piix4_acpi_pci_hotplug, DEVICE(s)); +} + static void piix4_pm_machine_ready(Notifier *n, void *opaque) { PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); @@ -407,6 +452,10 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) pci_conf[0x63] = 0x60; pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) | (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); + +if (s-use_acpi_pci_hotplug) { +pci_for_each_bus(d-bus, piix4_update_bus_hotplug, s); +} } static void piix4_pm_add_propeties(PIIX4PMState *s) @@ -528,6 +577,8 @@ static Property piix4_pm_properties[] = { DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), DEFINE_PROP_UINT8
[Qemu-devel] [PATCH v3 2/4] pcihp: generalization of piix4 acpi
Add ACPI based PCI hotplug library with bridge hotplug support. Design - each bus gets assigned bsel property. - ACPI code writes this number to a new BNUM register, then uses existing UP/DOWN registers to probe slot status; to eject, write number to BNUM register, then slot into existing EJ. The interface is actually backwards-compatible with existing PIIX4 ACPI (though not migration compatible). This is split out from PIIX4 codebase so we can reuse it for Q35 as well. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/pcihp.h | 72 +++ hw/acpi/pcihp.c | 312 hw/acpi/Makefile.objs | 2 +- 3 files changed, 385 insertions(+), 1 deletion(-) create mode 100644 include/hw/acpi/pcihp.h create mode 100644 hw/acpi/pcihp.c diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h new file mode 100644 index 000..6230e60 --- /dev/null +++ b/include/hw/acpi/pcihp.h @@ -0,0 +1,72 @@ +/* + * 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 (m...@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/pci/pci.h /* for PCIHotplugState */ + +typedef struct AcpiPciHpPciStatus { +uint32_t up; /* deprecated, maintained for migration compatibility */ +uint32_t down; +uint32_t hotplug_enable; +uint32_t device_present; +} AcpiPciHpPciStatus; + +#define ACPI_PCIHP_PROP_BSEL acpi-pcihp-bsel +#define ACPI_PCIHP_MAX_HOTPLUG_BUS 256 + +typedef struct AcpiPciHpState { +AcpiPciHpPciStatus acpi_pcihp_pci_status[ACPI_PCIHP_MAX_HOTPLUG_BUS]; +uint32_t hotplug_select; +PCIBus *root; +MemoryRegion io; +} AcpiPciHpState; + +void acpi_pcihp_init(AcpiPciHpState *, PCIBus *root, + MemoryRegion *address_space_io); + +/* Invoke on device hotplug */ +int acpi_pcihp_device_hotplug(AcpiPciHpState *, PCIDevice *, + PCIHotplugState state); + +/* 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/hw/acpi/pcihp.c b/hw/acpi/pcihp.c new file mode 100644 index 000..13938e6 --- /dev/null +++ b/hw/acpi/pcihp.c @@ -0,0 +1,312 @@ +/* + * 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 (m...@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. + */ + +#include hw/acpi/pcihp.h + +#include hw/hw.h +#include hw/i386/pc.h +#include hw/pci/pci.h
[Qemu-devel] [PATCH v3 4/4] acpi-build: enable hotplug for PCI bridges
This enables support for device hotplug behind pci bridges. Bridge devices themselves need to be pre-configured on qemu command line. Design: - at machine init time, assign bsel property to bridges with hotplug support - dynamically (At ACPI table read) generate ACPI code to handle hotplug events for each bridge with bsel property Note: ACPI doesn't support adding or removing bridges by hotplug. We detect and prevent removal of bridges by hotplug, unless they were added by hotplug previously (and so, are not described by ACPI). Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-build.c | 346 +++-- hw/i386/acpi-dsdt.dsl | 34 +++-- hw/i386/ssdt-pcihp.dsl | 11 +- 3 files changed, 297 insertions(+), 94 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 262d1d6..e8d39d9 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -39,6 +39,7 @@ /* Supported chipsets: */ #include hw/acpi/piix4.h +#include hw/acpi/pcihp.h #include hw/i386/ich9.h #include hw/pci/pci_bus.h #include hw/pci-host/q35.h @@ -78,6 +79,12 @@ typedef struct AcpiMiscInfo { uint16_t pvpanic_port; } AcpiMiscInfo; +typedef struct AcpiBuildPciBusHotplugState { +GArray *device_table; +GArray *notify_table; +struct AcpiBuildPciBusHotplugState *parent; +} AcpiBuildPciBusHotplugState; + static void acpi_get_dsdt(AcpiMiscInfo *info) { Object *piix = piix4_pm_find(); @@ -171,38 +178,6 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) NULL); } -static void acpi_get_hotplug_info(AcpiMiscInfo *misc) -{ -int i; -PCIBus *bus = find_i440fx(); - -if (!bus) { -/* Only PIIX supports ACPI hotplug */ -memset(misc-slot_hotplug_enable, 0, sizeof misc-slot_hotplug_enable); -return; -} - -memset(misc-slot_hotplug_enable, 0xff, - DIV_ROUND_UP(PCI_SLOT_MAX, BITS_PER_BYTE)); - -for (i = 0; i ARRAY_SIZE(bus-devices); ++i) { -PCIDeviceClass *pc; -PCIDevice *pdev = bus-devices[i]; - -if (!pdev) { -continue; -} - -pc = PCI_DEVICE_GET_CLASS(pdev); - -if (pc-no_hotplug) { -int slot = PCI_SLOT(i); - -clear_bit(slot, misc-slot_hotplug_enable); -} -} -} - static void acpi_get_misc_info(AcpiMiscInfo *info) { info-has_hpet = hpet_find(); @@ -366,6 +341,12 @@ static void build_package(GArray *package, uint8_t op, unsigned min_bytes) build_prepend_byte(package, op); } +static void build_extop_package(GArray *package, uint8_t op) +{ +build_package(package, op, 1); +build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ +} + static void build_append_value(GArray *table, uint32_t value, int size) { uint8_t prefix; @@ -392,8 +373,44 @@ static void build_append_value(GArray *table, uint32_t value, int size) } } -static void build_append_notify_target(GArray *method, GArray *target_name, - uint32_t value, int size) +static void build_append_int(GArray *table, uint32_t value) +{ +if (value == 0x00) { +build_append_byte(table, 0x00); /* ZeroOp */ +} else if (value == 0x01) { +build_append_byte(table, 0x01); /* OneOp */ +} else if (value = 0xFF) { +build_append_value(table, value, 1); +} else if (value = 0xF) { +build_append_value(table, value, 2); +} else { +build_append_value(table, value, 4); +} +} + +static GArray *build_alloc_method(const char *name, uint8_t arg_count) +{ +GArray *method = build_alloc_array(); + +build_append_nameseg(method, name); +build_append_byte(method, arg_count); /* MethodFlags: ArgCount */ + +return method; +} + +static void build_append_and_cleanup_method(GArray *device, GArray *method) +{ +uint8_t op = 0x14; /* MethodOp */ + +build_package(method, op, 0); + +build_append_array(device, method); +build_free_array(method); +} + +static void build_append_notify_target_ifequal(GArray *method, + GArray *target_name, + uint32_t value, int size) { GArray *notify = build_alloc_array(); uint8_t op = 0xA0; /* IfOp */ @@ -413,6 +430,7 @@ static void build_append_notify_target(GArray *method, GArray *target_name, build_free_array(notify); } +/* End here */ #define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */ static inline void *acpi_data_push(GArray *table_data, unsigned size) @@ -621,44 +639,234 @@ static inline char acpi_get_hex(uint32_t val) #include hw/i386/ssdt-pcihp.hex static void -build_append_notify(GArray *device, const char *name, -const char *format, int skip, int count) +build_append_notify_method(GArray *device, const char *name, + const char
[Qemu-devel] [PATCH v9 00/27] qemu: generate acpi tables for the guest
This code can also be found here: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git acpi While this patch still uses info not available in QOM, I think it's reasonable to merge it and then refactor as QOM properties cover more ground. In particular, merging this patchset blocks other projects so I think its preferable to merge now and not wait for all required QOM properties to materialize. I added QOM properties in ich/piix where I knew how to do this. If you already reviewed v8 then the only patch that changed significantly is i386: define pc guest info it now supplies numa info about all CPUs and not just the ones present at init. I also made a couple of trivial tweaks to i386: ACPI table generation code from seabios If you already reviewed v5 then the only patches that changed are: i386: define pc guest info i386: ACPI table generation code from seabios Gerd, Laszlo, I kept your Reviewed-by and Tested-by tags on these patches to ensure your contribution is recongnized, if you don't like this pls let me know. Or better yet re-ack this version :) Patches 1-3 are QOM patches really. Included here for completeness. Igor suggested dropping patches 1-2 and including error.h directly. I included his patch and dropped mine. I hope that's ok. If everything's in order, I intend to merge this through my tree. Please review, and comment. Changes from v8: - remove an unused function - fix typo in error message, reported by Igor - don't assert when adding a 4 byte value (we don't use this now but it's useful for follow-up bridge hotplug patches) - fix numa node reporting for hotplugged cpus, reported by Igor Changes from v7 reposted: - whitespace fixes - issues reported by Igor - typo fix in commit log reported by Eric Changes from v7: - removed all complex table patching and migration code we now only migrate a single byte patched/non patched all tables are simply regenerated on access, rewriting old data in particular this fixed a bug that Igor noticed: cpu online status is now updated correctly - removed bitmask of found cpus - use QOM to calculate it - dropped changes to typedefs.h - use Igor's patch instead Changes from v6: - fix 64 bit window bug reported by Igor - tweak comments in error.h Changes from v5: - update generated files to fix build on systems without iasl - fix mcfg failure reported by Gerd Changes from v4: - address comments by Paolo: rename loader interface reuse macro for hpet name better struct names move internal headers to hw/i386/ - fix typos resulting in bugs reported by Gerd Changes from v3: - reworked code to use QOM properties some info isn't yet available in QOM, use old-style APIs and lookups by type - address comments by Gerd: tables are now updated on guest access after pci configuration Changes from v2 repost: - address comment by Anthony - convert to use APIs implemented using QOM - address comment by Anthony - avoid tricky pointer path, use GArray from glib instead - Address lots of comments by Hu Tao and Laszlo Ersek Changes from v2: - added missing patches to make it actually build Changes from v1 RFC: - added code to address cross version compatibility - rebased to latest bits - updated seabios code to latest bits (added pvpanic device) This patchset moves all generation of ACPI tables from guest BIOS to the hypervisor. Although ACPI tables come from a system BIOS on real hw, it makes sense that the ACPI tables are coupled with the virtual machine, since they have to abstract the x86 machine to the OS's. This is widely desired as a way to avoid the churn and proliferation of QEMU-specific interfaces associated with ACPI tables in bios code. There's a bit of code duplication where we already declare similar acpi structures in qemu. I think it's best to do it in this order: port code directly, and apply cleanups and reduce duplication that results, on top. This way it's much easier to see that we don't introduce regressions. In particular, I booted a guest on qemu with and without the change, and verified that ACPI tables are unchanged except for trivial pointer address changes, and the SSDT P_BLK change in the last patch. Such binary compatibility makes it easier to be confident that this change won't break things. Igor Mammedov (1): cleanup object.h: include error.h directly Michael S. Tsirkin (26): qom: cleanup struct Error references qom: add pointer to int property helpers pci: fix up w64 size calculation helper fw_cfg: interface to trigger callback on read loader: support for unmapped ROM blobs pcie_host: expose UNMAPPED macro pcie_host: expose address format q35: use macro for MCFG property name q35: expose mmcfg size as a property i386: add ACPI table files from seabios acpi: add rules to compile ASL source acpi: pre-compiled ASL files acpi: ssdt pcihp: updat generated file loader: use file path size from fw_cfg.h i386: add bios linker/loader loader: allow
[Qemu-devel] [PATCH v9 02/27] qom: cleanup struct Error references
now that a typedef for struct Error is available, use it in qom/object.h to match coding style rules. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/qom/object.h | 50 +- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index d9a0063..6c1e7d3 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -301,7 +301,7 @@ typedef void (ObjectPropertyAccessor)(Object *obj, struct Visitor *v, void *opaque, const char *name, - struct Error **errp); + Error **errp); /** * ObjectPropertyRelease: @@ -790,9 +790,9 @@ void object_property_add(Object *obj, const char *name, const char *type, ObjectPropertyAccessor *get, ObjectPropertyAccessor *set, ObjectPropertyRelease *release, - void *opaque, struct Error **errp); + void *opaque, Error **errp); -void object_property_del(Object *obj, const char *name, struct Error **errp); +void object_property_del(Object *obj, const char *name, Error **errp); /** * object_property_find: @@ -803,7 +803,7 @@ void object_property_del(Object *obj, const char *name, struct Error **errp); * Look up a property for an object and return its #ObjectProperty if found. */ ObjectProperty *object_property_find(Object *obj, const char *name, - struct Error **errp); + Error **errp); void object_unparent(Object *obj); @@ -818,7 +818,7 @@ void object_unparent(Object *obj); * Reads a property from a object. */ void object_property_get(Object *obj, struct Visitor *v, const char *name, - struct Error **errp); + Error **errp); /** * object_property_set_str: @@ -829,7 +829,7 @@ void object_property_get(Object *obj, struct Visitor *v, const char *name, * Writes a string value to a property. */ void object_property_set_str(Object *obj, const char *value, - const char *name, struct Error **errp); + const char *name, Error **errp); /** * object_property_get_str: @@ -842,7 +842,7 @@ void object_property_set_str(Object *obj, const char *value, * The caller should free the string. */ char *object_property_get_str(Object *obj, const char *name, - struct Error **errp); + Error **errp); /** * object_property_set_link: @@ -853,7 +853,7 @@ char *object_property_get_str(Object *obj, const char *name, * Writes an object's canonical path to a property. */ void object_property_set_link(Object *obj, Object *value, - const char *name, struct Error **errp); + const char *name, Error **errp); /** * object_property_get_link: @@ -866,7 +866,7 @@ void object_property_set_link(Object *obj, Object *value, * string or not a valid object path). */ Object *object_property_get_link(Object *obj, const char *name, - struct Error **errp); + Error **errp); /** * object_property_set_bool: @@ -877,7 +877,7 @@ Object *object_property_get_link(Object *obj, const char *name, * Writes a bool value to a property. */ void object_property_set_bool(Object *obj, bool value, - const char *name, struct Error **errp); + const char *name, Error **errp); /** * object_property_get_bool: @@ -889,7 +889,7 @@ void object_property_set_bool(Object *obj, bool value, * an error occurs (including when the property value is not a bool). */ bool object_property_get_bool(Object *obj, const char *name, - struct Error **errp); + Error **errp); /** * object_property_set_int: @@ -900,7 +900,7 @@ bool object_property_get_bool(Object *obj, const char *name, * Writes an integer value to a property. */ void object_property_set_int(Object *obj, int64_t value, - const char *name, struct Error **errp); + const char *name, Error **errp); /** * object_property_get_int: @@ -912,7 +912,7 @@ void object_property_set_int(Object *obj, int64_t value, * an error occurs (including when the property value is not an integer). */ int64_t object_property_get_int(Object *obj, const char *name, -struct Error **errp); +Error **errp
[Qemu-devel] [PATCH v9 03/27] qom: add pointer to int property helpers
Make it easy to add read-only helpers for simple integer properties in memory. Reviewed-by: Paolo Bonzini pbonz...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/qom/object.h | 21 ++ qom/object.c | 60 2 files changed, 81 insertions(+) diff --git a/include/qom/object.h b/include/qom/object.h index 6c1e7d3..d02172a 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -795,6 +795,27 @@ void object_property_add(Object *obj, const char *name, const char *type, void object_property_del(Object *obj, const char *name, Error **errp); /** + * object_property_add_uint8_ptr: + * object_property_add_uint16_ptr: + * object_property_add_uint32_ptr: + * object_property_add_uint64_ptr: + * @obj: the object to add a property to + * @name: the name of the property + * @v: pointer to value + * + * Add an integer property in memory. This function will add a + * property of the appropriate type. + */ +void object_property_add_uint8_ptr(Object *obj, const char *name, + const uint8_t *v, Error **errp); +void object_property_add_uint16_ptr(Object *obj, const char *name, +const uint16_t *v, Error **errp); +void object_property_add_uint32_ptr(Object *obj, const char *name, +const uint32_t *v, Error **errp); +void object_property_add_uint64_ptr(Object *obj, const char *name, +const uint64_t *v, Error **Errp); + +/** * object_property_find: * @obj: the object * @name: the name of the property diff --git a/qom/object.c b/qom/object.c index e90e382..b617f26 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1344,6 +1344,66 @@ static char *qdev_get_type(Object *obj, Error **errp) return g_strdup(object_get_typename(obj)); } +static void property_get_uint8_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint8_t value = *(uint8_t *)opaque; +visit_type_uint8(v, value, name, errp); +} + +static void property_get_uint16_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint16_t value = *(uint16_t *)opaque; +visit_type_uint16(v, value, name, errp); +} + +static void property_get_uint32_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint32_t value = *(uint32_t *)opaque; +visit_type_uint32(v, value, name, errp); +} + +static void property_get_uint64_ptr(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +uint64_t value = *(uint64_t *)opaque; +visit_type_uint64(v, value, name, errp); +} + +void object_property_add_uint8_ptr(Object *obj, const char *name, + const uint8_t *v, Error **errp) +{ +object_property_add(obj, name, uint8, property_get_uint8_ptr, +NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint16_ptr(Object *obj, const char *name, +const uint16_t *v, Error **errp) +{ +object_property_add(obj, name, uint16, property_get_uint16_ptr, +NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint32_ptr(Object *obj, const char *name, +const uint32_t *v, Error **errp) +{ +object_property_add(obj, name, uint32, property_get_uint32_ptr, +NULL, NULL, (void *)v, errp); +} + +void object_property_add_uint64_ptr(Object *obj, const char *name, +const uint64_t *v, Error **errp) +{ +object_property_add(obj, name, uint64, property_get_uint64_ptr, +NULL, NULL, (void *)v, errp); +} + static void object_instance_init(Object *obj) { object_property_add_str(obj, type, qdev_get_type, NULL, NULL); -- MST
[Qemu-devel] [PATCH v9 06/27] loader: support for unmapped ROM blobs
Support ROM blobs not mapped into guest memory: same as ROM files really but use caller's buffer. Support invoking callback on access and return memory pointer making it easier for caller to update memory if necessary. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Reviewed-by: Laszlo Ersek ler...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/lm32/lm32_hwsetup.h | 2 +- include/hw/loader.h| 7 --- hw/core/loader.c | 23 --- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/hw/lm32/lm32_hwsetup.h b/hw/lm32/lm32_hwsetup.h index 3449bd8..9fd5e69 100644 --- a/hw/lm32/lm32_hwsetup.h +++ b/hw/lm32/lm32_hwsetup.h @@ -73,7 +73,7 @@ static inline void hwsetup_free(HWSetup *hw) static inline void hwsetup_create_rom(HWSetup *hw, hwaddr base) { -rom_add_blob(hwsetup, hw-data, TARGET_PAGE_SIZE, base); +rom_add_blob(hwsetup, hw-data, TARGET_PAGE_SIZE, base, NULL, NULL, NULL); } static inline void hwsetup_add_u8(HWSetup *hw, uint8_t u) diff --git a/include/hw/loader.h b/include/hw/loader.h index 6145736..e0c576b 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -40,8 +40,9 @@ extern bool rom_file_in_ram; 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); +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); @@ -53,7 +54,7 @@ void do_info_roms(Monitor *mon, const QDict *qdict); #define rom_add_file_fixed(_f, _a, _i) \ rom_add_file(_f, NULL, _a, _i) #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) ? 0 : -1) #define PC_ROM_MIN_VGA 0xc #define PC_ROM_MIN_OPTION 0xc8000 diff --git a/hw/core/loader.c b/hw/core/loader.c index 7b3d3ee..449bd4c 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -700,10 +700,12 @@ err: return -1; } -int rom_add_blob(const char *name, const void *blob, size_t len, - hwaddr addr) +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) { Rom *rom; +void *data = NULL; rom = g_malloc0(sizeof(*rom)); rom-name = g_strdup(name); @@ -713,7 +715,22 @@ int rom_add_blob(const char *name, const void *blob, size_t len, rom-data = g_malloc0(rom-datasize); memcpy(rom-data, blob, len); rom_insert(rom); -return 0; +if (fw_file_name fw_cfg) { +char devpath[100]; + +snprintf(devpath, sizeof(devpath), /rom@%s, fw_file_name); + +if (rom_file_in_ram) { +data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); +} else { +data = rom-data; +} + +fw_cfg_add_file_callback(fw_cfg, fw_file_name, + fw_callback, callback_opaque, + data, rom-romsize); +} +return data; } /* This function is specific for elf program because we don't need to allocate -- MST
[Qemu-devel] [PATCH v9 04/27] pci: fix up w64 size calculation helper
BAR base was calculated incorrectly. Use existing pci_bar_address to get it right. Tested-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/pci/pci.c | 20 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 00554a0..c3fdff4 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2264,7 +2264,7 @@ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) Range *range = opaque; PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); uint16_t cmd = pci_get_word(dev-config + PCI_COMMAND); -int r; +int i; if (!(cmd PCI_COMMAND_MEMORY)) { return; @@ -2283,17 +2283,21 @@ static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque) range_extend(range, pref_range); } } -for (r = 0; r PCI_NUM_REGIONS; ++r) { -PCIIORegion *region = dev-io_regions[r]; +for (i = 0; i PCI_NUM_REGIONS; ++i) { +PCIIORegion *r = dev-io_regions[i]; Range region_range; -if (!region-size || -(region-type PCI_BASE_ADDRESS_SPACE_IO) || -!(region-type PCI_BASE_ADDRESS_MEM_TYPE_64)) { +if (!r-size || +(r-type PCI_BASE_ADDRESS_SPACE_IO) || +!(r-type PCI_BASE_ADDRESS_MEM_TYPE_64)) { +continue; +} +region_range.begin = pci_bar_address(dev, i, r-type, r-size); +region_range.end = region_range.begin + r-size; + +if (region_range.begin == PCI_BAR_UNMAPPED) { continue; } -region_range.begin = pci_get_quad(dev-config + pci_bar(dev, r)); -region_range.end = region_range.begin + region-size; region_range.begin = MAX(region_range.begin, 0x1ULL 32); -- MST
[Qemu-devel] [PATCH v9 10/27] q35: expose mmcfg size as a property
Address is already exposed, expose size for symmetry. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 1 + hw/pci-host/q35.c | 14 ++ 2 files changed, 15 insertions(+) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index 33d75bd..acca45e 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -29,6 +29,7 @@ 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) diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index e46f286..a051b58 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -109,6 +109,16 @@ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v, visit_type_uint64(v, w64.end, name, errp); } +static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, +void *opaque, const char *name, +Error **errp) +{ +PCIExpressHost *e = PCIE_HOST_BRIDGE(obj); +uint32_t value = e-size; + +visit_type_uint32(v, value, name, errp); +} + static Property mch_props[] = { DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr, MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT), @@ -160,6 +170,10 @@ static void q35_host_initfn(Object *obj) q35_host_get_pci_hole64_end, NULL, NULL, NULL, NULL); +object_property_add(obj, PCIE_HOST_MCFG_SIZE, int, +q35_host_get_mmcfg_size, +NULL, NULL, NULL, NULL); + /* Leave enough space for the biggest MCFG BAR */ /* TODO: this matches current bios behaviour, but * it's not a power of two, which means an MTRR -- MST
[Qemu-devel] [PATCH v9 07/27] pcie_host: expose UNMAPPED macro
Make it possible to test unmapped status through QMP. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 3 +++ hw/pci/pcie_host.c | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index 1228e36..bac3c67 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -28,6 +28,9 @@ #define PCIE_HOST_BRIDGE(obj) \ OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE) +/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ +#define PCIE_BASE_ADDR_UNMAPPED ((hwaddr)-1ULL) + struct PCIExpressHost { PCIHostState pci; diff --git a/hw/pci/pcie_host.c b/hw/pci/pcie_host.c index b70e5ad..410ac08 100644 --- a/hw/pci/pcie_host.c +++ b/hw/pci/pcie_host.c @@ -104,9 +104,6 @@ static const MemoryRegionOps pcie_mmcfg_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -/* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ -#define PCIE_BASE_ADDR_UNMAPPED ((hwaddr)-1ULL) - int pcie_host_init(PCIExpressHost *e) { e-base_addr = PCIE_BASE_ADDR_UNMAPPED; -- MST
[Qemu-devel] [PATCH v9 05/27] fw_cfg: interface to trigger callback on read
Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/nvram/fw_cfg.h | 4 hw/nvram/fw_cfg.c | 33 - 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index f60dd67..2ab0fc2 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -60,6 +60,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 +71,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/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index d0820e5..f5dc3ea 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -42,6 +42,7 @@ typedef struct FWCfgEntry { uint8_t *data; void *callback_opaque; FWCfgCallback callback; +FWCfgReadCallback read_callback; } FWCfgEntry; struct FWCfgState { @@ -249,8 +250,12 @@ static uint8_t fw_cfg_read(FWCfgState *s) if (s-cur_entry == FW_CFG_INVALID || !e-data || s-cur_offset = e-len) ret = 0; -else +else { +if (e-read_callback) { +e-read_callback(e-callback_opaque, s-cur_offset); +} ret = e-data[s-cur_offset++]; +} trace_fw_cfg_read(s, ret); return ret; @@ -381,7 +386,10 @@ static const VMStateDescription vmstate_fw_cfg = { } }; -void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) +static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key, + FWCfgReadCallback callback, + void *callback_opaque, + void *data, size_t len) { int arch = !!(key FW_CFG_ARCH_LOCAL); @@ -391,6 +399,13 @@ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) s-entries[arch][key].data = data; s-entries[arch][key].len = (uint32_t)len; +s-entries[arch][key].read_callback = callback; +s-entries[arch][key].callback_opaque = callback_opaque; +} + +void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) +{ +fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len); } void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value) @@ -444,8 +459,9 @@ void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback, s-entries[arch][key].callback = callback; } -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) { int i, index; size_t dsize; @@ -459,7 +475,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, index = be32_to_cpu(s-files-count); assert(index FW_CFG_FILE_SLOTS); -fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len); +fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index, + callback, callback_opaque, data, len); pstrcpy(s-files-f[index].name, sizeof(s-files-f[index].name), filename); @@ -477,6 +494,12 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, s-files-count = cpu_to_be32(index+1); } +void fw_cfg_add_file(FWCfgState *s, const char *filename, + void *data, size_t len) +{ +fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len); +} + static void fw_cfg_machine_ready(struct Notifier *n, void *data) { size_t len; -- MST
[Qemu-devel] [PATCH v9 12/27] acpi: add rules to compile ASL source
Detect presence of IASL compiler and use it to process ASL source. If not there, use pre-compiled files in-tree. Add script to update the in-tree files. Note: distros are known to silently update iasl so detect correct iasl flags for the installed version on each run as opposed to at configure time. Reviewed-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- configure | 9 - hw/i386/Makefile.objs | 22 ++ scripts/update-acpi.sh | 4 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 scripts/update-acpi.sh diff --git a/configure b/configure index 2b83936..15405e1 100755 --- a/configure +++ b/configure @@ -119,6 +119,7 @@ path_of() { # default parameters source_path=`dirname $0` cpu= +iasl=iasl interp_prefix=/usr/gnemul/qemu-%M static=no cross_prefix= @@ -257,6 +258,8 @@ for opt do ;; --cxx=*) CXX=$optarg ;; + --iasl=*) iasl=$optarg + ;; --source-path=*) source_path=$optarg ;; --cpu=*) cpu=$optarg @@ -1055,6 +1058,7 @@ echo Advanced options (experts only): echo --source-path=PATH path of source code [$source_path] echo --cross-prefix=PREFIXuse PREFIX for compile tools [$cross_prefix] echo --cc=CC use C compiler CC [$cc] +echo --iasl=IASL use ACPI compiler IASL [$iasl] echo --host-cc=CC use C compiler CC [$host_cc] for code run at echobuild time echo --cxx=CXXuse C++ compiler CXX [$cxx] @@ -4239,6 +4243,9 @@ else fi echo PYTHON=$python $config_host_mak echo CC=$cc $config_host_mak +if $iasl -h /dev/null 21; then + echo IASL=$iasl $config_host_mak +fi echo CC_I386=$cc_i386 $config_host_mak echo HOST_CC=$host_cc $config_host_mak echo CXX=$cxx $config_host_mak @@ -4691,7 +4698,7 @@ for rom in seabios vgabios ; do echo BCC=bcc $config_mak echo CPP=$cpp $config_mak echo OBJCOPY=objcopy $config_mak -echo IASL=iasl $config_mak +echo IASL=$iasl $config_mak echo LD=$ld $config_mak done diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 45e6165..f950707 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -5,3 +5,25 @@ obj-y += pc_sysfw.o obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o obj-y += kvmvapic.o + +iasl-option=$(shell if test -z `$(1) $(2) 21 /dev/null` \ +; then echo $(2); else echo $(3); fi ;) + +ifdef IASL +#IASL Present. Generate hex files from .dsl +hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.dsl $(SRC_PATH)/scripts/acpi_extract_preprocess.py $(SRC_PATH)/scripts/acpi_extract.py + $(call quiet-command, cpp -P $ -o $*.dsl.i.orig, CPP $(TARGET_DIR)$*.dsl.i.orig) + $(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract_preprocess.py $*.dsl.i.orig $*.dsl.i, ACPI_PREPROCESS $(TARGET_DIR)$*.dsl.i) + $(call quiet-command, $(IASL) $(call iasl-option,$(IASL),-Pn,) -vs -l -tc -p $* $*.dsl.i $(if $(V), , /dev/null) 21 , IASL $(TARGET_DIR)$*.dsl.i) + $(call quiet-command, $(SRC_PATH)/scripts/acpi_extract.py $*.lst $*.off, ACPI_EXTRACT $(TARGET_DIR)$*.off) + $(call quiet-command, cat $*.off $@, CAT $(TARGET_DIR)$@) +else +#IASL Not present. Restore pre-generated hex files. +hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.hex.generated + $(call quiet-command, cp -f $ $@, CP $(TARGET_DIR)$@) +endif + +.PHONY: cleanhex +cleanhex: + rm -f hw/i386/*hex +clean: cleanhex diff --git a/scripts/update-acpi.sh b/scripts/update-acpi.sh new file mode 100644 index 000..b5f05ff --- /dev/null +++ b/scripts/update-acpi.sh @@ -0,0 +1,4 @@ +cd x86_64-softmmu +for file in hw/i386/*.hex; do +cp -f $file ../$file.generated +done -- MST
[Qemu-devel] [PATCH v9 08/27] pcie_host: expose address format
Callers pass in the address so it's helpful for them to be able to decode it. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 21 + hw/pci/pcie_host.c | 21 - 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index bac3c67..da0f275 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -54,4 +54,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_BIT12 +#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/hw/pci/pcie_host.c b/hw/pci/pcie_host.c index 410ac08..c6e1b57 100644 --- a/hw/pci/pcie_host.c +++ b/hw/pci/pcie_host.c @@ -24,27 +24,6 @@ #include hw/pci/pcie_host.h #include exec/address-spaces.h -/* - * PCI express mmcfig 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_BIT12 -#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) - - /* a helper function to get a PCIDevice for a given mmconfig address */ static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus *s, uint32_t mmcfg_addr) -- MST
[Qemu-devel] [PATCH v9 15/27] loader: use file path size from fw_cfg.h
Avoid a bit of code duplication, make max file path constant reusable. Suggested-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/nvram/fw_cfg.h | 4 +++- hw/core/loader.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 2ab0fc2..72b1549 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -46,12 +46,14 @@ #define FW_CFG_INVALID 0x +#define FW_CFG_MAX_FILE_PATH56 + #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 { diff --git a/hw/core/loader.c b/hw/core/loader.c index 449bd4c..060729f 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -663,7 +663,7 @@ int rom_add_file(const char *file, const char *fw_dir, rom_insert(rom); if (rom-fw_file fw_cfg) { const char *basename; -char fw_file_name[56]; +char fw_file_name[FW_CFG_MAX_FILE_PATH]; void *data; basename = strrchr(rom-fw_file, '/'); -- MST
[Qemu-devel] [PATCH v9 09/27] q35: use macro for MCFG property name
Useful to make it accessible through QOM. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 2 ++ hw/pci-host/q35.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index da0f275..33d75bd 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -28,6 +28,8 @@ #define PCIE_HOST_BRIDGE(obj) \ OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE) +#define PCIE_HOST_MCFG_BASE MCFG + /* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */ #define PCIE_BASE_ADDR_UNMAPPED ((hwaddr)-1ULL) diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 23dbeea..e46f286 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -110,7 +110,7 @@ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v, } static Property mch_props[] = { -DEFINE_PROP_UINT64(MCFG, Q35PCIHost, parent_obj.base_addr, +DEFINE_PROP_UINT64(PCIE_HOST_MCFG_BASE, Q35PCIHost, parent_obj.base_addr, MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT), DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost, mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE), -- MST
[Qemu-devel] [PATCH v9 23/27] hpet: add API to find it
Add API to find HPET using QOM. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/timer/hpet.h | 2 ++ hw/timer/hpet.c | 5 + 2 files changed, 7 insertions(+) diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h index 757f79f..ab44bd3 100644 --- a/include/hw/timer/hpet.h +++ b/include/hw/timer/hpet.h @@ -71,4 +71,6 @@ struct hpet_fw_config } QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; + +bool hpet_find(void); #endif diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index fcd22ae..2eb75ea 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -757,6 +757,11 @@ static void hpet_device_class_init(ObjectClass *klass, void *data) dc-props = hpet_device_properties; } +bool hpet_find(void) +{ +return object_resolve_path_type(, TYPE_HPET, NULL); +} + static const TypeInfo hpet_device_info = { .name = TYPE_HPET, .parent= TYPE_SYS_BUS_DEVICE, -- MST
[Qemu-devel] [PATCH v9 25/27] ssdt: fix PBLK length
We don't really support CPU throttling, so supply 0 PBLK length. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/ssdt-proc.dsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/ssdt-proc.dsl b/hw/i386/ssdt-proc.dsl index 58333c7..8229bfd 100644 --- a/hw/i386/ssdt-proc.dsl +++ b/hw/i386/ssdt-proc.dsl @@ -37,7 +37,7 @@ DefinitionBlock (ssdt-proc.aml, SSDT, 0x01, BXPC, BXSSDT, 0x1) ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name -Processor(CPAA, 0xAA, 0xb010, 0x06) { +Processor(CPAA, 0xAA, 0x, 0x0) { ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id Name(ID, 0xAA) /* -- MST
[Qemu-devel] [PATCH v9 14/27] acpi: ssdt pcihp: updat generated file
update generated file, not sure what changed Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/ssdt-pcihp.hex.generated | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated index 0d32a27..b3c2cd5 100644 --- a/hw/i386/ssdt-pcihp.hex.generated +++ b/hw/i386/ssdt-pcihp.hex.generated @@ -17,7 +17,7 @@ static unsigned char ssdp_pcihp_aml[] = { 0x0, 0x0, 0x1, -0x77, +0x76, 0x42, 0x58, 0x50, @@ -40,9 +40,9 @@ static unsigned char ssdp_pcihp_aml[] = { 0x4e, 0x54, 0x4c, -0x28, -0x5, -0x10, +0x23, +0x8, +0x13, 0x20, 0x10, 0x33, -- MST
[Qemu-devel] [PATCH v9 16/27] i386: add bios linker/loader
This adds a dynamic bios linker/loader. This will be used by acpi table generation code to: - load each table in the appropriate memory segment - link tables to each other - fix up checksums after said linking Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/bios-linker-loader.h | 27 hw/i386/bios-linker-loader.c | 158 +++ hw/i386/Makefile.objs| 1 + 3 files changed, 186 insertions(+) create mode 100644 hw/i386/bios-linker-loader.h create mode 100644 hw/i386/bios-linker-loader.c diff --git a/hw/i386/bios-linker-loader.h b/hw/i386/bios-linker-loader.h new file mode 100644 index 000..498c0af --- /dev/null +++ b/hw/i386/bios-linker-loader.h @@ -0,0 +1,27 @@ +#ifndef BIOS_LINKER_LOADER_H +#define BIOS_LINKER_LOADER_H + +#include glib.h +#include stdbool.h +#include inttypes.h + +GArray *bios_linker_loader_init(void); + +void bios_linker_loader_alloc(GArray *linker, + const char *file, + uint32_t alloc_align, + bool alloc_fseg); + +void bios_linker_loader_add_checksum(GArray *linker, const char *file, + void *table, + void *start, unsigned size, + uint8_t *checksum); + +void bios_linker_loader_add_pointer(GArray *linker, +const char *dest_file, +const char *src_file, +GArray *table, void *pointer, +uint8_t pointer_size); + +void *bios_linker_loader_cleanup(GArray *linker); +#endif diff --git a/hw/i386/bios-linker-loader.c b/hw/i386/bios-linker-loader.c new file mode 100644 index 000..0833853 --- /dev/null +++ b/hw/i386/bios-linker-loader.c @@ -0,0 +1,158 @@ +/* Dynamic linker/loader of ACPI tables + * + * Copyright (C) 2013 Red Hat Inc + * + * Author: Michael S. Tsirkin m...@redhat.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/. + */ + +#include bios-linker-loader.h +#include hw/nvram/fw_cfg.h + +#include string.h +#include assert.h +#include qemu/bswap.h + +#define BIOS_LINKER_LOADER_FILESZ FW_CFG_MAX_FILE_PATH + +struct BiosLinkerLoaderEntry { +uint32_t command; +union { +/* + * COMMAND_ALLOCATE - allocate a table from @alloc.file + * subject to @alloc.align alignment (must be power of 2) + * and @alloc.zone (can be HIGH or FSEG) requirements. + * + * Must appear exactly once for each file, and before + * this file is referenced by any other command. + */ +struct { +char file[BIOS_LINKER_LOADER_FILESZ]; +uint32_t align; +uint8_t zone; +} alloc; + +/* + * COMMAND_ADD_POINTER - patch the table (originating from + * @dest_file) at @pointer.offset, by adding a pointer to the table + * originating from @src_file. 1,2,4 or 8 byte unsigned + * addition is used depending on @pointer.size. + */ +struct { +char dest_file[BIOS_LINKER_LOADER_FILESZ]; +char src_file[BIOS_LINKER_LOADER_FILESZ]; +uint32_t offset; +uint8_t size; +} pointer; + +/* + * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by + * @cksum_start and @cksum_length fields, + * and then add the value at @cksum.offset. + * Checksum simply sums -X for each byte X in the range + * using 8-bit math. + */ +struct { +char file[BIOS_LINKER_LOADER_FILESZ]; +uint32_t offset; +uint32_t start; +uint32_t length; +} cksum; + +/* padding */ +char pad[124]; +}; +} QEMU_PACKED; +typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry; + +enum { +BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1, +BIOS_LINKER_LOADER_COMMAND_ADD_POINTER = 0x2, +BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3, +}; + +enum { +BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH = 0x1, +BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG = 0x2, +}; + +GArray *bios_linker_loader_init(void) +{ +return
[Qemu-devel] [PATCH v9 17/27] loader: allow adding ROMs in done callbacks
Don't abort if machine done callbacks add ROMs. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/loader.h | 1 + hw/core/loader.c| 6 +- vl.c| 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/hw/loader.h b/include/hw/loader.h index e0c576b..58eca98 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -46,6 +46,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len, 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); diff --git a/hw/core/loader.c b/hw/core/loader.c index 060729f..60d2ebd 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -812,10 +812,14 @@ int rom_load_all(void) memory_region_unref(section.mr); } qemu_register_reset(rom_reset, NULL); -roms_loaded = 1; return 0; } +void rom_load_done(void) +{ +roms_loaded = 1; +} + void rom_set_fw(FWCfgState *f) { fw_cfg = f; diff --git a/vl.c b/vl.c index fb8006e..46c29c4 100644 --- a/vl.c +++ b/vl.c @@ -4339,6 +4339,9 @@ int main(int argc, char **argv, char **envp) qemu_register_reset(qbus_reset_all_fn, sysbus_get_default()); qemu_run_machine_init_done_notifiers(); +/* Done notifiers can load ROMs */ +rom_load_done(); + qemu_system_reset(VMRESET_SILENT); if (loadvm) { if (load_vmstate(loadvm) 0) { -- MST
[Qemu-devel] [PATCH v9 18/27] i386: define pc guest info
This defines a structure that will be used to fill in acpi tables where relevant properties are not yet available using QOM. Reviewed-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 9 + hw/i386/pc.c | 21 + 2 files changed, 30 insertions(+) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 9b2ddc4..085a621 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -9,6 +9,9 @@ #include hw/i386/ioapic.h #include qemu/range.h +#include qemu/bitmap.h +#include sysemu/sysemu.h +#include hw/pci/pci.h /* PC-style peripherals (also used by other machines). */ @@ -20,6 +23,12 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; +hwaddr ram_size; +unsigned apic_id_limit; +bool apic_xrupt_override; +uint64_t numa_nodes; +uint64_t *node_mem; +uint64_t *node_cpu; FWCfgState *fw_cfg; }; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..d17d1d9 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1047,6 +1047,27 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, { PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state); PcGuestInfo *guest_info = guest_info_state-info; +int i, j; + +guest_info-ram_size = below_4g_mem_size + above_4g_mem_size; +guest_info-apic_id_limit = pc_apic_id_limit(max_cpus); +guest_info-apic_xrupt_override = kvm_allows_irq0_override(); +guest_info-numa_nodes = nb_numa_nodes; +guest_info-node_mem = g_memdup(node_mem, guest_info-numa_nodes * +sizeof *guest_info-node_mem); +guest_info-node_cpu = g_malloc0(guest_info-apic_id_limit * + sizeof *guest_info-node_cpu); + +for (i = 0; i max_cpus; i++) { +unsigned int apic_id = x86_cpu_apic_id_from_index(i); +assert(apic_id guest_info-apic_id_limit); +for (j = 0; j nb_numa_nodes; j++) { +if (test_bit(i, node_cpumask[j])) { +guest_info-node_cpu[apic_id] = j; +break; +} +} +} guest_info_state-machine_done.notify = pc_guest_info_machine_done; qemu_add_machine_init_done_notifier(guest_info_state-machine_done); -- MST
[Qemu-devel] [PATCH v9 19/27] acpi/piix: add macros for acpi property names
Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 10 ++ hw/acpi/piix4.c | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 085a621..5aefc5b 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -20,6 +20,16 @@ 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; diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index b46bd5e..4b8c1da 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -489,9 +489,9 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, static Property piix4_pm_properties[] = { DEFINE_PROP_UINT32(smb_io_base, PIIX4PMState, smb_io_base, 0), -DEFINE_PROP_UINT8(disable_s3, PIIX4PMState, disable_s3, 0), -DEFINE_PROP_UINT8(disable_s4, PIIX4PMState, disable_s4, 0), -DEFINE_PROP_UINT8(s4_val, PIIX4PMState, s4_val, 2), +DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), +DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), +DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), DEFINE_PROP_END_OF_LIST(), }; -- MST
[Qemu-devel] [PATCH v9 20/27] piix: APIs for pc guest info
This adds APIs that will be used to fill in guest acpi tables. Some required information is still lacking in QOM, so we fall back on lookups by type and returning explicit types. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/piix4.h | 8 include/hw/i386/pc.h| 1 + hw/acpi/piix4.c | 44 hw/pci-host/piix.c | 8 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 include/hw/acpi/piix4.h diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h new file mode 100644 index 000..65e6fd7 --- /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/i386/pc.h b/include/hw/i386/pc.h index 5aefc5b..95857be 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -192,6 +192,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, 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); diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 4b8c1da..3bcd890 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -29,6 +29,7 @@ #include exec/ioport.h #include hw/nvram/fw_cfg.h #include exec/address-spaces.h +#include hw/acpi/piix4.h //#define DEBUG @@ -69,6 +70,8 @@ typedef struct PIIX4PMState { /* public */ MemoryRegion io; +uint32_t io_base; + MemoryRegion io_gpe; MemoryRegion io_pci; MemoryRegion io_cpu; @@ -152,14 +155,13 @@ static void apm_ctrl_changed(uint32_t val, void *arg) static void pm_io_space_update(PIIX4PMState *s) { PCIDevice *d = PCI_DEVICE(s); -uint32_t pm_io_base; -pm_io_base = le32_to_cpu(*(uint32_t *)(d-config + 0x40)); -pm_io_base = 0xffc0; +s-io_base = le32_to_cpu(*(uint32_t *)(d-config + 0x40)); +s-io_base = 0xffc0; memory_region_transaction_begin(); memory_region_set_enabled(s-io, d-config[0x80] 1); -memory_region_set_address(s-io, pm_io_base); +memory_region_set_address(s-io, s-io_base); memory_region_transaction_commit(); } @@ -407,6 +409,28 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); } +static void piix4_pm_add_propeties(PIIX4PMState *s) +{ +static const uint8_t acpi_enable_cmd = ACPI_ENABLE; +static const uint8_t acpi_disable_cmd = ACPI_DISABLE; +static const uint32_t gpe0_blk = GPE_BASE; +static const uint32_t gpe0_blk_len = GPE_LEN; +static const uint16_t sci_int = 9; + +object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_ENABLE_CMD, + acpi_enable_cmd, NULL); +object_property_add_uint8_ptr(OBJECT(s), ACPI_PM_PROP_ACPI_DISABLE_CMD, + acpi_disable_cmd, NULL); +object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK, + gpe0_blk, NULL); +object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_GPE0_BLK_LEN, + gpe0_blk_len, NULL); +object_property_add_uint16_ptr(OBJECT(s), ACPI_PM_PROP_SCI_INT, + sci_int, NULL); +object_property_add_uint32_ptr(OBJECT(s), ACPI_PM_PROP_PM_IO_BASE, + s-io_base, NULL); +} + static int piix4_pm_initfn(PCIDevice *dev) { PIIX4PMState *s = PIIX4_PM(dev); @@ -456,9 +480,21 @@ static int piix4_pm_initfn(PCIDevice *dev) piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev-bus, s); +piix4_pm_add_propeties(s); return 0; } +Object *piix4_pm_find(void) +{ +bool ambig; +Object *o = object_resolve_path_type(, TYPE_PIIX4_PM, ambig); + +if (ambig || !o) { +return NULL; +} +return o; +} + 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) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index c041149..bad3953 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -416,6 +416,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, return b; } +PCIBus *find_i440fx(void) +{ +PCIHostState *s = OBJECT_CHECK(PCIHostState, + object_resolve_path(/machine/i440fx, NULL), + TYPE_PCI_HOST_BRIDGE); +return s ? s-bus : NULL; +} + /* PIIX3 PCI to ISA bridge */ static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq) { -- MST
[Qemu-devel] [PATCH v9 21/27] ich9: APIs for pc guest info
This adds APIs that will be used to fill in acpi tables, implemented using QOM, to various ich9 components. Some information is still missing in QOM, so we fall back on lookups by type instead. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/ich9.h| 2 ++ include/hw/i386/ich9.h| 2 ++ include/hw/pci-host/q35.h | 2 ++ hw/acpi/ich9.c| 24 hw/isa/lpc_ich9.c | 40 hw/pci-host/q35.c | 10 ++ 6 files changed, 80 insertions(+) diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index b1fe71f..82fcf9f 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -49,4 +49,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/i386/ich9.h b/include/hw/i386/ich9.h index c5f637b..4a68b35 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -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))) diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index 6eb7ab6..f9db770 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -156,4 +156,6 @@ typedef struct Q35PCIHost { #define MCH_PCIE_DEV 1 #define MCH_PCIE_FUNC 0 +uint64_t mch_mcfg_base(void); + #endif /* HW_Q35_H */ diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 3fb443d..7e0429e 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -24,6 +24,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include hw/hw.h +#include qapi/visitor.h #include hw/i386/pc.h #include hw/pci/pci.h #include qemu/timer.h @@ -228,3 +229,26 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, pm-powerdown_notifier.notify = pm_powerdown_req; qemu_register_powerdown_notifier(pm-powerdown_notifier); } + +static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +ICH9LPCPMRegs *pm = opaque; +uint32_t value = pm-pm_io_base + ICH9_PMIO_GPE0_STS; + +visit_type_uint32(v, value, name, errp); +} + +void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) +{ +static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN; + +object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE, + pm-pm_io_base, errp); +object_property_add(obj, ACPI_PM_PROP_GPE0_BLK, uint32, +ich9_pm_get_gpe0_blk, +NULL, NULL, pm, NULL); +object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN, + gpe0_len, errp); +} diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 5633d08..19b2198 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -29,6 +29,7 @@ */ #include qemu-common.h #include hw/hw.h +#include qapi/visitor.h #include qemu/range.h #include hw/isa/isa.h #include hw/sysbus.h @@ -525,6 +526,43 @@ static const MemoryRegionOps ich9_rst_cnt_ops = { .endianness = DEVICE_LITTLE_ENDIAN }; +Object *ich9_lpc_find(void) +{ +bool ambig; +Object *o = object_resolve_path_type(, TYPE_ICH9_LPC_DEVICE, ambig); + +if (ambig) { +return NULL; +} +return o; +} + +static void ich9_lpc_get_sci_int(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ +ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj); +uint32_t value = ich9_lpc_sci_irq(lpc); + +visit_type_uint32(v, value, name, errp); +} + +static void ich9_lpc_add_properties(ICH9LPCState *lpc) +{ +static const uint8_t acpi_enable_cmd = ICH9_APM_ACPI_ENABLE; +static const uint8_t acpi_disable_cmd = ICH9_APM_ACPI_DISABLE; + +object_property_add(OBJECT(lpc), ACPI_PM_PROP_SCI_INT, uint32, +ich9_lpc_get_sci_int, +NULL, NULL, NULL, NULL); +object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_ENABLE_CMD, + acpi_enable_cmd, NULL); +object_property_add_uint8_ptr(OBJECT(lpc), ACPI_PM_PROP_ACPI_DISABLE_CMD, + acpi_disable_cmd, NULL); + +ich9_pm_add_properties(OBJECT(lpc), lpc-pm, NULL); +} + static int ich9_lpc_initfn(PCIDevice *d) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(d); @@ -552,6 +590,8 @@ static int ich9_lpc_initfn(PCIDevice *d
[Qemu-devel] [PATCH v9 22/27] pvpanic: add API to access io port
Add API to find pvpanic device and get its io port. Will be used to fill in guest info structure. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 1 + hw/misc/pvpanic.c| 13 - 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 95857be..e3ee0a8 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -235,6 +235,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory, /* pvpanic.c */ void pvpanic_init(ISABus *bus); +uint16_t pvpanic_port(void); /* e820 types */ #define E820_RAM1 diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c index b64e3bb..226e298 100644 --- a/hw/misc/pvpanic.c +++ b/hw/misc/pvpanic.c @@ -117,8 +117,19 @@ void pvpanic_init(ISABus *bus) isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE); } +#define PVPANIC_IOPORT_PROP ioport + +uint16_t pvpanic_port(void) +{ +Object *o = object_resolve_path_type(, TYPE_ISA_PVPANIC_DEVICE, NULL); +if (!o) { +return 0; +} +return object_property_get_int(o, PVPANIC_IOPORT_PROP, NULL); +} + static Property pvpanic_isa_properties[] = { -DEFINE_PROP_UINT16(ioport, PVPanicState, ioport, 0x505), +DEFINE_PROP_UINT16(PVPANIC_IOPORT_PROP, PVPanicState, ioport, 0x505), DEFINE_PROP_END_OF_LIST(), }; -- MST
[Qemu-devel] [PATCH v9 26/27] ssdt-proc: update generated file
Update generated ssdt proc hex file (used for systems lacking IASL) after P_BLK length change. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/ssdt-proc.hex.generated | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/i386/ssdt-proc.hex.generated b/hw/i386/ssdt-proc.hex.generated index a28172e..bb9920d 100644 --- a/hw/i386/ssdt-proc.hex.generated +++ b/hw/i386/ssdt-proc.hex.generated @@ -11,7 +11,7 @@ static unsigned char ssdp_proc_aml[] = { 0x0, 0x0, 0x1, -0xb3, +0xb8, 0x42, 0x58, 0x50, @@ -34,9 +34,9 @@ static unsigned char ssdp_proc_aml[] = { 0x4e, 0x54, 0x4c, -0x28, -0x5, -0x10, +0x23, +0x8, +0x13, 0x20, 0x5b, 0x83, @@ -51,7 +51,7 @@ static unsigned char ssdp_proc_aml[] = { 0xb0, 0x0, 0x0, -0x6, +0x0, 0x8, 0x49, 0x44, -- MST
Re: [Qemu-devel] [PATCH v3 0/8] hw/pci: set irq without selecting INTx pin
On Mon, Oct 07, 2013 at 10:36:33AM +0300, Marcel Apfelbaum wrote: Interrupt pin is selected and saved into PCI_INTERRUPT_PIN register during device initialization. Devices should not call directly qemu_set_irq and specify the INTx pin. Added pci_* wrappers to replace qemu_set_irq, qemu_irq_raise, qemu_irq_lower and qemu_irq_pulse, setting the irq based on PCI_INTERRUPT_PIN. Added interface to allocate and free single irq. Added pci_allocate_irq wrapper to be used by devices that still need PCIDevice infrastructure to assert irqs. Removed irq field from PCIDevice, not needed anymore. Special cases of replacements were done in separate patches, all others in one patch hw: set interrupts using pci irq wrappers OK so Acked-by: Michael S. Tsirkin m...@redhat.com Let's wait for some acks, then I'll merge this. Changes from v2: - Addressed Michael S. Tsirkin's comments: - Terminate comments by . - Add fixme comment to pci_irq_pulse - Addressed Paolo Bonzini's comment: - fixed implementation of pci_irq_pulse - Addressed Alex Williamson's comments - replaced pci_irq_raise/lower with pci_irq_assert/deassert - replaced calls to pci_set_irq with pci_irq_assert/deassert when possible - Addressed Gerd Hoffmann's comment - removed irq_pin from UHCIState state because it is not used anymore - Fixed a bug in vmxnet3 (deassert was replaced by an assert) Changes from v1: - Addressed Michael S. Tsirkin's comments: - pci_set_irq directly calls pci_irq handler - removed irq field from PCIDevice - Added qemu interface to allocate single irq - Added pci wrappers to allocate and free pci irq - Added pci irq wrappers for all qemu methods setting irq and not only qemu_set_irq - Replace all qemu irq setters with pci wrappers Marcel Apfelbaum (9): hw/core: Add interface to allocate and free a single IRQ hw/pci: add pci wrappers for allocating and asserting irqs hw/pci-bridge: set PCI_INTERRUPT_PIN register before shpc init hw/vmxnet3: set interrupts using pci irq wrappers hw/vfio: set interrupts using pci irq wrappers hw: set interrupts using pci irq wrappers hw/pcie: AER and hot-plug events must use device's interrupt hw/pci: removed irq field from PCIDevice hw/audio/ac97.c| 4 ++-- hw/audio/es1370.c | 4 ++-- hw/audio/intel-hda.c | 2 +- hw/block/nvme.c| 2 +- hw/char/serial-pci.c | 5 +++-- hw/char/tpci200.c | 8 hw/core/irq.c | 16 hw/display/qxl.c | 2 +- hw/ide/cmd646.c| 2 +- hw/ide/ich.c | 3 ++- hw/isa/vt82c686.c | 2 +- hw/misc/ivshmem.c | 2 +- hw/misc/vfio.c | 11 ++- hw/net/e1000.c | 2 +- hw/net/eepro100.c | 4 ++-- hw/net/ne2000.c| 3 ++- hw/net/pcnet-pci.c | 3 ++- hw/net/rtl8139.c | 2 +- hw/net/vmxnet3.c | 13 +++-- hw/pci-bridge/pci_bridge_dev.c | 2 +- hw/pci/pci.c | 26 +- hw/pci/pcie.c | 4 ++-- hw/pci/pcie_aer.c | 4 ++-- hw/pci/shpc.c | 2 +- hw/scsi/esp-pci.c | 3 ++- hw/scsi/lsi53c895a.c | 2 +- hw/scsi/megasas.c | 6 +++--- hw/scsi/vmw_pvscsi.c | 2 +- hw/usb/hcd-ehci-pci.c | 2 +- hw/usb/hcd-ohci.c | 2 +- hw/usb/hcd-uhci.c | 6 ++ hw/usb/hcd-xhci.c | 7 ++- hw/virtio/virtio-pci.c | 4 ++-- include/hw/irq.h | 7 +++ include/hw/pci/pci.h | 26 +++--- include/hw/pci/pcie.h | 18 -- 36 files changed, 132 insertions(+), 81 deletions(-) -- 1.8.3.1
[Qemu-devel] [PATCH v9 01/27] cleanup object.h: include error.h directly
From: Igor Mammedov imamm...@redhat.com qapi/error.h is simple enough to be included in qom/object.h direcly and prepares qom/object.h to use Error typedef. Signed-off-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/qom/object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/qom/object.h b/include/qom/object.h index 1a7b71a..d9a0063 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -18,9 +18,9 @@ #include stdint.h #include stdbool.h #include qemu/queue.h +#include qapi/error.h struct Visitor; -struct Error; struct TypeImpl; typedef struct TypeImpl *Type; -- MST
Re: [Qemu-devel] [PATCH v9 27/27] don't post me: update bios
On Tue, Oct 08, 2013 at 01:10:56AM +0900, Peter Maydell wrote: On 7 October 2013 18:36, Michael S. Tsirkin m...@redhat.com wrote: update bios binaries to 55480e81704fa46429ac5bb4f8f452fadc9c0416 Subject: line doesn't match your actual behaviour :-) -- PMM Yes, I keep it around to simplify testing. Posted in error. Sigh. I won't repost the series just for this though.
Re: [Qemu-devel] [PATCH v5 0/3] pci: partially implement master abort protocol
On Mon, Sep 16, 2013 at 11:21:13AM +0300, Marcel Apfelbaum wrote: PCI spec requires that a transaction that has not been claimed by any PCI bus devices will be terminated by the initiator with master abort. For read transactions -1() is returned and writes are silently dropped. OK looks good to me, I put this on the pci branch. Implementation: - Allowed the MemoryRegion priority to be negative so a subregion will be visible on all the addresses not covered by other container subregions. - Added a memory region with negative priority that extends over all the pci address space. This region catches all the accesses to the unassigned pci addresses. - The MemoryRegion's ops emulates the master abort scenario. I am working on implementing the following on top of this series - Implement upstream master abort - Handling of RECEIVED MASTER ABORT BIT in Status register Changes from v4: - Addressed Peter Maydell comments - Changed memory patches commit comment - Addressed Michael S. Tsirkin comments - Changed PCI master_abort_mem ops endian-nes to DEVICE_LITTLE_ENDIAN Changes from v3: - Addressed Peter Maydell comments - Removed unnecessary changes to priority of MemoryListener - Ensured that priority is now signed in all related places - Added to memory docs explanation on signed priorities - Addresses Michael S. Tsirkin comments - Changed the name of the new Memory region to master_abort_mem - Made master abort priority INT_MIN instead of -1 - Removed handling of RECEIVED MASTER ABORT BIT; it will be taken care in a different series Changes from v2: - minor: changed nr of patches in the title - minor: modified series list Changes from v1: - pci-unassigned-mem MemoryRegion resides now in PCIBus and not on various Host Bridges - pci-unassgined-mem does not have a .valid.accept field and implements read write methods Marcel Apfelbaum (3): memory: Change MemoryRegion priorities from unsigned to signed docs/memory: Explictly state that MemoryRegion priority is signed hw/pci: partially handle pci master abort docs/memory.txt | 4 hw/core/sysbus.c | 4 ++-- hw/pci/pci.c | 27 +++ include/exec/memory.h| 4 ++-- include/hw/pci/pci_bus.h | 1 + include/hw/sysbus.h | 2 +- memory.c | 4 ++-- 7 files changed, 39 insertions(+), 7 deletions(-) -- 1.8.3.1
Re: [Qemu-devel] [PATCH v3 0/8] hw/pci: set irq without selecting INTx pin
On Mon, Oct 07, 2013 at 10:36:33AM +0300, Marcel Apfelbaum wrote: Interrupt pin is selected and saved into PCI_INTERRUPT_PIN register during device initialization. Devices should not call directly qemu_set_irq and specify the INTx pin. Added pci_* wrappers to replace qemu_set_irq, qemu_irq_raise, qemu_irq_lower and qemu_irq_pulse, setting the irq based on PCI_INTERRUPT_PIN. Added interface to allocate and free single irq. Added pci_allocate_irq wrapper to be used by devices that still need PCIDevice infrastructure to assert irqs. Removed irq field from PCIDevice, not needed anymore. Special cases of replacements were done in separate patches, all others in one patch hw: set interrupts using pci irq wrappers Applied, thanks. Changes from v2: - Addressed Michael S. Tsirkin's comments: - Terminate comments by . - Add fixme comment to pci_irq_pulse - Addressed Paolo Bonzini's comment: - fixed implementation of pci_irq_pulse - Addressed Alex Williamson's comments - replaced pci_irq_raise/lower with pci_irq_assert/deassert - replaced calls to pci_set_irq with pci_irq_assert/deassert when possible - Addressed Gerd Hoffmann's comment - removed irq_pin from UHCIState state because it is not used anymore - Fixed a bug in vmxnet3 (deassert was replaced by an assert) Changes from v1: - Addressed Michael S. Tsirkin's comments: - pci_set_irq directly calls pci_irq handler - removed irq field from PCIDevice - Added qemu interface to allocate single irq - Added pci wrappers to allocate and free pci irq - Added pci irq wrappers for all qemu methods setting irq and not only qemu_set_irq - Replace all qemu irq setters with pci wrappers Marcel Apfelbaum (9): hw/core: Add interface to allocate and free a single IRQ hw/pci: add pci wrappers for allocating and asserting irqs hw/pci-bridge: set PCI_INTERRUPT_PIN register before shpc init hw/vmxnet3: set interrupts using pci irq wrappers hw/vfio: set interrupts using pci irq wrappers hw: set interrupts using pci irq wrappers hw/pcie: AER and hot-plug events must use device's interrupt hw/pci: removed irq field from PCIDevice hw/audio/ac97.c| 4 ++-- hw/audio/es1370.c | 4 ++-- hw/audio/intel-hda.c | 2 +- hw/block/nvme.c| 2 +- hw/char/serial-pci.c | 5 +++-- hw/char/tpci200.c | 8 hw/core/irq.c | 16 hw/display/qxl.c | 2 +- hw/ide/cmd646.c| 2 +- hw/ide/ich.c | 3 ++- hw/isa/vt82c686.c | 2 +- hw/misc/ivshmem.c | 2 +- hw/misc/vfio.c | 11 ++- hw/net/e1000.c | 2 +- hw/net/eepro100.c | 4 ++-- hw/net/ne2000.c| 3 ++- hw/net/pcnet-pci.c | 3 ++- hw/net/rtl8139.c | 2 +- hw/net/vmxnet3.c | 13 +++-- hw/pci-bridge/pci_bridge_dev.c | 2 +- hw/pci/pci.c | 26 +- hw/pci/pcie.c | 4 ++-- hw/pci/pcie_aer.c | 4 ++-- hw/pci/shpc.c | 2 +- hw/scsi/esp-pci.c | 3 ++- hw/scsi/lsi53c895a.c | 2 +- hw/scsi/megasas.c | 6 +++--- hw/scsi/vmw_pvscsi.c | 2 +- hw/usb/hcd-ehci-pci.c | 2 +- hw/usb/hcd-ohci.c | 2 +- hw/usb/hcd-uhci.c | 6 ++ hw/usb/hcd-xhci.c | 7 ++- hw/virtio/virtio-pci.c | 4 ++-- include/hw/irq.h | 7 +++ include/hw/pci/pci.h | 26 +++--- include/hw/pci/pcie.h | 18 -- 36 files changed, 132 insertions(+), 81 deletions(-) -- 1.8.3.1
Re: [Qemu-devel] [PATCH v5 2/5] hpet: entitle more irq pins for hpet
On Wed, Oct 09, 2013 at 11:27:24AM +0800, liu ping fan wrote: On Mon, Sep 30, 2013 at 11:58 PM, Michael S. Tsirkin m...@redhat.com wrote: On Mon, Sep 30, 2013 at 05:48:03PM +0200, Paolo Bonzini wrote: Il 30/09/2013 11:30, Michael S. Tsirkin ha scritto: I was really only talking about q35 here. I thought it's ugly that users can control intcap directly. Can object_set_property be used after qdev_try_create? Yes, after that and before qdev_init. This is how Ping Fan is doing PIIX right now. PIIX has another issue: the default value in hpet is really Q35 specific, that's also kind of ugly, isn't it? Yeah, perhaps it is. So are you suggesting the default to be 4 (GSI2 only)? Paolo I suggest it fails unless caller set the property. Sorry, out of office for a long time, and did not keep up with this thread in time. When letting the caller set the intcap, we should consider the compatibility of q35. For pc-q35-1.7 or later, the caller should set the property, otherwise not. Set it always - just set it to a compatible value for 1.6. But how can the caller tell that it runs on q35-1.7? The essential problem is that set the property will always overwrite the property which is set up by compatible mechanism. So it is hard to implement without breaking the current mechanism. Do you think so? Thanks and regards, Ping fan Not that hard. Fail init if it wasn't set.
Re: [Qemu-devel] [PATCH v5 2/5] hpet: entitle more irq pins for hpet
On Wed, Oct 09, 2013 at 09:41:29AM +0200, Paolo Bonzini wrote: Il 09/10/2013 09:24, Michael S. Tsirkin ha scritto: Sorry, out of office for a long time, and did not keep up with this thread in time. When letting the caller set the intcap, we should consider the compatibility of q35. For pc-q35-1.7 or later, the caller should set the property, otherwise not. Set it always - just set it to a compatible value for 1.6. So you're suggesting skipping the mechanism we have for compatibility properties, and instead using a global variable or something like that? Paolo That's one option. Or we can use global properties - just set for 1.7 too. All this is not ideal: properties really need to integrate better with QOM, and using global properties for compat always was a hack. -- MST
[Qemu-devel] [PATCH 1/3] acpi: add interface to access user-installed tables
Also add a new API to install builtin tables, so that we can distinguish between the two. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/acpi.h | 4 hw/acpi/core.c | 40 2 files changed, 44 insertions(+) diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index 51733d3..6bbcb17 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h @@ -165,6 +165,10 @@ 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/hw/acpi/core.c b/hw/acpi/core.c index 7467b88..4d25d8e 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -309,6 +309,46 @@ out: error_propagate(errp, err); } +static bool acpi_table_builtin = false; + +void acpi_table_add_builtin(const QemuOpts *opts, Error **errp) +{ +acpi_table_builtin = true; +acpi_table_add(opts, errp); +} + +unsigned acpi_table_len(void *current) +{ +struct acpi_table_header *hdr = current - sizeof(hdr-_length); +return hdr-_length; +} + +static +void *acpi_table_hdr(void *h) +{ +struct acpi_table_header *hdr = h; +return hdr-sig; +} + +uint8_t *acpi_table_first(void) +{ +if (acpi_table_builtin || !acpi_tables) { +return NULL; +} +return acpi_table_hdr(acpi_tables + ACPI_TABLE_PFX_SIZE); +} + +uint8_t *acpi_table_next(uint8_t *current) +{ +uint8_t *next = current + acpi_table_len(current); + +if (next - acpi_tables = acpi_tables_len) { +return NULL; +} else { +return acpi_table_hdr(next); +} +} + static void acpi_notify_wakeup(Notifier *notifier, void *data) { ACPIREGS *ar = container_of(notifier, ACPIREGS, wakeup); -- MST
[Qemu-devel] [PATCH 0/3] acpi-build: add -acpitable support
This small patchset is on top of my acpi series v9 - as that is very big by now, sending as incremental patches to simplify review. Michael S. Tsirkin (3): acpi: add interface to access user-installed tables pc: use new api to add builtin tables acpi-build: load tables supplied by user include/hw/acpi/acpi.h | 4 hw/acpi/core.c | 40 hw/i386/acpi-build.c | 9 + hw/i386/pc.c | 2 +- 4 files changed, 54 insertions(+), 1 deletion(-) -- MST
[Qemu-devel] [PATCH 2/3] pc: use new api to add builtin tables
At this point the only builtin table we have is the DSDT used for Q35. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index a7fcbf9..a51f916 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1116,7 +1116,7 @@ void pc_acpi_init(const char *default_dsdt) opts = qemu_opts_parse(qemu_find_opts(acpi), arg, 0); g_assert(opts != NULL); -acpi_table_add(opts, err); +acpi_table_add_builtin(opts, err); if (err) { error_report(WARNING: failed to load %s: %s, filename, error_get_pretty(err)); -- MST
[Qemu-devel] [PATCH 3/3] acpi-build: load tables supplied by user
If user supplies any SSDTs using -acpi, install them in addition to the built-in ones. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-build.c | 9 + 1 file changed, 9 insertions(+) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 262d1d6..6cfa044 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1041,6 +1041,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) AcpiMiscInfo misc; AcpiMcfgInfo mcfg; PcPciInfo pci; +uint8_t *u; acpi_get_cpu_info(cpu); acpi_get_pm_info(pm); @@ -1092,6 +1093,14 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) build_mcfg_q35(tables-table_data, tables-linker, mcfg); } +/* Add tables supplied by user (if any) */ +for (u = acpi_table_first(); u; u = acpi_table_next(u)) { +unsigned len = acpi_table_len(u); + +acpi_add_table(table_offsets, tables-table_data); +g_array_append_vals(tables-table_data, u, len); +} + /* RSDT is pointed to by RSDP */ rsdt = tables-table_data-len; build_rsdt(tables-table_data, tables-linker, table_offsets); -- MST
Re: [Qemu-devel] [PATCH v6 2/5] hpet: enable to entitle more irq pins for hpet
On Thu, Oct 10, 2013 at 03:56:16PM +0800, Liu Ping Fan wrote: On q35, IRQ2/8 can be reserved for hpet timer 0/1. And pin 16~23 of ioapic can be dynamically assigned to hpet as guest chooses. So we introduce intcap property to do that. (currently, its value is IRQ2. Later, it should be set by board.) Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com --- hw/timer/hpet.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 8429eb3..5b11be4 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -25,6 +25,7 @@ */ #include hw/hw.h +#include hw/boards.h #include hw/i386/pc.h #include ui/console.h #include qemu/timer.h @@ -42,6 +43,9 @@ #define HPET_MSI_SUPPORT0 +/* Will fix: intcap is set by board, and should be 0 if nobody sets. */ +#define HPET_TN_INT_CAP_DEFAULT 0x4ULL + #define TYPE_HPET hpet #define HPET(obj) OBJECT_CHECK(HPETState, (obj), TYPE_HPET) @@ -73,6 +77,7 @@ typedef struct HPETState { uint8_t rtc_irq_level; qemu_irq pit_enabled; uint8_t num_timers; +uint32_t intcap; HPETTimer timer[HPET_MAX_TIMERS]; /* Memory-mapped, software visible registers */ @@ -663,8 +668,8 @@ static void hpet_reset(DeviceState *d) if (s-flags (1 HPET_MSI_SUPPORT)) { timer-config |= HPET_TN_FSB_CAP; } -/* advertise availability of ioapic inti2 */ -timer-config |= 0x0004ULL 32; +/* advertise availability of ioapic int */ +timer-config |= (uint64_t)s-intcap 32; timer-period = 0ULL; timer-wrap_flag = 0; } @@ -753,6 +758,7 @@ static void hpet_realize(DeviceState *dev, Error **errp) static Property hpet_device_properties[] = { DEFINE_PROP_UINT8(timers, HPETState, num_timers, HPET_MIN_TIMERS), DEFINE_PROP_BIT(msi, HPETState, flags, HPET_MSI_SUPPORT, false), +DEFINE_PROP_UINT32(intcap, HPETState, intcap, HPET_TN_INT_CAP_DEFAULT), DEFINE_PROP_END_OF_LIST(), }; Please add a macro for this name as you use it in other files later. -- 1.8.1.4
Re: [Qemu-devel] [PATCH v6 5/5] PC: differentiate hpet's interrupt capability on piix and q35
On Thu, Oct 10, 2013 at 03:56:19PM +0800, Liu Ping Fan wrote: For pc-piix-*, hpet's intcap is always hard coded as IRQ2. For q35, if it is pc-q35-1.7 and earlier, we use IRQ2 for compat reason, otherwise IRQ2, IRQ8, and IRQ16~23 are allowed. Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com --- hw/i386/pc.c | 21 - hw/i386/pc_piix.c| 3 ++- hw/i386/pc_q35.c | 2 +- include/hw/i386/pc.h | 3 ++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f2b7b6c..062019d 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1219,7 +1219,8 @@ static const MemoryRegionOps ioportF0_io_ops = { void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, - bool no_vmport) + bool no_vmport, + bool hpet_irqs) { int i; DriveInfo *fd[MAX_FD]; @@ -1249,10 +1250,20 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, /* In order to set property, here not using sysbus_try_create_simple */ hpet = qdev_try_create(NULL, hpet); if (hpet) { -/* tmp fix. For compat, hard code to IRQ2 until we have correct - * compat property and differentiate pc-iix with pc-q35 - */ -qdev_prop_set_uint32(hpet, intcap, 0x4); +/* For pc-piix-*, hpet's intcap is always IRQ2. */ +if (!hpet_irqs) { +qdev_prop_set_uint32(hpet, intcap, 0x4); +} else { +/* For pc-q35-1.7 and earlier, use IRQ2 for compat. */ +uint8_t compat = object_property_get_int(OBJECT(hpet), +compat, NULL); +if (compat) { +qdev_prop_set_uint32(hpet, intcap, 0x4); +} else { +/* using IRQ16~23, IRQ8 and IRQ2 */ +qdev_prop_set_uint32(hpet, intcap, 0xff0104); +} +} So why do we need an extra property? uint8_t compat = object_property_get_int(OBJECT(hpet), intcap, NULL); if (!intcap) { /* For pc-piix-*, hpet's intcap is IRQ2. */ /* For Q35, using IRQ16~23, IRQ8 and IRQ2 */ uint32_t intcap = hpet_irqs ? 0xff0104 : 0x4; qdev_prop_set_uint32(hpet, intcap, intcap); } now all you need to do for compat is set intcap property. qdev_init_nofail(hpet); sysbus_mmio_map(SYS_BUS_DEVICE(hpet), 0, HPET_BASE); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 90f1ea4..a45ce11 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -180,7 +180,8 @@ static void pc_init1(QEMUMachineInitArgs *args, pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL); /* init basic PC hardware */ -pc_basic_device_init(isa_bus, gsi, rtc_state, floppy, xen_enabled()); +pc_basic_device_init(isa_bus, gsi, rtc_state, floppy, xen_enabled(), +false); pc_nic_init(isa_bus, pci_bus); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index ca84e1c..9e41f4a 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -181,7 +181,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args) pc_register_ferr_irq(gsi[13]); /* init basic PC hardware */ -pc_basic_device_init(isa_bus, gsi, rtc_state, floppy, false); +pc_basic_device_init(isa_bus, gsi, rtc_state, floppy, false, true); /* connect pm stuff to lpc */ ich9_lpc_pm_init(lpc); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 80aa7bd..a49d9cd 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -134,7 +134,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, + bool 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, -- 1.8.1.4
Re: [Qemu-devel] [PATCH v6 3/5] PC: use qdev_xx to create hpet instead of sysbus_create_xx
On Thu, Oct 10, 2013 at 03:56:17PM +0800, Liu Ping Fan wrote: sysbus_create_xx func does not allow us to set a device's extra properties. While hpet need to set its compat property before initialization, so we abandon the wrapper function, and spread its logic inline Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com I would merge patches 3,4,5 together. It's generally not a good idea to change same line of code in multiple patches in a patchset, makes review harder instead of easier. --- hw/i386/pc.c| 11 +-- hw/timer/hpet.c | 4 +--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0c313fe..f2b7b6c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1246,9 +1246,16 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, * when the HPET wants to take over. Thus we have to disable the latter. */ if (!no_hpet (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { -hpet = sysbus_try_create_simple(hpet, HPET_BASE, NULL); - +/* In order to set property, here not using sysbus_try_create_simple */ +hpet = qdev_try_create(NULL, hpet); if (hpet) { +/* tmp fix. For compat, hard code to IRQ2 until we have correct + * compat property and differentiate pc-iix with pc-q35 + */ +qdev_prop_set_uint32(hpet, intcap, 0x4); +qdev_init_nofail(hpet); +sysbus_mmio_map(SYS_BUS_DEVICE(hpet), 0, HPET_BASE); + for (i = 0; i GSI_NUM_PINS; i++) { sysbus_connect_irq(SYS_BUS_DEVICE(hpet), i, gsi[i]); } diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 5b11be4..69ce587 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -43,8 +43,6 @@ #define HPET_MSI_SUPPORT0 -/* Will fix: intcap is set by board, and should be 0 if nobody sets. */ -#define HPET_TN_INT_CAP_DEFAULT 0x4ULL #define TYPE_HPET hpet #define HPET(obj) OBJECT_CHECK(HPETState, (obj), TYPE_HPET) @@ -758,7 +756,7 @@ static void hpet_realize(DeviceState *dev, Error **errp) static Property hpet_device_properties[] = { DEFINE_PROP_UINT8(timers, HPETState, num_timers, HPET_MIN_TIMERS), DEFINE_PROP_BIT(msi, HPETState, flags, HPET_MSI_SUPPORT, false), -DEFINE_PROP_UINT32(intcap, HPETState, intcap, HPET_TN_INT_CAP_DEFAULT), +DEFINE_PROP_UINT32(intcap, HPETState, intcap, 0), DEFINE_PROP_END_OF_LIST(), }; -- 1.8.1.4
Re: [Qemu-devel] [PATCH v6 2/5] hpet: enable to entitle more irq pins for hpet
On Thu, Oct 10, 2013 at 11:33:07AM +0200, Paolo Bonzini wrote: Il 10/10/2013 11:16, Michael S. Tsirkin ha scritto: On Thu, Oct 10, 2013 at 03:56:16PM +0800, Liu Ping Fan wrote: On q35, IRQ2/8 can be reserved for hpet timer 0/1. And pin 16~23 of ioapic can be dynamically assigned to hpet as guest chooses. So we introduce intcap property to do that. (currently, its value is IRQ2. Later, it should be set by board.) Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com --- hw/timer/hpet.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 8429eb3..5b11be4 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -25,6 +25,7 @@ */ #include hw/hw.h +#include hw/boards.h #include hw/i386/pc.h #include ui/console.h #include qemu/timer.h @@ -42,6 +43,9 @@ #define HPET_MSI_SUPPORT0 +/* Will fix: intcap is set by board, and should be 0 if nobody sets. */ +#define HPET_TN_INT_CAP_DEFAULT 0x4ULL + #define TYPE_HPET hpet #define HPET(obj) OBJECT_CHECK(HPETState, (obj), TYPE_HPET) @@ -73,6 +77,7 @@ typedef struct HPETState { uint8_t rtc_irq_level; qemu_irq pit_enabled; uint8_t num_timers; +uint32_t intcap; HPETTimer timer[HPET_MAX_TIMERS]; /* Memory-mapped, software visible registers */ @@ -663,8 +668,8 @@ static void hpet_reset(DeviceState *d) if (s-flags (1 HPET_MSI_SUPPORT)) { timer-config |= HPET_TN_FSB_CAP; } -/* advertise availability of ioapic inti2 */ -timer-config |= 0x0004ULL 32; +/* advertise availability of ioapic int */ +timer-config |= (uint64_t)s-intcap 32; timer-period = 0ULL; timer-wrap_flag = 0; } @@ -753,6 +758,7 @@ static void hpet_realize(DeviceState *dev, Error **errp) static Property hpet_device_properties[] = { DEFINE_PROP_UINT8(timers, HPETState, num_timers, HPET_MIN_TIMERS), DEFINE_PROP_BIT(msi, HPETState, flags, HPET_MSI_SUPPORT, false), +DEFINE_PROP_UINT32(intcap, HPETState, intcap, HPET_TN_INT_CAP_DEFAULT), DEFINE_PROP_END_OF_LIST(), }; Please add a macro for this name as you use it in other files later. Are you sure? This is not done for any other compat property. Paolo It's done if we use the property from C. See PCI_HOST_PROP_PCI_HOLE64_SIZE. You want compiler to catch errors, that's much better than a runtime failure. -- MST
Re: [Qemu-devel] [RFC] map 64-bit PCI devices after all possible RAM
On Thu, Oct 10, 2013 at 12:56:23PM +0200, Gerd Hoffmann wrote: Hi, So far from QEMU side it's partially (only memory region mapping and not ACPI window) configurable via {i440FX-pcihost|q35-pcihost}.pci-hole64-size property /me looks. Hmm, so the pci-hole64 memory region basically covers all non-memory area, leaving no free space. This is kind of derived from the PIIX spec although of course it did not discuss 64 bit memory. The window location can either be made configurable too, or we simply place it at the top of the address space, with address space being what the cpu can address according to cpuinfo. An earlier attempt by Michael to push complete PCI window placement info via etc/pci-info romfile to Seabios was rejected in favor of letting Seabios to program windows at hardcoded(32-bit/behind high mem) locations with a 64-bit window size (in ACPI) that covers all present devices but doesn't account for future PCI hotplug either. Correct. The ACPI tables should reflect what SeaBIOS has programmed, to avoid nasty dependencies between seabios and qemu. The same should apply to pci-hole64 IMO. That behavior maintained in his ACPI in QEMU series, see: http://patchwork.ozlabs.org/patch/281032/ acpi_get_pci_info()-i440fx_pcihost_get_pci_hole64_end()-pci_bus_get_w64_range() which is then embedded in ACPI table. So end result stays the same as before (no usable 64-bit PCI window for hotlug). Yes. And if we change seabios to do something else qemu nicely adapts to that, without requiring us to update things in lockstep. But 64-bit PCI window size, which is capped by QEMU to insane legacy 62 bits (memory region size), is a bit of orthogonal to freeing space for memory hotplug before it. Yep. So seabios should leave some free address space for memory hotplug. And if we change seabios to map the 64bit pci bars somewhere else we should also allow for a larger 64bit pci window to get some address space for pci hotplug. If we can do that without hints from the qemu I'd prefer that. I think the simplest way to do all this is simply to tell seabios that we have more memory. seabios already programs 64 bit BARs higher than memory. No new interface seems necessary. 40 address lines allow 1TB, so we would place the window just below 1TB. Comments? More to the point if OS supports/enforces 1Tb physical address space,the RAM and 64-bit PCI hole are going to contend for it, QEMU could abort on startup if they both do not fit in CPU supported address space but I don't see what else it could do. Yes. Proposed patch favors RAM vs 64-bit PCI hole and moves the hole behind the possible RAM, which in present state of QEMU potentially leaves the rest of address space up to 62 bits for hole. So you'd end up with the 64bit hole being above the address space the virtual cpu claims to support. Not exactly nice either. Maybe things work nevertheless, maybe not ... Both cases can easily be fixed by just using a cpu with enough physical address lines to fit everything in, so I don't think we should bother too much about this corner case. Just in case this wasn't clear: my idea is that seabios figures the address space size at runtime, so the 1TB would NOT be hard-coded, it just served as example with the current default qemu cpu. So with my idea the address space would have all RAM at the bottom (well, starting at 4g). All PCI devices at the top. Free space for hotplug inbetween. RAM can grow up. PCI space can grow down. Note that qemu can make 64bit pci window in the acpi tables larger than what is actually used by the mapped bars, to make room for hotplugging, without any help from seabios (once the acpi table generation patches are merged). So with the current seabios (bars mapped above memory) it can set the end address higher. When seabios starts mapping the pci bars high it can set the start address lower. Anyone has a use case not handled by this approach? I think the issue is with legacy guests. E.g. if VCPU claims to support 50 bit of memory do we put high PCI memory at 1 50? If yes old guests which expect at most 40 bit will not be able to use it. It has drawback that one can't get a working VM if QEMU is started in memory hotlug mode with old BIOS + PCI devices that require 64-bit bars, otherwise it's backward compatible. Yes. Updating seabios will be needed to use memory hotplug together with 64bit pci no matter how we tackle the issue.
Re: [Qemu-devel] [RFC] map 64-bit PCI devices after all possible RAM
On Wed, Oct 09, 2013 at 02:23:04PM +0200, Igor Mammedov wrote: I'm posting it to get an oppinion on one of possible approaches on where to map a hotplug memory. This patch assumes that a space for hotplug memory is located right after RamSizeOver4G region and QEMU will provide romfile to specify where it ends so that BIOS could know from what base to start 64-bit PCI devices mapping. Signed-off-by: Igor Mammedov imamm...@redhat.com Well there are two things bios does with RamSizeOver4G: determine where to map PCI devices, and fill in smbios. I wonder whether QEMU should fill smbios from qemu too, that would let us side-step the issue and just make RamSizeOver4G larger. Let's see how the ACPI patchset fares first ... --- src/fw/pciinit.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index b29db99..62f8d4e 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -18,6 +18,8 @@ #include paravirt.h // RamSize #include string.h // memset #include util.h // pci_setup +#include byteorder.h // le64_to_cpu +#include romfile.h // romfile_loadint #define PCI_DEVICE_MEM_MIN 0x1000 #define PCI_BRIDGE_IO_MIN 0x1000 @@ -764,6 +766,8 @@ static void pci_bios_map_devices(struct pci_bus *busses) { if (pci_bios_init_root_regions(busses)) { struct pci_region r64_mem, r64_pref; +u64 base64 = le64_to_cpu(romfile_loadint(etc/mem64-end, + 0x1ULL + RamSizeOver4G)); r64_mem.list.first = NULL; r64_pref.list.first = NULL; pci_region_migrate_64bit_entries(busses[0].r[PCI_REGION_TYPE_MEM], @@ -779,7 +783,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) u64 align_mem = pci_region_align(r64_mem); u64 align_pref = pci_region_align(r64_pref); -r64_mem.base = ALIGN(0x1LL + RamSizeOver4G, align_mem); +r64_mem.base = ALIGN(base64, align_mem); r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref); pcimem64_start = r64_mem.base; pcimem64_end = r64_pref.base + sum_pref; -- 1.8.3.1
Re: [Qemu-devel] [PATCH v6 2/5] hpet: enable to entitle more irq pins for hpet
On Thu, Oct 10, 2013 at 11:46:42AM +0200, Paolo Bonzini wrote: Il 10/10/2013 11:41, Michael S. Tsirkin ha scritto: Are you sure? This is not done for any other compat property. Paolo It's done if we use the property from C. See PCI_HOST_PROP_PCI_HOLE64_SIZE. You want compiler to catch errors, that's much better than a runtime failure. I agree, but I think there should be no need to use the property from C. Paolo Well this patchset does use it from C. If it's done it needs a macro.
Re: [Qemu-devel] [RFC] map 64-bit PCI devices after all possible RAM
On Thu, Oct 10, 2013 at 02:14:16PM +0200, Gerd Hoffmann wrote: Hi, I think the simplest way to do all this is simply to tell seabios that we have more memory. seabios already programs 64 bit BARs higher than memory. Hmm? As I understand Igor just wants some address space for memory hotplug. So there wouldn't be memory there (yet). And telling seabios there is although there isn't will make seabios place wrong info into the e820 tables. Not going to fly. True. Maybe we should get some smbios stuff from qemu too. I think the issue is with legacy guests. E.g. if VCPU claims to support 50 bit of memory do we put high PCI memory at 1 50? If yes old guests which expect at most 40 bit will not be able to use it. Hmm. Sure such guests exist? I wouldn't be surprised. At least some windows guests crash if you try to tell them your system has too much physical memory (e.g. 2^48). Note this is physical address lines, not virtual address space (where you might need an additional level of pagetables to fully use it, which is not something we could expect old guests being able to handle). cheers, Gerd
Re: [Qemu-devel] [PATCH v2] map 64-bit PCI BARs at location provided by emulator
On Sun, Oct 13, 2013 at 02:13:44PM +0200, Igor Mammedov wrote: Currently 64-bit PCI BARs are unconditionally mapped by BIOS right over 4G + RamSizeOver4G location, which doesn't allow to reserve extra space before 64-bit PCI window. For memory hotplug an extra RAM space might be reserved after present 64-bit RAM end and BIOS should map 64-bit PCI BARs after it. Introduce etc/pcimem64-start romfile to provide BIOS a hint where it should start mapping of 64-bit PCI BARs. If romfile is missing, BIOS reverts to legacy behavior and starts mapping right after high memory. Signed-off-by: Igor Mammedov imamm...@redhat.com --- v2: * place 64-bit window behind high RAM end if etc/pcimem64-start points below it. Hmm I had an alternative suggestion of passing smbios tables in from QEMU (seabios already has a mechanism for this). We could then simply increase the existing RamSize variable. What do you think about this idea? --- src/fw/pciinit.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index b29db99..798309b 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -18,6 +18,8 @@ #include paravirt.h // RamSize #include string.h // memset #include util.h // pci_setup +#include byteorder.h // le64_to_cpu +#include romfile.h // romfile_loadint #define PCI_DEVICE_MEM_MIN 0x1000 #define PCI_BRIDGE_IO_MIN 0x1000 @@ -764,6 +766,15 @@ static void pci_bios_map_devices(struct pci_bus *busses) { if (pci_bios_init_root_regions(busses)) { struct pci_region r64_mem, r64_pref; +u64 ram64_end = 0x1ULL + RamSizeOver4G; +u64 base64 = le64_to_cpu(romfile_loadint(etc/pcimem64-start, + ram64_end)); +if (base64 ram64_end) { +dprintf(1, ignorig etc/pcimem64-start [0x%llx] below present RAM, + placing 64-bit PCI window behind RAM end: %llx, +base64, ram64_end); +base64 = ram64_end; +} r64_mem.list.first = NULL; r64_pref.list.first = NULL; pci_region_migrate_64bit_entries(busses[0].r[PCI_REGION_TYPE_MEM], @@ -779,7 +790,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) u64 align_mem = pci_region_align(r64_mem); u64 align_pref = pci_region_align(r64_pref); -r64_mem.base = ALIGN(0x1LL + RamSizeOver4G, align_mem); +r64_mem.base = ALIGN(base64, align_mem); r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref); pcimem64_start = r64_mem.base; pcimem64_end = r64_pref.base + sum_pref; -- 1.8.3.1
Re: [Qemu-devel] [PATCH v2] map 64-bit PCI BARs at location provided by emulator
On Sun, Oct 13, 2013 at 05:11:54PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 15:31:23 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 02:13:44PM +0200, Igor Mammedov wrote: Currently 64-bit PCI BARs are unconditionally mapped by BIOS right over 4G + RamSizeOver4G location, which doesn't allow to reserve extra space before 64-bit PCI window. For memory hotplug an extra RAM space might be reserved after present 64-bit RAM end and BIOS should map 64-bit PCI BARs after it. Introduce etc/pcimem64-start romfile to provide BIOS a hint where it should start mapping of 64-bit PCI BARs. If romfile is missing, BIOS reverts to legacy behavior and starts mapping right after high memory. Signed-off-by: Igor Mammedov imamm...@redhat.com --- v2: * place 64-bit window behind high RAM end if etc/pcimem64-start points below it. Hmm I had an alternative suggestion of passing smbios tables in from QEMU (seabios already has a mechanism for this). We could then simply increase the existing RamSize variable. What do you think about this idea? There is several issues with RamSizeOver4G I see: 1. As Gerd pointed out it is also used to setup a part of e820 tables. It possibly could be also changed see [Qemu-devel] [RfC PATCH] e820: pass high memory too but it will be more complicated to keep seabios backward/forward compatible if we use RamSizeOver4G for passing. What are the compatibility worries, exactly? The way I see it, if QEMU wants to be compatible it can't use memory hotplug. In that case RamSizeOver4G will have the old meaning which should work without issues. 2. It doesn't scale if we are going to use more than 1Tb future. Extending RamSizeOver4G value via additional CMOS port wasn't welcomed either, see http://www.seabios.org/pipermail/seabios/2010-September/000911.html It looks like fw_cfg interface is preferred one and etc/pcimem64-start approach doesn't have backward/forward compatibility issues. Hmm but you aren't passing in memory size - pcimem64-start merely tells bios where to put PCI devices. So how would it help? --- src/fw/pciinit.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index b29db99..798309b 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -18,6 +18,8 @@ #include paravirt.h // RamSize #include string.h // memset #include util.h // pci_setup +#include byteorder.h // le64_to_cpu +#include romfile.h // romfile_loadint #define PCI_DEVICE_MEM_MIN 0x1000 #define PCI_BRIDGE_IO_MIN 0x1000 @@ -764,6 +766,15 @@ static void pci_bios_map_devices(struct pci_bus *busses) { if (pci_bios_init_root_regions(busses)) { struct pci_region r64_mem, r64_pref; +u64 ram64_end = 0x1ULL + RamSizeOver4G; +u64 base64 = le64_to_cpu(romfile_loadint(etc/pcimem64-start, + ram64_end)); +if (base64 ram64_end) { +dprintf(1, ignorig etc/pcimem64-start [0x%llx] below present RAM, + placing 64-bit PCI window behind RAM end: %llx, +base64, ram64_end); +base64 = ram64_end; +} r64_mem.list.first = NULL; r64_pref.list.first = NULL; pci_region_migrate_64bit_entries(busses[0].r[PCI_REGION_TYPE_MEM], @@ -779,7 +790,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) u64 align_mem = pci_region_align(r64_mem); u64 align_pref = pci_region_align(r64_pref); -r64_mem.base = ALIGN(0x1LL + RamSizeOver4G, align_mem); +r64_mem.base = ALIGN(base64, align_mem); r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref); pcimem64_start = r64_mem.base; pcimem64_end = r64_pref.base + sum_pref; -- 1.8.3.1 -- Regards, Igor
Re: [Qemu-devel] [PATCH v2] map 64-bit PCI BARs at location provided by emulator
On Sun, Oct 13, 2013 at 06:23:28PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 18:59:20 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 05:11:54PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 15:31:23 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 02:13:44PM +0200, Igor Mammedov wrote: Currently 64-bit PCI BARs are unconditionally mapped by BIOS right over 4G + RamSizeOver4G location, which doesn't allow to reserve extra space before 64-bit PCI window. For memory hotplug an extra RAM space might be reserved after present 64-bit RAM end and BIOS should map 64-bit PCI BARs after it. Introduce etc/pcimem64-start romfile to provide BIOS a hint where it should start mapping of 64-bit PCI BARs. If romfile is missing, BIOS reverts to legacy behavior and starts mapping right after high memory. Signed-off-by: Igor Mammedov imamm...@redhat.com --- v2: * place 64-bit window behind high RAM end if etc/pcimem64-start points below it. Hmm I had an alternative suggestion of passing smbios tables in from QEMU (seabios already has a mechanism for this). We could then simply increase the existing RamSize variable. What do you think about this idea? There is several issues with RamSizeOver4G I see: 1. As Gerd pointed out it is also used to setup a part of e820 tables. It possibly could be also changed see [Qemu-devel] [RfC PATCH] e820: pass high memory too but it will be more complicated to keep seabios backward/forward compatible if we use RamSizeOver4G for passing. What are the compatibility worries, exactly? The way I see it, if QEMU wants to be compatible it can't use memory hotplug. In that case RamSizeOver4G will have the old meaning which should work without issues. QEMU can't know what BIOS version is used and error out in wrong case, and that could cause hard to guess what going wrong bugs in the guest. 2. It doesn't scale if we are going to use more than 1Tb future. Extending RamSizeOver4G value via additional CMOS port wasn't welcomed either, see http://www.seabios.org/pipermail/seabios/2010-September/000911.html It looks like fw_cfg interface is preferred one and etc/pcimem64-start approach doesn't have backward/forward compatibility issues. Hmm but you aren't passing in memory size - pcimem64-start merely tells bios where to put PCI devices. So how would it help? If a lot of memory is reserved for memory hotplug (terabytes), that could put window behind what RamSizeOver4G could address it. All we care about for a compatible bios is that it keep working in old hardware configurations. IMO there's no real need for old BIOS to work with e.g. memory hotplug - it's reasonable to ask users to update fitmware if they want to use this feature. --- src/fw/pciinit.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index b29db99..798309b 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -18,6 +18,8 @@ #include paravirt.h // RamSize #include string.h // memset #include util.h // pci_setup +#include byteorder.h // le64_to_cpu +#include romfile.h // romfile_loadint #define PCI_DEVICE_MEM_MIN 0x1000 #define PCI_BRIDGE_IO_MIN 0x1000 @@ -764,6 +766,15 @@ static void pci_bios_map_devices(struct pci_bus *busses) { if (pci_bios_init_root_regions(busses)) { struct pci_region r64_mem, r64_pref; +u64 ram64_end = 0x1ULL + RamSizeOver4G; +u64 base64 = le64_to_cpu(romfile_loadint(etc/pcimem64-start, + ram64_end)); +if (base64 ram64_end) { +dprintf(1, ignorig etc/pcimem64-start [0x%llx] below present RAM, + placing 64-bit PCI window behind RAM end: %llx, +base64, ram64_end); +base64 = ram64_end; +} r64_mem.list.first = NULL; r64_pref.list.first = NULL; pci_region_migrate_64bit_entries(busses[0].r[PCI_REGION_TYPE_MEM], @@ -779,7 +790,7 @@ static void pci_bios_map_devices(struct pci_bus *busses) u64 align_mem = pci_region_align(r64_mem); u64 align_pref = pci_region_align(r64_pref); -r64_mem.base = ALIGN(0x1LL + RamSizeOver4G, align_mem); +r64_mem.base = ALIGN(base64, align_mem); r64_pref.base = ALIGN(r64_mem.base + sum_mem, align_pref); pcimem64_start = r64_mem.base; pcimem64_end = r64_pref.base + sum_pref; -- 1.8.3.1 -- Regards
Re: [Qemu-devel] [PATCH v9 00/27] qemu: generate acpi tables for the guest
On Mon, Oct 07, 2013 at 12:34:46PM +0300, Michael S. Tsirkin wrote: This code can also be found here: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git acpi No new issues has been raised in a week, I assume it's ok to merge now. Will apply around tomorrow.
Re: [Qemu-devel] [PATCH v2] map 64-bit PCI BARs at location provided by emulator
On Sun, Oct 13, 2013 at 07:33:19PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 19:46:09 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 06:23:28PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 18:59:20 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 05:11:54PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 15:31:23 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 02:13:44PM +0200, Igor Mammedov wrote: Currently 64-bit PCI BARs are unconditionally mapped by BIOS right over 4G + RamSizeOver4G location, which doesn't allow to reserve extra space before 64-bit PCI window. For memory hotplug an extra RAM space might be reserved after present 64-bit RAM end and BIOS should map 64-bit PCI BARs after it. Introduce etc/pcimem64-start romfile to provide BIOS a hint where it should start mapping of 64-bit PCI BARs. If romfile is missing, BIOS reverts to legacy behavior and starts mapping right after high memory. Signed-off-by: Igor Mammedov imamm...@redhat.com --- v2: * place 64-bit window behind high RAM end if etc/pcimem64-start points below it. Hmm I had an alternative suggestion of passing smbios tables in from QEMU (seabios already has a mechanism for this). We could then simply increase the existing RamSize variable. What do you think about this idea? There is several issues with RamSizeOver4G I see: 1. As Gerd pointed out it is also used to setup a part of e820 tables. It possibly could be also changed see [Qemu-devel] [RfC PATCH] e820: pass high memory too but it will be more complicated to keep seabios backward/forward compatible if we use RamSizeOver4G for passing. What are the compatibility worries, exactly? The way I see it, if QEMU wants to be compatible it can't use memory hotplug. In that case RamSizeOver4G will have the old meaning which should work without issues. QEMU can't know what BIOS version is used and error out in wrong case, and that could cause hard to guess what going wrong bugs in the guest. 2. It doesn't scale if we are going to use more than 1Tb future. Extending RamSizeOver4G value via additional CMOS port wasn't welcomed either, see http://www.seabios.org/pipermail/seabios/2010-September/000911.html It looks like fw_cfg interface is preferred one and etc/pcimem64-start approach doesn't have backward/forward compatibility issues. Hmm but you aren't passing in memory size - pcimem64-start merely tells bios where to put PCI devices. So how would it help? If a lot of memory is reserved for memory hotplug (terabytes), that could put window behind what RamSizeOver4G could address it. All we care about for a compatible bios is that it keep working in old hardware configurations. IMO there's no real need for old BIOS to work with e.g. memory hotplug - it's reasonable to ask users to update fitmware if they want to use this feature. Fine with me if we don't care about strange hangs if something misused. But RamSizeOver4G still doesn't allow correctly place PCI window if large amount of memory present/reserved. I'm fine with adding a new fw cfg really. I am however not sure we should have a single new base64 flag. Hardware has a set of ranges where guest can put PCI devices - would we be better off with an interface that lists all these ranges? I'm not saying we should but this needs a bit of thought. --- src/fw/pciinit.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/fw/pciinit.c b/src/fw/pciinit.c index b29db99..798309b 100644 --- a/src/fw/pciinit.c +++ b/src/fw/pciinit.c @@ -18,6 +18,8 @@ #include paravirt.h // RamSize #include string.h // memset #include util.h // pci_setup +#include byteorder.h // le64_to_cpu +#include romfile.h // romfile_loadint #define PCI_DEVICE_MEM_MIN 0x1000 #define PCI_BRIDGE_IO_MIN 0x1000 @@ -764,6 +766,15 @@ static void pci_bios_map_devices(struct pci_bus *busses) { if (pci_bios_init_root_regions(busses)) { struct pci_region r64_mem, r64_pref; +u64 ram64_end = 0x1ULL + RamSizeOver4G; +u64 base64 = le64_to_cpu(romfile_loadint(etc/pcimem64-start, + ram64_end)); +if (base64 ram64_end) { +dprintf(1, ignorig etc/pcimem64-start [0x%llx] below present RAM, + placing 64-bit PCI window behind RAM end: %llx
Re: [Qemu-devel] [PATCH v3 0/4] acpi hotplug of devices behind a pci bridge
On Mon, Oct 07, 2013 at 12:21:26PM +0300, Michael S. Tsirkin wrote: This is on top of patchset generating ACPI tables in qemu. Please review and consider for 1.7. No comments, I assume it's ok to merge this. Changes from v2: - split new code out to a separate file: acpi/pcihp.c this way we can reuse it for q35 later - rebased on top of the latest acpi-build patchset Changes from v1: - fixed some bugs - fixed migration and cross version compatibility - rebased to latest bits This adds support for device hotplug behind pci bridges, by generating ACPI tables describing the current hierarchy. Bridge devices themselves need to be pre-configured on qemu command line. How to use: Describe buses on command line. E.g.: -device pci-bridge,id=bar,chassis_nr=1 -device virtio-net,netdev=bur,addr=0x1,id=far,bus=bar use monitor command for hotplug: device_del far We don't currently use QOM properties to generate this info since: - info about hotpluggability of devices is lacking - we need to list all devices and buses in a predictable order For now, add a pci core function to do the above predictable order walk. This is on top of acpi patchset posted previously. with a small patch adding a core function to walk all pci buses, on top. Can also be found in my git tree git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git acpi-bridges Portability: - Non x86 (or any Linux) platforms don't need any of this code. They can keep happily using SHPC the way they always did. Things to note: - Extensive use of glib completely removes pointer math: we use g_array_append_vals exclusively. - As was the case previously, systems that lack working iasl are detected at configure time, pre-generated hex files in source tree are used in this case. This addresses the concern with iasl/big-endian systems. - Cross version migration: when running with -M 1.6 and older, new hotplug functionality is unavailable. All ACPI table generation is disabled. We present FW_CFG interface compatible with 1.6. Michael S. Tsirkin (4): pci: add pci_for_each_bus_depth_first pcihp: generalization of piix4 acpi piix4: add acpi pci hotplug support acpi-build: enable hotplug for PCI bridges include/hw/acpi/pcihp.h | 72 ++ include/hw/i386/pc.h| 5 + include/hw/pci/pci.h| 14 ++ hw/acpi/pcihp.c | 312 +++ hw/acpi/piix4.c | 75 +-- hw/i386/acpi-build.c| 346 ++-- hw/pci/pci.c| 28 hw/acpi/Makefile.objs | 2 +- hw/i386/acpi-dsdt.dsl | 34 +++-- hw/i386/ssdt-pcihp.dsl | 11 +- 10 files changed, 794 insertions(+), 105 deletions(-) create mode 100644 include/hw/acpi/pcihp.h create mode 100644 hw/acpi/pcihp.c -- MST
Re: [Qemu-devel] [PATCH v2] map 64-bit PCI BARs at location provided by emulator
On Mon, Oct 14, 2013 at 12:27:26PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 23:28:47 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 07:33:19PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 19:46:09 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 06:23:28PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 18:59:20 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 05:11:54PM +0200, Igor Mammedov wrote: On Sun, 13 Oct 2013 15:31:23 +0300 Michael S. Tsirkin m...@redhat.com wrote: On Sun, Oct 13, 2013 at 02:13:44PM +0200, Igor Mammedov wrote: Currently 64-bit PCI BARs are unconditionally mapped by BIOS right over 4G + RamSizeOver4G location, which doesn't allow to reserve extra space before 64-bit PCI window. For memory hotplug an extra RAM space might be reserved after present 64-bit RAM end and BIOS should map 64-bit PCI BARs after it. Introduce etc/pcimem64-start romfile to provide BIOS a hint where it should start mapping of 64-bit PCI BARs. If romfile is missing, BIOS reverts to legacy behavior and starts mapping right after high memory. Signed-off-by: Igor Mammedov imamm...@redhat.com --- v2: * place 64-bit window behind high RAM end if etc/pcimem64-start points below it. Hmm I had an alternative suggestion of passing smbios tables in from QEMU (seabios already has a mechanism for this). We could then simply increase the existing RamSize variable. What do you think about this idea? There is several issues with RamSizeOver4G I see: 1. As Gerd pointed out it is also used to setup a part of e820 tables. It possibly could be also changed see [Qemu-devel] [RfC PATCH] e820: pass high memory too but it will be more complicated to keep seabios backward/forward compatible if we use RamSizeOver4G for passing. What are the compatibility worries, exactly? The way I see it, if QEMU wants to be compatible it can't use memory hotplug. In that case RamSizeOver4G will have the old meaning which should work without issues. QEMU can't know what BIOS version is used and error out in wrong case, and that could cause hard to guess what going wrong bugs in the guest. 2. It doesn't scale if we are going to use more than 1Tb future. Extending RamSizeOver4G value via additional CMOS port wasn't welcomed either, see http://www.seabios.org/pipermail/seabios/2010-September/000911.html It looks like fw_cfg interface is preferred one and etc/pcimem64-start approach doesn't have backward/forward compatibility issues. Hmm but you aren't passing in memory size - pcimem64-start merely tells bios where to put PCI devices. So how would it help? If a lot of memory is reserved for memory hotplug (terabytes), that could put window behind what RamSizeOver4G could address it. All we care about for a compatible bios is that it keep working in old hardware configurations. IMO there's no real need for old BIOS to work with e.g. memory hotplug - it's reasonable to ask users to update fitmware if they want to use this feature. Fine with me if we don't care about strange hangs if something misused. But RamSizeOver4G still doesn't allow correctly place PCI window if large amount of memory present/reserved. I'm fine with adding a new fw cfg really. I am however not sure we should have a single new base64 flag. Hardware has a set of ranges where guest can put PCI devices - would we be better off with an interface that lists all these ranges? I'm not saying we should but this needs a bit of thought. I've offered to reuse your etc/pci-info fw_cfg that were rejected earlier, but it still seems no go: http://permalink.gmane.org/gmane.comp.emulators.qemu/237307 And there is slight difference between PCI holes and PCI address space mappings represented by MemoryRegion-s in QEMU. Basically we only need to inform BIOS where to PCI address spaces start and simple etc/pcimem64-start + etc/pcimem32-start are just fine for that. And for now (memory hotplug) we need only the first one, the second one is very well hardcoded in Seabios/QEMU. Hmm okay but the only reason we want to control this is because it conflicts with memory hotplug, no? I vaguely recall we discussed just passing amount of hot-pluggable memory in, in the past, but I don't remember the reason we decided against it. Could you refresh my memory? It's less
Re: [Qemu-devel] [PATCH v2] map 64-bit PCI BARs at location provided by emulator
On Mon, Oct 14, 2013 at 02:16:23PM +0200, Gerd Hoffmann wrote: Hi, And there is slight difference between PCI holes and PCI address space mappings represented by MemoryRegion-s in QEMU. Basically we only need to inform BIOS where to PCI address spaces start and simple etc/pcimem64-start + etc/pcimem32-start are just fine for that. And for now (memory hotplug) we need only the first one, the second one is very well hardcoded in Seabios/QEMU. Yes, 32bit hole is basically the [ end-of-memory - ioapic ] range. Can't see any reason to make that configurable, it is quite unlikely that this ever changes. For the 64bit window it makes sense to configure it, to give qemu a little more control about the address space layout. Hmm okay but the only reason we want to control this is because it conflicts with memory hotplug, no? I vaguely recall we discussed just passing amount of hot-pluggable memory in, in the past, but I don't remember the reason we decided against it. Could you refresh my memory? To me it makes more sense to just go the direct route and say please put the 64bit bars at this location rather than indirect we might want hotplug $thatmuch memory and then expect the bios to leave that much room. Only if the newfeature address is not under bios control. I know that bios is simplistic so all it cares about ATM is pci window, but can't shake the impression that we are better off telling the guest what's going on rather than what it should do. In particular the issue that was discussed (what to do if pci start is set by host to below ram end) will simply go away if we pass in an incremental value: there will be no invalid configurations. If we ever want reserve more address space for other reasons it'll be easier with the direct variant as the bios doesn't need to be aware that we'll need some address space for $newfeature too. We can call it reserved memory space rather than hotplug memory if you prefer. A more flexible approach would be a separate table (like e820 table, but only for PCI ranges), but it seems a bit of overkill for now (I can't picture a need for more than 2 PCI address space mappings). It's not unthinkable. Multiple ECAM regions (for multi-root systems) can make holes in the address space. Sounds pretty theoretic ... What? Multiple PCI roots? Also, we just ignore everything above the ioapic, but that's not a must, we could maybe use address space above ioapic. Any reason why we should that? cheers, Gerd 32 bit address space is contrained, using it is preferable for 32 bit guests ...
Re: [Qemu-devel] [PATCH v2] map 64-bit PCI BARs at location provided by emulator
On Mon, Oct 14, 2013 at 03:04:45PM +0200, Gerd Hoffmann wrote: Hi, To me it makes more sense to just go the direct route and say please put the 64bit bars at this location rather than indirect we might want hotplug $thatmuch memory and then expect the bios to leave that much room. Only if the newfeature address is not under bios control. I know that bios is simplistic so all it cares about ATM is pci window, but can't shake the impression that we are better off telling the guest what's going on rather than what it should do. In particular the issue that was discussed (what to do if pci start is set by host to below ram end) will simply go away if we pass in an incremental value: there will be no invalid configurations. The what is going on might need updates in both qemu and seabios if something new goes on. For example qemu getting support non-contignous memory. The leave that much address space free above memory suddenly is ambiguous as there are two (or more) memory blocks above 4g. please place 64bit pci bars there continues to work just fine. Yes but at the cost of overspecifying it. I think it's down to the name: it's called pcimem64-start but it can actually be less than 4G and we need to worry what to do then. Also, 64 doesn't really mean 4G. So how about reserve-memory-over-4g? bios then does 1ull 32 + reserve-memory-over-4g to figure out how much to skip. It's not unthinkable. Multiple ECAM regions (for multi-root systems) can make holes in the address space. Sounds pretty theoretic ... What? Multiple PCI roots? That we'll need pass multiple pci windows because of that. I expect we'll need seabios support for the new multi-root hardware anyway, and seabios will probably be aware of the hardware constrains then ... Also as far I know nobody is working on such a chipset. I simply wouldn't worry about that today. Designing a interface when you don't know the exact needs for the it has a high chance to go wrong. Well you were the one that asked about that :) Also, we just ignore everything above the ioapic, but that's not a must, we could maybe use address space above ioapic. Any reason why we should that? 32 bit address space is contrained, using it is preferable for 32 bit guests ... This wouldn't help in the cases I've seen in practice. We have no problems at all to fit in mmio pci bars, even lots of them, they are small enough. We can run out of address space if we have pci devices with larger chunks of memory on them, such as qxl or ivshmem. And these memory bars are too big to fit into any of the small holes above the ioapic. cheers, Gerd
[Qemu-devel] qemu master build errors
/scm/qemu/exec.c:720:51: error: initialization from incompatible pointer type [-Werror] static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc; ^ /scm/qemu/exec.c: In function ‘qemu_ram_alloc_from_ptr’: /scm/qemu/exec.c:1107:32: error: comparison of distinct pointer types lacks a cast [-Werror] if (phys_mem_alloc != qemu_anon_ram_alloc) { ^ /scm/qemu/exec.c: In function ‘qemu_ram_remap’: /scm/qemu/exec.c:1251:38: error: comparison of distinct pointer types lacks a cast [-Werror] assert(phys_mem_alloc == qemu_anon_ram_alloc); ^ cc1: all warnings being treated as errors make[1]: *** [exec.o] Error 1 make: *** [subdir-cris-softmmu] Error 2 make: *** Waiting for unfinished jobs CCarm-softmmu/translate-all.o /scm/qemu/exec.c:720:51: error: initialization from incompatible pointer type [-Werror] static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc; ^ /scm/qemu/exec.c: In function ‘qemu_ram_alloc_from_ptr’: /scm/qemu/exec.c:1107:32: error: comparison of distinct pointer types lacks a cast [-Werror] if (phys_mem_alloc != qemu_anon_ram_alloc) { ^ /scm/qemu/exec.c: In function ‘qemu_ram_remap’: /scm/qemu/exec.c:1251:38: error: comparison of distinct pointer types lacks a cast [-Werror] assert(phys_mem_alloc == qemu_anon_ram_alloc); ^ cc1: all warnings being treated as errors make[1]: *** [exec.o] Error 1 make: *** [subdir-alpha-softmmu] Error 2 CCarm-softmmu/cpu-exec.o CCarm-softmmu/tcg/tcg.o /scm/qemu/exec.c:720:51: error: initialization from incompatible pointer type [-Werror] static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc; ^ /scm/qemu/exec.c: In function ‘qemu_ram_alloc_from_ptr’: /scm/qemu/exec.c:1107:32: error: comparison of distinct pointer types lacks a cast [-Werror] if (phys_mem_alloc != qemu_anon_ram_alloc) { ^ /scm/qemu/exec.c: In function ‘qemu_ram_remap’: /scm/qemu/exec.c:1251:38: error: comparison of distinct pointer types lacks a cast [-Werror] assert(phys_mem_alloc == qemu_anon_ram_alloc); ^ cc1: all warnings being treated as errors make[1]: *** [exec.o] Error 1 make[1]: *** Waiting for unfinished jobs CCi386-softmmu/translate-all.o /scm/qemu/exec.c:720:51: error: initialization from incompatible pointer type [-Werror] static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc; ^ /scm/qemu/exec.c: In function ‘qemu_ram_alloc_from_ptr’: /scm/qemu/exec.c:1107:32: error: comparison of distinct pointer types lacks a cast [-Werror] if (phys_mem_alloc != qemu_anon_ram_alloc) { ^ /scm/qemu/exec.c: In function ‘qemu_ram_remap’: /scm/qemu/exec.c:1251:38: error: comparison of distinct pointer types lacks a cast [-Werror] assert(phys_mem_alloc == qemu_anon_ram_alloc); ^ cc1: all warnings being treated as errors
Re: [Qemu-devel] [PATCH v6 2/5] hpet: enable to entitle more irq pins for hpet
On Fri, Oct 11, 2013 at 05:18:30PM +0800, liu ping fan wrote: On Fri, Oct 11, 2013 at 4:38 PM, Paolo Bonzini pbonz...@redhat.com wrote: Il 11/10/2013 04:59, liu ping fan ha scritto: On Thu, Oct 10, 2013 at 7:41 PM, Michael S. Tsirkin m...@redhat.com wrote: On Thu, Oct 10, 2013 at 11:46:42AM +0200, Paolo Bonzini wrote: Il 10/10/2013 11:41, Michael S. Tsirkin ha scritto: Are you sure? This is not done for any other compat property. Paolo It's done if we use the property from C. See PCI_HOST_PROP_PCI_HOLE64_SIZE. You want compiler to catch errors, that's much better than a runtime failure. I agree, but I think there should be no need to use the property from C. Paolo Well this patchset does use it from C. If it's done it needs a macro. hpet.h is the ideal place to put the macro, so pc.c can see it. But what about PC_COMPAT_1_7 in pc.h? I think it is not right to include hpet.h. So can I do not use marco in pc.h? I think you shouldn't need the macro (no need to use the property from C, only from compat properties). We need to tell the compat and then decide to set intcap in pc_basic_device_init() uint8_t compat = object_property_get_int(OBJECT(hpet), intcap, NULL); if (!compat) { qdev_prop_set_uint32(hpet, intcap, 0xff0104); } Regards, Ping Fan So if you use it from C, please use a macro. If not, no need to.
Re: [Qemu-devel] [PATCH v6 2/5] hpet: enable to entitle more irq pins for hpet
On Fri, Oct 11, 2013 at 10:59:40AM +0800, liu ping fan wrote: On Thu, Oct 10, 2013 at 7:41 PM, Michael S. Tsirkin m...@redhat.com wrote: On Thu, Oct 10, 2013 at 11:46:42AM +0200, Paolo Bonzini wrote: Il 10/10/2013 11:41, Michael S. Tsirkin ha scritto: Are you sure? This is not done for any other compat property. Paolo It's done if we use the property from C. See PCI_HOST_PROP_PCI_HOLE64_SIZE. You want compiler to catch errors, that's much better than a runtime failure. I agree, but I think there should be no need to use the property from C. Paolo Well this patchset does use it from C. If it's done it needs a macro. hpet.h is the ideal place to put the macro, so pc.c can see it. But what about PC_COMPAT_1_7 in pc.h? I think it is not right to include hpet.h. Why not? So can I do not use marco in pc.h? Thanks and regards, Ping Fan
Re: [Qemu-devel] qemu master build errors
On Mon, Oct 14, 2013 at 05:08:58PM +0300, Michael S. Tsirkin wrote: /scm/qemu/exec.c:720:51: error: initialization from incompatible pointer type [-Werror] static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc; ^ /scm/qemu/exec.c: In function ‘qemu_ram_alloc_from_ptr’: /scm/qemu/exec.c:1107:32: error: comparison of distinct pointer types lacks a cast [-Werror] if (phys_mem_alloc != qemu_anon_ram_alloc) { ^ It could have to do with the fact build is done on a 32 bit machine.
Re: [Qemu-devel] [PATCH] exec: Fix prototype of phys_mem_set_alloc and related functions
On Sun, Sep 29, 2013 at 08:56:45PM +0200, Stefan Weil wrote: phys_mem_alloc and its assigned values qemu_anon_ram_alloc and legacy_s390_alloc must have identical argument lists. legacy_s390_alloc uses the size parameter to call mmap, so size_t is good enough for all of them. This patch fixes compiler errors on i686 Linux hosts: CCalpha-softmmu/exec.o exec.c:752:51: error: initialization from incompatible pointer type [-Werror] exec.c: In function 'qemu_ram_alloc_from_ptr': exec.c:1139:32: error: comparison of distinct pointer types lacks a cast [-Werror] exec.c: In function 'qemu_ram_remap': exec.c:1283:21: error: comparison of distinct pointer types lacks a cast [-Werror] Signed-off-by: Stefan Weil s...@weilnetz.de Fixes build on 32 build boxes. Reviewed-by: Michael S. Tsirkin m...@redhat.com Tested-by: Michael S. Tsirkin m...@redhat.com Anthony could you apply this quickly? Broken builds are annoying ... --- exec.c |4 ++-- include/exec/exec-all.h |2 +- target-s390x/kvm.c |4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/exec.c b/exec.c index 26681ce..1a08115 100644 --- a/exec.c +++ b/exec.c @@ -749,14 +749,14 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, uint16_t section); static subpage_t *subpage_init(AddressSpace *as, hwaddr base); -static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc; +static void *(*phys_mem_alloc)(size_t size) = qemu_anon_ram_alloc; /* * Set a custom physical guest memory alloator. * Accelerators with unusual needs may need this. Hopefully, we can * get rid of it eventually. */ -void phys_mem_set_alloc(void *(*alloc)(ram_addr_t)) +void phys_mem_set_alloc(void *(*alloc)(size_t)) { phys_mem_alloc = alloc; } diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 77242e2..50ecfd4 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -368,7 +368,7 @@ static inline uintptr_t tcg_getra_ext(uintptr_t ra) #if !defined(CONFIG_USER_ONLY) -void phys_mem_set_alloc(void *(*alloc)(ram_addr_t)); +void phys_mem_set_alloc(void *(*alloc)(size_t)); struct MemoryRegion *iotlb_to_region(hwaddr index); bool io_mem_read(struct MemoryRegion *mr, hwaddr addr, diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 4923e0a..d229bdf 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -93,7 +93,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { static int cap_sync_regs; -static void *legacy_s390_alloc(ram_addr_t size); +static void *legacy_s390_alloc(size_t size); int kvm_arch_init(KVMState *s) { @@ -325,7 +325,7 @@ int kvm_s390_get_registers_partial(CPUState *cs) * to grow. We also have to use MAP parameters that avoid * read-only mapping of guest pages. */ -static void *legacy_s390_alloc(ram_addr_t size) +static void *legacy_s390_alloc(size_t size) { void *mem; -- 1.7.10.4
Re: [Qemu-devel] qemu master build errors
On Mon, Oct 14, 2013 at 04:38:22PM +0200, Markus Armbruster wrote: Michael S. Tsirkin m...@redhat.com writes: /scm/qemu/exec.c:720:51: error: initialization from incompatible pointer type [-Werror] static void *(*phys_mem_alloc)(ram_addr_t size) = qemu_anon_ram_alloc; ^ /scm/qemu/exec.c: In function ‘qemu_ram_alloc_from_ptr’: /scm/qemu/exec.c:1107:32: error: comparison of distinct pointer types lacks a cast [-Werror] if (phys_mem_alloc != qemu_anon_ram_alloc) { ^ /scm/qemu/exec.c: In function ‘qemu_ram_remap’: /scm/qemu/exec.c:1251:38: error: comparison of distinct pointer types lacks a cast [-Werror] assert(phys_mem_alloc == qemu_anon_ram_alloc); ^ cc1: all warnings being treated as errors make[1]: *** [exec.o] Error 1 [...] Fix has been on list for a while: https://lists.nongnu.org/archive/html/qemu-devel/2013-09/msg04685.html Well who's picking it up?
[Qemu-devel] [PULL 04/43] hw/core: Add interface to allocate and free a single IRQ
From: Marcel Apfelbaum marce...@redhat.com qemu_allocate_irq returns a single qemu_irq. The interface allows to specify an interrupt number. qemu_free_irq frees it. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/irq.h | 7 +++ hw/core/irq.c| 16 2 files changed, 23 insertions(+) diff --git a/include/hw/irq.h b/include/hw/irq.h index 610e6b7..d08bc02 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/hw/core/irq.c b/hw/core/irq.c index 2078542..03c8cb3 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c @@ -68,6 +68,17 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n) return qemu_extend_irqs(NULL, 0, handler, opaque, n); } +qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n) +{ +struct IRQState *irq; + +irq = g_new(struct IRQState, 1); +irq-handler = handler; +irq-opaque = opaque; +irq-n = n; + +return irq; +} void qemu_free_irqs(qemu_irq *s) { @@ -75,6 +86,11 @@ void qemu_free_irqs(qemu_irq *s) g_free(s); } +void qemu_free_irq(qemu_irq irq) +{ +g_free(irq); +} + static void qemu_notirq(void *opaque, int line, int level) { struct IRQState *irq = opaque; -- MST
[Qemu-devel] [PULL 01/43] memory: Change MemoryRegion priorities from unsigned to signed
From: Marcel Apfelbaum marce...@redhat.com When memory regions overlap, priority can be used to specify which of them takes priority. By making the priority values signed rather than unsigned, we make it more convenient to implement a situation where one background region should appear only where no other region exists: rather than having to explicitly specify a high priority for all the other regions, we can let them take the default (zero) priority and specify a negative priority for the background region. Reviewed-by: Peter Maydell peter.mayd...@linaro.org Acked-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/exec/memory.h | 4 ++-- include/hw/sysbus.h | 2 +- hw/core/sysbus.c | 4 ++-- memory.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index ebe0d24..480dfbf 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -153,7 +153,7 @@ struct MemoryRegion { bool flush_coalesced_mmio; MemoryRegion *alias; hwaddr alias_offset; -unsigned priority; +int priority; bool may_overlap; QTAILQ_HEAD(subregions, MemoryRegion) subregions; QTAILQ_ENTRY(MemoryRegion) subregions_link; @@ -779,7 +779,7 @@ void memory_region_add_subregion(MemoryRegion *mr, void memory_region_add_subregion_overlap(MemoryRegion *mr, hwaddr offset, MemoryRegion *subregion, - unsigned priority); + int priority); /** * memory_region_get_ram_addr: Get the ram address associated with a memory diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index bb50a87..f5aaa05 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/hw/core/sysbus.c b/hw/core/sysbus.c index b84cd4a..146f50a 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -49,7 +49,7 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) } static void sysbus_mmio_map_common(SysBusDevice *dev, int n, hwaddr addr, - bool may_overlap, unsigned priority) + bool may_overlap, int priority) { assert(n = 0 n dev-num_mmio); @@ -81,7 +81,7 @@ 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) { sysbus_mmio_map_common(dev, n, addr, true, priority); } diff --git a/memory.c b/memory.c index 5a10fd0..f49d31a 100644 --- a/memory.c +++ b/memory.c @@ -1473,7 +1473,7 @@ void memory_region_add_subregion(MemoryRegion *mr, void memory_region_add_subregion_overlap(MemoryRegion *mr, hwaddr offset, MemoryRegion *subregion, - unsigned priority) + int priority) { subregion-may_overlap = true; subregion-priority = priority; @@ -1506,7 +1506,7 @@ void memory_region_set_enabled(MemoryRegion *mr, bool enabled) void memory_region_set_address(MemoryRegion *mr, hwaddr addr) { MemoryRegion *parent = mr-parent; -unsigned priority = mr-priority; +int priority = mr-priority; bool may_overlap = mr-may_overlap; if (addr == mr-addr || !parent) { -- MST
[Qemu-devel] [PULL 03/43] hw/pci: partially handle pci master abort
From: Marcel Apfelbaum marce...@redhat.com A MemoryRegion with negative priority was created and it spans over all the pci address space. It intercepts the accesses to unassigned pci address space and will follow the pci spec: 1. returns -1 on read 2. does nothing on write Note: setting the RECEIVED MASTER ABORT bit in the STATUS register of the device that initiated the transaction will be implemented in another series Signed-off-by: Marcel Apfelbaum marce...@redhat.com Acked-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pci_bus.h | 1 + hw/pci/pci.c | 26 ++ 2 files changed, 27 insertions(+) diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index 9df1788..2ad5edb 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -23,6 +23,7 @@ struct PCIBus { PCIDevice *parent_dev; MemoryRegion *address_space_mem; MemoryRegion *address_space_io; +MemoryRegion master_abort_mem; QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */ QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */ diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 00554a0..25626b8 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -283,6 +283,24 @@ const char *pci_root_bus_path(PCIDevice *dev) return rootbus-qbus.name; } +static uint64_t master_abort_mem_read(void *opaque, hwaddr addr, unsigned size) +{ + return -1ULL; +} + +static void master_abort_mem_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ +} + +static const MemoryRegionOps master_abort_mem_ops = { +.read = master_abort_mem_read, +.write = master_abort_mem_write, +.endianness = DEVICE_LITTLE_ENDIAN, +}; + +#define MASTER_ABORT_MEM_PRIORITY INT_MIN + static void pci_bus_init(PCIBus *bus, DeviceState *parent, const char *name, MemoryRegion *address_space_mem, @@ -294,6 +312,14 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent, bus-address_space_mem = address_space_mem; bus-address_space_io = address_space_io; + +memory_region_init_io(bus-master_abort_mem, OBJECT(bus), + master_abort_mem_ops, bus, pci-master-abort, + memory_region_size(bus-address_space_mem)); +memory_region_add_subregion_overlap(bus-address_space_mem, +0, bus-master_abort_mem, +MASTER_ABORT_MEM_PRIORITY); + /* host bridge */ QLIST_INIT(bus-child); -- MST
[Qemu-devel] [PULL 00/43] pci, pc, acpi fixes, enhancements
Anthony, I know you wanted to review some of the patches, since you didn't respond either all's well or you could not find the time. I think we are better off merging them for 1.7 and then - worst case, if major issues surface - disabling the functionality at the last minute than delaying the merge even more. The following changes since commit e26d3e734650640fabd7d95ace4f3a6f88725e0b: smbios: Factor out smbios_maybe_add_str() (2013-09-28 23:49:39 +0300) are available in the git repository at: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_anthony for you to fetch changes up to 6cab1e721fa6a487f67e1dba986f68fee30d: acpi-build: enable hotplug for PCI bridges (2013-10-14 17:48:58 +0300) pci, pc, acpi fixes, enhancements This includes some pretty big changes: - pci master abort support by Marcel - pci IRQ API rework by Marcel - acpi generation and pci bridge hotplug support by myself Everything has gone through several revisions, latest versions have been on list for a while without any more comments, tested by several people. Please pull for 1.7. Signed-off-by: Michael S. Tsirkin m...@redhat.com Igor Mammedov (1): cleanup object.h: include error.h directly Marcel Apfelbaum (11): memory: Change MemoryRegion priorities from unsigned to signed docs/memory: Explictly state that MemoryRegion priority is signed hw/pci: partially handle pci master abort hw/core: Add interface to allocate and free a single IRQ hw/pci: add pci wrappers for allocating and asserting irqs hw/pci-bridge: set PCI_INTERRUPT_PIN register before shpc init hw/vmxnet3: set interrupts using pci irq wrappers hw/vfio: set interrupts using pci irq wrappers hw: set interrupts using pci irq wrappers hw/pcie: AER and hot-plug events must use device's interrupt hw/pci: removed irq field from PCIDevice Michael S. Tsirkin (31): qom: cleanup struct Error references qom: add pointer to int property helpers pci: fix up w64 size calculation helper fw_cfg: interface to trigger callback on read loader: support for unmapped ROM blobs pcie_host: expose UNMAPPED macro pcie_host: expose address format q35: use macro for MCFG property name q35: expose mmcfg size as a property i386: add ACPI table files from seabios acpi: add rules to compile ASL source acpi: pre-compiled ASL files acpi: ssdt pcihp: updat generated file loader: use file path size from fw_cfg.h i386: add bios linker/loader loader: allow adding ROMs in done callbacks i386: define pc guest info acpi/piix: add macros for acpi property names piix: APIs for pc guest info ich9: APIs for pc guest info pvpanic: add API to access io port hpet: add API to find it acpi: add interface to access user-installed tables pc: use new api to add builtin tables i386: ACPI table generation code from seabios ssdt: fix PBLK length ssdt-proc: update generated file pci: add pci_for_each_bus_depth_first pcihp: generalization of piix4 acpi piix4: add acpi pci hotplug support acpi-build: enable hotplug for PCI bridges configure |9 +- hw/i386/acpi-build.h|9 + hw/i386/acpi-defs.h | 331 ++ hw/i386/bios-linker-loader.h| 27 + hw/lm32/lm32_hwsetup.h |2 +- include/exec/memory.h |4 +- include/hw/acpi/acpi.h |4 + include/hw/acpi/ich9.h |2 + include/hw/acpi/pcihp.h | 72 + include/hw/acpi/piix4.h |8 + include/hw/i386/ich9.h |2 + include/hw/i386/pc.h| 27 + include/hw/irq.h|7 + include/hw/loader.h |8 +- include/hw/nvram/fw_cfg.h |8 +- include/hw/pci-host/q35.h |2 + include/hw/pci/pci.h| 40 +- include/hw/pci/pci_bus.h|1 + include/hw/pci/pcie.h | 18 - include/hw/pci/pcie_host.h | 27 + include/hw/sysbus.h |2 +- include/hw/timer/hpet.h |2 + include/qom/object.h| 73 +- hw/acpi/core.c | 40 + hw/acpi/ich9.c | 24 + hw/acpi/pcihp.c | 312 ++ hw/acpi/piix4.c | 125 +- hw/audio/ac97.c |4 +- hw/audio/es1370.c |4 +- hw/audio/intel-hda.c|2 +- hw/block/nvme.c |2 +- hw/char/serial-pci.c|5 +- hw/char/tpci200.c |8 +- hw/core/irq.c | 16 + hw/core/loader.c
[Qemu-devel] [PULL 02/43] docs/memory: Explictly state that MemoryRegion priority is signed
From: Marcel Apfelbaum marce...@redhat.com When memory regions overlap, priority can be used to specify which of them takes priority. By making the priority values signed rather than unsigned, we make it more convenient to implement a situation where one background region should appear only where no other region exists: rather than having to explicitly specify a high priority for all the other regions, we can let them take the default (zero) priority and specify a negative priority for the background region. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Acked-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- docs/memory.txt | 4 1 file changed, 4 insertions(+) diff --git a/docs/memory.txt b/docs/memory.txt index feb9fe9..174c0d7 100644 --- a/docs/memory.txt +++ b/docs/memory.txt @@ -80,6 +80,10 @@ guest. This is done with memory_region_add_subregion_overlap(), which allows the region to overlap any other region in the same container, and specifies a priority that allows the core to decide which of two regions at the same address are visible (highest wins). +Priority values are signed, and the default value is zero. This means that +you can use memory_region_add_subregion_overlap() both to specify a region +that must sit 'above' any others (with a positive priority) and also a +background region that sits 'below' others (with a negative priority). Visibility -- -- MST
[Qemu-devel] [PULL 08/43] hw/vfio: set interrupts using pci irq wrappers
From: Marcel Apfelbaum marce...@redhat.com pci_set_irq and the other pci irq wrappers use PCI_INTERRUPT_PIN config register to compute device INTx pin to assert/deassert. save INTX pin into the config register before calling pci_set_irq Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/misc/vfio.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index a1c08fb..9d02e49 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -297,7 +297,7 @@ static void vfio_intx_interrupt(void *opaque) 'A' + vdev-intx.pin); vdev-intx.pending = true; -qemu_set_irq(vdev-pdev.irq[vdev-intx.pin], 1); +pci_irq_assert(vdev-pdev); vfio_mmap_set_enabled(vdev, false); if (vdev-intx.mmap_timeout) { timer_mod(vdev-intx.mmap_timer, @@ -315,7 +315,7 @@ static void vfio_eoi(VFIODevice *vdev) vdev-host.bus, vdev-host.slot, vdev-host.function); vdev-intx.pending = false; -qemu_set_irq(vdev-pdev.irq[vdev-intx.pin], 0); +pci_irq_deassert(vdev-pdev); vfio_unmask_intx(vdev); } @@ -341,7 +341,7 @@ static void vfio_enable_intx_kvm(VFIODevice *vdev) qemu_set_fd_handler(irqfd.fd, NULL, NULL, vdev); vfio_mask_intx(vdev); vdev-intx.pending = false; -qemu_set_irq(vdev-pdev.irq[vdev-intx.pin], 0); +pci_irq_deassert(vdev-pdev); /* Get an eventfd for resample/unmask */ if (event_notifier_init(vdev-intx.unmask, 0)) { @@ -417,7 +417,7 @@ static void vfio_disable_intx_kvm(VFIODevice *vdev) */ vfio_mask_intx(vdev); vdev-intx.pending = false; -qemu_set_irq(vdev-pdev.irq[vdev-intx.pin], 0); +pci_irq_deassert(vdev-pdev); /* Tell KVM to stop listening for an INTx irqfd */ if (kvm_vm_ioctl(kvm_state, KVM_IRQFD, irqfd)) { @@ -488,6 +488,7 @@ static int vfio_enable_intx(VFIODevice *vdev) vfio_disable_interrupts(vdev); vdev-intx.pin = pin - 1; /* Pin A (1) - irq[0] */ +pci_config_set_interrupt_pin(vdev-pdev.config, pin); #ifdef CONFIG_KVM /* @@ -547,7 +548,7 @@ static void vfio_disable_intx(VFIODevice *vdev) vfio_disable_intx_kvm(vdev); vfio_disable_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX); vdev-intx.pending = false; -qemu_set_irq(vdev-pdev.irq[vdev-intx.pin], 0); +pci_irq_deassert(vdev-pdev); vfio_mmap_set_enabled(vdev, true); fd = event_notifier_get_fd(vdev-intx.interrupt); -- MST
[Qemu-devel] [PULL 05/43] hw/pci: add pci wrappers for allocating and asserting irqs
From: Marcel Apfelbaum marce...@redhat.com Interrupt pin is selected and saved into PCI_INTERRUPT_PIN register during device initialization. Devices should not call directly qemu_set_irq and specify the INTx pin on each call. Added pci_* wrappers to replace qemu_set_irq, qemu_irq_raise, qemu_irq_lower and qemu_irq_pulse, setting the irq based on PCI_INTERRUPT_PIN. Added pci_allocate_irq wrapper to be used by devices that still need PCIDevice infrastructure to assert irqs. Renamed a static method which was named already pci_set_irq. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pci.h | 23 +++ hw/pci/pci.c | 26 ++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 4b90e5d..990342c 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -632,6 +632,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/hw/pci/pci.c b/hw/pci/pci.c index 25626b8..ff4b697 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -83,7 +83,7 @@ static const TypeInfo pcie_bus_info = { static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num); static void pci_update_mappings(PCIDevice *d); -static void pci_set_irq(void *opaque, int irq_num, int level); +static void pci_irq_handler(void *opaque, int irq_num, int level); static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom); static void pci_del_option_rom(PCIDevice *pdev); @@ -161,7 +161,7 @@ void pci_device_deassert_intx(PCIDevice *dev) { int i; for (i = 0; i PCI_NUM_PINS; ++i) { -qemu_set_irq(dev-irq[i], 0); +pci_irq_handler(dev, i, 0); } } @@ -889,7 +889,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, pci_dev-config_read = config_read; pci_dev-config_write = config_write; bus-devices[devfn] = pci_dev; -pci_dev-irq = qemu_allocate_irqs(pci_set_irq, pci_dev, PCI_NUM_PINS); +pci_dev-irq = qemu_allocate_irqs(pci_irq_handler, pci_dev, PCI_NUM_PINS); pci_dev-version_id = 2; /* Current pci device vmstate version */ return pci_dev; } @@ -1201,7 +1201,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) /* generic PCI irq support */ /* 0 = irq_num = 3. level must be 0 or 1 */ -static void pci_set_irq(void *opaque, int irq_num, int level) +static void pci_irq_handler(void *opaque, int irq_num, int level) { PCIDevice *pci_dev = opaque; int change; @@ -1217,6 +1217,24 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_change_irq_level(pci_dev, irq_num, change); } +static inline int pci_intx(PCIDevice *pci_dev) +{ +return pci_get_byte(pci_dev-config + PCI_INTERRUPT_PIN) - 1; +} + +qemu_irq pci_allocate_irq(PCIDevice *pci_dev) +{ +int intx = pci_intx(pci_dev); + +return qemu_allocate_irq(pci_irq_handler, pci_dev, intx); +} + +void pci_set_irq(PCIDevice *pci_dev, int level) +{ +int intx = pci_intx(pci_dev); +pci_irq_handler(pci_dev, intx, level); +} + /* Special hooks used by device assignment */ void pci_bus_set_route_irq_fn(PCIBus *bus, pci_route_irq_fn route_intx_to_irq) { -- MST
[Qemu-devel] [PULL 09/43] hw: set interrupts using pci irq wrappers
From: Marcel Apfelbaum marce...@redhat.com pci_set_irq and the other pci irq wrappers use PCI_INTERRUPT_PIN config register to compute device INTx pin to assert/deassert. An irq is allocated using pci_allocate_irq wrapper only if is needed by non pci devices. Removed irq related fields from state if not used anymore. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/audio/ac97.c| 4 ++-- hw/audio/es1370.c | 4 ++-- hw/audio/intel-hda.c | 2 +- hw/block/nvme.c| 2 +- hw/char/serial-pci.c | 5 +++-- hw/char/tpci200.c | 8 hw/display/qxl.c | 2 +- hw/ide/cmd646.c| 2 +- hw/ide/ich.c | 3 ++- hw/isa/vt82c686.c | 2 +- hw/misc/ivshmem.c | 2 +- hw/net/e1000.c | 2 +- hw/net/eepro100.c | 4 ++-- hw/net/ne2000.c| 3 ++- hw/net/pcnet-pci.c | 3 ++- hw/net/rtl8139.c | 2 +- hw/pci/shpc.c | 2 +- hw/scsi/esp-pci.c | 3 ++- hw/scsi/lsi53c895a.c | 2 +- hw/scsi/megasas.c | 6 +++--- hw/scsi/vmw_pvscsi.c | 2 +- hw/usb/hcd-ehci-pci.c | 2 +- hw/usb/hcd-ohci.c | 2 +- hw/usb/hcd-uhci.c | 6 ++ hw/usb/hcd-xhci.c | 7 ++- hw/virtio/virtio-pci.c | 4 ++-- 26 files changed, 43 insertions(+), 43 deletions(-) diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index 01b4dfb..03f4846 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -280,12 +280,12 @@ static void update_sr (AC97LinkState *s, AC97BusMasterRegs *r, uint32_t new_sr) if (level) { s-glob_sta |= masks[r - s-bm_regs]; dolog (set irq level=1\n); -qemu_set_irq (s-dev.irq[0], 1); +pci_irq_assert(s-dev); } else { s-glob_sta = ~masks[r - s-bm_regs]; dolog (set irq level=0\n); -qemu_set_irq (s-dev.irq[0], 0); +pci_irq_deassert(s-dev); } } diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index adb66ce..1ec7ace 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -323,7 +323,7 @@ static void es1370_update_status (ES1370State *s, uint32_t new_status) else { s-status = new_status ~STAT_INTR; } -qemu_set_irq (s-dev.irq[0], !!level); +pci_set_irq(s-dev, !!level); } static void es1370_reset (ES1370State *s) @@ -349,7 +349,7 @@ static void es1370_reset (ES1370State *s) s-dac_voice[i] = NULL; } } -qemu_irq_lower (s-dev.irq[0]); +pci_irq_deassert(s-dev); } static void es1370_maybe_lower_irq (ES1370State *s, uint32_t sctl) diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index ac6..4327264 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -269,7 +269,7 @@ static void intel_hda_update_irq(IntelHDAState *d) msi_notify(d-pci, 0); } } else { -qemu_set_irq(d-pci.irq[0], level); +pci_set_irq(d-pci, level); } } diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 5dee229..2882ffe 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -69,7 +69,7 @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq) if (msix_enabled((n-parent_obj))) { msix_notify((n-parent_obj), cq-vector); } else { -qemu_irq_pulse(n-parent_obj.irq[0]); +pci_irq_pulse(n-parent_obj); } } } diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index aec6705..991c99f 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -61,7 +61,7 @@ static int serial_pci_init(PCIDevice *dev) } pci-dev.config[PCI_INTERRUPT_PIN] = 0x01; -s-irq = pci-dev.irq[0]; +s-irq = pci_allocate_irq(pci-dev); memory_region_init_io(s-io, OBJECT(pci), serial_io_ops, s, serial, 8); pci_register_bar(pci-dev, 0, PCI_BASE_ADDRESS_SPACE_IO, s-io); @@ -79,7 +79,7 @@ static void multi_serial_irq_mux(void *opaque, int n, int level) pending = 1; } } -qemu_set_irq(pci-dev.irq[0], pending); +pci_set_irq(pci-dev, pending); } static int multi_serial_pci_init(PCIDevice *dev) @@ -132,6 +132,7 @@ static void serial_pci_exit(PCIDevice *dev) serial_exit_core(s); memory_region_destroy(s-io); +qemu_free_irq(s-irq); } static void multi_serial_pci_exit(PCIDevice *dev) diff --git a/hw/char/tpci200.c b/hw/char/tpci200.c index e04ff26..a49d2ed 100644 --- a/hw/char/tpci200.c +++ b/hw/char/tpci200.c @@ -134,8 +134,8 @@ static void tpci200_set_irq(void *opaque, int intno, int level) /* Check if the interrupt is edge sensitive */ if (dev-ctrl[ip_n] CTRL_INT_EDGE(intno)) { if (level) { -qemu_set_irq(dev-dev.irq[0], !dev-int_set); -qemu_set_irq(dev-dev.irq[0], dev-int_set); +pci_set_irq(dev-dev, !dev-int_set); +pci_set_irq(dev-dev, dev-int_set); } } else { unsigned i, j; @@ -153,10 +153,10 @@ static void tpci200_set_irq(void *opaque, int intno, int level
[Qemu-devel] [PULL 07/43] hw/vmxnet3: set interrupts using pci irq wrappers
From: Marcel Apfelbaum marce...@redhat.com pci_set_irq uses PCI_INTERRUPT_PIN config register to compute device INTx pin to assert/deassert. An assert is used to ensure that intx received from the quest OS corresponds to PCI_INTERRUPT_PIN. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/net/vmxnet3.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 49c2466..19687aa 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -336,7 +336,7 @@ static bool _vmxnet3_assert_interrupt_line(VMXNET3State *s, uint32_t int_idx) } VMW_IRPRN(Asserting line for interrupt %u, int_idx); -qemu_set_irq(d-irq[int_idx], 1); +pci_irq_assert(d); return true; } @@ -356,7 +356,7 @@ static void _vmxnet3_deassert_interrupt_line(VMXNET3State *s, int lidx) assert(!s-msi_used || !msi_enabled(d)); VMW_IRPRN(Deasserting line for interrupt %u, lidx); -qemu_set_irq(d-irq[lidx], 0); +pci_irq_deassert(d); } static void vmxnet3_update_interrupt_line_state(VMXNET3State *s, int lidx) @@ -1299,6 +1299,12 @@ static void vmxnet3_update_features(VMXNET3State *s) } } +static bool vmxnet3_verify_intx(VMXNET3State *s, int intx) +{ +return s-msix_used || s-msi_used || (intx == + (pci_get_byte(s-parent_obj.config + PCI_INTERRUPT_PIN) - 1)); +} + static void vmxnet3_activate_device(VMXNET3State *s) { int i; @@ -1332,6 +1338,7 @@ static void vmxnet3_activate_device(VMXNET3State *s) s-event_int_idx = VMXNET3_READ_DRV_SHARED8(s-drv_shmem, devRead.intrConf.eventIntrIdx); +assert(vmxnet3_verify_intx(s, s-event_int_idx)); VMW_CFPRN(Events interrupt line is %u, s-event_int_idx); s-auto_int_masking = @@ -1364,6 +1371,7 @@ static void vmxnet3_activate_device(VMXNET3State *s) /* Read interrupt number for this TX queue */ s-txq_descr[i].intr_idx = VMXNET3_READ_TX_QUEUE_DESCR8(qdescr_pa, conf.intrIdx); +assert(vmxnet3_verify_intx(s, s-txq_descr[i].intr_idx)); VMW_CFPRN(TX Queue %d interrupt: %d, i, s-txq_descr[i].intr_idx); @@ -1411,6 +1419,7 @@ static void vmxnet3_activate_device(VMXNET3State *s) /* Read interrupt number for this RX queue */ s-rxq_descr[i].intr_idx = VMXNET3_READ_TX_QUEUE_DESCR8(qd_pa, conf.intrIdx); +assert(vmxnet3_verify_intx(s, s-rxq_descr[i].intr_idx)); VMW_CFPRN(RX Queue %d interrupt: %d, i, s-rxq_descr[i].intr_idx); -- MST
[Qemu-devel] [PULL 16/43] fw_cfg: interface to trigger callback on read
Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Reviewed-by: Igor Mammedov imamm...@redhat.com Tested-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/nvram/fw_cfg.h | 4 hw/nvram/fw_cfg.c | 33 - 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index f60dd67..2ab0fc2 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -60,6 +60,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 +71,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/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index d0820e5..f5dc3ea 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -42,6 +42,7 @@ typedef struct FWCfgEntry { uint8_t *data; void *callback_opaque; FWCfgCallback callback; +FWCfgReadCallback read_callback; } FWCfgEntry; struct FWCfgState { @@ -249,8 +250,12 @@ static uint8_t fw_cfg_read(FWCfgState *s) if (s-cur_entry == FW_CFG_INVALID || !e-data || s-cur_offset = e-len) ret = 0; -else +else { +if (e-read_callback) { +e-read_callback(e-callback_opaque, s-cur_offset); +} ret = e-data[s-cur_offset++]; +} trace_fw_cfg_read(s, ret); return ret; @@ -381,7 +386,10 @@ static const VMStateDescription vmstate_fw_cfg = { } }; -void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) +static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key, + FWCfgReadCallback callback, + void *callback_opaque, + void *data, size_t len) { int arch = !!(key FW_CFG_ARCH_LOCAL); @@ -391,6 +399,13 @@ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) s-entries[arch][key].data = data; s-entries[arch][key].len = (uint32_t)len; +s-entries[arch][key].read_callback = callback; +s-entries[arch][key].callback_opaque = callback_opaque; +} + +void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len) +{ +fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len); } void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value) @@ -444,8 +459,9 @@ void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback, s-entries[arch][key].callback = callback; } -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) { int i, index; size_t dsize; @@ -459,7 +475,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, index = be32_to_cpu(s-files-count); assert(index FW_CFG_FILE_SLOTS); -fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len); +fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index, + callback, callback_opaque, data, len); pstrcpy(s-files-f[index].name, sizeof(s-files-f[index].name), filename); @@ -477,6 +494,12 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, s-files-count = cpu_to_be32(index+1); } +void fw_cfg_add_file(FWCfgState *s, const char *filename, + void *data, size_t len) +{ +fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len); +} + static void fw_cfg_machine_ready(struct Notifier *n, void *data) { size_t len; -- MST
[Qemu-devel] [PULL 19/43] pcie_host: expose address format
Callers pass in the address so it's helpful for them to be able to decode it. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Reviewed-by: Igor Mammedov imamm...@redhat.com Tested-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie_host.h | 21 + hw/pci/pcie_host.c | 21 - 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/hw/pci/pcie_host.h b/include/hw/pci/pcie_host.h index bac3c67..da0f275 100644 --- a/include/hw/pci/pcie_host.h +++ b/include/hw/pci/pcie_host.h @@ -54,4 +54,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_BIT12 +#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/hw/pci/pcie_host.c b/hw/pci/pcie_host.c index 410ac08..c6e1b57 100644 --- a/hw/pci/pcie_host.c +++ b/hw/pci/pcie_host.c @@ -24,27 +24,6 @@ #include hw/pci/pcie_host.h #include exec/address-spaces.h -/* - * PCI express mmcfig 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_BIT12 -#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) - - /* a helper function to get a PCIDevice for a given mmconfig address */ static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus *s, uint32_t mmcfg_addr) -- MST
[Qemu-devel] [PULL 10/43] hw/pcie: AER and hot-plug events must use device's interrupt
From: Marcel Apfelbaum marce...@redhat.com The fields hpev_intx and aer_intx were removed because both AER and hot-plug events must use device's interrupt. Assert/deassert interrupts using pci irq wrappers instead. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pcie.h | 18 -- hw/pci/pcie.c | 4 ++-- hw/pci/pcie_aer.c | 4 ++-- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h index c010007..1966169 100644 --- a/include/hw/pci/pcie.h +++ b/include/hw/pci/pcie.h @@ -64,15 +64,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 +73,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 */ diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 50af3c1..268a696 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -187,7 +187,7 @@ static void hotplug_event_notify(PCIDevice *dev) } else if (msi_enabled(dev)) { msi_notify(dev, pcie_cap_flags_get_vector(dev)); } else { -qemu_set_irq(dev-irq[dev-exp.hpev_intx], dev-exp.hpev_notified); +pci_set_irq(dev, dev-exp.hpev_notified); } } @@ -195,7 +195,7 @@ static void hotplug_event_clear(PCIDevice *dev) { hotplug_event_update_event_status(dev); if (!msix_enabled(dev) !msi_enabled(dev) !dev-exp.hpev_notified) { -qemu_set_irq(dev-irq[dev-exp.hpev_intx], 0); +pci_irq_deassert(dev); } } diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index ca762ab..32aa0c6 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -285,7 +285,7 @@ static void pcie_aer_root_notify(PCIDevice *dev) } else if (msi_enabled(dev)) { msi_notify(dev, pcie_aer_root_get_vector(dev)); } else { -qemu_set_irq(dev-irq[dev-exp.aer_intx], 1); +pci_irq_assert(dev); } } @@ -768,7 +768,7 @@ void pcie_aer_root_write_config(PCIDevice *dev, uint32_t root_cmd = pci_get_long(aer_cap + PCI_ERR_ROOT_COMMAND); /* 6.2.4.1.2 Interrupt Generation */ if (!msix_enabled(dev) !msi_enabled(dev)) { -qemu_set_irq(dev-irq[dev-exp.aer_intx], !!(root_cmd enabled_cmd)); +pci_set_irq(dev, !!(root_cmd enabled_cmd)); return; } -- MST
[Qemu-devel] [PULL 17/43] loader: support for unmapped ROM blobs
Support ROM blobs not mapped into guest memory: same as ROM files really but use caller's buffer. Support invoking callback on access and return memory pointer making it easier for caller to update memory if necessary. Reviewed-by: Gerd Hoffmann kra...@redhat.com Tested-by: Gerd Hoffmann kra...@redhat.com Reviewed-by: Laszlo Ersek ler...@redhat.com Reviewed-by: Igor Mammedov imamm...@redhat.com Tested-by: Igor Mammedov imamm...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/lm32/lm32_hwsetup.h | 2 +- include/hw/loader.h| 7 --- hw/core/loader.c | 23 --- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/hw/lm32/lm32_hwsetup.h b/hw/lm32/lm32_hwsetup.h index 3449bd8..9fd5e69 100644 --- a/hw/lm32/lm32_hwsetup.h +++ b/hw/lm32/lm32_hwsetup.h @@ -73,7 +73,7 @@ static inline void hwsetup_free(HWSetup *hw) static inline void hwsetup_create_rom(HWSetup *hw, hwaddr base) { -rom_add_blob(hwsetup, hw-data, TARGET_PAGE_SIZE, base); +rom_add_blob(hwsetup, hw-data, TARGET_PAGE_SIZE, base, NULL, NULL, NULL); } static inline void hwsetup_add_u8(HWSetup *hw, uint8_t u) diff --git a/include/hw/loader.h b/include/hw/loader.h index 6145736..e0c576b 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -40,8 +40,9 @@ extern bool rom_file_in_ram; 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); +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); @@ -53,7 +54,7 @@ void do_info_roms(Monitor *mon, const QDict *qdict); #define rom_add_file_fixed(_f, _a, _i) \ rom_add_file(_f, NULL, _a, _i) #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) ? 0 : -1) #define PC_ROM_MIN_VGA 0xc #define PC_ROM_MIN_OPTION 0xc8000 diff --git a/hw/core/loader.c b/hw/core/loader.c index 7b3d3ee..449bd4c 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -700,10 +700,12 @@ err: return -1; } -int rom_add_blob(const char *name, const void *blob, size_t len, - hwaddr addr) +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) { Rom *rom; +void *data = NULL; rom = g_malloc0(sizeof(*rom)); rom-name = g_strdup(name); @@ -713,7 +715,22 @@ int rom_add_blob(const char *name, const void *blob, size_t len, rom-data = g_malloc0(rom-datasize); memcpy(rom-data, blob, len); rom_insert(rom); -return 0; +if (fw_file_name fw_cfg) { +char devpath[100]; + +snprintf(devpath, sizeof(devpath), /rom@%s, fw_file_name); + +if (rom_file_in_ram) { +data = rom_set_mr(rom, OBJECT(fw_cfg), devpath); +} else { +data = rom-data; +} + +fw_cfg_add_file_callback(fw_cfg, fw_file_name, + fw_callback, callback_opaque, + data, rom-romsize); +} +return data; } /* This function is specific for elf program because we don't need to allocate -- MST