mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
vhost, virtio, pci, pc, acpi nvdimm work sparse cpu id rework ipmi enhancements fixes all over the place pxb option to tweak chassis number Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Tue 15 Mar 2016 14:33:10 GMT using RSA key ID D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: (51 commits) hw/acpi: fix GSI links UID ipmi: add some local variables in ipmi_sdr_init ipmi: remove the need of an ending record in the SDR table ipmi: use a function to initialize the SDR table ipmi: add a realize function to the device class ipmi: add rsp_buffer_set_error() helper ipmi: remove IPMI_CHECK_RESERVATION() macro ipmi: replace IPMI_ADD_RSP_DATA() macro with inline helpers ipmi: remove IPMI_CHECK_CMD_LEN() macro MAINTAINERS: machine core MAINTAINERS: Add an entry for virtio header files pc: acpi: clarify why possible LAPIC entries must be present in MADT pc: acpi: drop cpu->found_cpus bitmap pc: acpi: create Processor and Notify objects only for valid lapics pc: acpi: create MADT.lapic entries only for valid lapics pc: acpi: SRAT: create only valid processor lapic entries pc: acpi: cleanup qdev_get_machine() calls machine: introduce MachineClass.possible_cpu_arch_ids() hook pc: init pcms->apic_id_limit once and use it throughout pc.c pc: acpi: remove NOP assignment ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -717,6 +717,12 @@ F: hw/timer/hpet*
|
||||
F: hw/timer/i8254*
|
||||
F: hw/timer/mc146818rtc*
|
||||
|
||||
Machine core
|
||||
M: Eduardo Habkost <ehabkost@redhat.com>
|
||||
M: Marcel Apfelbaum <marcel@redhat.com>
|
||||
S: Supported
|
||||
F: hw/core/machine.c
|
||||
F: include/hw/boards.h
|
||||
|
||||
Xtensa Machines
|
||||
---------------
|
||||
@@ -878,6 +884,7 @@ M: Michael S. Tsirkin <mst@redhat.com>
|
||||
S: Supported
|
||||
F: hw/*/virtio*
|
||||
F: net/vhost-user.c
|
||||
F: include/hw/virtio/
|
||||
|
||||
virtio-9p
|
||||
M: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
||||
|
||||
@@ -24,8 +24,8 @@ A detailed command line would be:
|
||||
-object memory-backend-ram,size=1024M,policy=bind,host-nodes=0,id=ram-node0 -numa node,nodeid=0,cpus=0,memdev=ram-node0
|
||||
-object memory-backend-ram,size=1024M,policy=bind,host-nodes=1,id=ram-node1 -numa node,nodeid=1,cpus=1,memdev=ram-node1
|
||||
-device pxb,id=bridge1,bus=pci.0,numa_node=1,bus_nr=4 -netdev user,id=nd -device e1000,bus=bridge1,addr=0x4,netdev=nd
|
||||
-device pxb,id=bridge2,bus=pci.0,numa_node=0,bus_nr=8, -device e1000,bus=bridge2,addr=0x3
|
||||
-device pxb,id=bridge3,bus=pci.0,bus_nr=40, -drive if=none,id=drive0,file=[img] -device virtio-blk-pci,drive=drive0,scsi=off,bus=bridge3,addr=1
|
||||
-device pxb,id=bridge2,bus=pci.0,numa_node=0,bus_nr=8 -device e1000,bus=bridge2,addr=0x3
|
||||
-device pxb,id=bridge3,bus=pci.0,bus_nr=40 -drive if=none,id=drive0,file=[img] -device virtio-blk-pci,drive=drive0,scsi=off,bus=bridge3,addr=1
|
||||
|
||||
Here you have:
|
||||
- 2 NUMA nodes for the guest, 0 and 1. (both mapped to the same NUMA node in host, but you can and should put it in different host NUMA nodes)
|
||||
@@ -43,7 +43,7 @@ Implementation
|
||||
==============
|
||||
The PXB is composed by:
|
||||
- HostBridge (TYPE_PXB_HOST)
|
||||
The host bridge allows to register and query the PXB's rPCI root bus in QEMU.
|
||||
The host bridge allows to register and query the PXB's PCI root bus in QEMU.
|
||||
- PXBDev(TYPE_PXB_DEVICE)
|
||||
It is a regular PCI Device that resides on the piix host-bridge bus and its bus uses the same PCI domain.
|
||||
However, the bus behind is exposed through ACPI as a primary PCI bus and starts a new PCI hierarchy.
|
||||
|
||||
+17
-7
@@ -15,13 +15,23 @@ The 1000 -> 10ff device ID range is used as follows for virtio-pci devices.
|
||||
Note that this allocation separate from the virtio device IDs, which are
|
||||
maintained as part of the virtio specification.
|
||||
|
||||
1af4:1000 network device
|
||||
1af4:1001 block device
|
||||
1af4:1002 balloon device
|
||||
1af4:1003 console device
|
||||
1af4:1004 SCSI host bus adapter device
|
||||
1af4:1005 entropy generator device
|
||||
1af4:1009 9p filesystem device
|
||||
1af4:1000 network device (legacy)
|
||||
1af4:1001 block device (legacy)
|
||||
1af4:1002 balloon device (legacy)
|
||||
1af4:1003 console device (legacy)
|
||||
1af4:1004 SCSI host bus adapter device (legacy)
|
||||
1af4:1005 entropy generator device (legacy)
|
||||
1af4:1009 9p filesystem device (legacy)
|
||||
|
||||
1af4:1041 network device (modern)
|
||||
1af4:1042 block device (modern)
|
||||
1af4:1043 console device (modern)
|
||||
1af4:1044 entropy generator device (modern)
|
||||
1af4:1045 balloon device (modern)
|
||||
1af4:1048 SCSI host bus adapter device (modern)
|
||||
1af4:1049 9p filesystem device (modern)
|
||||
1af4:1050 virtio gpu device (modern)
|
||||
1af4:1052 virtio input device (modern)
|
||||
|
||||
1af4:10f0 Available for experimental usage without registration. Must get
|
||||
to official ID when the code leaves the test lab (i.e. when seeking
|
||||
|
||||
@@ -2,7 +2,7 @@ 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_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o
|
||||
common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
|
||||
obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
|
||||
common-obj-$(CONFIG_ACPI) += acpi_interface.o
|
||||
common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
|
||||
common-obj-$(CONFIG_ACPI) += aml-build.o
|
||||
|
||||
+51
-2
@@ -258,6 +258,34 @@ static void build_append_int(GArray *table, uint64_t value)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword,
|
||||
* and return the offset to 0x00000000 for runtime patching.
|
||||
*
|
||||
* Warning: runtime patching is best avoided. Only use this as
|
||||
* a replacement for DataTableRegion (for guests that don't
|
||||
* support it).
|
||||
*/
|
||||
int
|
||||
build_append_named_dword(GArray *array, const char *name_format, ...)
|
||||
{
|
||||
int offset;
|
||||
va_list ap;
|
||||
|
||||
build_append_byte(array, 0x08); /* NameOp */
|
||||
va_start(ap, name_format);
|
||||
build_append_namestringv(array, name_format, ap);
|
||||
va_end(ap);
|
||||
|
||||
build_append_byte(array, 0x0C); /* DWordPrefix */
|
||||
|
||||
offset = array->len;
|
||||
build_append_int_noprefix(array, 0x00000000, 4);
|
||||
assert(array->len == offset + 4);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static GPtrArray *alloc_list;
|
||||
|
||||
static Aml *aml_alloc(void)
|
||||
@@ -942,14 +970,14 @@ Aml *aml_package(uint8_t num_elements)
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
|
||||
Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
|
||||
uint32_t offset, uint32_t len)
|
||||
Aml *offset, uint32_t len)
|
||||
{
|
||||
Aml *var = aml_alloc();
|
||||
build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
|
||||
build_append_byte(var->buf, 0x80); /* OpRegionOp */
|
||||
build_append_namestring(var->buf, "%s", name);
|
||||
build_append_byte(var->buf, rs);
|
||||
build_append_int(var->buf, offset);
|
||||
aml_append(var, offset);
|
||||
build_append_int(var->buf, len);
|
||||
return var;
|
||||
}
|
||||
@@ -997,6 +1025,20 @@ Aml *create_field_common(int opcode, Aml *srcbuf, Aml *index, const char *name)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
|
||||
Aml *aml_create_field(Aml *srcbuf, Aml *bit_index, Aml *num_bits,
|
||||
const char *name)
|
||||
{
|
||||
Aml *var = aml_alloc();
|
||||
build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
|
||||
build_append_byte(var->buf, 0x13); /* CreateFieldOp */
|
||||
aml_append(var, srcbuf);
|
||||
aml_append(var, bit_index);
|
||||
aml_append(var, num_bits);
|
||||
build_append_namestring(var->buf, "%s", name);
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
|
||||
Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
|
||||
{
|
||||
@@ -1423,6 +1465,13 @@ Aml *aml_alias(const char *source_object, const char *alias_object)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
|
||||
Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
|
||||
{
|
||||
return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
|
||||
target);
|
||||
}
|
||||
|
||||
void
|
||||
build_header(GArray *linker, GArray *table_data,
|
||||
AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
|
||||
|
||||
+223
-8
@@ -29,6 +29,8 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/acpi/acpi.h"
|
||||
#include "hw/acpi/aml-build.h"
|
||||
#include "hw/acpi/bios-linker-loader.h"
|
||||
#include "hw/nvram/fw_cfg.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
|
||||
static int nvdimm_plugged_device_list(Object *obj, void *opaque)
|
||||
@@ -370,15 +372,131 @@ static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
|
||||
g_array_free(structures, true);
|
||||
}
|
||||
|
||||
struct NvdimmDsmIn {
|
||||
uint32_t handle;
|
||||
uint32_t revision;
|
||||
uint32_t function;
|
||||
/* the remaining size in the page is used by arg3. */
|
||||
union {
|
||||
uint8_t arg3[0];
|
||||
};
|
||||
} QEMU_PACKED;
|
||||
typedef struct NvdimmDsmIn NvdimmDsmIn;
|
||||
|
||||
struct NvdimmDsmOut {
|
||||
/* the size of buffer filled by QEMU. */
|
||||
uint32_t len;
|
||||
uint8_t data[0];
|
||||
} QEMU_PACKED;
|
||||
typedef struct NvdimmDsmOut NvdimmDsmOut;
|
||||
|
||||
struct NvdimmDsmFunc0Out {
|
||||
/* the size of buffer filled by QEMU. */
|
||||
uint32_t len;
|
||||
uint32_t supported_func;
|
||||
} QEMU_PACKED;
|
||||
typedef struct NvdimmDsmFunc0Out NvdimmDsmFunc0Out;
|
||||
|
||||
struct NvdimmDsmFuncNoPayloadOut {
|
||||
/* the size of buffer filled by QEMU. */
|
||||
uint32_t len;
|
||||
uint32_t func_ret_status;
|
||||
} QEMU_PACKED;
|
||||
typedef struct NvdimmDsmFuncNoPayloadOut NvdimmDsmFuncNoPayloadOut;
|
||||
|
||||
static uint64_t
|
||||
nvdimm_dsm_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
nvdimm_debug("BUG: we never read _DSM IO Port.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nvdimm_dsm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||
{
|
||||
NvdimmDsmIn *in;
|
||||
hwaddr dsm_mem_addr = val;
|
||||
|
||||
nvdimm_debug("dsm memory address %#" HWADDR_PRIx ".\n", dsm_mem_addr);
|
||||
|
||||
/*
|
||||
* The DSM memory is mapped to guest address space so an evil guest
|
||||
* can change its content while we are doing DSM emulation. Avoid
|
||||
* this by copying DSM memory to QEMU local memory.
|
||||
*/
|
||||
in = g_malloc(TARGET_PAGE_SIZE);
|
||||
cpu_physical_memory_read(dsm_mem_addr, in, TARGET_PAGE_SIZE);
|
||||
|
||||
le32_to_cpus(&in->revision);
|
||||
le32_to_cpus(&in->function);
|
||||
le32_to_cpus(&in->handle);
|
||||
|
||||
nvdimm_debug("Revision %#x Handler %#x Function %#x.\n", in->revision,
|
||||
in->handle, in->function);
|
||||
|
||||
/*
|
||||
* function 0 is called to inquire which functions are supported by
|
||||
* OSPM
|
||||
*/
|
||||
if (in->function == 0) {
|
||||
NvdimmDsmFunc0Out func0 = {
|
||||
.len = cpu_to_le32(sizeof(func0)),
|
||||
/* No function supported other than function 0 */
|
||||
.supported_func = cpu_to_le32(0),
|
||||
};
|
||||
cpu_physical_memory_write(dsm_mem_addr, &func0, sizeof func0);
|
||||
} else {
|
||||
/* No function except function 0 is supported yet. */
|
||||
NvdimmDsmFuncNoPayloadOut out = {
|
||||
.len = cpu_to_le32(sizeof(out)),
|
||||
.func_ret_status = cpu_to_le32(1) /* Not Supported */,
|
||||
};
|
||||
cpu_physical_memory_write(dsm_mem_addr, &out, sizeof(out));
|
||||
}
|
||||
|
||||
g_free(in);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps nvdimm_dsm_ops = {
|
||||
.read = nvdimm_dsm_read,
|
||||
.write = nvdimm_dsm_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
};
|
||||
|
||||
void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io,
|
||||
FWCfgState *fw_cfg, Object *owner)
|
||||
{
|
||||
memory_region_init_io(&state->io_mr, owner, &nvdimm_dsm_ops, state,
|
||||
"nvdimm-acpi-io", NVDIMM_ACPI_IO_LEN);
|
||||
memory_region_add_subregion(io, NVDIMM_ACPI_IO_BASE, &state->io_mr);
|
||||
|
||||
state->dsm_mem = g_array_new(false, true /* clear */, 1);
|
||||
acpi_data_push(state->dsm_mem, TARGET_PAGE_SIZE);
|
||||
fw_cfg_add_file(fw_cfg, NVDIMM_DSM_MEM_FILE, state->dsm_mem->data,
|
||||
state->dsm_mem->len);
|
||||
}
|
||||
|
||||
#define NVDIMM_COMMON_DSM "NCAL"
|
||||
#define NVDIMM_ACPI_MEM_ADDR "MEMA"
|
||||
|
||||
static void nvdimm_build_common_dsm(Aml *dev)
|
||||
{
|
||||
Aml *method, *ifctx, *function;
|
||||
Aml *method, *ifctx, *function, *dsm_mem, *unpatched, *result_size;
|
||||
uint8_t byte_list[1];
|
||||
|
||||
method = aml_method(NVDIMM_COMMON_DSM, 4, AML_NOTSERIALIZED);
|
||||
method = aml_method(NVDIMM_COMMON_DSM, 4, AML_SERIALIZED);
|
||||
function = aml_arg(2);
|
||||
dsm_mem = aml_name(NVDIMM_ACPI_MEM_ADDR);
|
||||
|
||||
/*
|
||||
* do not support any method if DSM memory address has not been
|
||||
* patched.
|
||||
*/
|
||||
unpatched = aml_if(aml_equal(dsm_mem, aml_int(0x0)));
|
||||
|
||||
/*
|
||||
* function 0 is called to inquire what functions are supported by
|
||||
@@ -387,12 +505,38 @@ static void nvdimm_build_common_dsm(Aml *dev)
|
||||
ifctx = aml_if(aml_equal(function, aml_int(0)));
|
||||
byte_list[0] = 0 /* No function Supported */;
|
||||
aml_append(ifctx, aml_return(aml_buffer(1, byte_list)));
|
||||
aml_append(method, ifctx);
|
||||
aml_append(unpatched, ifctx);
|
||||
|
||||
/* No function is supported yet. */
|
||||
byte_list[0] = 1 /* Not Supported */;
|
||||
aml_append(method, aml_return(aml_buffer(1, byte_list)));
|
||||
aml_append(unpatched, aml_return(aml_buffer(1, byte_list)));
|
||||
aml_append(method, unpatched);
|
||||
|
||||
/*
|
||||
* The HDLE indicates the DSM function is issued from which device,
|
||||
* it is not used at this time as no function is supported yet.
|
||||
* Currently we make it always be 0 for all the devices and will set
|
||||
* the appropriate value once real function is implemented.
|
||||
*/
|
||||
aml_append(method, aml_store(aml_int(0x0), aml_name("HDLE")));
|
||||
aml_append(method, aml_store(aml_arg(1), aml_name("REVS")));
|
||||
aml_append(method, aml_store(aml_arg(2), aml_name("FUNC")));
|
||||
|
||||
/*
|
||||
* tell QEMU about the real address of DSM memory, then QEMU
|
||||
* gets the control and fills the result in DSM memory.
|
||||
*/
|
||||
aml_append(method, aml_store(dsm_mem, aml_name("NTFI")));
|
||||
|
||||
result_size = aml_local(1);
|
||||
aml_append(method, aml_store(aml_name("RLEN"), result_size));
|
||||
aml_append(method, aml_store(aml_shiftleft(result_size, aml_int(3)),
|
||||
result_size));
|
||||
aml_append(method, aml_create_field(aml_name("ODAT"), aml_int(0),
|
||||
result_size, "OBUF"));
|
||||
aml_append(method, aml_concatenate(aml_buffer(0, NULL), aml_name("OBUF"),
|
||||
aml_arg(6)));
|
||||
aml_append(method, aml_return(aml_arg(6)));
|
||||
aml_append(dev, method);
|
||||
}
|
||||
|
||||
@@ -435,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)
|
||||
{
|
||||
Aml *ssdt, *sb_scope, *dev;
|
||||
Aml *ssdt, *sb_scope, *dev, *field;
|
||||
int mem_addr_offset, nvdimm_ssdt;
|
||||
|
||||
acpi_add_table(table_offsets, table_data);
|
||||
|
||||
@@ -459,19 +604,89 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
|
||||
*/
|
||||
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0012")));
|
||||
|
||||
/* map DSM memory and IO into ACPI namespace. */
|
||||
aml_append(dev, aml_operation_region("NPIO", AML_SYSTEM_IO,
|
||||
aml_int(NVDIMM_ACPI_IO_BASE), NVDIMM_ACPI_IO_LEN));
|
||||
aml_append(dev, aml_operation_region("NRAM", AML_SYSTEM_MEMORY,
|
||||
aml_name(NVDIMM_ACPI_MEM_ADDR), TARGET_PAGE_SIZE));
|
||||
|
||||
/*
|
||||
* DSM notifier:
|
||||
* NTFI: write the address of DSM memory and notify QEMU to emulate
|
||||
* the access.
|
||||
*
|
||||
* It is the IO port so that accessing them will cause VM-exit, the
|
||||
* control will be transferred to QEMU.
|
||||
*/
|
||||
field = aml_field("NPIO", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
|
||||
aml_append(field, aml_named_field("NTFI",
|
||||
sizeof(uint32_t) * BITS_PER_BYTE));
|
||||
aml_append(dev, field);
|
||||
|
||||
/*
|
||||
* DSM input:
|
||||
* HDLE: store device's handle, it's zero if the _DSM call happens
|
||||
* on NVDIMM Root Device.
|
||||
* REVS: store the Arg1 of _DSM call.
|
||||
* FUNC: store the Arg2 of _DSM call.
|
||||
* ARG3: store the Arg3 of _DSM call.
|
||||
*
|
||||
* They are RAM mapping on host so that these accesses never cause
|
||||
* VM-EXIT.
|
||||
*/
|
||||
field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
|
||||
aml_append(field, aml_named_field("HDLE",
|
||||
sizeof(typeof_field(NvdimmDsmIn, handle)) * BITS_PER_BYTE));
|
||||
aml_append(field, aml_named_field("REVS",
|
||||
sizeof(typeof_field(NvdimmDsmIn, revision)) * BITS_PER_BYTE));
|
||||
aml_append(field, aml_named_field("FUNC",
|
||||
sizeof(typeof_field(NvdimmDsmIn, function)) * BITS_PER_BYTE));
|
||||
aml_append(field, aml_named_field("ARG3",
|
||||
(TARGET_PAGE_SIZE - offsetof(NvdimmDsmIn, arg3)) *
|
||||
BITS_PER_BYTE));
|
||||
aml_append(dev, field);
|
||||
|
||||
/*
|
||||
* DSM output:
|
||||
* RLEN: the size of the buffer filled by QEMU.
|
||||
* ODAT: the buffer QEMU uses to store the result.
|
||||
*
|
||||
* Since the page is reused by both input and out, the input data
|
||||
* will be lost after storing new result into ODAT so we should fetch
|
||||
* all the input data before writing the result.
|
||||
*/
|
||||
field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE);
|
||||
aml_append(field, aml_named_field("RLEN",
|
||||
sizeof(typeof_field(NvdimmDsmOut, len)) * BITS_PER_BYTE));
|
||||
aml_append(field, aml_named_field("ODAT",
|
||||
(TARGET_PAGE_SIZE - offsetof(NvdimmDsmOut, data)) *
|
||||
BITS_PER_BYTE));
|
||||
aml_append(dev, field);
|
||||
|
||||
nvdimm_build_common_dsm(dev);
|
||||
nvdimm_build_device_dsm(dev);
|
||||
|
||||
nvdimm_build_nvdimm_devices(device_list, dev);
|
||||
|
||||
aml_append(sb_scope, dev);
|
||||
|
||||
aml_append(ssdt, sb_scope);
|
||||
|
||||
nvdimm_ssdt = table_data->len;
|
||||
|
||||
/* copy AML table into ACPI tables blob and patch header there */
|
||||
g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
|
||||
mem_addr_offset = build_append_named_dword(table_data,
|
||||
NVDIMM_ACPI_MEM_ADDR);
|
||||
|
||||
bios_linker_loader_alloc(linker, NVDIMM_DSM_MEM_FILE, TARGET_PAGE_SIZE,
|
||||
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));
|
||||
build_header(linker, table_data,
|
||||
(void *)(table_data->data + table_data->len - ssdt->buf->len),
|
||||
"SSDT", ssdt->buf->len, 1, NULL, "NVDIMM");
|
||||
(void *)(table_data->data + nvdimm_ssdt),
|
||||
"SSDT", table_data->len - nvdimm_ssdt, 1, NULL, "NVDIMM");
|
||||
free_aml_allocator();
|
||||
}
|
||||
|
||||
|
||||
@@ -2557,6 +2557,29 @@ FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
|
||||
return isa->state.drives[i].drive;
|
||||
}
|
||||
|
||||
void isa_fdc_get_drive_max_chs(FloppyDriveType type,
|
||||
uint8_t *maxc, uint8_t *maxh, uint8_t *maxs)
|
||||
{
|
||||
const FDFormat *fdf;
|
||||
|
||||
*maxc = *maxh = *maxs = 0;
|
||||
for (fdf = fd_formats; fdf->drive != FLOPPY_DRIVE_TYPE_NONE; fdf++) {
|
||||
if (fdf->drive != type) {
|
||||
continue;
|
||||
}
|
||||
if (*maxc < fdf->max_track) {
|
||||
*maxc = fdf->max_track;
|
||||
}
|
||||
if (*maxh < fdf->max_head) {
|
||||
*maxh = fdf->max_head;
|
||||
}
|
||||
if (*maxs < fdf->last_sect) {
|
||||
*maxs = fdf->last_sect;
|
||||
}
|
||||
}
|
||||
(*maxc)--;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_isa_fdc ={
|
||||
.name = "fdc",
|
||||
.version_id = 2,
|
||||
|
||||
+168
-133
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -186,7 +186,7 @@ static void kvm_apic_realize(DeviceState *dev, Error **errp)
|
||||
APIC_SPACE_SIZE);
|
||||
|
||||
if (kvm_has_gsi_routing()) {
|
||||
msi_supported = true;
|
||||
msi_nonbroken = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+63
-34
@@ -199,7 +199,7 @@ static void pic_irq_request(void *opaque, int irq, int level)
|
||||
|
||||
#define REG_EQUIPMENT_BYTE 0x14
|
||||
|
||||
static int cmos_get_fd_drive_type(FloppyDriveType fd0)
|
||||
int cmos_get_fd_drive_type(FloppyDriveType fd0)
|
||||
{
|
||||
int val;
|
||||
|
||||
@@ -699,18 +699,6 @@ static uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculates the limit to CPU APIC ID values
|
||||
*
|
||||
* This function returns the limit for the APIC ID value, so that all
|
||||
* CPU APIC IDs are < pc_apic_id_limit().
|
||||
*
|
||||
* This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
|
||||
*/
|
||||
static unsigned int pc_apic_id_limit(unsigned int max_cpus)
|
||||
{
|
||||
return x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
|
||||
}
|
||||
|
||||
static void pc_build_smbios(FWCfgState *fw_cfg)
|
||||
{
|
||||
uint8_t *smbios_tables, *smbios_anchor;
|
||||
@@ -748,12 +736,11 @@ static void pc_build_smbios(FWCfgState *fw_cfg)
|
||||
}
|
||||
}
|
||||
|
||||
static FWCfgState *bochs_bios_init(AddressSpace *as)
|
||||
static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
|
||||
{
|
||||
FWCfgState *fw_cfg;
|
||||
uint64_t *numa_fw_cfg;
|
||||
int i, j;
|
||||
unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
|
||||
|
||||
fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
|
||||
|
||||
@@ -771,7 +758,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
|
||||
* [1] The only kind of "CPU identifier" used between SeaBIOS and QEMU is
|
||||
* the APIC ID, not the "CPU index"
|
||||
*/
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)apic_id_limit);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)pcms->apic_id_limit);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_ACPI_TABLES,
|
||||
acpi_tables, acpi_tables_len);
|
||||
@@ -789,11 +776,11 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
|
||||
* of nodes, one word for each VCPU->node and one word for each node to
|
||||
* hold the amount of memory.
|
||||
*/
|
||||
numa_fw_cfg = g_new0(uint64_t, 1 + apic_id_limit + nb_numa_nodes);
|
||||
numa_fw_cfg = g_new0(uint64_t, 1 + pcms->apic_id_limit + nb_numa_nodes);
|
||||
numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
|
||||
for (i = 0; i < max_cpus; i++) {
|
||||
unsigned int apic_id = x86_cpu_apic_id_from_index(i);
|
||||
assert(apic_id < apic_id_limit);
|
||||
assert(apic_id < pcms->apic_id_limit);
|
||||
for (j = 0; j < nb_numa_nodes; j++) {
|
||||
if (test_bit(i, numa_info[j].node_cpu)) {
|
||||
numa_fw_cfg[apic_id + 1] = cpu_to_le64(j);
|
||||
@@ -802,10 +789,11 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nb_numa_nodes; i++) {
|
||||
numa_fw_cfg[apic_id_limit + 1 + i] = cpu_to_le64(numa_info[i].node_mem);
|
||||
numa_fw_cfg[pcms->apic_id_limit + 1 + i] =
|
||||
cpu_to_le64(numa_info[i].node_mem);
|
||||
}
|
||||
fw_cfg_add_bytes(fw_cfg, FW_CFG_NUMA, numa_fw_cfg,
|
||||
(1 + apic_id_limit + nb_numa_nodes) *
|
||||
(1 + pcms->apic_id_limit + nb_numa_nodes) *
|
||||
sizeof(*numa_fw_cfg));
|
||||
|
||||
return fw_cfg;
|
||||
@@ -1119,7 +1107,6 @@ void pc_cpus_init(PCMachineState *pcms)
|
||||
int i;
|
||||
X86CPU *cpu = NULL;
|
||||
MachineState *machine = MACHINE(pcms);
|
||||
unsigned long apic_id_limit;
|
||||
|
||||
/* init CPUs */
|
||||
if (machine->cpu_model == NULL) {
|
||||
@@ -1130,17 +1117,31 @@ void pc_cpus_init(PCMachineState *pcms)
|
||||
#endif
|
||||
}
|
||||
|
||||
apic_id_limit = pc_apic_id_limit(max_cpus);
|
||||
if (apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) {
|
||||
error_report("max_cpus is too large. APIC ID of last CPU is %lu",
|
||||
apic_id_limit - 1);
|
||||
/* Calculates the limit to CPU APIC ID values
|
||||
*
|
||||
* Limit for the APIC ID value, so that all
|
||||
* CPU APIC IDs are < pcms->apic_id_limit.
|
||||
*
|
||||
* This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().
|
||||
*/
|
||||
pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
|
||||
if (pcms->apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) {
|
||||
error_report("max_cpus is too large. APIC ID of last CPU is %u",
|
||||
pcms->apic_id_limit - 1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i),
|
||||
&error_fatal);
|
||||
object_unref(OBJECT(cpu));
|
||||
pcms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
|
||||
sizeof(CPUArchId) * max_cpus);
|
||||
for (i = 0; i < max_cpus; i++) {
|
||||
pcms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i);
|
||||
pcms->possible_cpus->len++;
|
||||
if (i < smp_cpus) {
|
||||
cpu = pc_new_cpu(machine->cpu_model, x86_cpu_apic_id_from_index(i),
|
||||
&error_fatal);
|
||||
pcms->possible_cpus->cpus[i].cpu = CPU(cpu);
|
||||
object_unref(OBJECT(cpu));
|
||||
}
|
||||
}
|
||||
|
||||
/* tell smbios about cpuid version and features */
|
||||
@@ -1186,7 +1187,6 @@ void pc_guest_info_init(PCMachineState *pcms)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
pcms->apic_id_limit = pc_apic_id_limit(max_cpus);
|
||||
pcms->apic_xrupt_override = kvm_allows_irq0_override();
|
||||
pcms->numa_nodes = nb_numa_nodes;
|
||||
pcms->node_mem = g_malloc0(pcms->numa_nodes *
|
||||
@@ -1371,7 +1371,7 @@ void pc_memory_init(PCMachineState *pcms,
|
||||
option_rom_mr,
|
||||
1);
|
||||
|
||||
fw_cfg = bochs_bios_init(&address_space_memory);
|
||||
fw_cfg = bochs_bios_init(&address_space_memory, pcms);
|
||||
|
||||
rom_set_fw(fw_cfg);
|
||||
|
||||
@@ -1664,9 +1664,19 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev,
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static int pc_apic_cmp(const void *a, const void *b)
|
||||
{
|
||||
CPUArchId *apic_a = (CPUArchId *)a;
|
||||
CPUArchId *apic_b = (CPUArchId *)b;
|
||||
|
||||
return apic_a->arch_id - apic_b->arch_id;
|
||||
}
|
||||
|
||||
static void pc_cpu_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(dev);
|
||||
CPUArchId apic_id, *found_cpu;
|
||||
HotplugHandlerClass *hhc;
|
||||
Error *local_err = NULL;
|
||||
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
|
||||
@@ -1689,6 +1699,13 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
|
||||
|
||||
/* increment the number of CPUs */
|
||||
rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
|
||||
|
||||
apic_id.arch_id = cc->get_arch_id(CPU(dev));
|
||||
found_cpu = bsearch(&apic_id, pcms->possible_cpus->cpus,
|
||||
pcms->possible_cpus->len, sizeof(*pcms->possible_cpus->cpus),
|
||||
pc_apic_cmp);
|
||||
assert(found_cpu);
|
||||
found_cpu->cpu = CPU(dev);
|
||||
out:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
@@ -1853,14 +1870,14 @@ static bool pc_machine_get_nvdimm(Object *obj, Error **errp)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(obj);
|
||||
|
||||
return pcms->nvdimm;
|
||||
return pcms->acpi_nvdimm_state.is_enabled;
|
||||
}
|
||||
|
||||
static void pc_machine_set_nvdimm(Object *obj, bool value, Error **errp)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(obj);
|
||||
|
||||
pcms->nvdimm = value;
|
||||
pcms->acpi_nvdimm_state.is_enabled = value;
|
||||
}
|
||||
|
||||
static void pc_machine_initfn(Object *obj)
|
||||
@@ -1899,7 +1916,7 @@ static void pc_machine_initfn(Object *obj)
|
||||
&error_abort);
|
||||
|
||||
/* nvdimm is disabled on default. */
|
||||
pcms->nvdimm = false;
|
||||
pcms->acpi_nvdimm_state.is_enabled = false;
|
||||
object_property_add_bool(obj, PC_MACHINE_NVDIMM, pc_machine_get_nvdimm,
|
||||
pc_machine_set_nvdimm, &error_abort);
|
||||
}
|
||||
@@ -1931,6 +1948,17 @@ static unsigned pc_cpu_index_to_socket_id(unsigned cpu_index)
|
||||
return topo.pkg_id;
|
||||
}
|
||||
|
||||
static CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *machine)
|
||||
{
|
||||
PCMachineState *pcms = PC_MACHINE(machine);
|
||||
int len = sizeof(CPUArchIdList) +
|
||||
sizeof(CPUArchId) * (pcms->possible_cpus->len);
|
||||
CPUArchIdList *list = g_malloc(len);
|
||||
|
||||
memcpy(list, pcms->possible_cpus, len);
|
||||
return list;
|
||||
}
|
||||
|
||||
static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
@@ -1953,6 +1981,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
|
||||
pcmc->save_tsc_khz = true;
|
||||
mc->get_hotplug_handler = pc_get_hotpug_handler;
|
||||
mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id;
|
||||
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
|
||||
mc->default_boot_order = "cad";
|
||||
mc->hot_add_cpu = pc_hot_add_cpu;
|
||||
mc->max_cpus = 255;
|
||||
|
||||
@@ -274,6 +274,11 @@ static void pc_init1(MachineState *machine,
|
||||
if (pcmc->pci_enabled) {
|
||||
pc_pci_device_init(pci_bus);
|
||||
}
|
||||
|
||||
if (pcms->acpi_nvdimm_state.is_enabled) {
|
||||
nvdimm_init_acpi_state(&pcms->acpi_nvdimm_state, system_io,
|
||||
pcms->fw_cfg, OBJECT(pcms));
|
||||
}
|
||||
}
|
||||
|
||||
/* Looking for a pc_compat_2_4() function? It doesn't exist.
|
||||
|
||||
+7
-1
@@ -61,6 +61,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
PCIDevice *lpc;
|
||||
BusState *idebus[MAX_SATA_PORTS];
|
||||
ISADevice *rtc_state;
|
||||
MemoryRegion *system_io = get_system_io();
|
||||
MemoryRegion *pci_memory;
|
||||
MemoryRegion *rom_memory;
|
||||
MemoryRegion *ram_memory;
|
||||
@@ -160,7 +161,7 @@ static void pc_q35_init(MachineState *machine)
|
||||
q35_host->mch.ram_memory = ram_memory;
|
||||
q35_host->mch.pci_address_space = pci_memory;
|
||||
q35_host->mch.system_memory = get_system_memory();
|
||||
q35_host->mch.address_space_io = get_system_io();
|
||||
q35_host->mch.address_space_io = system_io;
|
||||
q35_host->mch.below_4g_mem_size = pcms->below_4g_mem_size;
|
||||
q35_host->mch.above_4g_mem_size = pcms->above_4g_mem_size;
|
||||
/* pci */
|
||||
@@ -251,6 +252,11 @@ static void pc_q35_init(MachineState *machine)
|
||||
if (pcmc->pci_enabled) {
|
||||
pc_pci_device_init(host_bus);
|
||||
}
|
||||
|
||||
if (pcms->acpi_nvdimm_state.is_enabled) {
|
||||
nvdimm_init_acpi_state(&pcms->acpi_nvdimm_state, system_io,
|
||||
pcms->fw_cfg, OBJECT(pcms));
|
||||
}
|
||||
}
|
||||
|
||||
#define DEFINE_Q35_MACHINE(suffix, name, compatfn, optionfn) \
|
||||
|
||||
@@ -44,7 +44,7 @@ static void xen_apic_realize(DeviceState *dev, Error **errp)
|
||||
s->vapic_control = 0;
|
||||
memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s,
|
||||
"xen-apic-msi", APIC_SPACE_SIZE);
|
||||
msi_supported = true;
|
||||
msi_nonbroken = true;
|
||||
}
|
||||
|
||||
static void xen_apic_set_base(APICCommonState *s, uint64_t val)
|
||||
|
||||
+1
-1
@@ -874,7 +874,7 @@ static void apic_realize(DeviceState *dev, Error **errp)
|
||||
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, apic_timer, s);
|
||||
local_apics[s->idx] = s;
|
||||
|
||||
msi_supported = true;
|
||||
msi_nonbroken = true;
|
||||
}
|
||||
|
||||
static void apic_class_init(ObjectClass *klass, void *data)
|
||||
|
||||
@@ -148,7 +148,7 @@ static void gicv2m_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->spi[i]);
|
||||
}
|
||||
|
||||
msi_supported = true;
|
||||
msi_nonbroken = true;
|
||||
kvm_gsi_direct_mapping = true;
|
||||
kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1375,7 +1375,7 @@ static void fsl_common_init(OpenPICState *opp)
|
||||
|
||||
opp->irq_msi = 224;
|
||||
|
||||
msi_supported = true;
|
||||
msi_nonbroken = true;
|
||||
for (i = 0; i < opp->fsl->max_ext; i++) {
|
||||
opp->src[i].level = false;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ static void kvm_openpic_realize(DeviceState *dev, Error **errp)
|
||||
memory_listener_register(&opp->mem_listener, &address_space_memory);
|
||||
|
||||
/* indicate pic capabilities */
|
||||
msi_supported = true;
|
||||
msi_nonbroken = true;
|
||||
kvm_kernel_irqchip = true;
|
||||
kvm_async_interrupts_allowed = true;
|
||||
|
||||
|
||||
+360
-365
File diff suppressed because it is too large
Load Diff
+18
-17
@@ -409,18 +409,18 @@ ich9_lpc_pmbase_update(ICH9LPCState *lpc)
|
||||
ich9_pm_iospace_update(&lpc->pm, pm_io_base);
|
||||
}
|
||||
|
||||
/* config:RBCA */
|
||||
static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rbca_old)
|
||||
/* config:RCBA */
|
||||
static void ich9_lpc_rcba_update(ICH9LPCState *lpc, uint32_t rcba_old)
|
||||
{
|
||||
uint32_t rbca = pci_get_long(lpc->d.config + ICH9_LPC_RCBA);
|
||||
uint32_t rcba = pci_get_long(lpc->d.config + ICH9_LPC_RCBA);
|
||||
|
||||
if (rbca_old & ICH9_LPC_RCBA_EN) {
|
||||
memory_region_del_subregion(get_system_memory(), &lpc->rbca_mem);
|
||||
if (rcba_old & ICH9_LPC_RCBA_EN) {
|
||||
memory_region_del_subregion(get_system_memory(), &lpc->rcrb_mem);
|
||||
}
|
||||
if (rbca & ICH9_LPC_RCBA_EN) {
|
||||
memory_region_add_subregion_overlap(get_system_memory(),
|
||||
rbca & ICH9_LPC_RCBA_BA_MASK,
|
||||
&lpc->rbca_mem, 1);
|
||||
if (rcba & ICH9_LPC_RCBA_EN) {
|
||||
memory_region_add_subregion_overlap(get_system_memory(),
|
||||
rcba & ICH9_LPC_RCBA_BA_MASK,
|
||||
&lpc->rcrb_mem, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ static int ich9_lpc_post_load(void *opaque, int version_id)
|
||||
ICH9LPCState *lpc = opaque;
|
||||
|
||||
ich9_lpc_pmbase_update(lpc);
|
||||
ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RBCA_EN */);
|
||||
ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RCBA_EN */);
|
||||
ich9_lpc_pmcon_update(lpc);
|
||||
return 0;
|
||||
}
|
||||
@@ -453,14 +453,14 @@ static void ich9_lpc_config_write(PCIDevice *d,
|
||||
uint32_t addr, uint32_t val, int len)
|
||||
{
|
||||
ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
|
||||
uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
|
||||
uint32_t rcba_old = pci_get_long(d->config + ICH9_LPC_RCBA);
|
||||
|
||||
pci_default_write_config(d, addr, val, len);
|
||||
if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4)) {
|
||||
ich9_lpc_pmbase_update(lpc);
|
||||
}
|
||||
if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) {
|
||||
ich9_lpc_rcba_update(lpc, rbca_old);
|
||||
ich9_lpc_rcba_update(lpc, rcba_old);
|
||||
}
|
||||
if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) {
|
||||
pci_bus_fire_intx_routing_notifier(lpc->d.bus);
|
||||
@@ -477,7 +477,7 @@ static void ich9_lpc_reset(DeviceState *qdev)
|
||||
{
|
||||
PCIDevice *d = PCI_DEVICE(qdev);
|
||||
ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
|
||||
uint32_t rbca_old = pci_get_long(d->config + ICH9_LPC_RCBA);
|
||||
uint32_t rcba_old = pci_get_long(d->config + ICH9_LPC_RCBA);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
@@ -496,13 +496,14 @@ static void ich9_lpc_reset(DeviceState *qdev)
|
||||
ich9_cc_reset(lpc);
|
||||
|
||||
ich9_lpc_pmbase_update(lpc);
|
||||
ich9_lpc_rcba_update(lpc, rbca_old);
|
||||
ich9_lpc_rcba_update(lpc, rcba_old);
|
||||
|
||||
lpc->sci_level = 0;
|
||||
lpc->rst_cnt = 0;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps rbca_mmio_ops = {
|
||||
/* root complex register block is mapped into memory space */
|
||||
static const MemoryRegionOps rcrb_mmio_ops = {
|
||||
.read = ich9_cc_read,
|
||||
.write = ich9_cc_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
@@ -616,8 +617,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
|
||||
pci_set_long(d->wmask + ICH9_LPC_PMBASE,
|
||||
ICH9_LPC_PMBASE_BASE_ADDRESS_MASK);
|
||||
|
||||
memory_region_init_io(&lpc->rbca_mem, OBJECT(d), &rbca_mmio_ops, lpc,
|
||||
"lpc-rbca-mmio", ICH9_CC_SIZE);
|
||||
memory_region_init_io(&lpc->rcrb_mem, OBJECT(d), &rcrb_mmio_ops, lpc,
|
||||
"lpc-rcrb-mmio", ICH9_CC_SIZE);
|
||||
|
||||
lpc->isa_bus = isa_bus;
|
||||
|
||||
|
||||
+10
-3
@@ -364,15 +364,22 @@ static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name,
|
||||
Object *val, Error **errp)
|
||||
{
|
||||
MemoryRegion *mr;
|
||||
Error *local_err = NULL;
|
||||
|
||||
mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), errp);
|
||||
mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), &local_err);
|
||||
if (local_err) {
|
||||
goto out;
|
||||
}
|
||||
if (memory_region_is_mapped(mr)) {
|
||||
char *path = object_get_canonical_path_component(val);
|
||||
error_setg(errp, "can't use already busy memdev: %s", path);
|
||||
error_setg(&local_err, "can't use already busy memdev: %s", path);
|
||||
g_free(path);
|
||||
} else {
|
||||
qdev_prop_allow_set_link_before_realize(obj, name, val, errp);
|
||||
qdev_prop_allow_set_link_before_realize(obj, name, val, &local_err);
|
||||
}
|
||||
|
||||
out:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static void pc_dimm_init(Object *obj)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user