summaryrefslogtreecommitdiffstats
path: root/hw/pci-host/q35.c
diff options
context:
space:
mode:
authorPaolo Bonzini2015-03-31 14:10:22 +0200
committerPaolo Bonzini2015-06-05 17:36:39 +0200
commitfe6567d5fddfb7501a352c5e080a9eecf7b89177 (patch)
tree218595cffdd4f6c5119d454ee99273987b290e76 /hw/pci-host/q35.c
parenttarget-i386: create a separate AddressSpace for each CPU (diff)
downloadqemu-fe6567d5fddfb7501a352c5e080a9eecf7b89177.tar.gz
qemu-fe6567d5fddfb7501a352c5e080a9eecf7b89177.tar.xz
qemu-fe6567d5fddfb7501a352c5e080a9eecf7b89177.zip
hw/i386: add a separate region that tracks the SMRAME bit
This region is exported at /machine/smram. It is "empty" if SMRAME=0 and points to SMRAM if SMRAME=1. The CPU will enable/disable it as it enters or exits SMRAM. While touching nearby code, the existing memory region setup was slightly inconsistent. The smram_region is *disabled* in order to open SMRAM (because the smram_region shows the low VRAM instead of the RAM at 0xa0000). Because SMRAM is closed at startup, the smram_region must be enabled when creating the i440fx or q35 devices. Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/pci-host/q35.c')
-rw-r--r--hw/pci-host/q35.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index c8827cc000..db4d871908 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -270,6 +270,8 @@ static void mch_update_smram(MCHPCIState *mch)
memory_region_transaction_begin();
smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
mch->smm_enabled);
+ memory_region_set_enabled(&mch->smram,
+ pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME);
memory_region_transaction_commit();
}
@@ -399,13 +401,24 @@ static void mch_realize(PCIDevice *d, Error **errp)
pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
mch->pci_address_space);
- /* smram */
+ /* if *disabled* show SMRAM to all CPUs */
cpu_smm_register(&mch_set_smm, mch);
memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",
mch->pci_address_space, 0xa0000, 0x20000);
memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,
&mch->smram_region, 1);
- memory_region_set_enabled(&mch->smram_region, false);
+ memory_region_set_enabled(&mch->smram_region, true);
+
+ /* smram, as seen by SMM CPUs */
+ memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32);
+ memory_region_set_enabled(&mch->smram, true);
+ memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low",
+ mch->system_memory, 0xa0000, 0x20000);
+ memory_region_set_enabled(&mch->low_smram, true);
+ memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram);
+ object_property_add_const_link(qdev_get_machine(), "smram",
+ OBJECT(&mch->smram), &error_abort);
+
init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,
mch->pci_address_space, &mch->pam_regions[0],
PAM_BIOS_BASE, PAM_BIOS_SIZE);