1df4fd7d5SPhilippe Mathieu-Daudé /* 232cad1ffSPhilippe Mathieu-Daudé * QEMU CPU model (system specific) 3df4fd7d5SPhilippe Mathieu-Daudé * 4df4fd7d5SPhilippe Mathieu-Daudé * Copyright (c) 2012-2014 SUSE LINUX Products GmbH 5df4fd7d5SPhilippe Mathieu-Daudé * 6df4fd7d5SPhilippe Mathieu-Daudé * This program is free software; you can redistribute it and/or 7df4fd7d5SPhilippe Mathieu-Daudé * modify it under the terms of the GNU General Public License 8df4fd7d5SPhilippe Mathieu-Daudé * as published by the Free Software Foundation; either version 2 9df4fd7d5SPhilippe Mathieu-Daudé * of the License, or (at your option) any later version. 10df4fd7d5SPhilippe Mathieu-Daudé * 11df4fd7d5SPhilippe Mathieu-Daudé * This program is distributed in the hope that it will be useful, 12df4fd7d5SPhilippe Mathieu-Daudé * but WITHOUT ANY WARRANTY; without even the implied warranty of 13df4fd7d5SPhilippe Mathieu-Daudé * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14df4fd7d5SPhilippe Mathieu-Daudé * GNU General Public License for more details. 15df4fd7d5SPhilippe Mathieu-Daudé * 16df4fd7d5SPhilippe Mathieu-Daudé * You should have received a copy of the GNU General Public License 17df4fd7d5SPhilippe Mathieu-Daudé * along with this program; if not, see 18df4fd7d5SPhilippe Mathieu-Daudé * <http://www.gnu.org/licenses/gpl-2.0.html> 19df4fd7d5SPhilippe Mathieu-Daudé */ 20df4fd7d5SPhilippe Mathieu-Daudé 21df4fd7d5SPhilippe Mathieu-Daudé #include "qemu/osdep.h" 22df4fd7d5SPhilippe Mathieu-Daudé #include "qapi/error.h" 23*e3a575f5SPhilippe Mathieu-Daudé #include "exec/memory.h" 2442508261SPhilippe Mathieu-Daudé #include "exec/tswap.h" 25*e3a575f5SPhilippe Mathieu-Daudé #include "hw/qdev-core.h" 26*e3a575f5SPhilippe Mathieu-Daudé #include "hw/qdev-properties.h" 27da383e02SPhilippe Mathieu-Daudé #include "hw/core/sysemu-cpu-ops.h" 28df4fd7d5SPhilippe Mathieu-Daudé 2977ba5d50SPhilippe Mathieu-Daudé bool cpu_paging_enabled(const CPUState *cpu) 3077ba5d50SPhilippe Mathieu-Daudé { 3177ba5d50SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 3277ba5d50SPhilippe Mathieu-Daudé 336bc0d6a0SPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_paging_enabled) { 346bc0d6a0SPhilippe Mathieu-Daudé return cc->sysemu_ops->get_paging_enabled(cpu); 3577ba5d50SPhilippe Mathieu-Daudé } 3677ba5d50SPhilippe Mathieu-Daudé 3777ba5d50SPhilippe Mathieu-Daudé return false; 3877ba5d50SPhilippe Mathieu-Daudé } 3977ba5d50SPhilippe Mathieu-Daudé 408a5b974bSMarc-André Lureau bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list, 4165c57115SPhilippe Mathieu-Daudé Error **errp) 4265c57115SPhilippe Mathieu-Daudé { 4365c57115SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 4465c57115SPhilippe Mathieu-Daudé 452b60b62eSPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_memory_mapping) { 468a5b974bSMarc-André Lureau return cc->sysemu_ops->get_memory_mapping(cpu, list, errp); 4765c57115SPhilippe Mathieu-Daudé } 4865c57115SPhilippe Mathieu-Daudé 4965c57115SPhilippe Mathieu-Daudé error_setg(errp, "Obtaining memory mappings is unsupported on this CPU."); 508a5b974bSMarc-André Lureau return false; 5165c57115SPhilippe Mathieu-Daudé } 5265c57115SPhilippe Mathieu-Daudé 53a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, 54a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs *attrs) 55a41d3aaeSPhilippe Mathieu-Daudé { 56a41d3aaeSPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 571cceedd7SDavid Hildenbrand hwaddr paddr; 58a41d3aaeSPhilippe Mathieu-Daudé 5908928c6dSPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_phys_page_attrs_debug) { 601cceedd7SDavid Hildenbrand paddr = cc->sysemu_ops->get_phys_page_attrs_debug(cpu, addr, attrs); 611cceedd7SDavid Hildenbrand } else { 62a41d3aaeSPhilippe Mathieu-Daudé /* Fallback for CPUs which don't implement the _attrs_ hook */ 63a41d3aaeSPhilippe Mathieu-Daudé *attrs = MEMTXATTRS_UNSPECIFIED; 641cceedd7SDavid Hildenbrand paddr = cc->sysemu_ops->get_phys_page_debug(cpu, addr); 651cceedd7SDavid Hildenbrand } 661cceedd7SDavid Hildenbrand /* Indicate that this is a debug access. */ 671cceedd7SDavid Hildenbrand attrs->debug = 1; 681cceedd7SDavid Hildenbrand return paddr; 69a41d3aaeSPhilippe Mathieu-Daudé } 70a41d3aaeSPhilippe Mathieu-Daudé 71a41d3aaeSPhilippe Mathieu-Daudé hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr) 72a41d3aaeSPhilippe Mathieu-Daudé { 73a41d3aaeSPhilippe Mathieu-Daudé MemTxAttrs attrs = {}; 74a41d3aaeSPhilippe Mathieu-Daudé 75a41d3aaeSPhilippe Mathieu-Daudé return cpu_get_phys_page_attrs_debug(cpu, addr, &attrs); 76a41d3aaeSPhilippe Mathieu-Daudé } 77a41d3aaeSPhilippe Mathieu-Daudé 78a41d3aaeSPhilippe Mathieu-Daudé int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs) 79a41d3aaeSPhilippe Mathieu-Daudé { 80a41d3aaeSPhilippe Mathieu-Daudé int ret = 0; 81a41d3aaeSPhilippe Mathieu-Daudé 82b404ca37SAlex Bennée if (cpu->cc->sysemu_ops->asidx_from_attrs) { 83b404ca37SAlex Bennée ret = cpu->cc->sysemu_ops->asidx_from_attrs(cpu, attrs); 84a41d3aaeSPhilippe Mathieu-Daudé assert(ret < cpu->num_ases && ret >= 0); 85a41d3aaeSPhilippe Mathieu-Daudé } 86a41d3aaeSPhilippe Mathieu-Daudé return ret; 87a41d3aaeSPhilippe Mathieu-Daudé } 88a41d3aaeSPhilippe Mathieu-Daudé 895ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 905ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 915ef2d5a4SPhilippe Mathieu-Daudé { 925ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 935ef2d5a4SPhilippe Mathieu-Daudé 94715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf32_qemunote) { 955ef2d5a4SPhilippe Mathieu-Daudé return 0; 965ef2d5a4SPhilippe Mathieu-Daudé } 97715e3c1aSPhilippe Mathieu-Daudé return (*cc->sysemu_ops->write_elf32_qemunote)(f, cpu, opaque); 985ef2d5a4SPhilippe Mathieu-Daudé } 995ef2d5a4SPhilippe Mathieu-Daudé 1005ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu, 1015ef2d5a4SPhilippe Mathieu-Daudé int cpuid, void *opaque) 1025ef2d5a4SPhilippe Mathieu-Daudé { 1035ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 1045ef2d5a4SPhilippe Mathieu-Daudé 105715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf32_note) { 1065ef2d5a4SPhilippe Mathieu-Daudé return -1; 1075ef2d5a4SPhilippe Mathieu-Daudé } 108715e3c1aSPhilippe Mathieu-Daudé return (*cc->sysemu_ops->write_elf32_note)(f, cpu, cpuid, opaque); 1095ef2d5a4SPhilippe Mathieu-Daudé } 1105ef2d5a4SPhilippe Mathieu-Daudé 1115ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu, 1125ef2d5a4SPhilippe Mathieu-Daudé void *opaque) 1135ef2d5a4SPhilippe Mathieu-Daudé { 1145ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 1155ef2d5a4SPhilippe Mathieu-Daudé 116715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf64_qemunote) { 1175ef2d5a4SPhilippe Mathieu-Daudé return 0; 1185ef2d5a4SPhilippe Mathieu-Daudé } 119715e3c1aSPhilippe Mathieu-Daudé return (*cc->sysemu_ops->write_elf64_qemunote)(f, cpu, opaque); 1205ef2d5a4SPhilippe Mathieu-Daudé } 1215ef2d5a4SPhilippe Mathieu-Daudé 1225ef2d5a4SPhilippe Mathieu-Daudé int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu, 1235ef2d5a4SPhilippe Mathieu-Daudé int cpuid, void *opaque) 1245ef2d5a4SPhilippe Mathieu-Daudé { 1255ef2d5a4SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 1265ef2d5a4SPhilippe Mathieu-Daudé 127715e3c1aSPhilippe Mathieu-Daudé if (!cc->sysemu_ops->write_elf64_note) { 1285ef2d5a4SPhilippe Mathieu-Daudé return -1; 1295ef2d5a4SPhilippe Mathieu-Daudé } 130715e3c1aSPhilippe Mathieu-Daudé return (*cc->sysemu_ops->write_elf64_note)(f, cpu, cpuid, opaque); 1315ef2d5a4SPhilippe Mathieu-Daudé } 1325ef2d5a4SPhilippe Mathieu-Daudé 133cdba7e2fSPhilippe Mathieu-Daudé bool cpu_virtio_is_big_endian(CPUState *cpu) 134cdba7e2fSPhilippe Mathieu-Daudé { 135cdba7e2fSPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 136cdba7e2fSPhilippe Mathieu-Daudé 137da383e02SPhilippe Mathieu-Daudé if (cc->sysemu_ops->virtio_is_big_endian) { 138da383e02SPhilippe Mathieu-Daudé return cc->sysemu_ops->virtio_is_big_endian(cpu); 139cdba7e2fSPhilippe Mathieu-Daudé } 140cdba7e2fSPhilippe Mathieu-Daudé return target_words_bigendian(); 141cdba7e2fSPhilippe Mathieu-Daudé } 142cdba7e2fSPhilippe Mathieu-Daudé 143df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *cpu_get_crash_info(CPUState *cpu) 144df4fd7d5SPhilippe Mathieu-Daudé { 145df4fd7d5SPhilippe Mathieu-Daudé CPUClass *cc = CPU_GET_CLASS(cpu); 146df4fd7d5SPhilippe Mathieu-Daudé GuestPanicInformation *res = NULL; 147df4fd7d5SPhilippe Mathieu-Daudé 14883ec01b6SPhilippe Mathieu-Daudé if (cc->sysemu_ops->get_crash_info) { 14983ec01b6SPhilippe Mathieu-Daudé res = cc->sysemu_ops->get_crash_info(cpu); 150df4fd7d5SPhilippe Mathieu-Daudé } 151df4fd7d5SPhilippe Mathieu-Daudé return res; 152df4fd7d5SPhilippe Mathieu-Daudé } 153*e3a575f5SPhilippe Mathieu-Daudé 154*e3a575f5SPhilippe Mathieu-Daudé static const Property cpu_system_props[] = { 155*e3a575f5SPhilippe Mathieu-Daudé /* 156*e3a575f5SPhilippe Mathieu-Daudé * Create a memory property for system CPU object, so users can 157*e3a575f5SPhilippe Mathieu-Daudé * wire up its memory. The default if no link is set up is to use 158*e3a575f5SPhilippe Mathieu-Daudé * the system address space. 159*e3a575f5SPhilippe Mathieu-Daudé */ 160*e3a575f5SPhilippe Mathieu-Daudé DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION, 161*e3a575f5SPhilippe Mathieu-Daudé MemoryRegion *), 162*e3a575f5SPhilippe Mathieu-Daudé }; 163*e3a575f5SPhilippe Mathieu-Daudé 164*e3a575f5SPhilippe Mathieu-Daudé static bool cpu_get_start_powered_off(Object *obj, Error **errp) 165*e3a575f5SPhilippe Mathieu-Daudé { 166*e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 167*e3a575f5SPhilippe Mathieu-Daudé return cpu->start_powered_off; 168*e3a575f5SPhilippe Mathieu-Daudé } 169*e3a575f5SPhilippe Mathieu-Daudé 170*e3a575f5SPhilippe Mathieu-Daudé static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp) 171*e3a575f5SPhilippe Mathieu-Daudé { 172*e3a575f5SPhilippe Mathieu-Daudé CPUState *cpu = CPU(obj); 173*e3a575f5SPhilippe Mathieu-Daudé cpu->start_powered_off = value; 174*e3a575f5SPhilippe Mathieu-Daudé } 175*e3a575f5SPhilippe Mathieu-Daudé 176*e3a575f5SPhilippe Mathieu-Daudé void cpu_class_init_props(DeviceClass *dc) 177*e3a575f5SPhilippe Mathieu-Daudé { 178*e3a575f5SPhilippe Mathieu-Daudé ObjectClass *oc = OBJECT_CLASS(dc); 179*e3a575f5SPhilippe Mathieu-Daudé 180*e3a575f5SPhilippe Mathieu-Daudé /* 181*e3a575f5SPhilippe Mathieu-Daudé * We can't use DEFINE_PROP_BOOL in the Property array for this 182*e3a575f5SPhilippe Mathieu-Daudé * property, because we want this to be settable after realize. 183*e3a575f5SPhilippe Mathieu-Daudé */ 184*e3a575f5SPhilippe Mathieu-Daudé object_class_property_add_bool(oc, "start-powered-off", 185*e3a575f5SPhilippe Mathieu-Daudé cpu_get_start_powered_off, 186*e3a575f5SPhilippe Mathieu-Daudé cpu_set_start_powered_off); 187*e3a575f5SPhilippe Mathieu-Daudé 188*e3a575f5SPhilippe Mathieu-Daudé device_class_set_props(dc, cpu_system_props); 189*e3a575f5SPhilippe Mathieu-Daudé } 190