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 34b061f059SPaolo 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 42b061f059SPaolo 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; 48*3568adc9SZhao Liu /* 49*3568adc9SZhao Liu * Though smp.modules means the number of modules in one cluster, 50*3568adc9SZhao Liu * i386 doesn't support cluster level so that the smp.clusters 51*3568adc9SZhao Liu * always defaults to 1, therefore using smp.modules directly is 52*3568adc9SZhao Liu * fine here. 53*3568adc9SZhao Liu */ 54*3568adc9SZhao Liu topo_info->modules_per_die = ms->smp.modules; 55*3568adc9SZhao Liu topo_info->cores_per_module = ms->smp.cores; 5653a5e7bdSBabu Moger topo_info->threads_per_core = ms->smp.threads; 5753a5e7bdSBabu Moger } 5853a5e7bdSBabu Moger 59549e984eSSergio Lopez /* 60549e984eSSergio Lopez * Calculates initial APIC ID for a specific CPU index 61549e984eSSergio Lopez * 62549e984eSSergio Lopez * Currently we need to be able to calculate the APIC ID from the CPU index 63549e984eSSergio Lopez * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have 64549e984eSSergio Lopez * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of 65549e984eSSergio Lopez * all CPUs up to max_cpus. 66549e984eSSergio Lopez */ 67703a548aSSergio Lopez uint32_t x86_cpu_apic_id_from_index(X86MachineState *x86ms, 68549e984eSSergio Lopez unsigned int cpu_index) 69549e984eSSergio Lopez { 7053a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 71549e984eSSergio Lopez 7253a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 7353a5e7bdSBabu Moger 74e6895f04SIgor Mammedov return x86_apicid_from_cpu_idx(&topo_info, cpu_index); 75549e984eSSergio Lopez } 76549e984eSSergio Lopez 77b348fdcdSPaolo Bonzini static CpuInstanceProperties 78549e984eSSergio Lopez x86_cpu_index_to_props(MachineState *ms, unsigned cpu_index) 79549e984eSSergio Lopez { 80549e984eSSergio Lopez MachineClass *mc = MACHINE_GET_CLASS(ms); 81549e984eSSergio Lopez const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); 82549e984eSSergio Lopez 83549e984eSSergio Lopez assert(cpu_index < possible_cpus->len); 84549e984eSSergio Lopez return possible_cpus->cpus[cpu_index].props; 85549e984eSSergio Lopez } 86549e984eSSergio Lopez 87b348fdcdSPaolo Bonzini static int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx) 88549e984eSSergio Lopez { 89dcf08bc6SBabu Moger X86CPUTopoIDs topo_ids; 90f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(ms); 9153a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 9253a5e7bdSBabu Moger 9353a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 94549e984eSSergio Lopez 95549e984eSSergio Lopez assert(idx < ms->possible_cpus->len); 96dfe7ed0aSBabu Moger x86_topo_ids_from_apicid(ms->possible_cpus->cpus[idx].arch_id, 97dfe7ed0aSBabu Moger &topo_info, &topo_ids); 98dcf08bc6SBabu Moger return topo_ids.pkg_id % ms->numa_state->num_nodes; 99549e984eSSergio Lopez } 100549e984eSSergio Lopez 101b348fdcdSPaolo Bonzini static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms) 102549e984eSSergio Lopez { 103f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(ms); 104549e984eSSergio Lopez unsigned int max_cpus = ms->smp.max_cpus; 10553a5e7bdSBabu Moger X86CPUTopoInfo topo_info; 10653a5e7bdSBabu Moger int i; 107549e984eSSergio Lopez 108549e984eSSergio Lopez if (ms->possible_cpus) { 109549e984eSSergio Lopez /* 110549e984eSSergio Lopez * make sure that max_cpus hasn't changed since the first use, i.e. 111549e984eSSergio Lopez * -smp hasn't been parsed after it 112549e984eSSergio Lopez */ 113549e984eSSergio Lopez assert(ms->possible_cpus->len == max_cpus); 114549e984eSSergio Lopez return ms->possible_cpus; 115549e984eSSergio Lopez } 116549e984eSSergio Lopez 117549e984eSSergio Lopez ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + 118549e984eSSergio Lopez sizeof(CPUArchId) * max_cpus); 119549e984eSSergio Lopez ms->possible_cpus->len = max_cpus; 12053a5e7bdSBabu Moger 12153a5e7bdSBabu Moger init_topo_info(&topo_info, x86ms); 12253a5e7bdSBabu Moger 123549e984eSSergio Lopez for (i = 0; i < ms->possible_cpus->len; i++) { 124dcf08bc6SBabu Moger X86CPUTopoIDs topo_ids; 125549e984eSSergio Lopez 126549e984eSSergio Lopez ms->possible_cpus->cpus[i].type = ms->cpu_type; 127549e984eSSergio Lopez ms->possible_cpus->cpus[i].vcpus_count = 1; 128dfe7ed0aSBabu Moger ms->possible_cpus->cpus[i].arch_id = 129dfe7ed0aSBabu Moger x86_cpu_apic_id_from_index(x86ms, i); 130dfe7ed0aSBabu Moger x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, 131dfe7ed0aSBabu Moger &topo_info, &topo_ids); 132549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_socket_id = true; 133dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.socket_id = topo_ids.pkg_id; 13467872eb8SPaolo Bonzini if (ms->smp.dies > 1) { 135549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_die_id = true; 136dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.die_id = topo_ids.die_id; 137549e984eSSergio Lopez } 138549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_core_id = true; 139dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.core_id = topo_ids.core_id; 140549e984eSSergio Lopez ms->possible_cpus->cpus[i].props.has_thread_id = true; 141dcf08bc6SBabu Moger ms->possible_cpus->cpus[i].props.thread_id = topo_ids.smt_id; 142549e984eSSergio Lopez } 143549e984eSSergio Lopez return ms->possible_cpus; 144549e984eSSergio Lopez } 145549e984eSSergio Lopez 146f0bb276bSPaolo Bonzini static void x86_nmi(NMIState *n, int cpu_index, Error **errp) 147f0bb276bSPaolo Bonzini { 148f0bb276bSPaolo Bonzini /* cpu index isn't used */ 149f0bb276bSPaolo Bonzini CPUState *cs; 150f0bb276bSPaolo Bonzini 151f0bb276bSPaolo Bonzini CPU_FOREACH(cs) { 152f0bb276bSPaolo Bonzini X86CPU *cpu = X86_CPU(cs); 153f0bb276bSPaolo Bonzini 154c2e6d7d8SBernhard Beschow if (cpu_is_apic_enabled(cpu->apic_state)) { 155f0bb276bSPaolo Bonzini apic_deliver_nmi(cpu->apic_state); 156f22f3a92SBernhard Beschow } else { 157f22f3a92SBernhard Beschow cpu_interrupt(cs, CPU_INTERRUPT_NMI); 158f0bb276bSPaolo Bonzini } 159f0bb276bSPaolo Bonzini } 160f0bb276bSPaolo Bonzini } 161f0bb276bSPaolo Bonzini 1629927a632SGerd Hoffmann bool x86_machine_is_smm_enabled(const X86MachineState *x86ms) 163ed9e923cSPaolo Bonzini { 164ed9e923cSPaolo Bonzini bool smm_available = false; 165ed9e923cSPaolo Bonzini 166ed9e923cSPaolo Bonzini if (x86ms->smm == ON_OFF_AUTO_OFF) { 167ed9e923cSPaolo Bonzini return false; 168ed9e923cSPaolo Bonzini } 169ed9e923cSPaolo Bonzini 170ed9e923cSPaolo Bonzini if (tcg_enabled() || qtest_enabled()) { 171ed9e923cSPaolo Bonzini smm_available = true; 172ed9e923cSPaolo Bonzini } else if (kvm_enabled()) { 173ed9e923cSPaolo Bonzini smm_available = kvm_has_smm(); 174ed9e923cSPaolo Bonzini } 175ed9e923cSPaolo Bonzini 176ed9e923cSPaolo Bonzini if (smm_available) { 177ed9e923cSPaolo Bonzini return true; 178ed9e923cSPaolo Bonzini } 179ed9e923cSPaolo Bonzini 180ed9e923cSPaolo Bonzini if (x86ms->smm == ON_OFF_AUTO_ON) { 181ed9e923cSPaolo Bonzini error_report("System Management Mode not supported by this hypervisor."); 182ed9e923cSPaolo Bonzini exit(1); 183ed9e923cSPaolo Bonzini } 184ed9e923cSPaolo Bonzini return false; 185ed9e923cSPaolo Bonzini } 186ed9e923cSPaolo Bonzini 187ed9e923cSPaolo Bonzini static void x86_machine_get_smm(Object *obj, Visitor *v, const char *name, 188ed9e923cSPaolo Bonzini void *opaque, Error **errp) 189ed9e923cSPaolo Bonzini { 190ed9e923cSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 191ed9e923cSPaolo Bonzini OnOffAuto smm = x86ms->smm; 192ed9e923cSPaolo Bonzini 193ed9e923cSPaolo Bonzini visit_type_OnOffAuto(v, name, &smm, errp); 194ed9e923cSPaolo Bonzini } 195ed9e923cSPaolo Bonzini 196ed9e923cSPaolo Bonzini static void x86_machine_set_smm(Object *obj, Visitor *v, const char *name, 197ed9e923cSPaolo Bonzini void *opaque, Error **errp) 198ed9e923cSPaolo Bonzini { 199ed9e923cSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 200ed9e923cSPaolo Bonzini 201ed9e923cSPaolo Bonzini visit_type_OnOffAuto(v, name, &x86ms->smm, errp); 202ed9e923cSPaolo Bonzini } 203ed9e923cSPaolo Bonzini 2049927a632SGerd Hoffmann bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms) 20517e89077SGerd Hoffmann { 20617e89077SGerd Hoffmann if (x86ms->acpi == ON_OFF_AUTO_OFF) { 20717e89077SGerd Hoffmann return false; 20817e89077SGerd Hoffmann } 20917e89077SGerd Hoffmann return true; 21017e89077SGerd Hoffmann } 21117e89077SGerd Hoffmann 21217e89077SGerd Hoffmann static void x86_machine_get_acpi(Object *obj, Visitor *v, const char *name, 21317e89077SGerd Hoffmann void *opaque, Error **errp) 21417e89077SGerd Hoffmann { 21517e89077SGerd Hoffmann X86MachineState *x86ms = X86_MACHINE(obj); 21617e89077SGerd Hoffmann OnOffAuto acpi = x86ms->acpi; 21717e89077SGerd Hoffmann 21817e89077SGerd Hoffmann visit_type_OnOffAuto(v, name, &acpi, errp); 21917e89077SGerd Hoffmann } 22017e89077SGerd Hoffmann 22117e89077SGerd Hoffmann static void x86_machine_set_acpi(Object *obj, Visitor *v, const char *name, 22217e89077SGerd Hoffmann void *opaque, Error **errp) 22317e89077SGerd Hoffmann { 22417e89077SGerd Hoffmann X86MachineState *x86ms = X86_MACHINE(obj); 22517e89077SGerd Hoffmann 22617e89077SGerd Hoffmann visit_type_OnOffAuto(v, name, &x86ms->acpi, errp); 22717e89077SGerd Hoffmann } 22817e89077SGerd Hoffmann 2299dee7e51SXiaoyao Li static void x86_machine_get_pit(Object *obj, Visitor *v, const char *name, 2309dee7e51SXiaoyao Li void *opaque, Error **errp) 2319dee7e51SXiaoyao Li { 2329dee7e51SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 2339dee7e51SXiaoyao Li OnOffAuto pit = x86ms->pit; 2349dee7e51SXiaoyao Li 2359dee7e51SXiaoyao Li visit_type_OnOffAuto(v, name, &pit, errp); 2369dee7e51SXiaoyao Li } 2379dee7e51SXiaoyao Li 2389dee7e51SXiaoyao Li static void x86_machine_set_pit(Object *obj, Visitor *v, const char *name, 2399dee7e51SXiaoyao Li void *opaque, Error **errp) 2409dee7e51SXiaoyao Li { 2419dee7e51SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj);; 2429dee7e51SXiaoyao Li 2439dee7e51SXiaoyao Li visit_type_OnOffAuto(v, name, &x86ms->pit, errp); 2449dee7e51SXiaoyao Li } 2459dee7e51SXiaoyao Li 246c300bbe8SXiaoyao Li static void x86_machine_get_pic(Object *obj, Visitor *v, const char *name, 247c300bbe8SXiaoyao Li void *opaque, Error **errp) 248c300bbe8SXiaoyao Li { 249c300bbe8SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 250c300bbe8SXiaoyao Li OnOffAuto pic = x86ms->pic; 251c300bbe8SXiaoyao Li 252c300bbe8SXiaoyao Li visit_type_OnOffAuto(v, name, &pic, errp); 253c300bbe8SXiaoyao Li } 254c300bbe8SXiaoyao Li 255c300bbe8SXiaoyao Li static void x86_machine_set_pic(Object *obj, Visitor *v, const char *name, 256c300bbe8SXiaoyao Li void *opaque, Error **errp) 257c300bbe8SXiaoyao Li { 258c300bbe8SXiaoyao Li X86MachineState *x86ms = X86_MACHINE(obj); 259c300bbe8SXiaoyao Li 260c300bbe8SXiaoyao Li visit_type_OnOffAuto(v, name, &x86ms->pic, errp); 261c300bbe8SXiaoyao Li } 262c300bbe8SXiaoyao Li 263d07b2286SMarian Postevca static char *x86_machine_get_oem_id(Object *obj, Error **errp) 264d07b2286SMarian Postevca { 265d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 266d07b2286SMarian Postevca 267d07b2286SMarian Postevca return g_strdup(x86ms->oem_id); 268d07b2286SMarian Postevca } 269d07b2286SMarian Postevca 270d07b2286SMarian Postevca static void x86_machine_set_oem_id(Object *obj, const char *value, Error **errp) 271d07b2286SMarian Postevca { 272d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 273d07b2286SMarian Postevca size_t len = strlen(value); 274d07b2286SMarian Postevca 275d07b2286SMarian Postevca if (len > 6) { 276d07b2286SMarian Postevca error_setg(errp, 277d07b2286SMarian Postevca "User specified "X86_MACHINE_OEM_ID" value is bigger than " 278d07b2286SMarian Postevca "6 bytes in size"); 279d07b2286SMarian Postevca return; 280d07b2286SMarian Postevca } 281d07b2286SMarian Postevca 282d07b2286SMarian Postevca strncpy(x86ms->oem_id, value, 6); 283d07b2286SMarian Postevca } 284d07b2286SMarian Postevca 285d07b2286SMarian Postevca static char *x86_machine_get_oem_table_id(Object *obj, Error **errp) 286d07b2286SMarian Postevca { 287d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 288d07b2286SMarian Postevca 289d07b2286SMarian Postevca return g_strdup(x86ms->oem_table_id); 290d07b2286SMarian Postevca } 291d07b2286SMarian Postevca 292d07b2286SMarian Postevca static void x86_machine_set_oem_table_id(Object *obj, const char *value, 293d07b2286SMarian Postevca Error **errp) 294d07b2286SMarian Postevca { 295d07b2286SMarian Postevca X86MachineState *x86ms = X86_MACHINE(obj); 296d07b2286SMarian Postevca size_t len = strlen(value); 297d07b2286SMarian Postevca 298d07b2286SMarian Postevca if (len > 8) { 299d07b2286SMarian Postevca error_setg(errp, 300d07b2286SMarian Postevca "User specified "X86_MACHINE_OEM_TABLE_ID 301d07b2286SMarian Postevca " value is bigger than " 302d07b2286SMarian Postevca "8 bytes in size"); 303d07b2286SMarian Postevca return; 304d07b2286SMarian Postevca } 305d07b2286SMarian Postevca strncpy(x86ms->oem_table_id, value, 8); 306d07b2286SMarian Postevca } 307d07b2286SMarian Postevca 308035d1ef2SChenyi Qiang static void x86_machine_get_bus_lock_ratelimit(Object *obj, Visitor *v, 309035d1ef2SChenyi Qiang const char *name, void *opaque, Error **errp) 310035d1ef2SChenyi Qiang { 311035d1ef2SChenyi Qiang X86MachineState *x86ms = X86_MACHINE(obj); 312035d1ef2SChenyi Qiang uint64_t bus_lock_ratelimit = x86ms->bus_lock_ratelimit; 313035d1ef2SChenyi Qiang 314035d1ef2SChenyi Qiang visit_type_uint64(v, name, &bus_lock_ratelimit, errp); 315035d1ef2SChenyi Qiang } 316035d1ef2SChenyi Qiang 317035d1ef2SChenyi Qiang static void x86_machine_set_bus_lock_ratelimit(Object *obj, Visitor *v, 318035d1ef2SChenyi Qiang const char *name, void *opaque, Error **errp) 319035d1ef2SChenyi Qiang { 320035d1ef2SChenyi Qiang X86MachineState *x86ms = X86_MACHINE(obj); 321035d1ef2SChenyi Qiang 322035d1ef2SChenyi Qiang visit_type_uint64(v, name, &x86ms->bus_lock_ratelimit, errp); 323035d1ef2SChenyi Qiang } 324035d1ef2SChenyi Qiang 325dfce81f1SSean Christopherson static void machine_get_sgx_epc(Object *obj, Visitor *v, const char *name, 326dfce81f1SSean Christopherson void *opaque, Error **errp) 327dfce81f1SSean Christopherson { 328dfce81f1SSean Christopherson X86MachineState *x86ms = X86_MACHINE(obj); 329dfce81f1SSean Christopherson SgxEPCList *list = x86ms->sgx_epc_list; 330dfce81f1SSean Christopherson 331dfce81f1SSean Christopherson visit_type_SgxEPCList(v, name, &list, errp); 332dfce81f1SSean Christopherson } 333dfce81f1SSean Christopherson 334dfce81f1SSean Christopherson static void machine_set_sgx_epc(Object *obj, Visitor *v, const char *name, 335dfce81f1SSean Christopherson void *opaque, Error **errp) 336dfce81f1SSean Christopherson { 337dfce81f1SSean Christopherson X86MachineState *x86ms = X86_MACHINE(obj); 338dfce81f1SSean Christopherson SgxEPCList *list; 339dfce81f1SSean Christopherson 340dfce81f1SSean Christopherson list = x86ms->sgx_epc_list; 341dfce81f1SSean Christopherson visit_type_SgxEPCList(v, name, &x86ms->sgx_epc_list, errp); 342dfce81f1SSean Christopherson 343dfce81f1SSean Christopherson qapi_free_SgxEPCList(list); 344dfce81f1SSean Christopherson } 345dfce81f1SSean Christopherson 346ee88612dSPaolo Bonzini static int x86_kvm_type(MachineState *ms, const char *vm_type) 347ee88612dSPaolo Bonzini { 348ee88612dSPaolo Bonzini /* 349ee88612dSPaolo Bonzini * No x86 machine has a kvm-type property. If one is added that has 350ee88612dSPaolo Bonzini * it, it should call kvm_get_vm_type() directly or not use it at all. 351ee88612dSPaolo Bonzini */ 352ee88612dSPaolo Bonzini assert(vm_type == NULL); 353ee88612dSPaolo Bonzini return kvm_enabled() ? kvm_get_vm_type(ms) : 0; 354ee88612dSPaolo Bonzini } 355ee88612dSPaolo Bonzini 356f0bb276bSPaolo Bonzini static void x86_machine_initfn(Object *obj) 357f0bb276bSPaolo Bonzini { 358f0bb276bSPaolo Bonzini X86MachineState *x86ms = X86_MACHINE(obj); 359f0bb276bSPaolo Bonzini 360ed9e923cSPaolo Bonzini x86ms->smm = ON_OFF_AUTO_AUTO; 36117e89077SGerd Hoffmann x86ms->acpi = ON_OFF_AUTO_AUTO; 3629dee7e51SXiaoyao Li x86ms->pit = ON_OFF_AUTO_AUTO; 363c300bbe8SXiaoyao Li x86ms->pic = ON_OFF_AUTO_AUTO; 3641b2802c4SGerd Hoffmann x86ms->pci_irq_mask = ACPI_BUILD_PCI_IRQS; 365d07b2286SMarian Postevca x86ms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); 366d07b2286SMarian Postevca x86ms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); 367035d1ef2SChenyi Qiang x86ms->bus_lock_ratelimit = 0; 3684ab4c330SJoao Martins x86ms->above_4g_mem_start = 4 * GiB; 369f0bb276bSPaolo Bonzini } 370f0bb276bSPaolo Bonzini 371f0bb276bSPaolo Bonzini static void x86_machine_class_init(ObjectClass *oc, void *data) 372f0bb276bSPaolo Bonzini { 373f0bb276bSPaolo Bonzini MachineClass *mc = MACHINE_CLASS(oc); 374f0bb276bSPaolo Bonzini X86MachineClass *x86mc = X86_MACHINE_CLASS(oc); 375f0bb276bSPaolo Bonzini NMIClass *nc = NMI_CLASS(oc); 376f0bb276bSPaolo Bonzini 377f0bb276bSPaolo Bonzini mc->cpu_index_to_instance_props = x86_cpu_index_to_props; 378f0bb276bSPaolo Bonzini mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; 379f0bb276bSPaolo Bonzini mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; 380ee88612dSPaolo Bonzini mc->kvm_type = x86_kvm_type; 3812f34ebf2SLiam Merwick x86mc->save_tsc_khz = true; 382f014c974SPaolo Bonzini x86mc->fwcfg_dma_enabled = true; 383f0bb276bSPaolo Bonzini nc->nmi_monitor_handler = x86_nmi; 384f0bb276bSPaolo Bonzini 385ed9e923cSPaolo Bonzini object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto", 386ed9e923cSPaolo Bonzini x86_machine_get_smm, x86_machine_set_smm, 387d2623129SMarkus Armbruster NULL, NULL); 388ed9e923cSPaolo Bonzini object_class_property_set_description(oc, X86_MACHINE_SMM, 3897eecec7dSMarkus Armbruster "Enable SMM"); 39017e89077SGerd Hoffmann 39117e89077SGerd Hoffmann object_class_property_add(oc, X86_MACHINE_ACPI, "OnOffAuto", 39217e89077SGerd Hoffmann x86_machine_get_acpi, x86_machine_set_acpi, 393d2623129SMarkus Armbruster NULL, NULL); 39417e89077SGerd Hoffmann object_class_property_set_description(oc, X86_MACHINE_ACPI, 3957eecec7dSMarkus Armbruster "Enable ACPI"); 396d07b2286SMarian Postevca 3979dee7e51SXiaoyao Li object_class_property_add(oc, X86_MACHINE_PIT, "OnOffAuto", 3989dee7e51SXiaoyao Li x86_machine_get_pit, 3999dee7e51SXiaoyao Li x86_machine_set_pit, 4009dee7e51SXiaoyao Li NULL, NULL); 4019dee7e51SXiaoyao Li object_class_property_set_description(oc, X86_MACHINE_PIT, 4029dee7e51SXiaoyao Li "Enable i8254 PIT"); 4039dee7e51SXiaoyao Li 404c300bbe8SXiaoyao Li object_class_property_add(oc, X86_MACHINE_PIC, "OnOffAuto", 405c300bbe8SXiaoyao Li x86_machine_get_pic, 406c300bbe8SXiaoyao Li x86_machine_set_pic, 407c300bbe8SXiaoyao Li NULL, NULL); 408c300bbe8SXiaoyao Li object_class_property_set_description(oc, X86_MACHINE_PIC, 409c300bbe8SXiaoyao Li "Enable i8259 PIC"); 410c300bbe8SXiaoyao Li 411d07b2286SMarian Postevca object_class_property_add_str(oc, X86_MACHINE_OEM_ID, 412d07b2286SMarian Postevca x86_machine_get_oem_id, 413d07b2286SMarian Postevca x86_machine_set_oem_id); 414d07b2286SMarian Postevca object_class_property_set_description(oc, X86_MACHINE_OEM_ID, 415d07b2286SMarian Postevca "Override the default value of field OEMID " 416d07b2286SMarian Postevca "in ACPI table header." 417d07b2286SMarian Postevca "The string may be up to 6 bytes in size"); 418d07b2286SMarian Postevca 419d07b2286SMarian Postevca 420d07b2286SMarian Postevca object_class_property_add_str(oc, X86_MACHINE_OEM_TABLE_ID, 421d07b2286SMarian Postevca x86_machine_get_oem_table_id, 422d07b2286SMarian Postevca x86_machine_set_oem_table_id); 423d07b2286SMarian Postevca object_class_property_set_description(oc, X86_MACHINE_OEM_TABLE_ID, 424d07b2286SMarian Postevca "Override the default value of field OEM Table ID " 425d07b2286SMarian Postevca "in ACPI table header." 426d07b2286SMarian Postevca "The string may be up to 8 bytes in size"); 427035d1ef2SChenyi Qiang 428035d1ef2SChenyi Qiang object_class_property_add(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, "uint64_t", 429035d1ef2SChenyi Qiang x86_machine_get_bus_lock_ratelimit, 430035d1ef2SChenyi Qiang x86_machine_set_bus_lock_ratelimit, NULL, NULL); 431035d1ef2SChenyi Qiang object_class_property_set_description(oc, X86_MACHINE_BUS_LOCK_RATELIMIT, 432035d1ef2SChenyi Qiang "Set the ratelimit for the bus locks acquired in VMs"); 433dfce81f1SSean Christopherson 434dfce81f1SSean Christopherson object_class_property_add(oc, "sgx-epc", "SgxEPC", 435dfce81f1SSean Christopherson machine_get_sgx_epc, machine_set_sgx_epc, 436dfce81f1SSean Christopherson NULL, NULL); 437dfce81f1SSean Christopherson object_class_property_set_description(oc, "sgx-epc", 438dfce81f1SSean Christopherson "SGX EPC device"); 439f0bb276bSPaolo Bonzini } 440f0bb276bSPaolo Bonzini 441f0bb276bSPaolo Bonzini static const TypeInfo x86_machine_info = { 442f0bb276bSPaolo Bonzini .name = TYPE_X86_MACHINE, 443f0bb276bSPaolo Bonzini .parent = TYPE_MACHINE, 444f0bb276bSPaolo Bonzini .abstract = true, 445f0bb276bSPaolo Bonzini .instance_size = sizeof(X86MachineState), 446f0bb276bSPaolo Bonzini .instance_init = x86_machine_initfn, 447f0bb276bSPaolo Bonzini .class_size = sizeof(X86MachineClass), 448f0bb276bSPaolo Bonzini .class_init = x86_machine_class_init, 449f0bb276bSPaolo Bonzini .interfaces = (InterfaceInfo[]) { 450f0bb276bSPaolo Bonzini { TYPE_NMI }, 451f0bb276bSPaolo Bonzini { } 452f0bb276bSPaolo Bonzini }, 453f0bb276bSPaolo Bonzini }; 454f0bb276bSPaolo Bonzini 455f0bb276bSPaolo Bonzini static void x86_machine_register_types(void) 456f0bb276bSPaolo Bonzini { 457f0bb276bSPaolo Bonzini type_register_static(&x86_machine_info); 458f0bb276bSPaolo Bonzini } 459f0bb276bSPaolo Bonzini 460f0bb276bSPaolo Bonzini type_init(x86_machine_register_types) 461