diff options
Diffstat (limited to 'hw')
49 files changed, 851 insertions, 837 deletions
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index 46d787627a..d2030fdf56 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -4,7 +4,6 @@ #include <dirent.h> #include <utime.h> #include <sys/resource.h> -#include <glib.h> #include "fsdev/file-op-9p.h" #include "fsdev/9p-iov-marshal.h" #include "qemu/thread.h" diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs index faee86c5c4..66bd72702b 100644 --- a/hw/acpi/Makefile.objs +++ b/hw/acpi/Makefile.objs @@ -1,6 +1,6 @@ common-obj-$(CONFIG_ACPI_X86) += core.o piix4.o pcihp.o common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o -common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o cpu_hotplug_acpi_table.o +common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o common-obj-$(CONFIG_ACPI) += acpi_interface.o diff --git a/hw/acpi/acpi_interface.c b/hw/acpi/acpi_interface.c index d82131326a..6583917b8e 100644 --- a/hw/acpi/acpi_interface.c +++ b/hw/acpi/acpi_interface.c @@ -2,6 +2,15 @@ #include "hw/acpi/acpi_dev_interface.h" #include "qemu/module.h" +void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event) +{ + AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(dev); + if (adevc->send_event) { + AcpiDeviceIf *adev = ACPI_DEVICE_IF(dev); + adevc->send_event(adev, event); + } +} + static void register_types(void) { static const TypeInfo acpi_dev_if_info = { diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index cedb74e7cf..123160a94e 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -24,7 +24,6 @@ #include "hw/acpi/aml-build.h" #include "qemu/bswap.h" #include "qemu/bitops.h" -#include "hw/acpi/bios-linker-loader.h" static GArray *build_alloc_array(void) { @@ -406,6 +405,15 @@ Aml *aml_return(Aml *val) return var; } +/* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */ +Aml *aml_debug(void) +{ + Aml *var = aml_alloc(); + build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */ + build_append_byte(var->buf, 0x31); /* DebugOp */ + return var; +} + /* * ACPI 1.0b: 16.2.3 Data Objects Encoding: * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp @@ -1407,6 +1415,14 @@ Aml *aml_unicode(const char *str) return var; } +/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */ +Aml *aml_refof(Aml *arg) +{ + Aml *var = aml_opcode(0x71 /* RefOfOp */); + aml_append(var, arg); + return var; +} + /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */ Aml *aml_derefof(Aml *arg) { @@ -1473,10 +1489,12 @@ Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target) } void -build_header(GArray *linker, GArray *table_data, +build_header(BIOSLinker *linker, GArray *table_data, AcpiTableHeader *h, const char *sig, int len, uint8_t rev, const char *oem_id, const char *oem_table_id) { + unsigned tbl_offset = (char *)h - table_data->data; + unsigned checksum_offset = (char *)&h->checksum - table_data->data; memcpy(&h->signature, sig, 4); h->length = cpu_to_le32(len); h->revision = rev; @@ -1497,10 +1515,9 @@ build_header(GArray *linker, GArray *table_data, h->oem_revision = cpu_to_le32(1); memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4); h->asl_compiler_revision = cpu_to_le32(1); - h->checksum = 0; /* Checksum to be filled in by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE, - table_data, h, len, &h->checksum); + tbl_offset, len, checksum_offset); } void *acpi_data_push(GArray *table_data, unsigned size) @@ -1518,7 +1535,7 @@ unsigned acpi_data_len(GArray *table) void acpi_add_table(GArray *table_offsets, GArray *table_data) { - uint32_t offset = cpu_to_le32(table_data->len); + uint32_t offset = table_data->len; g_array_append_val(table_offsets, offset); } @@ -1532,8 +1549,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables) void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) { - void *linker_data = bios_linker_loader_cleanup(tables->linker); - g_free(linker_data); + bios_linker_loader_cleanup(tables->linker); g_array_free(tables->rsdp, true); g_array_free(tables->table_data, true); g_array_free(tables->tcpalog, mfre); @@ -1541,24 +1557,26 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre) /* Build rsdt table */ void -build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets, +build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets, const char *oem_id, const char *oem_table_id) { - AcpiRsdtDescriptorRev1 *rsdt; - size_t rsdt_len; int i; - const int table_data_len = (sizeof(uint32_t) * table_offsets->len); + unsigned rsdt_entries_offset; + AcpiRsdtDescriptorRev1 *rsdt; + const unsigned table_data_len = (sizeof(uint32_t) * table_offsets->len); + const unsigned rsdt_entry_size = sizeof(rsdt->table_offset_entry[0]); + const size_t rsdt_len = sizeof(*rsdt) + table_data_len; - rsdt_len = sizeof(*rsdt) + table_data_len; rsdt = acpi_data_push(table_data, rsdt_len); - memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len); + rsdt_entries_offset = (char *)rsdt->table_offset_entry - table_data->data; for (i = 0; i < table_offsets->len; ++i) { + uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i); + uint32_t rsdt_entry_offset = rsdt_entries_offset + rsdt_entry_size * i; + /* rsdt->table_offset_entry to be filled by Guest linker */ bios_linker_loader_add_pointer(linker, - ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &rsdt->table_offset_entry[i], - sizeof(uint32_t)); + ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size, + ACPI_BUILD_TABLE_FILE, ref_tbl_offset); } build_header(linker, table_data, (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id); diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c index 5153ab151b..d963ebe241 100644 --- a/hw/acpi/bios-linker-loader.c +++ b/hw/acpi/bios-linker-loader.c @@ -96,134 +96,170 @@ enum { }; /* - * bios_linker_loader_init: allocate a new linker file blob array. + * BiosLinkerFileEntry: + * + * An internal type used for book-keeping file entries + */ +typedef struct BiosLinkerFileEntry { + char *name; /* file name */ + GArray *blob; /* data accosiated with @name */ +} BiosLinkerFileEntry; + +/* + * bios_linker_loader_init: allocate a new linker object instance. * * After initialization, linker commands can be added, and will - * be stored in the array. + * be stored in the linker.cmd_blob array. */ -GArray *bios_linker_loader_init(void) +BIOSLinker *bios_linker_loader_init(void) { - return g_array_new(false, true /* clear */, 1); + BIOSLinker *linker = g_new(BIOSLinker, 1); + + linker->cmd_blob = g_array_new(false, true /* clear */, 1); + linker->file_list = g_array_new(false, true /* clear */, + sizeof(BiosLinkerFileEntry)); + return linker; } -/* Free linker wrapper and return the linker array. */ -void *bios_linker_loader_cleanup(GArray *linker) +/* Free linker wrapper */ +void bios_linker_loader_cleanup(BIOSLinker *linker) { - return g_array_free(linker, false); + int i; + BiosLinkerFileEntry *entry; + + g_array_free(linker->cmd_blob, true); + + for (i = 0; i < linker->file_list->len; i++) { + entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i); + g_free(entry->name); + } + g_array_free(linker->file_list, true); + g_free(linker); +} + +static const BiosLinkerFileEntry * +bios_linker_find_file(const BIOSLinker *linker, const char *name) +{ + int i; + BiosLinkerFileEntry *entry; + + for (i = 0; i < linker->file_list->len; i++) { + entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i); + if (!strcmp(entry->name, name)) { + return entry; + } + } + return NULL; } /* * bios_linker_loader_alloc: ask guest to load file into guest memory. * - * @linker: linker file blob array - * @file: file to be loaded + * @linker: linker object instance + * @file_name: name of the file blob to be loaded + * @file_blob: pointer to blob corresponding to @file_name * @alloc_align: required minimal alignment in bytes. Must be a power of 2. * @alloc_fseg: request allocation in FSEG zone (useful for the RSDP ACPI table) * * Note: this command must precede any other linker command using this file. */ -void bios_linker_loader_alloc(GArray *linker, - const char *file, +void bios_linker_loader_alloc(BIOSLinker *linker, + const char *file_name, + GArray *file_blob, uint32_t alloc_align, bool alloc_fseg) { BiosLinkerLoaderEntry entry; + BiosLinkerFileEntry file = { g_strdup(file_name), file_blob}; assert(!(alloc_align & (alloc_align - 1))); + assert(!bios_linker_find_file(linker, file_name)); + g_array_append_val(linker->file_list, file); + memset(&entry, 0, sizeof entry); - strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1); + strncpy(entry.alloc.file, file_name, sizeof entry.alloc.file - 1); entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE); entry.alloc.align = cpu_to_le32(alloc_align); entry.alloc.zone = alloc_fseg ? BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG : BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH; /* Alloc entries must come first, so prepend them */ - g_array_prepend_vals(linker, &entry, sizeof entry); + g_array_prepend_vals(linker->cmd_blob, &entry, sizeof entry); } /* - * bios_linker_loader_add_checksum: ask guest to add checksum of file data - * into (same) file at the specified pointer. + * bios_linker_loader_add_checksum: ask guest to add checksum of ACPI + * table in the specified file at the specified offset. * * Checksum calculation simply sums -X for each byte X in the range * using 8-bit math (i.e. ACPI checksum). * - * @linker: linker file blob array + * @linker: linker object instance * @file: file that includes the checksum to be calculated * and the data to be checksummed - * @table: @file blob contents - * @start, @size: range of data to checksum - * @checksum: location of the checksum to be patched within file blob - * - * Notes: - * - checksum byte initial value must have been pushed into @table - * and reside at address @checksum. - * - @size bytes must have been pushed into @table and reside at address - * @start. - * - Guest calculates checksum of specified range of data, result is added to - * initial value at @checksum into copy of @file in Guest memory. - * - Range might include the checksum itself. - * - To avoid confusion, caller must always put 0x0 at @checksum. - * - @file must be loaded into Guest memory using bios_linker_loader_alloc + * @start_offset, @size: range of data in the file to checksum, + * relative to the start of file blob + * @checksum_offset: location of the checksum to be patched within file blob, + * relative to the start of file blob */ -void bios_linker_loader_add_checksum(GArray *linker, const char *file, - GArray *table, - void *start, unsigned size, - uint8_t *checksum) +void bios_linker_loader_add_checksum(BIOSLinker *linker, const char *file_name, + unsigned start_offset, unsigned size, + unsigned checksum_offset) { BiosLinkerLoaderEntry entry; - ptrdiff_t checksum_offset = (gchar *)checksum - table->data; - ptrdiff_t start_offset = (gchar *)start - table->data; + const BiosLinkerFileEntry *file = bios_linker_find_file(linker, file_name); - assert(checksum_offset >= 0); - assert(start_offset >= 0); - assert(checksum_offset + 1 <= table->len); - assert(start_offset + size <= table->len); - assert(*checksum == 0x0); + assert(file); + assert(start_offset < file->blob->len); + assert(start_offset + size <= file->blob->len); + assert(checksum_offset >= start_offset); + assert(checksum_offset + 1 <= start_offset + size); + *(file->blob->data + checksum_offset) = 0; memset(&entry, 0, sizeof entry); - strncpy(entry.cksum.file, file, sizeof entry.cksum.file - 1); + strncpy(entry.cksum.file, file_name, sizeof entry.cksum.file - 1); entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM); entry.cksum.offset = cpu_to_le32(checksum_offset); entry.cksum.start = cpu_to_le32(start_offset); entry.cksum.length = cpu_to_le32(size); - g_array_append_vals(linker, &entry, sizeof entry); + g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); } /* - * bios_linker_loader_add_pointer: ask guest to add address of source file - * into destination file at the specified pointer. + * bios_linker_loader_add_pointer: ask guest to patch address in + * destination file with a pointer to source file * - * @linker: linker file blob array + * @linker: linker object instance * @dest_file: destination file that must be changed + * @dst_patched_offset: location within destination file blob to be patched + * with the pointer to @src_file+@src_offset (i.e. source + * blob allocated in guest memory + @src_offset), in bytes + * @dst_patched_offset_size: size of the pointer to be patched + * at @dst_patched_offset in @dest_file blob, in bytes * @src_file: source file who's address must be taken - * @table: @dest_file blob contents array - * @pointer: location of the pointer to be patched within destination file blob - * @pointer_size: size of pointer to be patched, in bytes - * - * Notes: - * - @pointer_size bytes must have been pushed into @table - * and reside at address @pointer. - * - Guest address is added to initial value at @pointer - * into copy of @dest_file in Guest memory. - * e.g. to get start of src_file in guest memory, put 0x0 there - * to get address of a field at offset 0x10 in src_file, put 0x10 there - * - Both @dest_file and @src_file must be - * loaded into Guest memory using bios_linker_loader_alloc + * @src_offset: location within source file blob to which + * @dest_file+@dst_patched_offset will point to after + * firmware's executed ADD_POINTER command */ -void bios_linker_loader_add_pointer(GArray *linker, +void bios_linker_loader_add_pointer(BIOSLinker *linker, const char *dest_file, + uint32_t dst_patched_offset, + uint8_t dst_patched_size, const char *src_file, - GArray *table, void *pointer, - uint8_t pointer_size) + uint32_t src_offset) { + uint64_t le_src_offset; BiosLinkerLoaderEntry entry; - ptrdiff_t offset = (gchar *)pointer - table->data; + const BiosLinkerFileEntry *dst_file = + bios_linker_find_file(linker, dest_file); + const BiosLinkerFileEntry *source_file = + bios_linker_find_file(linker, src_file); - assert(offset >= 0); - assert(offset + pointer_size <= table->len); + assert(dst_patched_offset < dst_file->blob->len); + assert(dst_patched_offset + dst_patched_size <= dst_file->blob->len); + assert(src_offset < source_file->blob->len); memset(&entry, 0, sizeof entry); strncpy(entry.pointer.dest_file, dest_file, @@ -231,10 +267,14 @@ void bios_linker_loader_add_pointer(GArray *linker, strncpy(entry.pointer.src_file, src_file, sizeof entry.pointer.src_file - 1); entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER); - entry.pointer.offset = cpu_to_le32(offset); - entry.pointer.size = pointer_size; - assert(pointer_size == 1 || pointer_size == 2 || - pointer_size == 4 || pointer_size == 8); + entry.pointer.offset = cpu_to_le32(dst_patched_offset); + entry.pointer.size = dst_patched_size; + assert(dst_patched_size == 1 || dst_patched_size == 2 || + dst_patched_size == 4 || dst_patched_size == 8); + + le_src_offset = cpu_to_le64(src_offset); + memcpy(dst_file->blob->data + dst_patched_offset, + &le_src_offset, dst_patched_size); - g_array_append_vals(linker, &entry, sizeof entry); + g_array_append_vals(linker->cmd_blob, &entry, sizeof entry); } diff --git a/hw/acpi/core.c b/hw/acpi/core.c index 1ffd155c11..d24b9a98c8 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c @@ -698,7 +698,7 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr) } void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq, - AcpiGPEStatusBits status) + AcpiEventStatusBits status) { ar->gpe.sts[0] |= status; acpi_update_sci(ar, irq); diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 4d86743fde..fe75bd9ac9 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -14,6 +14,14 @@ #include "hw/acpi/cpu_hotplug.h" #include "qapi/error.h" #include "qom/cpu.h" +#include "hw/i386/pc.h" + +#define CPU_EJECT_METHOD "CPEJ" +#define CPU_MAT_METHOD "CPMA" +#define CPU_ON_BITMAP "CPON" +#define CPU_STATUS_METHOD "CPST" +#define CPU_STATUS_MAP "PRS" +#define CPU_SCAN_METHOD "PRSC" static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size) { @@ -54,19 +62,18 @@ static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu, g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); } -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, - AcpiCpuHotplug *g, DeviceState *dev, Error **errp) +void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev, + AcpiCpuHotplug *g, DeviceState *dev, Error **errp) { acpi_set_cpu_present_bit(g, CPU(dev), errp); if (*errp != NULL) { return; } - - acpi_send_gpe_event(ar, irq, ACPI_CPU_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_CPU_HOTPLUG_STATUS); } -void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, - AcpiCpuHotplug *gpe_cpu, uint16_t base) +void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base) { CPUState *cpu; @@ -77,3 +84,230 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN); memory_region_add_subregion(parent, base, &gpe_cpu->io); } + +void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine, + uint16_t io_base) +{ + Aml *dev; + Aml *crs; + Aml *pkg; + Aml *field; + Aml *method; + Aml *if_ctx; + Aml *else_ctx; + int i, apic_idx; + Aml *sb_scope = aml_scope("_SB"); + uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}; + Aml *cpu_id = aml_arg(1); + Aml *apic_id = aml_arg(0); + Aml *cpu_on = aml_local(0); + Aml *madt = aml_local(1); + Aml *cpus_map = aml_name(CPU_ON_BITMAP); + Aml *zero = aml_int(0); + Aml *one = aml_int(1); + MachineClass *mc = MACHINE_GET_CLASS(machine); + CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); + PCMachineState *pcms = PC_MACHINE(machine); + + /* + * _MAT method - creates an madt apic buffer + * apic_id = Arg0 = Local APIC ID + * cpu_id = Arg1 = Processor ID + * cpu_on = Local0 = CPON flag for this cpu + * madt = Local1 = Buffer (in madt apic form) to return + */ + method = aml_method(CPU_MAT_METHOD, 2, AML_NOTSERIALIZED); + aml_append(method, + aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on)); + aml_append(method, + aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt)); + /* Update the processor id, lapic id, and enable/disable status */ + aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2)))); + aml_append(method, aml_store(apic_id, aml_index(madt, aml_int(3)))); + aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4)))); + aml_append(method, aml_return(madt)); + aml_append(sb_scope, method); + + /* + * _STA method - return ON status of cpu + * apic_id = Arg0 = Local APIC ID + * cpu_on = Local0 = CPON flag for this cpu + */ + method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED); + aml_append(method, + aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on)); + if_ctx = aml_if(cpu_on); + { + aml_append(if_ctx, aml_return(aml_int(0xF))); + } + aml_append(method, if_ctx); + else_ctx = aml_else(); + { + aml_append(else_ctx, aml_return(zero)); + } + aml_append(method, else_ctx); + aml_append(sb_scope, method); + + method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED); + aml_append(method, aml_sleep(200)); + aml_append(sb_scope, method); + + method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED); + { + Aml *while_ctx, *if_ctx2, *else_ctx2; + Aml *bus_check_evt = aml_int(1); + Aml *remove_evt = aml_int(3); + Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */ + Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */ + Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */ + Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */ + Aml *status = aml_local(3); /* Local3 = active state for cpu */ + + aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map)); + aml_append(method, aml_store(zero, byte)); + aml_append(method, aml_store(zero, idx)); + + /* While (idx < SizeOf(CPON)) */ + while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map))); + aml_append(while_ctx, + aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on)); + + if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL)); + { + /* Shift down previously read bitmap byte */ + aml_append(if_ctx, aml_shiftright(byte, one, byte)); + } + aml_append(while_ctx, if_ctx); + + else_ctx = aml_else(); + { + /* Read next byte from cpu bitmap */ + aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map, + aml_shiftright(idx, aml_int(3), NULL))), byte)); + } + aml_append(while_ctx, else_ctx); + + aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status)); + if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status))); + { + /* State change - update CPON with new state */ + aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx))); + if_ctx2 = aml_if(aml_equal(status, one)); + { + aml_append(if_ctx2, + aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt)); + } + aml_append(if_ctx, if_ctx2); + else_ctx2 = aml_else(); + { + aml_append(else_ctx2, + aml_call2(AML_NOTIFY_METHOD, idx, remove_evt)); + } + } + aml_append(if_ctx, else_ctx2); + aml_append(while_ctx, if_ctx); + + aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */ + aml_append(method, while_ctx); + } + aml_append(sb_scope, method); + + /* The current AML generator can cover the APIC ID range [0..255], + * inclusive, for VCPU hotplug. */ + QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256); + g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT); + + /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */ + dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06"))); + aml_append(dev, + aml_name_decl("_UID", aml_string("CPU Hotplug resources")) + ); + /* device present, functioning, decoding, not shown in UI */ + aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); + crs = aml_resource_template(); + aml_append(crs, + aml_io(AML_DECODE16, io_base, io_base, 1, ACPI_GPE_PROC_LEN) + ); + aml_append(dev, aml_name_decl("_CRS", crs)); + aml_append(sb_scope, dev); + /* declare CPU hotplug MMIO region and PRS field to access it */ + aml_append(sb_scope, aml_operation_region( + "PRST", AML_SYSTEM_IO, aml_int(io_base), ACPI_GPE_PROC_LEN)); + field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); + aml_append(field, aml_named_field("PRS", 256)); + aml_append(sb_scope, field); + + /* build Processor object for each processor */ + for (i = 0; i < apic_ids->len; i++) { + int apic_id = apic_ids->cpus[i].arch_id; + + assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT); + + dev = aml_processor(i, 0, 0, "CP%.02X", apic_id); + + method = aml_method("_MAT", 0, AML_NOTSERIALIZED); + aml_append(method, + aml_return(aml_call2(CPU_MAT_METHOD, aml_int(apic_id), aml_int(i)) + )); + aml_append(dev, method); + + method = aml_method("_STA", 0, AML_NOTSERIALIZED); + aml_append(method, + aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id)))); + aml_append(dev, method); + + method = aml_method("_EJ0", 1, AML_NOTSERIALIZED); + aml_append(method, + aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id), + aml_arg(0))) + ); + aml_append(dev, method); + + aml_append(sb_scope, dev); + } + + /* build this code: + * Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...} + */ + /* Arg0 = APIC ID */ + method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED); + for (i = 0; i < apic_ids->len; i++) { + int apic_id = apic_ids->cpus[i].arch_id; + + if_ctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id))); + aml_append(if_ctx, + aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1)) + ); + aml_append(method, if_ctx); + } + aml_append(sb_scope, method); + + /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" + * + * Note: The ability to create variable-sized packages was first + * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages + * ith up to 255 elements. Windows guests up to win2k8 fail when + * VarPackageOp is used. + */ + pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) : + aml_varpackage(pcms->apic_id_limit); + + for (i = 0, apic_idx = 0; i < apic_ids->len; i++) { + int apic_id = apic_ids->cpus[i].arch_id; + + for (; apic_idx < apic_id; apic_idx++) { + aml_append(pkg, aml_int(0)); + } + aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0)); + apic_idx = apic_id + 1; + } + aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg)); + g_free(apic_ids); + + aml_append(ctx, sb_scope); + + method = aml_method("\\_GPE._E02", 0, AML_NOTSERIALIZED); + aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD)); + aml_append(ctx, method); +} diff --git a/hw/acpi/cpu_hotplug_acpi_table.c b/hw/acpi/cpu_hotplug_acpi_table.c deleted file mode 100644 index 97bb1092a2..0000000000 --- a/hw/acpi/cpu_hotplug_acpi_table.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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 "qemu/osdep.h" -#include "hw/acpi/cpu_hotplug.h" - -void build_cpu_hotplug_aml(Aml *ctx) -{ - Aml *method; - Aml *if_ctx; - Aml *else_ctx; - Aml *sb_scope = aml_scope("_SB"); - uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0}; - Aml *cpu_id = aml_arg(0); - Aml *cpu_on = aml_local(0); - Aml *madt = aml_local(1); - Aml *cpus_map = aml_name(CPU_ON_BITMAP); - Aml *zero = aml_int(0); - Aml *one = aml_int(1); - - /* - * _MAT method - creates an madt apic buffer - * cpu_id = Arg0 = Processor ID = Local APIC ID - * cpu_on = Local0 = CPON flag for this cpu - * madt = Local1 = Buffer (in madt apic form) to return - */ - method = aml_method(CPU_MAT_METHOD, 1, AML_NOTSERIALIZED); - aml_append(method, - aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on)); - aml_append(method, - aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt)); - /* Update the processor id, lapic id, and enable/disable status */ - aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2)))); - aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(3)))); - aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4)))); - aml_append(method, aml_return(madt)); - aml_append(sb_scope, method); - - /* - * _STA method - return ON status of cpu - * cpu_id = Arg0 = Processor ID = Local APIC ID - * cpu_on = Local0 = CPON flag for this cpu - */ - method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED); - aml_append(method, - aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on)); - if_ctx = aml_if(cpu_on); - { - aml_append(if_ctx, aml_return(aml_int(0xF))); - } - aml_append(method, if_ctx); - else_ctx = aml_else(); - { - aml_append(else_ctx, aml_return(zero)); - } - aml_append(method, else_ctx); - aml_append(sb_scope, method); - - method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED); - aml_append(method, aml_sleep(200)); - aml_append(sb_scope, method); - - method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED); - { - Aml *while_ctx, *if_ctx2, *else_ctx2; - Aml *bus_check_evt = aml_int(1); - Aml *remove_evt = aml_int(3); - Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */ - Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */ - Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */ - Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */ - Aml *status = aml_local(3); /* Local3 = active state for cpu */ - - aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map)); - aml_append(method, aml_store(zero, byte)); - aml_append(method, aml_store(zero, idx)); - - /* While (idx < SizeOf(CPON)) */ - while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map))); - aml_append(while_ctx, - aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on)); - - if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL)); - { - /* Shift down previously read bitmap byte */ - aml_append(if_ctx, aml_shiftright(byte, one, byte)); - } - aml_append(while_ctx, if_ctx); - - else_ctx = aml_else(); - { - /* Read next byte from cpu bitmap */ - aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map, - aml_shiftright(idx, aml_int(3), NULL))), byte)); - } - aml_append(while_ctx, else_ctx); - - aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status)); - if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status))); - { - /* State change - update CPON with new state */ - aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx))); - if_ctx2 = aml_if(aml_equal(status, one)); - { - aml_append(if_ctx2, - aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt)); - } - aml_append(if_ctx, if_ctx2); - else_ctx2 = aml_else(); - { - aml_append(else_ctx2, - aml_call2(AML_NOTIFY_METHOD, idx, remove_evt)); - } - } - aml_append(if_ctx, else_ctx2); - aml_append(while_ctx, if_ctx); - - aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */ - aml_append(method, while_ctx); - } - aml_append(sb_scope, method); - - aml_append(ctx, sb_scope); -} diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 27e978f5fd..853c9c4eb7 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -273,8 +273,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, pm->powerdown_notifier.notify = pm_powerdown_req; qemu_register_powerdown_notifier(&pm->powerdown_notifier); - acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), - &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); + legacy_acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), + OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); if (pm->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), @@ -430,39 +430,47 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp) NULL); } -void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp) +void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) { - if (pm->acpi_memory_hotplug.is_enabled && + ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + + if (lpc->pm.acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug, + acpi_memory_plug_cb(hotplug_dev, &lpc->pm.acpi_memory_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { - acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp); + legacy_acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.gpe_cpu, dev, errp); } else { error_setg(errp, "acpi: device plug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); } } -void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, - Error **errp) +void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev, + DeviceState *dev, Error **errp) { - if (pm->acpi_memory_hotplug.is_enabled && + ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + + if (lpc->pm.acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq, - &pm->acpi_memory_hotplug, dev, errp); + acpi_memory_unplug_request_cb(hotplug_dev, + &lpc->pm.acpi_memory_hotplug, dev, + errp); } else { error_setg(errp, "acpi: device unplug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); } } -void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, +void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - if (pm->acpi_memory_hotplug.is_enabled && + ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); + + if (lpc->pm.acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp); + acpi_memory_unplug_cb(&lpc->pm.acpi_memory_hotplug, dev, errp); } else { error_setg(errp, "acpi: device unplug for not supported device" " type: %s", object_get_typename(OBJECT(dev))); diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index f65a3a21ef..ec4e64b361 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -228,7 +228,7 @@ acpi_memory_slot_status(MemHotplugState *mem_st, return &mem_st->devs[slot]; } -void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, +void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, DeviceState *dev, Error **errp) { MemStatus *mdev; @@ -247,13 +247,11 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st, mdev->is_enabled = true; if (dev->hotplugged) { mdev->is_inserting = true; - - /* do ACPI magic */ - acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); } } -void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, +void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, DeviceState *dev, Error **errp) { @@ -265,9 +263,7 @@ void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq, } mdev->is_removing = true; - - /* Do ACPI magic */ - acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); } void acpi_memory_unplug_cb(MemHotplugState *mem_st, diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index fb925dccae..b4c22627df 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -353,7 +353,7 @@ static GArray *nvdimm_build_device_structure(GSList *device_list) } static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets, - GArray *table_data, GArray *linker) + GArray *table_data, BIOSLinker *linker) { GArray *structures = nvdimm_build_device_structure(device_list); unsigned int header; @@ -579,7 +579,8 @@ static void nvdimm_build_nvdimm_devices(GSList *device_list, Aml *root_dev) } static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, - GArray *table_data, GArray *linker) + GArray *table_data, BIOSLinker *linker, + GArray *dsm_dma_arrea) { Aml *ssdt, *sb_scope, *dev, *field; int mem_addr_offset, nvdimm_ssdt; @@ -678,12 +679,12 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, mem_addr_offset = build_append_named_dword(table_data, NVDIMM_ACPI_MEM_ADDR); - bios_linker_loader_alloc(linker, NVDIMM_DSM_MEM_FILE, sizeof(NvdimmDsmIn), - false /* high memory */); - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - NVDIMM_DSM_MEM_FILE, table_data, - table_data->data + mem_addr_offset, - sizeof(uint32_t)); + bios_linker_loader_alloc(linker, + NVDIMM_DSM_MEM_FILE, dsm_dma_arrea, + sizeof(NvdimmDsmIn), false /* high memory */); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, mem_addr_offset, sizeof(uint32_t), + NVDIMM_DSM_MEM_FILE, 0); build_header(linker, table_data, (void *)(table_data->data + nvdimm_ssdt), "SSDT", table_data->len - nvdimm_ssdt, 1, NULL, "NVDIMM"); @@ -691,7 +692,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, } void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, - GArray *linker) + BIOSLinker *linker, GArray *dsm_dma_arrea) { GSList *device_list; @@ -701,6 +702,7 @@ void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, return; } nvdimm_build_nfit(device_list, table_offsets, table_data, linker); - nvdimm_build_ssdt(device_list, table_offsets, table_data, linker); + nvdimm_build_ssdt(device_list, table_offsets, table_data, linker, + dsm_dma_arrea); g_slist_free(device_list); } diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 71f4c4e14b..d957d1e30d 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -182,7 +182,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s) acpi_pcihp_update(s); } -void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, +void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, DeviceState *dev, Error **errp) { PCIDevice *pdev = PCI_DEVICE(dev); @@ -202,11 +202,10 @@ void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, } s->acpi_pcihp_pci_status[bsel].up |= (1U << slot); - - acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); } -void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, +void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, DeviceState *dev, Error **errp) { PCIDevice *pdev = PCI_DEVICE(dev); @@ -219,8 +218,7 @@ void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, } s->acpi_pcihp_pci_status[bsel].down |= (1U << slot); - - acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS); + acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); } static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index b3e3bb306a..c48cb1b91a 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -348,12 +348,11 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev, if (s->acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_plug_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, dev, errp); + acpi_memory_plug_cb(hotplug_dev, &s->acpi_memory_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { - acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, - errp); + acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { - acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp); + legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp); } else { error_setg(errp, "acpi: device plug request for not supported device" " type: %s", object_get_typename(OBJECT(dev))); @@ -367,10 +366,10 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev, if (s->acpi_memory_hotplug.is_enabled && object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) { - acpi_memory_unplug_request_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, + acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { - acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, + acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp); } else { error_setg(errp, "acpi: device unplug request for not supported device" @@ -571,8 +570,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent, s->use_acpi_pci_hotplug); - acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu, - PIIX4_CPU_HOTPLUG_IO_BASE); + legacy_acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu, + PIIX4_CPU_HOTPLUG_IO_BASE); if (s->acpi_memory_hotplug.is_enabled) { acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug); @@ -586,6 +585,13 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) acpi_memory_ospm_status(&s->acpi_memory_hotplug, list); } +static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) +{ + PIIX4PMState *s = PIIX4_PM(adev); + + acpi_send_gpe_event(&s->ar, s->irq, ev); +} + static Property piix4_pm_properties[] = { DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0), DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), @@ -624,6 +630,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) hc->unplug_request = piix4_device_unplug_request_cb; hc->unplug = piix4_device_unplug_cb; adevc->ospm_status = piix4_ospm_status; + adevc->send_event = piix4_send_gpe; } static const TypeInfo piix4_pm_info = { diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 83a54203b8..735ab864a0 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -354,11 +354,14 @@ static void acpi_dsdt_add_power_button(Aml *scope) /* RSDP */ static GArray * -build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt) +build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); + unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address); + unsigned rsdt_pa_offset = + (char *)&rsdp->rsdt_physical_address - rsdp_table->data; - bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16, + bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16, true /* fseg memory */); memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature)); @@ -366,24 +369,21 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt) rsdp->length = cpu_to_le32(sizeof(*rsdp)); rsdp->revision = 0x02; - /* Point to RSDT */ - rsdp->rsdt_physical_address = cpu_to_le32(rsdt); /* Address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, - ACPI_BUILD_TABLE_FILE, - rsdp_table, &rsdp->rsdt_physical_address, - sizeof rsdp->rsdt_physical_address); - rsdp->checksum = 0; + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size, + ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset); + /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, - rsdp_table, rsdp, sizeof *rsdp, - &rsdp->checksum); + (char *)rsdp - rsdp_table->data, sizeof *rsdp, + (char *)&rsdp->checksum - rsdp_table->data); return rsdp_table; } static void -build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { AcpiSerialPortConsoleRedirection *spcr; const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART]; @@ -416,7 +416,7 @@ build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) } static void -build_srat(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { AcpiSystemResourceAffinityTable *srat; AcpiSratProcessorGiccAffinity *core; @@ -456,13 +456,12 @@ build_srat(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) mem_base += numa_info[i].node_mem; } - build_header(linker, table_data, - (void *)(table_data->data + srat_start), "SRAT", + build_header(linker, table_data, (void *)srat, "SRAT", table_data->len - srat_start, 3, NULL, NULL); } static void -build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { AcpiTableMcfg *mcfg; const MemMapEntry *memmap = guest_info->memmap; @@ -482,7 +481,7 @@ build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) /* GTDT */ static void -build_gtdt(GArray *table_data, GArray *linker) +build_gtdt(GArray *table_data, BIOSLinker *linker) { int gtdt_start = table_data->len; AcpiGenericTimerTable *gtdt; @@ -508,7 +507,7 @@ build_gtdt(GArray *table_data, GArray *linker) /* MADT */ static void -build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { int madt_start = table_data->len; const MemMapEntry *memmap = guest_info->memmap; @@ -567,9 +566,10 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) /* FADT */ static void -build_fadt(GArray *table_data, GArray *linker, unsigned dsdt) +build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset) { AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt)); + unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data; /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */ fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI); @@ -579,12 +579,10 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt) /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */ fadt->minor_revision = 0x1; - fadt->dsdt = cpu_to_le32(dsdt); /* DSDT address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &fadt->dsdt, - sizeof fadt->dsdt); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt), + ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset); build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL); @@ -592,7 +590,7 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt) /* DSDT */ static void -build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) +build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info) { Aml *scope, *dsdt; const MemMapEntry *memmap = guest_info->memmap; @@ -652,7 +650,8 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables) table_offsets = g_array_new(false, true /* clear */, sizeof(uint32_t)); - bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE, + bios_linker_loader_alloc(tables->linker, + ACPI_BUILD_TABLE_FILE, tables_blob, 64, false /* high memory */); /* @@ -731,7 +730,7 @@ static void virt_acpi_build_update(void *build_opaque) acpi_ram_update(build_state->table_mr, tables.table_data); acpi_ram_update(build_state->rsdp_mr, tables.rsdp); - acpi_ram_update(build_state->linker_mr, tables.linker); + acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); acpi_build_tables_cleanup(&tables, true); @@ -789,7 +788,8 @@ void virt_acpi_setup(VirtGuestInfo *guest_info) assert(build_state->table_mr != NULL); build_state->linker_mr = - acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); + acpi_add_rom_blob(build_state, tables.linker->cmd_blob, + "etc/table-loader", 0); fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); diff --git a/hw/audio/gus.c b/hw/audio/gus.c index 9dd6947bee..6c02646773 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -144,7 +144,7 @@ static void GUS_callback (void *opaque, int free) s->left = samples; reset: - gus_irqgen (&s->emu, muldiv64 (net, 1000000, s->freq)); + gus_irqgen (&s->emu, (uint64_t)net * 1000000 / s->freq); } int GUS_irqrequest (GUSEmuState *emu, int hwirq, int n) diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index f9afc8edad..d2599604d1 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -35,7 +35,7 @@ #define PCSPK_BUF_LEN 1792 #define PCSPK_SAMPLE_RATE 32000 #define PCSPK_MAX_FREQ (PCSPK_SAMPLE_RATE >> 1) -#define PCSPK_MIN_COUNT ((PIT_FREQ + PCSPK_MAX_FREQ - 1) / PCSPK_MAX_FREQ) +#define PCSPK_MIN_COUNT DIV_ROUND_UP(PIT_FREQ, PCSPK_MAX_FREQ) #define PC_SPEAKER(obj) OBJECT_CHECK(PCSpkState, (obj), TYPE_PC_SPEAKER) diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 3cb97c9a29..2073f9a270 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -37,8 +37,6 @@ struct VirtIOBlockDataPlane { EventNotifier *guest_notifier; /* irq */ QEMUBH *bh; /* bh for guest notification */ - Notifier insert_notifier, remove_notifier; - /* Note that these EventNotifiers are assigned by value. This is * fine as long as you do not call event_notifier_cleanup on them * (because you don't own the file descriptor or handle; you just @@ -46,9 +44,6 @@ struct VirtIOBlockDataPlane { */ IOThread *iothread; AioContext *ctx; - - /* Operation blocker on BDS */ - Error *blocker; }; /* Raise an interrupt to signal guest, if necessary */ @@ -68,54 +63,6 @@ static void notify_guest_bh(void *opaque) event_notifier_set(s->guest_notifier); } -static void data_plane_set_up_op_blockers(VirtIOBlockDataPlane *s) -{ - assert(!s->blocker); - error_setg(&s->blocker, "block device is in use by data plane"); - blk_op_block_all(s->conf->conf.blk, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_CHANGE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_COMMIT_SOURCE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_COMMIT_TARGET, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_EJECT, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, - s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, - s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, - s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_MIRROR_SOURCE, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker); - blk_op_unblock(s->conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker); -} - -static void data_plane_remove_op_blockers(VirtIOBlockDataPlane *s) -{ - if (s->blocker) { - blk_op_unblock_all(s->conf->conf.blk, s->blocker); - error_free(s->blocker); - s->blocker = NULL; - } -} - -static void data_plane_blk_insert_notifier(Notifier *n, void *data) -{ - VirtIOBlockDataPlane *s = container_of(n, VirtIOBlockDataPlane, - insert_notifier); - assert(s->conf->conf.blk == data); - data_plane_set_up_op_blockers(s); -} - -static void data_plane_blk_remove_notifier(Notifier *n, void *data) -{ - VirtIOBlockDataPlane *s = container_of(n, VirtIOBlockDataPlane, - remove_notifier); - assert(s->conf->conf.blk == data); - data_plane_remove_op_blockers(s); -} - /* Context: QEMU global mutex held */ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, VirtIOBlockDataPlane **dataplane, @@ -158,13 +105,6 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf, s->ctx = iothread_get_aio_context(s->iothread); s->bh = aio_bh_new(s->ctx, notify_guest_bh, s); - s->insert_notifier.notify = data_plane_blk_insert_notifier; - s->remove_notifier.notify = data_plane_blk_remove_notifier; - blk_add_insert_bs_notifier(conf->conf.blk, &s->insert_notifier); - blk_add_remove_bs_notifier(conf->conf.blk, &s->remove_notifier); - - data_plane_set_up_op_blockers(s); - *dataplane = s; } @@ -176,9 +116,6 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s) } virtio_blk_data_plane_stop(s); - data_plane_remove_op_blockers(s); - notifier_remove(&s->insert_notifier); - notifier_remove(&s->remove_notifier); qemu_bh_delete(s->bh); object_unref(OBJECT(s->iothread)); g_free(s); diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c index 7909d5041e..1d9f7ee000 100644 --- a/hw/block/tc58128.c +++ b/hw/block/tc58128.c @@ -45,7 +45,7 @@ static void init_dev(tc58128_dev * dev, const char *filename) } } else { /* Build first block with number of blocks */ - blocks = (ret + 528 * 32 - 1) / (528 * 32); + blocks = DIV_ROUND_UP(ret, 528 * 32); dev->flash_contents[0] = blocks & 0xff; dev->flash_contents[1] = (blocks >> 8) & 0xff; dev->flash_contents[2] = (blocks >> 16) & 0xff; diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 853162b670..0a05a5295c 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -58,9 +58,6 @@ const char *qdev_fw_name(DeviceState *dev) return object_get_typename(OBJECT(dev)); } -static void qdev_property_add_legacy(DeviceState *dev, Property *prop, - Error **errp); - static void bus_remove_child(BusState *bus, DeviceState *child) { BusChild *kid; @@ -733,13 +730,20 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v, } /** - * @qdev_add_legacy_property - adds a legacy property + * qdev_property_add_legacy: + * @dev: Device to add the property to. + * @prop: The qdev property definition. + * @errp: location to store error information. + * + * Add a legacy QOM property to @dev for qdev property @prop. + * On error, store error in @errp. * - * Do not use this is new code! Properties added through this interface will - * be given names and types in the "legacy" namespace. + * Legacy properties are string versions of QOM properties. The format of + * the string depends on the property type. Legacy properties are only + * needed for "info qtree". * - * Legacy properties are string versions of other OOM properties. The format - * of the string depends on the property type. + * Do not use this is new code! QOM Properties added through this interface + * will be given names in the "legacy" namespace. */ static void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp) @@ -762,10 +766,14 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop, } /** - * @qdev_property_add_static - add a @Property to a device. + * qdev_property_add_static: + * @dev: Device to add the property to. + * @prop: The qdev property definition. + * @errp: location to store error information. * - * Static properties access data in a struct. The actual type of the - * property and the field depends on the property type. + * Add a static QOM property to @dev for qdev property @prop. + * On error, store error in @errp. Static properties access data in a struct. + * The type of the QOM property is derived from prop->info. */ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp) diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 9866dfda5f..570b0977c3 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -472,9 +472,9 @@ static int xenfb_map_fb(struct XenFB *xenfb) xenfb->pixels = NULL; } - xenfb->fbpages = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; + xenfb->fbpages = DIV_ROUND_UP(xenfb->fb_len, XC_PAGE_SIZE); n_fbdirs = xenfb->fbpages * mode / 8; - n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; + n_fbdirs = DIV_ROUND_UP(n_fbdirs, XC_PAGE_SIZE); pgmfns = g_malloc0(sizeof(xen_pfn_t) * n_fbdirs); fbmfns = g_malloc0(sizeof(xen_pfn_t) * xenfb->fbpages); diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 279f0d7d05..8ca203211a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -23,7 +23,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "acpi-build.h" -#include <glib.h> #include "qemu-common.h" #include "qemu/bitmap.h" #include "qemu/error-report.h" @@ -94,7 +93,6 @@ typedef struct AcpiPmInfo { uint32_t gpe0_blk_len; uint32_t io_base; uint16_t cpu_hp_io_base; - uint16_t cpu_hp_io_len; uint16_t mem_hp_io_base; uint16_t mem_hp_io_len; uint16_t pcihp_io_base; @@ -142,7 +140,6 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) } assert(obj); - pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN; pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE; pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN; @@ -262,7 +259,7 @@ static void acpi_align_size(GArray *blob, unsigned align) /* FACS */ static void -build_facs(GArray *table_data, GArray *linker) +build_facs(GArray *table_data, BIOSLinker *linker) { AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs); memcpy(&facs->signature, "FACS", 4); @@ -307,34 +304,31 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm) /* FADT */ static void -build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm, - unsigned facs, unsigned dsdt, +build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, + unsigned facs_tbl_offset, unsigned dsdt_tbl_offset, const char *oem_id, const char *oem_table_id) { AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt)); + unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data; + unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data; - fadt->firmware_ctrl = cpu_to_le32(facs); /* FACS address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &fadt->firmware_ctrl, - sizeof fadt->firmware_ctrl); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->firmware_ctrl), + ACPI_BUILD_TABLE_FILE, facs_tbl_offset); - fadt->dsdt = cpu_to_le32(dsdt); /* DSDT address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TABLE_FILE, - table_data, &fadt->dsdt, - sizeof fadt->dsdt); - fadt_setup(fadt, pm); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt), + ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset); build_header(linker, table_data, (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id); } static void -build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms) +build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms) { MachineClass *mc = MACHINE_GET_CLASS(pcms); CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(pcms)); @@ -356,7 +350,7 @@ build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms) apic->type = ACPI_APIC_PROCESSOR; apic->length = sizeof(*apic); - apic->processor_id = apic_id; + apic->processor_id = i; apic->local_apic_id = apic_id; if (apic_ids->cpus[i].cpu != NULL) { apic->flags = cpu_to_le32(1); @@ -943,114 +937,6 @@ static Aml *build_crs(PCIHostState *host, return crs; } -static void build_processor_devices(Aml *sb_scope, MachineState *machine, - AcpiPmInfo *pm) -{ - int i, apic_idx; - Aml *dev; - Aml *crs; - Aml *pkg; - Aml *field; - Aml *ifctx; - Aml *method; - MachineClass *mc = MACHINE_GET_CLASS(machine); - CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine); - PCMachineState *pcms = PC_MACHINE(machine); - - /* The current AML generator can cover the APIC ID range [0..255], - * inclusive, for VCPU hotplug. */ - QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256); - g_assert(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT); - - /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */ - dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE)); - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06"))); - aml_append(dev, - aml_name_decl("_UID", aml_string("CPU Hotplug resources")) - ); - /* device present, functioning, decoding, not shown in UI */ - aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); - crs = aml_resource_template(); - aml_append(crs, - aml_io(AML_DECODE16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1, - pm->cpu_hp_io_len) - ); - aml_append(dev, aml_name_decl("_CRS", crs)); - aml_append(sb_scope, dev); - /* declare CPU hotplug MMIO region and PRS field to access it */ - aml_append(sb_scope, aml_operation_region( - "PRST", AML_SYSTEM_IO, aml_int(pm->cpu_hp_io_base), pm->cpu_hp_io_len)); - field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); - aml_append(field, aml_named_field("PRS", 256)); - aml_append(sb_scope, field); - - /* build Processor object for each processor */ - for (i = 0; i < apic_ids->len; i++) { - int apic_id = apic_ids->cpus[i].arch_id; - - assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT); - - dev = aml_processor(apic_id, 0, 0, "CP%.02X", apic_id); - - method = aml_method("_MAT", 0, AML_NOTSERIALIZED); - aml_append(method, - aml_return(aml_call1(CPU_MAT_METHOD, aml_int(apic_id)))); - aml_append(dev, method); - - method = aml_method("_STA", 0, AML_NOTSERIALIZED); - aml_append(method, - aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id)))); - aml_append(dev, method); - - method = aml_method("_EJ0", 1, AML_NOTSERIALIZED); - aml_append(method, - aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id), - aml_arg(0))) - ); - aml_append(dev, method); - - aml_append(sb_scope, dev); - } - - /* build this code: - * Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...} - */ - /* Arg0 = Processor ID = APIC ID */ - method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED); - for (i = 0; i < apic_ids->len; i++) { - int apic_id = apic_ids->cpus[i].arch_id; - - ifctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id))); - aml_append(ifctx, - aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1)) - ); - aml_append(method, ifctx); - } - aml_append(sb_scope, method); - - /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" - * - * Note: The ability to create variable-sized packages was first - * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages - * ith up to 255 elements. Windows guests up to win2k8 fail when - * VarPackageOp is used. - */ - pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) : - aml_varpackage(pcms->apic_id_limit); - - for (i = 0, apic_idx = 0; i < apic_ids->len; i++) { - int apic_id = apic_ids->cpus[i].arch_id; - - for (; apic_idx < apic_id; apic_idx++) { - aml_append(pkg, aml_int(0)); - } - aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0)); - apic_idx = apic_id + 1; - } - aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg)); - g_free(apic_ids); -} - static void build_memory_devices(Aml *sb_scope, int nr_mem, uint16_t io_base, uint16_t io_len) { @@ -1979,7 +1865,7 @@ static Aml *build_q35_osc_method(void) } static void -build_dsdt(GArray *table_data, GArray *linker, +build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, PcPciInfo *pci, MachineState *machine) { @@ -2043,7 +1929,7 @@ build_dsdt(GArray *table_data, GArray *linker, build_q35_pci0_int(dsdt); } - build_cpu_hotplug_aml(dsdt); + build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base); build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base, pm->mem_hp_io_len); @@ -2051,8 +1937,6 @@ build_dsdt(GArray *table_data, GArray *linker, { aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); - aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED)); - if (misc->is_piix4) { method = aml_method("_E01", 0, AML_NOTSERIALIZED); aml_append(method, @@ -2060,30 +1944,11 @@ build_dsdt(GArray *table_data, GArray *linker, aml_append(method, aml_call0("\\_SB.PCI0.PCNT")); aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK"))); aml_append(scope, method); - } else { - aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED)); } - method = aml_method("_E02", 0, AML_NOTSERIALIZED); - aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD)); - aml_append(scope, method); - method = aml_method("_E03", 0, AML_NOTSERIALIZED); aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH)); aml_append(scope, method); - - aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED)); - aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED)); } aml_append(dsdt, scope); @@ -2322,8 +2187,6 @@ build_dsdt(GArray *table_data, GArray *linker, sb_scope = aml_scope("\\_SB"); { - build_processor_devices(sb_scope, machine, pm); - build_memory_devices(sb_scope, nr_mem, pm->mem_hp_io_base, pm->mem_hp_io_len); @@ -2373,7 +2236,7 @@ build_dsdt(GArray *table_data, GArray *linker, } static void -build_hpet(GArray *table_data, GArray *linker) +build_hpet(GArray *table_data, BIOSLinker *linker) { Acpi20Hpet *hpet; @@ -2388,32 +2251,31 @@ build_hpet(GArray *table_data, GArray *linker) } static void -build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog) +build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) { Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa); - uint64_t log_area_start_address = acpi_data_len(tcpalog); + unsigned log_addr_size = sizeof(tcpa->log_area_start_address); + unsigned log_addr_offset = + (char *)&tcpa->log_area_start_address - table_data->data; tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT); tcpa->log_area_minimum_length = cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE); - tcpa->log_area_start_address = cpu_to_le64(log_area_start_address); + acpi_data_push(tcpalog, le32_to_cpu(tcpa->log_area_minimum_length)); - bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, 1, + bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, tcpalog, 1, false /* high memory */); /* log area start address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, - ACPI_BUILD_TPMLOG_FILE, - table_data, &tcpa->log_area_start_address, - sizeof(tcpa->log_area_start_address)); + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_TABLE_FILE, log_addr_offset, log_addr_size, + ACPI_BUILD_TPMLOG_FILE, 0); build_header(linker, table_data, (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL); - - acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE); } static void -build_tpm2(GArray *table_data, GArray *linker) +build_tpm2(GArray *table_data, BIOSLinker *linker) { Acpi20TPM2 *tpm2_ptr; @@ -2428,7 +2290,7 @@ build_tpm2(GArray *table_data, GArray *linker) } static void -build_srat(GArray *table_data, GArray *linker, MachineState *machine) +build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) { AcpiSystemResourceAffinityTable *srat; AcpiSratProcessorAffinity *core; @@ -2525,7 +2387,7 @@ build_srat(GArray *table_data, GArray *linker, MachineState *machine) } static void -build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info) +build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info) { AcpiTableMcfg *mcfg; const char *sig; @@ -2554,7 +2416,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info) } static void -build_dmar_q35(GArray *table_data, GArray *linker) +build_dmar_q35(GArray *table_data, BIOSLinker *linker) { int dmar_start = table_data->len; @@ -2578,26 +2440,27 @@ build_dmar_q35(GArray *table_data, GArray *linker) } static GArray * -build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt) +build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset) { AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp); + unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address); + unsigned rsdt_pa_offset = + (char *)&rsdp->rsdt_physical_address - rsdp_table->data; - bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16, + bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16, true /* fseg memory */); memcpy(&rsdp->signature, "RSD PTR ", 8); memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6); - rsdp->rsdt_physical_address = cpu_to_le32(rsdt); /* Address to be filled by Guest linker */ - bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE, - ACPI_BUILD_TABLE_FILE, - rsdp_table, &rsdp->rsdt_physical_address, - sizeof rsdp->rsdt_physical_address); - rsdp->checksum = 0; + bios_linker_loader_add_pointer(linker, + ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size, + ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset); + /* Checksum to be filled by Guest linker */ bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE, - rsdp_table, rsdp, sizeof *rsdp, - &rsdp->checksum); + (char *)rsdp - rsdp_table->data, sizeof *rsdp, + (char *)&rsdp->checksum - rsdp_table->data); return rsdp_table; } @@ -2670,7 +2533,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) sizeof(uint32_t)); ACPI_BUILD_DPRINTF("init ACPI tables\n"); - bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE, + bios_linker_loader_alloc(tables->linker, + ACPI_BUILD_TABLE_FILE, tables_blob, 64 /* Ensure FACS is aligned */, false /* high memory */); @@ -2727,7 +2591,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) build_dmar_q35(tables_blob, tables->linker); } if (pcms->acpi_nvdimm_state.is_enabled) { - nvdimm_build_acpi(table_offsets, tables_blob, tables->linker); + nvdimm_build_acpi(table_offsets, tables_blob, tables->linker, + pcms->acpi_nvdimm_state.dsm_mem); } /* Add tables supplied by user (if any) */ @@ -2790,7 +2655,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE); } - acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE); + acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE); /* Cleanup memory that's no longer used. */ g_array_free(table_offsets, true); @@ -2830,7 +2695,7 @@ static void acpi_build_update(void *build_opaque) acpi_ram_update(build_state->rsdp_mr, tables.rsdp); } - acpi_ram_update(build_state->linker_mr, tables.linker); + acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob); acpi_build_tables_cleanup(&tables, true); } @@ -2894,7 +2759,8 @@ void acpi_setup(void) assert(build_state->table_mr != NULL); build_state->linker_mr = - acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); + acpi_add_rom_blob(build_state, tables.linker->cmd_blob, + "etc/table-loader", 0); fw_cfg_add_file(pcms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index bfaf5a399b..7198ed533c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -765,8 +765,6 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms) acpi_tables, acpi_tables_len); fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override()); - pc_build_smbios(fw_cfg); - fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE, &e820_reserve, sizeof(e820_reserve)); fw_cfg_add_file(fw_cfg, "etc/e820", e820_table, @@ -1149,14 +1147,6 @@ void pc_cpus_init(PCMachineState *pcms) smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]); } -/* pci-info ROM file. Little endian format */ -typedef struct PcRomPciInfo { - uint64_t w32_min; - uint64_t w32_max; - uint64_t w64_min; - uint64_t w64_max; -} PcRomPciInfo; - static void pc_machine_done(Notifier *notifier, void *data) { @@ -1182,6 +1172,9 @@ void pc_machine_done(Notifier *notifier, void *data) } acpi_setup(); + if (pcms->fw_cfg) { + pc_build_smbios(pcms->fw_cfg); + } } void pc_guest_info_init(PCMachineState *pcms) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 7b4790f86f..14dd0cc774 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -23,7 +23,6 @@ */ #include "qemu/osdep.h" -#include <glib.h> #include "hw/hw.h" #include "hw/loader.h" diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 42ad68a1c0..78c10a0406 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -271,7 +271,8 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) if (s->lba == -1) { /* Non-block ATAPI transfer - just copy to RAM */ s->io_buffer_size = MIN(s->io_buffer_size, io->len); - cpu_physical_memory_write(io->addr, s->io_buffer, s->io_buffer_size); + dma_memory_write(&address_space_memory, io->addr, s->io_buffer, + s->io_buffer_size); ide_atapi_cmd_ok(s); m->dma_active = false; goto done; diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c index 725d5b62c5..2370e7485f 100644 --- a/hw/intc/aspeed_vic.c +++ b/hw/intc/aspeed_vic.c @@ -28,7 +28,6 @@ */ #include "qemu/osdep.h" -#include <inttypes.h> #include "hw/intc/aspeed_vic.h" #include "qemu/bitops.h" #include "qemu/log.h" diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c index 6adec1e990..f09f217e78 100644 --- a/hw/ipmi/ipmi.c +++ b/hw/ipmi/ipmi.c @@ -30,6 +30,13 @@ #include "qom/object_interfaces.h" #include "qapi/visitor.h" +static uint32_t ipmi_current_uuid = 1; + +uint32_t ipmi_next_uuid(void) +{ + return ipmi_current_uuid++; +} + static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly) { switch (op) { @@ -122,30 +129,3 @@ static void ipmi_register_types(void) } type_init(ipmi_register_types) - -static IPMIFwInfo *ipmi_fw_info; -static unsigned int ipmi_fw_info_len; - -static uint32_t current_uuid = 1; - -void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp) -{ - info->uuid = current_uuid++; - ipmi_fw_info = g_realloc(ipmi_fw_info, - sizeof(*ipmi_fw_info) * (ipmi_fw_info_len + 1)); - ipmi_fw_info[ipmi_fw_info_len] = *info; -} - -IPMIFwInfo *ipmi_first_fwinfo(void) -{ - return ipmi_fw_info; -} - -IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current) -{ - current++; - if (current >= &ipmi_fw_info[ipmi_fw_info_len]) { - return NULL; - } - return current; -} diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c index fe12112a2f..157879e177 100644 --- a/hw/ipmi/ipmi_bmc_extern.c +++ b/hw/ipmi/ipmi_bmc_extern.c @@ -190,7 +190,7 @@ static void ipmi_bmc_extern_handle_command(IPMIBmc *b, if (ibe->outlen) { /* We already have a command queued. Shouldn't ever happen. */ fprintf(stderr, "IPMI KCS: Got command when not finished with the" - " previous commmand\n"); + " previous command\n"); abort(); } diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index aaea12ecdd..f03661715c 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -390,16 +390,6 @@ static void ipmi_bt_init(IPMIInterface *ii, Error **errp) memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3); } -static void ipmi_bt_class_init(IPMIInterfaceClass *iic) -{ - iic->init = ipmi_bt_init; - iic->set_atn = ipmi_bt_set_atn; - iic->handle_rsp = ipmi_bt_handle_rsp; - iic->handle_if_event = ipmi_bt_handle_event; - iic->set_irq_enable = ipmi_bt_set_irq_enable; - iic->reset = ipmi_bt_handle_reset; -} - #define TYPE_ISA_IPMI_BT "isa-ipmi-bt" #define ISA_IPMI_BT(obj) OBJECT_CHECK(ISAIPMIBTDevice, (obj), \ @@ -409,9 +399,38 @@ typedef struct ISAIPMIBTDevice { ISADevice dev; int32_t isairq; IPMIBT bt; - IPMIFwInfo fwinfo; + uint32_t uuid; } ISAIPMIBTDevice; +static void ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info) +{ + ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii); + + info->interface_name = "bt"; + info->interface_type = IPMI_SMBIOS_BT; + info->ipmi_spec_major_revision = 2; + info->ipmi_spec_minor_revision = 0; + info->base_address = iib->bt.io_base; + info->register_length = iib->bt.io_length; + info->register_spacing = 1; + info->memspace = IPMI_MEMSPACE_IO; + info->irq_type = IPMI_LEVEL_IRQ; + info->interrupt_number = iib->isairq; + info->i2c_slave_address = iib->bt.bmc->slave_addr; + info->uuid = iib->uuid; +} + +static void ipmi_bt_class_init(IPMIInterfaceClass *iic) +{ + iic->init = ipmi_bt_init; + iic->set_atn = ipmi_bt_set_atn; + iic->handle_rsp = ipmi_bt_handle_rsp; + iic->handle_if_event = ipmi_bt_handle_event; + iic->set_irq_enable = ipmi_bt_set_irq_enable; + iic->reset = ipmi_bt_handle_reset; + iic->get_fwinfo = ipmi_bt_get_fwinfo; +} + static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) { ISADevice *isadev = ISA_DEVICE(dev); @@ -424,6 +443,8 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) return; } + iib->uuid = ipmi_next_uuid(); + iib->bt.bmc->intf = ii; iic->init(ii, errp); @@ -438,20 +459,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp) qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length); isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base); - - iib->fwinfo.interface_name = "bt"; - iib->fwinfo.interface_type = IPMI_SMBIOS_BT; - iib->fwinfo.ipmi_spec_major_revision = 2; - iib->fwinfo.ipmi_spec_minor_revision = 0; - iib->fwinfo.base_address = iib->bt.io_base; - iib->fwinfo.register_length = iib->bt.io_length; - iib->fwinfo.register_spacing = 1; - iib->fwinfo.memspace = IPMI_MEMSPACE_IO; - iib->fwinfo.irq_type = IPMI_LEVEL_IRQ; - iib->fwinfo.interrupt_number = iib->isairq; - iib->fwinfo.acpi_parent = "\\_SB.PCI0.ISA"; - iib->fwinfo.i2c_slave_address = iib->bt.bmc->slave_addr; - ipmi_add_fwinfo(&iib->fwinfo, errp); } static const VMStateDescription vmstate_ISAIPMIBTDevice = { diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c index 2742ce06c4..9a38f8a28a 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -354,16 +354,6 @@ static void ipmi_kcs_init(IPMIInterface *ii, Error **errp) memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2); } -static void ipmi_kcs_class_init(IPMIInterfaceClass *iic) -{ - iic->init = ipmi_kcs_init; - iic->set_atn = ipmi_kcs_set_atn; - iic->handle_rsp = ipmi_kcs_handle_rsp; - iic->handle_if_event = ipmi_kcs_handle_event; - iic->set_irq_enable = ipmi_kcs_set_irq_enable; -} - - #define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs" #define ISA_IPMI_KCS(obj) OBJECT_CHECK(ISAIPMIKCSDevice, (obj), \ TYPE_ISA_IPMI_KCS) @@ -372,9 +362,37 @@ typedef struct ISAIPMIKCSDevice { ISADevice dev; int32_t isairq; IPMIKCS kcs; - IPMIFwInfo fwinfo; + uint32_t uuid; } ISAIPMIKCSDevice; +static void ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info) +{ + ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii); + + info->interface_name = "kcs"; + info->interface_type = IPMI_SMBIOS_KCS; + info->ipmi_spec_major_revision = 2; + info->ipmi_spec_minor_revision = 0; + info->base_address = iik->kcs.io_base; + info->i2c_slave_address = iik->kcs.bmc->slave_addr; + info->register_length = iik->kcs.io_length; + info->register_spacing = 1; + info->memspace = IPMI_MEMSPACE_IO; + info->irq_type = IPMI_LEVEL_IRQ; + info->interrupt_number = iik->isairq; + info->uuid = iik->uuid; +} + +static void ipmi_kcs_class_init(IPMIInterfaceClass *iic) +{ + iic->init = ipmi_kcs_init; + iic->set_atn = ipmi_kcs_set_atn; + iic->handle_rsp = ipmi_kcs_handle_rsp; + iic->handle_if_event = ipmi_kcs_handle_event; + iic->set_irq_enable = ipmi_kcs_set_irq_enable; + iic->get_fwinfo = ipmi_kcs_get_fwinfo; +} + static void ipmi_isa_realize(DeviceState *dev, Error **errp) { ISADevice *isadev = ISA_DEVICE(dev); @@ -387,6 +405,8 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) return; } + iik->uuid = ipmi_next_uuid(); + iik->kcs.bmc->intf = ii; iic->init(ii, errp); @@ -401,20 +421,6 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp) qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length); isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base); - - iik->fwinfo.interface_name = "kcs"; - iik->fwinfo.interface_type = IPMI_SMBIOS_KCS; - iik->fwinfo.ipmi_spec_major_revision = 2; - iik->fwinfo.ipmi_spec_minor_revision = 0; - iik->fwinfo.base_address = iik->kcs.io_base; - iik->fwinfo.i2c_slave_address = iik->kcs.bmc->slave_addr; - iik->fwinfo.register_length = iik->kcs.io_length; - iik->fwinfo.register_spacing = 1; - iik->fwinfo.memspace = IPMI_MEMSPACE_IO; - iik->fwinfo.irq_type = IPMI_LEVEL_IRQ; - iik->fwinfo.interrupt_number = iik->isairq; - iik->fwinfo.acpi_parent = "\\_SB.PCI0.ISA"; - ipmi_add_fwinfo(&iik->fwinfo, errp); } const VMStateDescription vmstate_ISAIPMIKCSDevice = { diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 4f8ca45f6d..213741bc21 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -97,8 +97,8 @@ static void ich9_cc_update(ICH9LPCState *lpc) /* * D30: DMI2PCI bridge - * It is arbitrarily decided how INTx lines of PCI devicesbehind the bridge - * are connected to pirq lines. Our choice is PIRQ[E-H]. + * It is arbitrarily decided how INTx lines of PCI devices behind + * the bridge are connected to pirq lines. Our choice is PIRQ[E-H]. * INT[A-D] are connected to PIRQ[E-H] */ for (pci_intx = 0; pci_intx < PCI_NUM_PINS; pci_intx++) { @@ -637,30 +637,6 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) 1); } -static void ich9_device_plug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); - - ich9_pm_device_plug_cb(&lpc->pm, dev, errp); -} - -static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); - - ich9_pm_device_unplug_request_cb(&lpc->pm, dev, errp); -} - -static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev, - DeviceState *dev, Error **errp) -{ - ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); - - ich9_pm_device_unplug_cb(&lpc->pm, dev, errp); -} - static bool ich9_rst_cnt_needed(void *opaque) { ICH9LPCState *lpc = opaque; @@ -703,6 +679,13 @@ static Property ich9_lpc_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void ich9_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev) +{ + ICH9LPCState *s = ICH9_LPC_DEVICE(adev); + + acpi_send_gpe_event(&s->pm.acpi_regs, s->pm.irq, ev); +} + static void ich9_lpc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -726,10 +709,11 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data) * pc_q35_init() */ dc->cannot_instantiate_with_device_add_yet = true; - hc->plug = ich9_device_plug_cb; - hc->unplug_request = ich9_device_unplug_request_cb; - hc->unplug = ich9_device_unplug_cb; + hc->plug = ich9_pm_device_plug_cb; + hc->unplug_request = ich9_pm_device_unplug_request_cb; + hc->unplug = ich9_pm_device_unplug_cb; adevc->ospm_status = ich9_pm_ospm_status; + adevc->send_event = ich9_send_gpe; } static const TypeInfo ich9_lpc_info = { diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 9e7de56829..6de2275986 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -354,8 +354,9 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name, int64_t value; MemoryRegion *mr; PCDIMMDevice *dimm = PC_DIMM(obj); + PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj); - mr = host_memory_backend_get_memory(dimm->hostmem, errp); + mr = ddc->get_memory_region(dimm); value = memory_region_size(mr); visit_type_int(v, name, &value, errp); @@ -399,6 +400,7 @@ static void pc_dimm_init(Object *obj) static void pc_dimm_realize(DeviceState *dev, Error **errp) { PCDIMMDevice *dimm = PC_DIMM(dev); + PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); if (!dimm->hostmem) { error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set"); @@ -411,6 +413,10 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp) dimm->node, nb_numa_nodes ? nb_numa_nodes : 1); return; } + + if (ddc->realize) { + ddc->realize(dimm, errp); + } } static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 5632743d36..f116f9c36d 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -42,6 +42,7 @@ #include "hw/ppc/mac_dbdma.h" #include "qemu/main-loop.h" #include "qemu/log.h" +#include "sysemu/dma.h" /* debug DBDMA */ //#define DEBUG_DBDMA @@ -81,8 +82,8 @@ static void dbdma_cmdptr_load(DBDMA_channel *ch) { DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n", ch->regs[DBDMA_CMDPTR_LO]); - cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO], - &ch->current, sizeof(dbdma_cmd)); + dma_memory_read(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], + &ch->current, sizeof(dbdma_cmd)); } static void dbdma_cmdptr_save(DBDMA_channel *ch) @@ -92,8 +93,8 @@ static void dbdma_cmdptr_save(DBDMA_channel *ch) DBDMA_DPRINTF("xfer_status 0x%08x res_count 0x%04x\n", le16_to_cpu(ch->current.xfer_status), le16_to_cpu(ch->current.res_count)); - cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO], - &ch->current, sizeof(dbdma_cmd)); + dma_memory_write(&address_space_memory, ch->regs[DBDMA_CMDPTR_LO], + &ch->current, sizeof(dbdma_cmd)); } static void kill_channel(DBDMA_channel *ch) @@ -353,7 +354,7 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr, return; } - cpu_physical_memory_read(addr, &val, len); + dma_memory_read(&address_space_memory, addr, &val, len); if (len == 2) val = (val << 16) | (current->cmd_dep & 0x0000ffff); @@ -398,7 +399,7 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr, else if (len == 1) val >>= 24; - cpu_physical_memory_write(addr, &val, len); + dma_memory_write(&address_space_memory, addr, &val, len); if (conditional_wait(ch)) goto wait; diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 36e3dbe347..1202371271 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -311,11 +311,9 @@ set_interrupt_cause(E1000State *s, int index, uint32_t val) */ mit_delay = (mit_delay < 500) ? 500 : mit_delay; - if (mit_delay) { - s->mit_timer_on = 1; - timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - mit_delay * 256); - } + s->mit_timer_on = 1; + timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + mit_delay * 256); s->mit_ide = 0; } } diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c index 0a134ebca8..9b1e0d2441 100644 --- a/hw/net/rocker/rocker_of_dpa.c +++ b/hw/net/rocker/rocker_of_dpa.c @@ -103,9 +103,8 @@ typedef struct of_dpa_flow_key { /* Width of key which includes field 'f' in u64s, rounded up */ #define FLOW_KEY_WIDTH(f) \ - ((offsetof(OfDpaFlowKey, f) + \ - sizeof(((OfDpaFlowKey *)0)->f) + \ - sizeof(uint64_t) - 1) / sizeof(uint64_t)) + DIV_ROUND_UP(offsetof(OfDpaFlowKey, f) + sizeof(((OfDpaFlowKey *)0)->f), \ + sizeof(uint64_t)) typedef struct of_dpa_flow_action { uint32_t goto_tbl; diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index cdbdfb5320..74a0079ca6 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -729,15 +729,20 @@ static int get_fw_cfg_order(FWCfgState *s, const char *name) { int i; - if (s->fw_cfg_order_override > 0) - return s->fw_cfg_order_override; + if (s->fw_cfg_order_override > 0) { + return s->fw_cfg_order_override; + } for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) { - if (fw_cfg_order[i].name == NULL) - continue; - if (strcmp(name, fw_cfg_order[i].name) == 0) - return fw_cfg_order[i].order; + if (fw_cfg_order[i].name == NULL) { + continue; + } + + if (strcmp(name, fw_cfg_order[i].name) == 0) { + return fw_cfg_order[i].order; + } } + /* Stick unknown stuff at the end. */ error_report("warning: Unknown firmware file in legacy mode: %s\n", name); return FW_CFG_ORDER_OVERRIDE_LAST; diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index cdf9f258ae..1bcf740f0e 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -880,7 +880,7 @@ static int timebase_post_load(void *opaque, int version_id) host_ns = qemu_clock_get_ns(QEMU_CLOCK_HOST); ns_diff = MAX(0, host_ns - tb_remote->time_of_the_day_ns); migration_duration_ns = MIN(NANOSECONDS_PER_SECOND, ns_diff); - migration_duration_tb = muldiv64(migration_duration_ns, freq, + migration_duration_tb = muldiv64(freq, migration_duration_ns, NANOSECONDS_PER_SECOND); guest_tb = tb_remote->guest_timebase + MIN(0, migration_duration_tb); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 44e401ae99..0636642341 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1816,11 +1816,21 @@ static void ppc_spapr_init(MachineState *machine) /* initialize hotplug memory address space */ if (machine->ram_size < machine->maxram_size) { ram_addr_t hotplug_mem_size = machine->maxram_size - machine->ram_size; + /* + * Limit the number of hotpluggable memory slots to half the number + * slots that KVM supports, leaving the other half for PCI and other + * devices. However ensure that number of slots doesn't drop below 32. + */ + int max_memslots = kvm_enabled() ? kvm_get_max_memslots() / 2 : + SPAPR_MAX_RAM_SLOTS; - if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) { + if (max_memslots < SPAPR_MAX_RAM_SLOTS) { + max_memslots = SPAPR_MAX_RAM_SLOTS; + } + if (machine->ram_slots > max_memslots) { error_report("Specified number of memory slots %" PRIu64" exceeds max supported %d", - machine->ram_slots, SPAPR_MAX_RAM_SLOTS); + machine->ram_slots, max_memslots); exit(1); } @@ -2344,18 +2354,36 @@ static const TypeInfo spapr_machine_info = { type_init(spapr_machine_register_##suffix) /* + * pseries-2.7 + */ +static void spapr_machine_2_7_instance_options(MachineState *machine) +{ +} + +static void spapr_machine_2_7_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(2_7, "2.7", true); + +/* * pseries-2.6 */ +#define SPAPR_COMPAT_2_6 \ + HW_COMPAT_2_6 + static void spapr_machine_2_6_instance_options(MachineState *machine) { } static void spapr_machine_2_6_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_2_7_class_options(mc); + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6); } -DEFINE_SPAPR_MACHINE(2_6, "2.6", true); +DEFINE_SPAPR_MACHINE(2_6, "2.6", false); /* * pseries-2.5 diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 96bb0181a7..a3cc5722f1 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -17,6 +17,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qemu/error-report.h" #include "hw/hw.h" #include "qemu/log.h" #include "sysemu/kvm.h" @@ -137,33 +138,92 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr, return ret; } +static void spapr_tce_table_pre_save(void *opaque) +{ + sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); + + tcet->mig_table = tcet->table; + tcet->mig_nb_table = tcet->nb_table; + + trace_spapr_iommu_pre_save(tcet->liobn, tcet->mig_nb_table, + tcet->bus_offset, tcet->page_shift); +} + static int spapr_tce_table_post_load(void *opaque, int version_id) { sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque); + uint32_t old_nb_table = tcet->nb_table; + uint64_t old_bus_offset = tcet->bus_offset; + uint32_t old_page_shift = tcet->page_shift; if (tcet->vdev) { spapr_vio_set_bypass(tcet->vdev, tcet->bypass); } + if (tcet->mig_nb_table != tcet->nb_table) { + spapr_tce_table_disable(tcet); + } + + if (tcet->mig_nb_table) { + if (!tcet->nb_table) { + spapr_tce_table_enable(tcet, old_page_shift, old_bus_offset, + tcet->mig_nb_table); + } + + memcpy(tcet->table, tcet->mig_table, + tcet->nb_table * sizeof(tcet->table[0])); + + free(tcet->mig_table); + tcet->mig_table = NULL; + } + + trace_spapr_iommu_post_load(tcet->liobn, old_nb_table, tcet->nb_table, + tcet->bus_offset, tcet->page_shift); + return 0; } +static bool spapr_tce_table_ex_needed(void *opaque) +{ + sPAPRTCETable *tcet = opaque; + + return tcet->bus_offset || tcet->page_shift != 0xC; +} + +static const VMStateDescription vmstate_spapr_tce_table_ex = { + .name = "spapr_iommu_ex", + .version_id = 1, + .minimum_version_id = 1, + .needed = spapr_tce_table_ex_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(bus_offset, sPAPRTCETable), + VMSTATE_UINT32(page_shift, sPAPRTCETable), + VMSTATE_END_OF_LIST() + }, +}; + static const VMStateDescription vmstate_spapr_tce_table = { .name = "spapr_iommu", .version_id = 2, .minimum_version_id = 2, + .pre_save = spapr_tce_table_pre_save, .post_load = spapr_tce_table_post_load, .fields = (VMStateField []) { /* Sanity check */ VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable), - VMSTATE_UINT32_EQUAL(nb_table, sPAPRTCETable), /* IOMMU state */ + VMSTATE_UINT32(mig_nb_table, sPAPRTCETable), VMSTATE_BOOL(bypass, sPAPRTCETable), - VMSTATE_VARRAY_UINT32(table, sPAPRTCETable, nb_table, 0, vmstate_info_uint64, uint64_t), + VMSTATE_VARRAY_UINT32_ALLOC(mig_table, sPAPRTCETable, mig_nb_table, 0, + vmstate_info_uint64, uint64_t), VMSTATE_END_OF_LIST() }, + .subsections = (const VMStateDescription*[]) { + &vmstate_spapr_tce_table_ex, + NULL + } }; static MemoryRegionIOMMUOps spapr_iommu_ops = { @@ -173,17 +233,16 @@ static MemoryRegionIOMMUOps spapr_iommu_ops = { static int spapr_tce_table_realize(DeviceState *dev) { sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); + Object *tcetobj = OBJECT(tcet); + char tmp[32]; tcet->fd = -1; - tcet->table = spapr_tce_alloc_table(tcet->liobn, - tcet->page_shift, - tcet->nb_table, - &tcet->fd, - tcet->need_vfio); + tcet->need_vfio = false; + snprintf(tmp, sizeof(tmp), "tce-root-%x", tcet->liobn); + memory_region_init(&tcet->root, tcetobj, tmp, UINT64_MAX); - memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops, - "iommu-spapr", - (uint64_t)tcet->nb_table << tcet->page_shift); + snprintf(tmp, sizeof(tmp), "tce-iommu-%x", tcet->liobn); + memory_region_init_iommu(&tcet->iommu, tcetobj, &spapr_iommu_ops, tmp, 0); QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); @@ -225,14 +284,10 @@ void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio) tcet->table = newtable; } -sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, - uint64_t bus_offset, - uint32_t page_shift, - uint32_t nb_table, - bool need_vfio) +sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn) { sPAPRTCETable *tcet; - char tmp[64]; + char tmp[32]; if (spapr_tce_find_by_liobn(liobn)) { fprintf(stderr, "Attempted to create TCE table with duplicate" @@ -240,16 +295,8 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, return NULL; } - if (!nb_table) { - return NULL; - } - tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE)); tcet->liobn = liobn; - tcet->bus_offset = bus_offset; - tcet->page_shift = page_shift; - tcet->nb_table = nb_table; - tcet->need_vfio = need_vfio; snprintf(tmp, sizeof(tmp), "tce-table-%x", liobn); object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet), NULL); @@ -259,19 +306,58 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, return tcet; } +void spapr_tce_table_enable(sPAPRTCETable *tcet, + uint32_t page_shift, uint64_t bus_offset, + uint32_t nb_table) +{ + if (tcet->nb_table) { + error_report("Warning: trying to enable already enabled TCE table"); + return; + } + + tcet->bus_offset = bus_offset; + tcet->page_shift = page_shift; + tcet->nb_table = nb_table; + tcet->table = spapr_tce_alloc_table(tcet->liobn, + tcet->page_shift, + tcet->nb_table, + &tcet->fd, + tcet->need_vfio); + + memory_region_set_size(&tcet->iommu, + (uint64_t)tcet->nb_table << tcet->page_shift); + memory_region_add_subregion(&tcet->root, tcet->bus_offset, &tcet->iommu); +} + +void spapr_tce_table_disable(sPAPRTCETable *tcet) +{ + if (!tcet->nb_table) { + return; + } + + memory_region_del_subregion(&tcet->root, &tcet->iommu); + memory_region_set_size(&tcet->iommu, 0); + + spapr_tce_free_table(tcet->table, tcet->fd, tcet->nb_table); + tcet->fd = -1; + tcet->table = NULL; + tcet->bus_offset = 0; + tcet->page_shift = 0; + tcet->nb_table = 0; +} + static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp) { sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev); QLIST_REMOVE(tcet, list); - spapr_tce_free_table(tcet->table, tcet->fd, tcet->nb_table); - tcet->fd = -1; + spapr_tce_table_disable(tcet); } MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet) { - return &tcet->iommu; + return &tcet->root; } static void spapr_tce_reset(DeviceState *dev) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 856aec7f51..9f28fb3829 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1310,7 +1310,6 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) PCIBus *bus; uint64_t msi_window_size = 4096; sPAPRTCETable *tcet; - uint32_t nb_table; if (sphb->index != (uint32_t)-1) { hwaddr windows_base; @@ -1462,18 +1461,15 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) } } - nb_table = sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT; - tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn, - 0, SPAPR_TCE_PAGE_SHIFT, nb_table, false); + tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn); if (!tcet) { error_setg(errp, "Unable to create TCE table for %s", sphb->dtbusname); return; } - /* Register default 32bit DMA window */ - memory_region_add_subregion(&sphb->iommu_root, sphb->dma_win_addr, - spapr_tce_get_iommu(tcet)); + memory_region_add_subregion_overlap(&sphb->iommu_root, 0, + spapr_tce_get_iommu(tcet), 0); sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); } @@ -1489,8 +1485,25 @@ static int spapr_phb_children_reset(Object *child, void *opaque) return 0; } +void spapr_phb_dma_reset(sPAPRPHBState *sphb) +{ + sPAPRTCETable *tcet = spapr_tce_find_by_liobn(sphb->dma_liobn); + + if (tcet && tcet->nb_table) { + spapr_tce_table_disable(tcet); + } + + /* Register default 32bit DMA window */ + spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr, + sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT); +} + static void spapr_phb_reset(DeviceState *qdev) { + sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(qdev); + + spapr_phb_dma_reset(sphb); + /* Reset the IOMMU state */ object_child_foreach(OBJECT(qdev), spapr_phb_children_reset, NULL); @@ -1624,7 +1637,6 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data) dc->reset = spapr_phb_reset; dc->vmsd = &vmstate_spapr_pci; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); - dc->cannot_instantiate_with_device_add_yet = false; hp->plug = spapr_phb_hot_plug_child; hp->unplug = spapr_phb_hot_unplug_child; } diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index d084aedadf..3d9b9c60f4 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -483,11 +483,9 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) memory_region_add_subregion_overlap(&dev->mrroot, 0, &dev->mrbypass, 1); address_space_init(&dev->as, &dev->mrroot, qdev->id); - dev->tcet = spapr_tce_new_table(qdev, liobn, - 0, - SPAPR_TCE_PAGE_SHIFT, - pc->rtce_window_size >> - SPAPR_TCE_PAGE_SHIFT, false); + dev->tcet = spapr_tce_new_table(qdev, liobn); + spapr_tce_table_enable(dev->tcet, SPAPR_TCE_PAGE_SHIFT, 0, + pc->rtce_window_size >> SPAPR_TCE_PAGE_SHIFT); dev->tcet->vdev = dev; memory_region_add_subregion_overlap(&dev->mrroot, 0, spapr_tce_get_iommu(dev->tcet), 2); diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index a1c1ed9496..2b68e5e87d 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1476,7 +1476,7 @@ static void virtio_ccw_device_plugged(DeviceState *d, Error **errp) int n = virtio_get_num_queues(vdev); if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) { - error_setg(errp, "The nubmer of virtqueues %d " + error_setg(errp, "The number of virtqueues %d " "exceeds ccw limit %d", n, VIRTIO_CCW_QUEUE_MAX); return; diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 30415c6a92..71d09d3ef3 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -185,7 +185,7 @@ static void virtio_scsi_save_request(QEMUFile *f, SCSIRequest *sreq) { VirtIOSCSIReq *req = sreq->hba_private; VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(req->dev); - uint32_t n = virtio_queue_get_id(req->vq) - 2; + uint32_t n = virtio_get_queue_index(req->vq) - 2; assert(n < vs->conf.num_queues); qemu_put_be32s(f, &n); @@ -773,22 +773,6 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense) } } -static void virtio_scsi_blk_insert_notifier(Notifier *n, void *data) -{ - VirtIOSCSIBlkChangeNotifier *cn = DO_UPCAST(VirtIOSCSIBlkChangeNotifier, - n, n); - assert(cn->sd->conf.blk == data); - blk_op_block_all(cn->sd->conf.blk, cn->s->blocker); -} - -static void virtio_scsi_blk_remove_notifier(Notifier *n, void *data) -{ - VirtIOSCSIBlkChangeNotifier *cn = DO_UPCAST(VirtIOSCSIBlkChangeNotifier, - n, n); - assert(cn->sd->conf.blk == data); - blk_op_unblock_all(cn->sd->conf.blk, cn->s->blocker); -} - static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -797,29 +781,13 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, SCSIDevice *sd = SCSI_DEVICE(dev); if (s->ctx && !s->dataplane_fenced) { - VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier; - if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { return; } - blk_op_block_all(sd->conf.blk, s->blocker); aio_context_acquire(s->ctx); blk_set_aio_context(sd->conf.blk, s->ctx); aio_context_release(s->ctx); - insert_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1); - insert_notifier->n.notify = virtio_scsi_blk_insert_notifier; - insert_notifier->s = s; - insert_notifier->sd = sd; - blk_add_insert_bs_notifier(sd->conf.blk, &insert_notifier->n); - QTAILQ_INSERT_TAIL(&s->insert_notifiers, insert_notifier, next); - - remove_notifier = g_new0(VirtIOSCSIBlkChangeNotifier, 1); - remove_notifier->n.notify = virtio_scsi_blk_remove_notifier; - remove_notifier->s = s; - remove_notifier->sd = sd; - blk_add_remove_bs_notifier(sd->conf.blk, &remove_notifier->n); - QTAILQ_INSERT_TAIL(&s->remove_notifiers, remove_notifier, next); } if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { @@ -835,7 +803,6 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev); VirtIOSCSI *s = VIRTIO_SCSI(vdev); SCSIDevice *sd = SCSI_DEVICE(dev); - VirtIOSCSIBlkChangeNotifier *insert_notifier, *remove_notifier; if (virtio_vdev_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) { virtio_scsi_push_event(s, sd, @@ -843,28 +810,6 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, VIRTIO_SCSI_EVT_RESET_REMOVED); } - if (s->ctx) { - blk_op_unblock_all(sd->conf.blk, s->blocker); - } - - QTAILQ_FOREACH(insert_notifier, &s->insert_notifiers, next) { - if (insert_notifier->sd == sd) { - notifier_remove(&insert_notifier->n); - QTAILQ_REMOVE(&s->insert_notifiers, insert_notifier, next); - g_free(insert_notifier); - break; - } - } - - QTAILQ_FOREACH(remove_notifier, &s->remove_notifiers, next) { - if (remove_notifier->sd == sd) { - notifier_remove(&remove_notifier->n); - QTAILQ_REMOVE(&s->remove_notifiers, remove_notifier, next); - g_free(remove_notifier); - break; - } - } - qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); } @@ -950,11 +895,6 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp) register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1, virtio_scsi_save, virtio_scsi_load, s); - - error_setg(&s->blocker, "block device is in use by data plane"); - - QTAILQ_INIT(&s->insert_notifiers); - QTAILQ_INIT(&s->remove_notifiers); } static void virtio_scsi_instance_init(Object *obj) @@ -980,8 +920,6 @@ static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp) { VirtIOSCSI *s = VIRTIO_SCSI(dev); - error_free(s->blocker); - unregister_savevm(dev, "virtio-scsi", s); virtio_scsi_common_unrealize(dev, errp); } diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 2ac0fd3e48..a11b8b4b21 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -22,7 +22,6 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" -#include "config-target.h" #include "qemu/cutils.h" #include "qemu/bcd.h" #include "hw/hw.h" diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c index 3a43863042..5e3e8a6d70 100644 --- a/hw/timer/omap_gptimer.c +++ b/hw/timer/omap_gptimer.c @@ -133,8 +133,8 @@ static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer) timer_mod(timer->timer, timer->time + expires); if (timer->ce && timer->match_val >= timer->val) { - matches = muldiv64(timer->match_val - timer->val, - timer->ticks_per_sec, timer->rate); + matches = muldiv64(timer->ticks_per_sec, + timer->match_val - timer->val, timer->rate); timer_mod(timer->match, timer->time + matches); } else timer_del(timer->match); diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 16d9ff7b4b..fa5703832c 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -1474,7 +1474,7 @@ static uint32_t ohci_get_frame_remaining(OHCIState *ohci) if (tks >= usb_frame_time) return (ohci->frt << 31); - tks = muldiv64(1, tks, usb_bit_time); + tks = tks / usb_bit_time; fr = (uint16_t)(ohci->fi - tks); return (ohci->frt << 31) | fr; diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 8d8054037f..8ec8484349 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -542,9 +542,9 @@ static void usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p, start_iso.pkts_per_urb = 32; } - start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size + - start_iso.pkts_per_urb - 1) / - start_iso.pkts_per_urb; + start_iso.no_urbs = DIV_ROUND_UP( + dev->endpoint[EP2I(ep)].bufpq_target_size, + start_iso.pkts_per_urb); /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest as overflow buffer. Also see the usbredir protocol documentation */ if (!(ep & USB_DIR_IN)) { diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 4400718154..81cc5b0ae3 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -767,15 +767,11 @@ static inline bool vhost_needs_vring_endian(VirtIODevice *vdev) if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { return false; } -#ifdef TARGET_IS_BIENDIAN #ifdef HOST_WORDS_BIGENDIAN return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_LITTLE; #else return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG; #endif -#else - return false; -#endif } static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev, diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 30ede3d1cc..7ed06eafa6 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1062,13 +1062,6 @@ int virtio_get_num_queues(VirtIODevice *vdev) return i; } -int virtio_queue_get_id(VirtQueue *vq) -{ - VirtIODevice *vdev = vq->vdev; - assert(vq >= &vdev->vq[0] && vq < &vdev->vq[VIRTIO_QUEUE_MAX]); - return vq - &vdev->vq[0]; -} - void virtio_queue_set_align(VirtIODevice *vdev, int n, int align) { BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index ccf65fd8ad..2bed64f15b 100644 --- a/hw/xtensa/pic_cpu.c +++ b/hw/xtensa/pic_cpu.c @@ -122,8 +122,8 @@ void xtensa_rearm_ccompare_timer(CPUXtensaState *env) } env->wake_ccount = wake_ccount; timer_mod(env->ccompare_timer, env->halt_clock + - muldiv64(wake_ccount - env->sregs[CCOUNT], - 1000000, env->config->clock_freq_khz)); + (uint64_t)(wake_ccount - env->sregs[CCOUNT]) * + 1000000 / env->config->clock_freq_khz); } static void xtensa_ccompare_cb(void *opaque) |