1549e984eSSergio Lopez /* 2549e984eSSergio Lopez * Copyright (c) 2003-2004 Fabrice Bellard 3549e984eSSergio Lopez * Copyright (c) 2019 Red Hat, Inc. 4549e984eSSergio Lopez * 5549e984eSSergio Lopez * Permission is hereby granted, free of charge, to any person obtaining a copy 6549e984eSSergio Lopez * of this software and associated documentation files (the "Software"), to deal 7549e984eSSergio Lopez * in the Software without restriction, including without limitation the rights 8549e984eSSergio Lopez * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9549e984eSSergio Lopez * copies of the Software, and to permit persons to whom the Software is 10549e984eSSergio Lopez * furnished to do so, subject to the following conditions: 11549e984eSSergio Lopez * 12549e984eSSergio Lopez * The above copyright notice and this permission notice shall be included in 13549e984eSSergio Lopez * all copies or substantial portions of the Software. 14549e984eSSergio Lopez * 15549e984eSSergio Lopez * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16549e984eSSergio Lopez * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17549e984eSSergio Lopez * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18549e984eSSergio Lopez * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19549e984eSSergio Lopez * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20549e984eSSergio Lopez * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21549e984eSSergio Lopez * THE SOFTWARE. 22549e984eSSergio Lopez */ 23549e984eSSergio Lopez #include "qemu/osdep.h" 24549e984eSSergio Lopez #include "qemu/error-report.h" 25549e984eSSergio Lopez #include "qemu/units.h" 26549e984eSSergio Lopez #include "qapi/error.h" 27549e984eSSergio Lopez #include "qapi/qapi-visit-common.h" 28dfce81f1SSean Christopherson #include "qapi/qapi-visit-machine.h" 29549e984eSSergio Lopez #include "qapi/visitor.h" 30549e984eSSergio Lopez #include "sysemu/qtest.h" 31549e984eSSergio Lopez #include "sysemu/numa.h" 3289a289c7SPaolo Bonzini #include "trace.h" 33549e984eSSergio Lopez 34*b061f059SPaolo Bonzini #include "hw/acpi/aml-build.h" 35549e984eSSergio Lopez #include "hw/i386/x86.h" 36549e984eSSergio Lopez #include "hw/i386/topology.h" 37549e984eSSergio Lopez 38549e984eSSergio Lopez #include "hw/nmi.h" 39a9dc68d9SClaudio Fontana #include "kvm/kvm_i386.h" 40549e984eSSergio Lopez 414f81baa3SDavid Woodhouse 42*b061f059SPaolo Bonzini void init_topo_info(X86CPUTopoInfo *topo_info, 4353a5e7bdSBabu Moger const X86MachineState *x86ms) 4453a5e7bdSBabu Moger { 4553a5e7bdSBabu Moger MachineState *ms = MACHINE(x86ms); 4653a5e7bdSBabu Moger 4767872eb8SPaolo Bonzini topo_info->dies_per_pkg = ms->smp.dies; 4853a5e7bdSBabu Moger topo_info->cores_per_die = ms->smp.cores; 4953a5e7bdSBabu Moger topo_info->threads_per_core = ms->smp.threads; 5053a5e7bdSBabu Moger } 5153a5e7bdSBabu Moger 52549e984eSSergio Lopez /* 53549e984eSSergio Lopez * Calculates initial APIC ID for a specific CPU index 54549e984eSSergio Lopez * 55549e984eSSergio Lopez * Currently we need to be able to calculate the APIC ID from the CPU index 56549e984eSSergio Lopez * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have 57549e984eSSergio Lopez * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of 58549e984eSSergio Lopez * all CPUs up to max_cpus. 59549e984eSSergio Lopez */ 60703a548aSSergio Lopez uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, 61549e984eSSergio Lopez unsigned int cpu_index) 62549e984eSSergio Lopez { 6353a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 64549e984eSSergio Lopez 6553a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 6653a5e7bdSBabu Moger 67e6895f04SIgor Mammedov return x86_apicid_from_cpu_idx(&topo_info, cpu_index); 68549e984eSSergio Lopez } 69549e984eSSergio Lopez 70b348fdcdSPaolo Bonzini static CpuInstanceProperties 71549e984eSSergio Lopez x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index) 72549e984eSSergio Lopez { 73549e984eSSergio Lopez MachineClass *mc = MACHINE_GET_CLASS(ms); 74549e984eSSergio Lopez const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); 75549e984eSSergio Lopez 76549e984eSSergio Lopez assert(cpu_index < possible_cpus->len); 77549e984eSSergio Lopez return possible_cpus->cpus[cpu_index].props; 78549e984eSSergio Lopez } 79549e984eSSergio Lopez 80b348fdcdSPaolo Bonzini static int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) 81549e984eSSergio Lopez { 82dcf08bc6SBabu Moger X86CPUTopoIDs topo_ids; 83f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(ms); 8453a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 8553a5e7bdSBabu Moger 8653a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 87549e984eSSergio Lopez 88549e984eSSergio Lopez assert(idx < ms->possible_cpus->len); 89dfe7ed0aSBabu Moger x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, 90dfe7ed0aSBabu Moger &topo_info, &topo_ids); 91dcf08bc6SBabu Moger return topo_ids.pkg_id % ms->numa_state->num_nodes; 92549e984eSSergio Lopez } 93549e984eSSergio Lopez 94b348fdcdSPaolo Bonzini static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) 95549e984eSSergio Lopez { 96f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(ms); 97549e984eSSergio Lopez unsigned int max_cpus = ms->smp.max_cpus; 9853a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 9953a5e7bdSBabu Moger int i; 100549e984eSSergio Lopez 101549e984eSSergio Lopez if (ms->possible_cpus) { 102549e984eSSergio Lopez /* 103549e984eSSergio Lopez * make sure that max_cpus hasn't changed since the first use, i.e. 104549e984eSSergio Lopez * -smp hasn't been parsed after it 105549e984eSSergio Lopez */ 106549e984eSSergio Lopez assert(ms->possible_cpus->len == max_cpus); 107549e984eSSergio Lopez return ms->possible_cpus; 108549e984eSSergio Lopez } 109549e984eSSergio Lopez 110549e984eSSergio Lopez ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + 111549e984eSSergio Lopez sizeof(CPUArchId) * max_cpus); 112549e984eSSergio Lopez ms->possible_cpus->len = max_cpus; 11353a5e7bdSBabu Moger 11453a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 11553a5e7bdSBabu Moger 116549e984eSSergio Lopez for (i = 0; i < ms->possible_cpus->len; i++) { 117dcf08bc6SBabu Moger X86CPUTopoIDs topo_ids; 118549e984eSSergio Lopez 119549e984eSSergio Lopez ms->possible_cpus->cpus[i].type = ms->cpu_type; 120549e984eSSergio Lopez ms->possible_cpus->cpus[i].vcpus_count = 1; 121dfe7ed0aSBabu Moger ms->possible_cpus->cpus[i].arch_id = 122dfe7ed0aSBabu Moger x86_cpu_apic_id_from_index(x86ms, i); 123dfe7ed0aSBabu Moger x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, 124dfe7ed0aSBabu Moger &topo_info, &topo_ids); 125549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_socket_id = true; 126dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id; 12767872eb8SPaolo Bonzini if (ms->smp.dies > 1) { 128549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_die_id = true; 129dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id; 130549e984eSSergio Lopez } 131549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_core_id = true; 132dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.core_id = topo_ids.core_id; 133549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_thread_id = true; 134dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.thread_id = topo_ids.smt_id; 135549e984eSSergio Lopez } 136549e984eSSergio Lopez return ms->possible_cpus; 137549e984eSSergio Lopez } 138549e984eSSergio Lopez 139f0bb276bSPaolo Bonzini static void x86_nmi(NMIState *n, int cpu_index, Error **errp) 140f0bb276bSPaolo Bonzini { 141f0bb276bSPaolo Bonzini /* cpu index isn't used */ 142f0bb276bSPaolo Bonzini CPUState *cs; 143f0bb276bSPaolo Bonzini 144f0bb276bSPaolo Bonzini CPU_FOREACH(cs) { 145f0bb276bSPaolo Bonzini X86CPU *cpu = X86_CPU(cs); 146f0bb276bSPaolo Bonzini 147c2e6d7d8SBernhard Beschow if (cpu_is_apic_enabled(cpu->apic_state)) { 148f0bb276bSPaolo Bonzini apic_deliver_nmi(cpu->apic_state); 149f22f3a92SBernhard Beschow } else { 150f22f3a92SBernhard Beschow cpu_interrupt(cs, CPU_INTERRUPT_NMI); 151f0bb276bSPaolo Bonzini } 152f0bb276bSPaolo Bonzini } 153f0bb276bSPaolo Bonzini } 154f0bb276bSPaolo Bonzini 1559927a632SGerd Hoffmann bool x86_machine_is_smm_enabled(const X86MachineState *x86ms) 156ed9e923cSPaolo Bonzini { 157ed9e923cSPaolo Bonzini bool smm_available = false; 158ed9e923cSPaolo Bonzini 159ed9e923cSPaolo Bonzini if (x86ms->smm == ON_OFF_AUTO_OFF) { 160ed9e923cSPaolo Bonzini return false; 161ed9e923cSPaolo Bonzini } 162ed9e923cSPaolo Bonzini 163ed9e923cSPaolo Bonzini if (tcg_enabled() || qtest_enabled()) { 164ed9e923cSPaolo Bonzini smm_available = true; 165ed9e923cSPaolo Bonzini } else if (kvm_enabled()) { 166ed9e923cSPaolo Bonzini smm_available = kvm_has_smm(); 167ed9e923cSPaolo Bonzini } 168ed9e923cSPaolo Bonzini 169ed9e923cSPaolo Bonzini if (smm_available) { 170ed9e923cSPaolo Bonzini return true; 171ed9e923cSPaolo Bonzini } 172ed9e923cSPaolo Bonzini 173ed9e923cSPaolo Bonzini if (x86ms->smm == ON_OFF_AUTO_ON) { 174ed9e923cSPaolo Bonzini error_report("System Management Mode not supported by this hypervisor."); 175ed9e923cSPaolo Bonzini exit(1); 176ed9e923cSPaolo Bonzini } 177ed9e923cSPaolo Bonzini return false; 178ed9e923cSPaolo Bonzini } 179ed9e923cSPaolo Bonzini 180ed9e923cSPaolo Bonzini static void x86_machine_get_smm(Object *obj, Visitor *v, const char *name, 181ed9e923cSPaolo Bonzini void *opaque, Error **errp) 182ed9e923cSPaolo Bonzini { 183ed9e923cSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 184ed9e923cSPaolo Bonzini OnOffAuto smm = x86ms->smm; 185ed9e923cSPaolo Bonzini 186ed9e923cSPaolo Bonzini visit_type_OnOffAuto(v, name, &smm, errp); 187ed9e923cSPaolo Bonzini } 188ed9e923cSPaolo Bonzini 189ed9e923cSPaolo Bonzini static void x86_machine_set_smm(Object *obj, Visitor *v, const char *name, 190ed9e923cSPaolo Bonzini void *opaque, Error **errp) 191ed9e923cSPaolo Bonzini { 192ed9e923cSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 193ed9e923cSPaolo Bonzini 194ed9e923cSPaolo Bonzini visit_type_OnOffAuto(v, name, &x86ms->smm, errp); 195ed9e923cSPaolo Bonzini } 196ed9e923cSPaolo Bonzini 1979927a632SGerd Hoffmann bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms) 19817e89077SGerd Hoffmann { 19917e89077SGerd Hoffmann if (x86ms->acpi == ON_OFF_AUTO_OFF) { 20017e89077SGerd Hoffmann return false; 20117e89077SGerd Hoffmann } 20217e89077SGerd Hoffmann return true; 20317e89077SGerd Hoffmann } 20417e89077SGerd Hoffmann 20517e89077SGerd Hoffmann static void x86_machine_get_acpi(Object *obj, Visitor *v, const char *name, 20617e89077SGerd Hoffmann void *opaque, Error **errp) 20717e89077SGerd Hoffmann { 20817e89077SGerd Hoffmann X86MachineState *x86ms = X86_MACHINE(obj); 20917e89077SGerd Hoffmann OnOffAuto acpi = x86ms->acpi; 21017e89077SGerd Hoffmann 21117e89077SGerd Hoffmann visit_type_OnOffAuto(v, name, &acpi, errp); 21217e89077SGerd Hoffmann } 21317e89077SGerd Hoffmann 21417e89077SGerd Hoffmann static void x86_machine_set_acpi(Object *obj, Visitor *v, const char *name, 21517e89077SGerd Hoffmann void *opaque, Error **errp) 21617e89077SGerd Hoffmann { 21717e89077SGerd Hoffmann X86MachineState *x86ms = X86_MACHINE(obj); 21817e89077SGerd Hoffmann 21917e89077SGerd Hoffmann visit_type_OnOffAuto(v, name, &x86ms->acpi, errp); 22017e89077SGerd Hoffmann } 22117e89077SGerd Hoffmann 2229dee7e51SXiaoyao Li static void x86_machine_get_pit(Object *obj, Visitor *v, const char *name, 2239dee7e51SXiaoyao Li void *opaque, Error **errp) 2249dee7e51SXiaoyao Li { 2259dee7e51SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 2269dee7e51SXiaoyao Li OnOffAuto pit = x86ms->pit; 2279dee7e51SXiaoyao Li 2289dee7e51SXiaoyao Li visit_type_OnOffAuto(v, name, &pit, errp); 2299dee7e51SXiaoyao Li } 2309dee7e51SXiaoyao Li 2319dee7e51SXiaoyao Li static void x86_machine_set_pit(Object *obj, Visitor *v, const char *name, 2329dee7e51SXiaoyao Li void *opaque, Error **errp) 2339dee7e51SXiaoyao Li { 2349dee7e51SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj);; 2359dee7e51SXiaoyao Li 2369dee7e51SXiaoyao Li visit_type_OnOffAuto(v, name, &x86ms->pit, errp); 2379dee7e51SXiaoyao Li } 2389dee7e51SXiaoyao Li 239c300bbe8SXiaoyao Li static void x86_machine_get_pic(Object *obj, Visitor *v, const char *name, 240c300bbe8SXiaoyao Li void *opaque, Error **errp) 241c300bbe8SXiaoyao Li { 242c300bbe8SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 243c300bbe8SXiaoyao Li OnOffAuto pic = x86ms->pic; 244c300bbe8SXiaoyao Li 245c300bbe8SXiaoyao Li visit_type_OnOffAuto(v, name, &pic, errp); 246c300bbe8SXiaoyao Li } 247c300bbe8SXiaoyao Li 248c300bbe8SXiaoyao Li static void x86_machine_set_pic(Object *obj, Visitor *v, const char *name, 249c300bbe8SXiaoyao Li void *opaque, Error **errp) 250c300bbe8SXiaoyao Li { 251c300bbe8SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 252c300bbe8SXiaoyao Li 253c300bbe8SXiaoyao Li visit_type_OnOffAuto(v, name, &x86ms->pic, errp); 254c300bbe8SXiaoyao Li } 255c300bbe8SXiaoyao Li 256d07b2286SMarian Postevca static char *x86_machine_get_oem_id(Object *obj, Error **errp) 257d07b2286SMarian Postevca { 258d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 259d07b2286SMarian Postevca 260d07b2286SMarian Postevca return g_strdup(x86ms->oem_id); 261d07b2286SMarian Postevca } 262d07b2286SMarian Postevca 263d07b2286SMarian Postevca static void x86_machine_set_oem_id(Object *obj, const char *value, Error **errp) 264d07b2286SMarian Postevca { 265d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 266d07b2286SMarian Postevca size_t len = strlen(value); 267d07b2286SMarian Postevca 268d07b2286SMarian Postevca if (len > 6) { 269d07b2286SMarian Postevca error_setg(errp, 270d07b2286SMarian Postevca "User specified "X86_MACHINE_OEM_ID" value is bigger than " 271d07b2286SMarian Postevca "6 bytes in size"); 272d07b2286SMarian Postevca return; 273d07b2286SMarian Postevca } 274d07b2286SMarian Postevca 275d07b2286SMarian Postevca strncpy(x86ms->oem_id, value, 6); 276d07b2286SMarian Postevca } 277d07b2286SMarian Postevca 278d07b2286SMarian Postevca static char *x86_machine_get_oem_table_id(Object *obj, Error **errp) 279d07b2286SMarian Postevca { 280d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 281d07b2286SMarian Postevca 282d07b2286SMarian Postevca return g_strdup(x86ms->oem_table_id); 283d07b2286SMarian Postevca } 284d07b2286SMarian Postevca 285d07b2286SMarian Postevca static void x86_machine_set_oem_table_id(Object *obj, const char *value, 286d07b2286SMarian Postevca Error **errp) 287d07b2286SMarian Postevca { 288d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 289d07b2286SMarian Postevca size_t len = strlen(value); 290d07b2286SMarian Postevca 291d07b2286SMarian Postevca if (len > 8) { 292d07b2286SMarian Postevca error_setg(errp, 293d07b2286SMarian Postevca "User specified "X86_MACHINE_OEM_TABLE_ID 294d07b2286SMarian Postevca " value is bigger than " 295d07b2286SMarian Postevca "8 bytes in size"); 296d07b2286SMarian Postevca return; 297d07b2286SMarian Postevca } 298d07b2286SMarian Postevca strncpy(x86ms->oem_table_id, value, 8); 299d07b2286SMarian Postevca } 300d07b2286SMarian Postevca 301035d1ef2SChenyi Qiang static void x86_machine_get_bus_lock_ratelimit(Object *obj, Visitor *v, 302035d1ef2SChenyi Qiang const char *name, void *opaque, Error **errp) 303035d1ef2SChenyi Qiang { 304035d1ef2SChenyi Qiang X86MachineState *x86ms = X86_MACHINE(obj); 305035d1ef2SChenyi Qiang uint64_t bus_lock_ratelimit = x86ms->bus_lock_ratelimit; 306035d1ef2SChenyi Qiang 307035d1ef2SChenyi Qiang visit_type_uint64(v, name, &bus_lock_ratelimit, errp); 308035d1ef2SChenyi Qiang } 309035d1ef2SChenyi Qiang 310035d1ef2SChenyi Qiang static void x86_machine_set_bus_lock_ratelimit(Object *obj, Visitor *v, 311035d1ef2SChenyi Qiang const char *name, void *opaque, Error **errp) 312035d1ef2SChenyi Qiang { 313035d1ef2SChenyi Qiang X86MachineState *x86ms = X86_MACHINE(obj); 314035d1ef2SChenyi Qiang 315035d1ef2SChenyi Qiang visit_type_uint64(v, name, &x86ms->bus_lock_ratelimit, errp); 316035d1ef2SChenyi Qiang } 317035d1ef2SChenyi Qiang 318dfce81f1SSean Christopherson static void machine_get_sgx_epc(Object *obj, Visitor *v, const char *name, 319dfce81f1SSean Christopherson void *opaque, Error **errp) 320dfce81f1SSean Christopherson { 321dfce81f1SSean Christopherson X86MachineState *x86ms = X86_MACHINE(obj); 322dfce81f1SSean Christopherson SgxEPCList *list = x86ms->sgx_epc_list; 323dfce81f1SSean Christopherson 324dfce81f1SSean Christopherson visit_type_SgxEPCList(v, name, &list, errp); 325dfce81f1SSean Christopherson } 326dfce81f1SSean Christopherson 327dfce81f1SSean Christopherson static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name, 328dfce81f1SSean Christopherson void *opaque, Error **errp) 329dfce81f1SSean Christopherson { 330dfce81f1SSean Christopherson X86MachineState *x86ms = X86_MACHINE(obj); 331dfce81f1SSean Christopherson SgxEPCList *list; 332dfce81f1SSean Christopherson 333dfce81f1SSean Christopherson list = x86ms->sgx_epc_list; 334dfce81f1SSean Christopherson visit_type_SgxEPCList(v, name, &x86ms->sgx_epc_list, errp); 335dfce81f1SSean Christopherson 336dfce81f1SSean Christopherson qapi_free_SgxEPCList(list); 337dfce81f1SSean Christopherson } 338dfce81f1SSean Christopherson 339ee88612dSPaolo Bonzini static int x86_kvm_type(MachineState *ms, const char *vm_type) 340ee88612dSPaolo Bonzini { 341ee88612dSPaolo Bonzini /* 342ee88612dSPaolo Bonzini * No x86 machine has a kvm-type property. If one is added that has 343ee88612dSPaolo Bonzini * it, it should call kvm_get_vm_type() directly or not use it at all. 344ee88612dSPaolo Bonzini */ 345ee88612dSPaolo Bonzini assert(vm_type == NULL); 346ee88612dSPaolo Bonzini return kvm_enabled() ? kvm_get_vm_type(ms) : 0; 347ee88612dSPaolo Bonzini } 348ee88612dSPaolo Bonzini 349f0bb276bSPaolo Bonzini static void x86_machine_initfn(Object *obj) 350f0bb276bSPaolo Bonzini { 351f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 352f0bb276bSPaolo Bonzini 353ed9e923cSPaolo Bonzini x86ms->smm = ON_OFF_AUTO_AUTO; 35417e89077SGerd Hoffmann x86ms->acpi = ON_OFF_AUTO_AUTO; 3559dee7e51SXiaoyao Li x86ms->pit = ON_OFF_AUTO_AUTO; 356c300bbe8SXiaoyao Li x86ms->pic = ON_OFF_AUTO_AUTO; 3571b2802c4SGerd Hoffmann x86ms->pci_irq_mask = ACPI_BUILD_PCI_IRQS; 358d07b2286SMarian Postevca x86ms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); 359d07b2286SMarian Postevca x86ms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); 360035d1ef2SChenyi Qiang x86ms->bus_lock_ratelimit = 0; 3614ab4c330SJoao Martins x86ms->above_4g_mem_start = 4 * GiB; 362f0bb276bSPaolo Bonzini } 363f0bb276bSPaolo Bonzini 364f0bb276bSPaolo Bonzini static void x86_machine_class_init(ObjectClass *oc, void *data) 365f0bb276bSPaolo Bonzini { 366f0bb276bSPaolo Bonzini MachineClass *mc = MACHINE_CLASS(oc); 367f0bb276bSPaolo Bonzini X86MachineClass *x86mc = X86_MACHINE_CLASS(oc); 368f0bb276bSPaolo Bonzini NMIClass *nc = NMI_CLASS(oc); 369f0bb276bSPaolo Bonzini 370f0bb276bSPaolo Bonzini mc->cpu_index_to_instance_props = x86_cpu_index_to_props; 371f0bb276bSPaolo Bonzini mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; 372f0bb276bSPaolo Bonzini mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; 373ee88612dSPaolo Bonzini mc->kvm_type = x86_kvm_type; 3742f34ebf2SLiam Merwick x86mc->save_tsc_khz = true; 375f014c974SPaolo Bonzini x86mc->fwcfg_dma_enabled = true; 376f0bb276bSPaolo Bonzini nc->nmi_monitor_handler = x86_nmi; 377f0bb276bSPaolo Bonzini 378ed9e923cSPaolo Bonzini object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto", 379ed9e923cSPaolo Bonzini x86_machine_get_smm, x86_machine_set_smm, 380d2623129SMarkus Armbruster NULL, NULL); 381ed9e923cSPaolo Bonzini object_class_property_set_description(oc, X86_MACHINE_SMM, 3827eecec7dSMarkus Armbruster "Enable SMM"); 38317e89077SGerd Hoffmann 38417e89077SGerd Hoffmann object_class_property_add(oc, X86_MACHINE_ACPI, "OnOffAuto", 38517e89077SGerd Hoffmann x86_machine_get_acpi, x86_machine_set_acpi, 386d2623129SMarkus Armbruster NULL, NULL); 38717e89077SGerd Hoffmann object_class_property_set_description(oc, X86_MACHINE_ACPI, 3887eecec7dSMarkus Armbruster "Enable ACPI"); 389d07b2286SMarian Postevca 3909dee7e51SXiaoyao Li object_class_property_add(oc, X86_MACHINE_PIT, "OnOffAuto", 3919dee7e51SXiaoyao Li x86_machine_get_pit, 3929dee7e51SXiaoyao Li x86_machine_set_pit, 3939dee7e51SXiaoyao Li NULL, NULL); 3949dee7e51SXiaoyao Li object_class_property_set_description(oc, X86_MACHINE_PIT, 3959dee7e51SXiaoyao Li "Enable i8254 PIT"); 3969dee7e51SXiaoyao Li 397c300bbe8SXiaoyao Li object_class_property_add(oc, X86_MACHINE_PIC, "OnOffAuto", 398c300bbe8SXiaoyao Li x86_machine_get_pic, 399c300bbe8SXiaoyao Li x86_machine_set_pic, 400c300bbe8SXiaoyao Li NULL, NULL); 401c300bbe8SXiaoyao Li object_class_property_set_description(oc, X86_MACHINE_PIC, 402c300bbe8SXiaoyao Li "Enable i8259 PIC"); 403c300bbe8SXiaoyao Li 404d07b2286SMarian Postevca object_class_property_add_str(oc, X86_MACHINE_OEM_ID, 405d07b2286SMarian Postevca x86_machine_get_oem_id, 406d07b2286SMarian Postevca x86_machine_set_oem_id); 407d07b2286SMarian Postevca object_class_property_set_description(oc, X86_MACHINE_OEM_ID, 408d07b2286SMarian Postevca "Override the default value of field OEMID " 409d07b2286SMarian Postevca "in ACPI table header." 410d07b2286SMarian Postevca "The string may be up to 6 bytes in size"); 411d07b2286SMarian Postevca 412d07b2286SMarian Postevca 413d07b2286SMarian Postevca object_class_property_add_str(oc, X86_MACHINE_OEM_TABLE_ID, 414d07b2286SMarian Postevca x86_machine_get_oem_table_id, 415d07b2286SMarian Postevca x86_machine_set_oem_table_id); 416d07b2286SMarian Postevca object_class_property_set_description(oc, X86_MACHINE_OEM_TABLE_ID, 417d07b2286SMarian Postevca "Override the default value of field OEM Table ID " 418d07b2286SMarian Postevca "in ACPI table header." 419d07b2286SMarian Postevca "The string may be up to 8 bytes in size"); 420035d1ef2SChenyi Qiang 421035d1ef2SChenyi Qiang object_class_property_add(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, "uint64_t", 422035d1ef2SChenyi Qiang x86_machine_get_bus_lock_ratelimit, 423035d1ef2SChenyi Qiang x86_machine_set_bus_lock_ratelimit, NULL, NULL); 424035d1ef2SChenyi Qiang object_class_property_set_description(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, 425035d1ef2SChenyi Qiang "Set the ratelimit for the bus locks acquired in VMs"); 426dfce81f1SSean Christopherson 427dfce81f1SSean Christopherson object_class_property_add(oc, "sgx-epc", "SgxEPC", 428dfce81f1SSean Christopherson machine_get_sgx_epc, machine_set_sgx_epc, 429dfce81f1SSean Christopherson NULL, NULL); 430dfce81f1SSean Christopherson object_class_property_set_description(oc, "sgx-epc", 431dfce81f1SSean Christopherson "SGX EPC device"); 432f0bb276bSPaolo Bonzini } 433f0bb276bSPaolo Bonzini 434f0bb276bSPaolo Bonzini static const TypeInfo x86_machine_info = { 435f0bb276bSPaolo Bonzini .name = TYPE_X86_MACHINE, 436f0bb276bSPaolo Bonzini .parent = TYPE_MACHINE, 437f0bb276bSPaolo Bonzini .abstract = true, 438f0bb276bSPaolo Bonzini .instance_size = sizeof(X86MachineState), 439f0bb276bSPaolo Bonzini .instance_init = x86_machine_initfn, 440f0bb276bSPaolo Bonzini .class_size = sizeof(X86MachineClass), 441f0bb276bSPaolo Bonzini .class_init = x86_machine_class_init, 442f0bb276bSPaolo Bonzini .interfaces = (InterfaceInfo[]) { 443f0bb276bSPaolo Bonzini { TYPE_NMI }, 444f0bb276bSPaolo Bonzini { } 445f0bb276bSPaolo Bonzini }, 446f0bb276bSPaolo Bonzini }; 447f0bb276bSPaolo Bonzini 448f0bb276bSPaolo Bonzini static void x86_machine_register_types(void) 449f0bb276bSPaolo Bonzini { 450f0bb276bSPaolo Bonzini type_register_static(&x86_machine_info); 451f0bb276bSPaolo Bonzini } 452f0bb276bSPaolo Bonzini 453f0bb276bSPaolo Bonzini type_init(x86_machine_register_types) 454