aboutsummaryrefslogtreecommitdiff
path: root/target-i386/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-i386/cpu.c')
-rw-r--r--target-i386/cpu.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 051abc92cb..4e7cdaaaa5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2751,6 +2751,21 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
object_property_set_bool(OBJECT(cpu->apic_state), true, "realized",
errp);
}
+
+static void x86_cpu_machine_done(Notifier *n, void *unused)
+{
+ X86CPU *cpu = container_of(n, X86CPU, machine_done);
+ MemoryRegion *smram =
+ (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
+
+ if (smram) {
+ cpu->smram = g_new(MemoryRegion, 1);
+ memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
+ smram, 0, 1ull << 32);
+ memory_region_set_enabled(cpu->smram, false);
+ memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
+ }
+}
#else
static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
{
@@ -2815,12 +2830,26 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
#ifndef CONFIG_USER_ONLY
if (tcg_enabled()) {
+ cpu->cpu_as_mem = g_new(MemoryRegion, 1);
cpu->cpu_as_root = g_new(MemoryRegion, 1);
cs->as = g_new(AddressSpace, 1);
- memory_region_init_alias(cpu->cpu_as_root, OBJECT(cpu), "memory",
- get_system_memory(), 0, ~0ull);
+
+ /* Outer container... */
+ memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
memory_region_set_enabled(cpu->cpu_as_root, true);
+
+ /* ... with two regions inside: normal system memory with low
+ * priority, and...
+ */
+ memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
+ get_system_memory(), 0, ~0ull);
+ memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
+ memory_region_set_enabled(cpu->cpu_as_mem, true);
address_space_init(cs->as, cpu->cpu_as_root, "CPU");
+
+ /* ... SMRAM with higher priority, linked from /machine/smram. */
+ cpu->machine_done.notify = x86_cpu_machine_done;
+ qemu_add_machine_init_done_notifier(&cpu->machine_done);
}
#endif