| /* |
| * i386 TCG cpu class initialization functions specific to sysemu |
| * |
| * Copyright (c) 2003 Fabrice Bellard |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| #include "qemu/osdep.h" |
| #include "cpu.h" |
| #include "tcg/helper-tcg.h" |
| |
| #include "sysemu/sysemu.h" |
| #include "qemu/units.h" |
| #include "exec/address-spaces.h" |
| |
| #include "tcg/tcg-cpu.h" |
| |
| static void tcg_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, 4 * GiB); |
| memory_region_set_enabled(cpu->smram, true); |
| memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, |
| cpu->smram, 1); |
| } |
| } |
| |
| bool tcg_cpu_realizefn(CPUState *cs, Error **errp) |
| { |
| X86CPU *cpu = X86_CPU(cs); |
| |
| /* |
| * The realize order is important, since x86_cpu_realize() checks if |
| * nothing else has been set by the user (or by accelerators) in |
| * cpu->ucode_rev and cpu->phys_bits, and the memory regions |
| * initialized here are needed for the vcpu initialization. |
| * |
| * realize order: |
| * tcg_cpu -> host_cpu -> x86_cpu |
| */ |
| cpu->cpu_as_mem = g_new(MemoryRegion, 1); |
| cpu->cpu_as_root = g_new(MemoryRegion, 1); |
| |
| /* 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); |
| |
| cs->num_ases = 2; |
| cpu_address_space_init(cs, 0, "cpu-memory", cs->memory); |
| cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root); |
| |
| /* ... SMRAM with higher priority, linked from /machine/smram. */ |
| cpu->machine_done.notify = tcg_cpu_machine_done; |
| qemu_add_machine_init_done_notifier(&cpu->machine_done); |
| return true; |
| } |