1d9f24bf5SPaolo Bonzini /* 2d9f24bf5SPaolo Bonzini * Target-specific parts of the CPU object 3d9f24bf5SPaolo Bonzini * 4d9f24bf5SPaolo Bonzini * Copyright (c) 2003 Fabrice Bellard 5d9f24bf5SPaolo Bonzini * 6d9f24bf5SPaolo Bonzini * This library is free software; you can redistribute it and/or 7d9f24bf5SPaolo Bonzini * modify it under the terms of the GNU Lesser General Public 8d9f24bf5SPaolo Bonzini * License as published by the Free Software Foundation; either 9d9f24bf5SPaolo Bonzini * version 2 of the License, or (at your option) any later version. 10d9f24bf5SPaolo Bonzini * 11d9f24bf5SPaolo Bonzini * This library is distributed in the hope that it will be useful, 12d9f24bf5SPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of 13d9f24bf5SPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14d9f24bf5SPaolo Bonzini * Lesser General Public License for more details. 15d9f24bf5SPaolo Bonzini * 16d9f24bf5SPaolo Bonzini * You should have received a copy of the GNU Lesser General Public 17d9f24bf5SPaolo Bonzini * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18d9f24bf5SPaolo Bonzini */ 19d9f24bf5SPaolo Bonzini 20d9f24bf5SPaolo Bonzini #include "qemu/osdep.h" 21d9f24bf5SPaolo Bonzini #include "qapi/error.h" 22d9f24bf5SPaolo Bonzini 23d9f24bf5SPaolo Bonzini #include "exec/target_page.h" 24d9f24bf5SPaolo Bonzini #include "hw/qdev-core.h" 25d9f24bf5SPaolo Bonzini #include "hw/qdev-properties.h" 26d9f24bf5SPaolo Bonzini #include "qemu/error-report.h" 27d9f24bf5SPaolo Bonzini #include "migration/vmstate.h" 28d9f24bf5SPaolo Bonzini #ifdef CONFIG_USER_ONLY 29d9f24bf5SPaolo Bonzini #include "qemu.h" 30d9f24bf5SPaolo Bonzini #else 318b80bd28SPhilippe Mathieu-Daudé #include "hw/core/sysemu-cpu-ops.h" 32d9f24bf5SPaolo Bonzini #include "exec/address-spaces.h" 33d9f24bf5SPaolo Bonzini #endif 34412ae126SMads Ynddal #include "sysemu/cpus.h" 35d9f24bf5SPaolo Bonzini #include "sysemu/tcg.h" 365b5968c4SPhilippe Mathieu-Daudé #include "exec/replay-core.h" 37377bf6f3SPhilippe Mathieu-Daudé #include "exec/cpu-common.h" 383b04508cSPhilippe Mathieu-Daudé #include "exec/exec-all.h" 39548c9609SAlex Bennée #include "exec/tb-flush.h" 403b9bd3f4SPaolo Bonzini #include "exec/translate-all.h" 41d9f24bf5SPaolo Bonzini #include "exec/log.h" 4230565f10SClaudio Fontana #include "hw/core/accel-cpu.h" 43ad1a706fSRichard Henderson #include "trace/trace-root.h" 443b04508cSPhilippe Mathieu-Daudé #include "qemu/accel.h" 45720ace24SRichard Henderson #include "qemu/plugin.h" 46d9f24bf5SPaolo Bonzini 47d9f24bf5SPaolo Bonzini uintptr_t qemu_host_page_size; 48d9f24bf5SPaolo Bonzini intptr_t qemu_host_page_mask; 49d9f24bf5SPaolo Bonzini 50d9f24bf5SPaolo Bonzini #ifndef CONFIG_USER_ONLY 51d9f24bf5SPaolo Bonzini static int cpu_common_post_load(void *opaque, int version_id) 52d9f24bf5SPaolo Bonzini { 53d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 54d9f24bf5SPaolo Bonzini 55d9f24bf5SPaolo Bonzini /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the 56d9f24bf5SPaolo Bonzini version_id is increased. */ 57d9f24bf5SPaolo Bonzini cpu->interrupt_request &= ~0x01; 58d9f24bf5SPaolo Bonzini tlb_flush(cpu); 59d9f24bf5SPaolo Bonzini 60d9f24bf5SPaolo Bonzini /* loadvm has just updated the content of RAM, bypassing the 61d9f24bf5SPaolo Bonzini * usual mechanisms that ensure we flush TBs for writes to 62d9f24bf5SPaolo Bonzini * memory we've translated code from. So we must flush all TBs, 63d9f24bf5SPaolo Bonzini * which will now be stale. 64d9f24bf5SPaolo Bonzini */ 65d9f24bf5SPaolo Bonzini tb_flush(cpu); 66d9f24bf5SPaolo Bonzini 67d9f24bf5SPaolo Bonzini return 0; 68d9f24bf5SPaolo Bonzini } 69d9f24bf5SPaolo Bonzini 70d9f24bf5SPaolo Bonzini static int cpu_common_pre_load(void *opaque) 71d9f24bf5SPaolo Bonzini { 72d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 73d9f24bf5SPaolo Bonzini 74d9f24bf5SPaolo Bonzini cpu->exception_index = -1; 75d9f24bf5SPaolo Bonzini 76d9f24bf5SPaolo Bonzini return 0; 77d9f24bf5SPaolo Bonzini } 78d9f24bf5SPaolo Bonzini 79d9f24bf5SPaolo Bonzini static bool cpu_common_exception_index_needed(void *opaque) 80d9f24bf5SPaolo Bonzini { 81d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 82d9f24bf5SPaolo Bonzini 83d9f24bf5SPaolo Bonzini return tcg_enabled() && cpu->exception_index != -1; 84d9f24bf5SPaolo Bonzini } 85d9f24bf5SPaolo Bonzini 86d9f24bf5SPaolo Bonzini static const VMStateDescription vmstate_cpu_common_exception_index = { 87d9f24bf5SPaolo Bonzini .name = "cpu_common/exception_index", 88d9f24bf5SPaolo Bonzini .version_id = 1, 89d9f24bf5SPaolo Bonzini .minimum_version_id = 1, 90d9f24bf5SPaolo Bonzini .needed = cpu_common_exception_index_needed, 91d9f24bf5SPaolo Bonzini .fields = (VMStateField[]) { 92d9f24bf5SPaolo Bonzini VMSTATE_INT32(exception_index, CPUState), 93d9f24bf5SPaolo Bonzini VMSTATE_END_OF_LIST() 94d9f24bf5SPaolo Bonzini } 95d9f24bf5SPaolo Bonzini }; 96d9f24bf5SPaolo Bonzini 97d9f24bf5SPaolo Bonzini static bool cpu_common_crash_occurred_needed(void *opaque) 98d9f24bf5SPaolo Bonzini { 99d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 100d9f24bf5SPaolo Bonzini 101d9f24bf5SPaolo Bonzini return cpu->crash_occurred; 102d9f24bf5SPaolo Bonzini } 103d9f24bf5SPaolo Bonzini 104d9f24bf5SPaolo Bonzini static const VMStateDescription vmstate_cpu_common_crash_occurred = { 105d9f24bf5SPaolo Bonzini .name = "cpu_common/crash_occurred", 106d9f24bf5SPaolo Bonzini .version_id = 1, 107d9f24bf5SPaolo Bonzini .minimum_version_id = 1, 108d9f24bf5SPaolo Bonzini .needed = cpu_common_crash_occurred_needed, 109d9f24bf5SPaolo Bonzini .fields = (VMStateField[]) { 110d9f24bf5SPaolo Bonzini VMSTATE_BOOL(crash_occurred, CPUState), 111d9f24bf5SPaolo Bonzini VMSTATE_END_OF_LIST() 112d9f24bf5SPaolo Bonzini } 113d9f24bf5SPaolo Bonzini }; 114d9f24bf5SPaolo Bonzini 115d9f24bf5SPaolo Bonzini const VMStateDescription vmstate_cpu_common = { 116d9f24bf5SPaolo Bonzini .name = "cpu_common", 117d9f24bf5SPaolo Bonzini .version_id = 1, 118d9f24bf5SPaolo Bonzini .minimum_version_id = 1, 119d9f24bf5SPaolo Bonzini .pre_load = cpu_common_pre_load, 120d9f24bf5SPaolo Bonzini .post_load = cpu_common_post_load, 121d9f24bf5SPaolo Bonzini .fields = (VMStateField[]) { 122d9f24bf5SPaolo Bonzini VMSTATE_UINT32(halted, CPUState), 123d9f24bf5SPaolo Bonzini VMSTATE_UINT32(interrupt_request, CPUState), 124d9f24bf5SPaolo Bonzini VMSTATE_END_OF_LIST() 125d9f24bf5SPaolo Bonzini }, 126d9f24bf5SPaolo Bonzini .subsections = (const VMStateDescription*[]) { 127d9f24bf5SPaolo Bonzini &vmstate_cpu_common_exception_index, 128d9f24bf5SPaolo Bonzini &vmstate_cpu_common_crash_occurred, 129d9f24bf5SPaolo Bonzini NULL 130d9f24bf5SPaolo Bonzini } 131d9f24bf5SPaolo Bonzini }; 132d9f24bf5SPaolo Bonzini #endif 133d9f24bf5SPaolo Bonzini 1347df5e3d6SClaudio Fontana void cpu_exec_realizefn(CPUState *cpu, Error **errp) 135d9f24bf5SPaolo Bonzini { 1366fbdff87SAlex Bennée /* cache the cpu class for the hotpath */ 1376fbdff87SAlex Bennée cpu->cc = CPU_GET_CLASS(cpu); 138d9f24bf5SPaolo Bonzini 139bd684b2fSPhilippe Mathieu-Daudé if (!accel_cpu_common_realize(cpu, errp)) { 1409ea057dcSClaudio Fontana return; 1419ea057dcSClaudio Fontana } 1424e4fa6c1SRichard Henderson 1437df5e3d6SClaudio Fontana /* NB: errp parameter is unused currently */ 1447df5e3d6SClaudio Fontana if (tcg_enabled()) { 1457df5e3d6SClaudio Fontana tcg_exec_realizefn(cpu, errp); 1467df5e3d6SClaudio Fontana } 1477df5e3d6SClaudio Fontana 1484e4fa6c1SRichard Henderson /* Wait until cpu initialization complete before exposing cpu. */ 1494e4fa6c1SRichard Henderson cpu_list_add(cpu); 1504e4fa6c1SRichard Henderson 1514e4fa6c1SRichard Henderson /* Plugin initialization must wait until cpu_index assigned. */ 1524e4fa6c1SRichard Henderson if (tcg_enabled()) { 1534e4fa6c1SRichard Henderson qemu_plugin_vcpu_init_hook(cpu); 1544e4fa6c1SRichard Henderson } 1554e4fa6c1SRichard Henderson 1567df5e3d6SClaudio Fontana #ifdef CONFIG_USER_ONLY 1574336073bSPhilippe Mathieu-Daudé assert(qdev_get_vmsd(DEVICE(cpu)) == NULL || 1584336073bSPhilippe Mathieu-Daudé qdev_get_vmsd(DEVICE(cpu))->unmigratable); 1597df5e3d6SClaudio Fontana #else 1607df5e3d6SClaudio Fontana if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 1617df5e3d6SClaudio Fontana vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu); 1627df5e3d6SClaudio Fontana } 1636fbdff87SAlex Bennée if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 1646fbdff87SAlex Bennée vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu); 1657df5e3d6SClaudio Fontana } 1667df5e3d6SClaudio Fontana #endif /* CONFIG_USER_ONLY */ 1677df5e3d6SClaudio Fontana } 1687df5e3d6SClaudio Fontana 1697df5e3d6SClaudio Fontana void cpu_exec_unrealizefn(CPUState *cpu) 1707df5e3d6SClaudio Fontana { 171feece4d0SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 1727df5e3d6SClaudio Fontana CPUClass *cc = CPU_GET_CLASS(cpu); 173d9f24bf5SPaolo Bonzini 174feece4d0SPhilippe Mathieu-Daudé if (cc->sysemu_ops->legacy_vmsd != NULL) { 175feece4d0SPhilippe Mathieu-Daudé vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu); 176d9f24bf5SPaolo Bonzini } 177d9f24bf5SPaolo Bonzini if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 178d9f24bf5SPaolo Bonzini vmstate_unregister(NULL, &vmstate_cpu_common, cpu); 179d9f24bf5SPaolo Bonzini } 180d9f24bf5SPaolo Bonzini #endif 1814731f89bSEmilio Cota 1824731f89bSEmilio Cota /* Call the plugin hook before clearing cpu->cpu_index in cpu_list_remove */ 1837df5e3d6SClaudio Fontana if (tcg_enabled()) { 1844731f89bSEmilio Cota qemu_plugin_vcpu_exit_hook(cpu); 1857df5e3d6SClaudio Fontana } 1867df5e3d6SClaudio Fontana 1877df5e3d6SClaudio Fontana cpu_list_remove(cpu); 1884731f89bSEmilio Cota /* 1894731f89bSEmilio Cota * Now that the vCPU has been removed from the RCU list, we can call 190*1aa1d830SPhilippe Mathieu-Daudé * tcg_exec_unrealizefn and 191*1aa1d830SPhilippe Mathieu-Daudé * accel_cpu_common_unrealize, which may free fields using call_rcu. 1924731f89bSEmilio Cota */ 193*1aa1d830SPhilippe Mathieu-Daudé accel_cpu_common_unrealize(cpu); 1944731f89bSEmilio Cota if (tcg_enabled()) { 1954731f89bSEmilio Cota tcg_exec_unrealizefn(cpu); 1964731f89bSEmilio Cota } 197d9f24bf5SPaolo Bonzini } 198d9f24bf5SPaolo Bonzini 199995b87deSRichard Henderson /* 2006e8dcacdSRichard Henderson * This can't go in hw/core/cpu.c because that file is compiled only 2016e8dcacdSRichard Henderson * once for both user-mode and system builds. 2026e8dcacdSRichard Henderson */ 2036e8dcacdSRichard Henderson static Property cpu_common_props[] = { 2046e8dcacdSRichard Henderson #ifdef CONFIG_USER_ONLY 2056e8dcacdSRichard Henderson /* 2066e8dcacdSRichard Henderson * Create a property for the user-only object, so users can 2076e8dcacdSRichard Henderson * adjust prctl(PR_SET_UNALIGN) from the command-line. 2086e8dcacdSRichard Henderson * Has no effect if the target does not support the feature. 2096e8dcacdSRichard Henderson */ 2106e8dcacdSRichard Henderson DEFINE_PROP_BOOL("prctl-unalign-sigbus", CPUState, 2116e8dcacdSRichard Henderson prctl_unalign_sigbus, false), 2126e8dcacdSRichard Henderson #else 2136e8dcacdSRichard Henderson /* 2146e8dcacdSRichard Henderson * Create a memory property for softmmu CPU object, so users can 2156e8dcacdSRichard Henderson * wire up its memory. The default if no link is set up is to use 216995b87deSRichard Henderson * the system address space. 217995b87deSRichard Henderson */ 218995b87deSRichard Henderson DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION, 219995b87deSRichard Henderson MemoryRegion *), 220995b87deSRichard Henderson #endif 221995b87deSRichard Henderson DEFINE_PROP_END_OF_LIST(), 222995b87deSRichard Henderson }; 223995b87deSRichard Henderson 2240c3c25fcSPeter Maydell static bool cpu_get_start_powered_off(Object *obj, Error **errp) 2250c3c25fcSPeter Maydell { 2260c3c25fcSPeter Maydell CPUState *cpu = CPU(obj); 2270c3c25fcSPeter Maydell return cpu->start_powered_off; 2280c3c25fcSPeter Maydell } 2290c3c25fcSPeter Maydell 2300c3c25fcSPeter Maydell static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp) 2310c3c25fcSPeter Maydell { 2320c3c25fcSPeter Maydell CPUState *cpu = CPU(obj); 2330c3c25fcSPeter Maydell cpu->start_powered_off = value; 2340c3c25fcSPeter Maydell } 2350c3c25fcSPeter Maydell 236995b87deSRichard Henderson void cpu_class_init_props(DeviceClass *dc) 237995b87deSRichard Henderson { 2380c3c25fcSPeter Maydell ObjectClass *oc = OBJECT_CLASS(dc); 2390c3c25fcSPeter Maydell 240995b87deSRichard Henderson device_class_set_props(dc, cpu_common_props); 2410c3c25fcSPeter Maydell /* 2420c3c25fcSPeter Maydell * We can't use DEFINE_PROP_BOOL in the Property array for this 2430c3c25fcSPeter Maydell * property, because we want this to be settable after realize. 2440c3c25fcSPeter Maydell */ 2450c3c25fcSPeter Maydell object_class_property_add_bool(oc, "start-powered-off", 2460c3c25fcSPeter Maydell cpu_get_start_powered_off, 2470c3c25fcSPeter Maydell cpu_set_start_powered_off); 248995b87deSRichard Henderson } 249995b87deSRichard Henderson 250d9f24bf5SPaolo Bonzini void cpu_exec_initfn(CPUState *cpu) 251d9f24bf5SPaolo Bonzini { 252d9f24bf5SPaolo Bonzini cpu->as = NULL; 253d9f24bf5SPaolo Bonzini cpu->num_ases = 0; 254d9f24bf5SPaolo Bonzini 255d9f24bf5SPaolo Bonzini #ifndef CONFIG_USER_ONLY 256d9f24bf5SPaolo Bonzini cpu->thread_id = qemu_get_thread_id(); 257d9f24bf5SPaolo Bonzini cpu->memory = get_system_memory(); 258d9f24bf5SPaolo Bonzini object_ref(OBJECT(cpu->memory)); 259d9f24bf5SPaolo Bonzini #endif 260d9f24bf5SPaolo Bonzini } 261d9f24bf5SPaolo Bonzini 262d9f24bf5SPaolo Bonzini const char *parse_cpu_option(const char *cpu_option) 263d9f24bf5SPaolo Bonzini { 264d9f24bf5SPaolo Bonzini ObjectClass *oc; 265d9f24bf5SPaolo Bonzini CPUClass *cc; 266d9f24bf5SPaolo Bonzini gchar **model_pieces; 267d9f24bf5SPaolo Bonzini const char *cpu_type; 268d9f24bf5SPaolo Bonzini 269d9f24bf5SPaolo Bonzini model_pieces = g_strsplit(cpu_option, ",", 2); 270d9f24bf5SPaolo Bonzini if (!model_pieces[0]) { 271d9f24bf5SPaolo Bonzini error_report("-cpu option cannot be empty"); 272d9f24bf5SPaolo Bonzini exit(1); 273d9f24bf5SPaolo Bonzini } 274d9f24bf5SPaolo Bonzini 275d9f24bf5SPaolo Bonzini oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]); 276d9f24bf5SPaolo Bonzini if (oc == NULL) { 277d9f24bf5SPaolo Bonzini error_report("unable to find CPU model '%s'", model_pieces[0]); 278d9f24bf5SPaolo Bonzini g_strfreev(model_pieces); 279d9f24bf5SPaolo Bonzini exit(EXIT_FAILURE); 280d9f24bf5SPaolo Bonzini } 281d9f24bf5SPaolo Bonzini 282d9f24bf5SPaolo Bonzini cpu_type = object_class_get_name(oc); 283d9f24bf5SPaolo Bonzini cc = CPU_CLASS(oc); 284d9f24bf5SPaolo Bonzini cc->parse_features(cpu_type, model_pieces[1], &error_fatal); 285d9f24bf5SPaolo Bonzini g_strfreev(model_pieces); 286d9f24bf5SPaolo Bonzini return cpu_type; 287d9f24bf5SPaolo Bonzini } 288d9f24bf5SPaolo Bonzini 289c138c3b8SThomas Huth void list_cpus(void) 290377bf6f3SPhilippe Mathieu-Daudé { 291377bf6f3SPhilippe Mathieu-Daudé /* XXX: implement xxx_cpu_list for targets that still miss it */ 292377bf6f3SPhilippe Mathieu-Daudé #if defined(cpu_list) 293377bf6f3SPhilippe Mathieu-Daudé cpu_list(); 294377bf6f3SPhilippe Mathieu-Daudé #endif 295377bf6f3SPhilippe Mathieu-Daudé } 296377bf6f3SPhilippe Mathieu-Daudé 297d9f24bf5SPaolo Bonzini #if defined(CONFIG_USER_ONLY) 298c814c892SAnton Johansson void tb_invalidate_phys_addr(hwaddr addr) 299d9f24bf5SPaolo Bonzini { 300d9f24bf5SPaolo Bonzini mmap_lock(); 301d6d1fd29SRichard Henderson tb_invalidate_phys_page(addr); 302d9f24bf5SPaolo Bonzini mmap_unlock(); 303d9f24bf5SPaolo Bonzini } 304d9f24bf5SPaolo Bonzini #else 305d9f24bf5SPaolo Bonzini void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs) 306d9f24bf5SPaolo Bonzini { 307d9f24bf5SPaolo Bonzini ram_addr_t ram_addr; 308d9f24bf5SPaolo Bonzini MemoryRegion *mr; 309d9f24bf5SPaolo Bonzini hwaddr l = 1; 310d9f24bf5SPaolo Bonzini 311d9f24bf5SPaolo Bonzini if (!tcg_enabled()) { 312d9f24bf5SPaolo Bonzini return; 313d9f24bf5SPaolo Bonzini } 314d9f24bf5SPaolo Bonzini 315d9f24bf5SPaolo Bonzini RCU_READ_LOCK_GUARD(); 316d9f24bf5SPaolo Bonzini mr = address_space_translate(as, addr, &addr, &l, false, attrs); 317d9f24bf5SPaolo Bonzini if (!(memory_region_is_ram(mr) 318d9f24bf5SPaolo Bonzini || memory_region_is_romd(mr))) { 319d9f24bf5SPaolo Bonzini return; 320d9f24bf5SPaolo Bonzini } 321d9f24bf5SPaolo Bonzini ram_addr = memory_region_get_ram_addr(mr) + addr; 322d6d1fd29SRichard Henderson tb_invalidate_phys_page(ram_addr); 323d9f24bf5SPaolo Bonzini } 324d9f24bf5SPaolo Bonzini #endif 325d9f24bf5SPaolo Bonzini 326d9f24bf5SPaolo Bonzini /* enable or disable single step mode. EXCP_DEBUG is returned by the 327d9f24bf5SPaolo Bonzini CPU loop after each instruction */ 328d9f24bf5SPaolo Bonzini void cpu_single_step(CPUState *cpu, int enabled) 329d9f24bf5SPaolo Bonzini { 330d9f24bf5SPaolo Bonzini if (cpu->singlestep_enabled != enabled) { 331d9f24bf5SPaolo Bonzini cpu->singlestep_enabled = enabled; 332412ae126SMads Ynddal 333412ae126SMads Ynddal #if !defined(CONFIG_USER_ONLY) 334412ae126SMads Ynddal const AccelOpsClass *ops = cpus_get_accel(); 335412ae126SMads Ynddal if (ops->update_guest_debug) { 336412ae126SMads Ynddal ops->update_guest_debug(cpu); 337d9f24bf5SPaolo Bonzini } 338412ae126SMads Ynddal #endif 339412ae126SMads Ynddal 340ad1a706fSRichard Henderson trace_breakpoint_singlestep(cpu->cpu_index, enabled); 341d9f24bf5SPaolo Bonzini } 342d9f24bf5SPaolo Bonzini } 343d9f24bf5SPaolo Bonzini 344d9f24bf5SPaolo Bonzini void cpu_abort(CPUState *cpu, const char *fmt, ...) 345d9f24bf5SPaolo Bonzini { 346d9f24bf5SPaolo Bonzini va_list ap; 347d9f24bf5SPaolo Bonzini va_list ap2; 348d9f24bf5SPaolo Bonzini 349d9f24bf5SPaolo Bonzini va_start(ap, fmt); 350d9f24bf5SPaolo Bonzini va_copy(ap2, ap); 351d9f24bf5SPaolo Bonzini fprintf(stderr, "qemu: fatal: "); 352d9f24bf5SPaolo Bonzini vfprintf(stderr, fmt, ap); 353d9f24bf5SPaolo Bonzini fprintf(stderr, "\n"); 354d9f24bf5SPaolo Bonzini cpu_dump_state(cpu, stderr, CPU_DUMP_FPU | CPU_DUMP_CCOP); 355d9f24bf5SPaolo Bonzini if (qemu_log_separate()) { 356c60f599bSRichard Henderson FILE *logfile = qemu_log_trylock(); 35778b54858SRichard Henderson if (logfile) { 35878b54858SRichard Henderson fprintf(logfile, "qemu: fatal: "); 35978b54858SRichard Henderson vfprintf(logfile, fmt, ap2); 36078b54858SRichard Henderson fprintf(logfile, "\n"); 36178b54858SRichard Henderson cpu_dump_state(cpu, logfile, CPU_DUMP_FPU | CPU_DUMP_CCOP); 362d9f24bf5SPaolo Bonzini qemu_log_unlock(logfile); 36378b54858SRichard Henderson } 364d9f24bf5SPaolo Bonzini } 365d9f24bf5SPaolo Bonzini va_end(ap2); 366d9f24bf5SPaolo Bonzini va_end(ap); 367d9f24bf5SPaolo Bonzini replay_finish(); 368d9f24bf5SPaolo Bonzini #if defined(CONFIG_USER_ONLY) 369d9f24bf5SPaolo Bonzini { 370d9f24bf5SPaolo Bonzini struct sigaction act; 371d9f24bf5SPaolo Bonzini sigfillset(&act.sa_mask); 372d9f24bf5SPaolo Bonzini act.sa_handler = SIG_DFL; 373d9f24bf5SPaolo Bonzini act.sa_flags = 0; 374d9f24bf5SPaolo Bonzini sigaction(SIGABRT, &act, NULL); 375d9f24bf5SPaolo Bonzini } 376d9f24bf5SPaolo Bonzini #endif 377d9f24bf5SPaolo Bonzini abort(); 378d9f24bf5SPaolo Bonzini } 379d9f24bf5SPaolo Bonzini 380d9f24bf5SPaolo Bonzini /* physical memory access (slow version, mainly for debug) */ 381d9f24bf5SPaolo Bonzini #if defined(CONFIG_USER_ONLY) 38273842ef0SPhilippe Mathieu-Daudé int cpu_memory_rw_debug(CPUState *cpu, vaddr addr, 38373842ef0SPhilippe Mathieu-Daudé void *ptr, size_t len, bool is_write) 384d9f24bf5SPaolo Bonzini { 385d9f24bf5SPaolo Bonzini int flags; 38673842ef0SPhilippe Mathieu-Daudé vaddr l, page; 387d9f24bf5SPaolo Bonzini void * p; 388d9f24bf5SPaolo Bonzini uint8_t *buf = ptr; 389d9f24bf5SPaolo Bonzini 390d9f24bf5SPaolo Bonzini while (len > 0) { 391d9f24bf5SPaolo Bonzini page = addr & TARGET_PAGE_MASK; 392d9f24bf5SPaolo Bonzini l = (page + TARGET_PAGE_SIZE) - addr; 393d9f24bf5SPaolo Bonzini if (l > len) 394d9f24bf5SPaolo Bonzini l = len; 395d9f24bf5SPaolo Bonzini flags = page_get_flags(page); 396d9f24bf5SPaolo Bonzini if (!(flags & PAGE_VALID)) 397d9f24bf5SPaolo Bonzini return -1; 398d9f24bf5SPaolo Bonzini if (is_write) { 399d9f24bf5SPaolo Bonzini if (!(flags & PAGE_WRITE)) 400d9f24bf5SPaolo Bonzini return -1; 401d9f24bf5SPaolo Bonzini /* XXX: this code should not depend on lock_user */ 402d9f24bf5SPaolo Bonzini if (!(p = lock_user(VERIFY_WRITE, addr, l, 0))) 403d9f24bf5SPaolo Bonzini return -1; 404d9f24bf5SPaolo Bonzini memcpy(p, buf, l); 405d9f24bf5SPaolo Bonzini unlock_user(p, addr, l); 406d9f24bf5SPaolo Bonzini } else { 407d9f24bf5SPaolo Bonzini if (!(flags & PAGE_READ)) 408d9f24bf5SPaolo Bonzini return -1; 409d9f24bf5SPaolo Bonzini /* XXX: this code should not depend on lock_user */ 410d9f24bf5SPaolo Bonzini if (!(p = lock_user(VERIFY_READ, addr, l, 1))) 411d9f24bf5SPaolo Bonzini return -1; 412d9f24bf5SPaolo Bonzini memcpy(buf, p, l); 413d9f24bf5SPaolo Bonzini unlock_user(p, addr, 0); 414d9f24bf5SPaolo Bonzini } 415d9f24bf5SPaolo Bonzini len -= l; 416d9f24bf5SPaolo Bonzini buf += l; 417d9f24bf5SPaolo Bonzini addr += l; 418d9f24bf5SPaolo Bonzini } 419d9f24bf5SPaolo Bonzini return 0; 420d9f24bf5SPaolo Bonzini } 421d9f24bf5SPaolo Bonzini #endif 422d9f24bf5SPaolo Bonzini 423d9f24bf5SPaolo Bonzini bool target_words_bigendian(void) 424d9f24bf5SPaolo Bonzini { 425ded625e7SThomas Huth return TARGET_BIG_ENDIAN; 426d9f24bf5SPaolo Bonzini } 427d9f24bf5SPaolo Bonzini 4281077f50bSThomas Huth const char *target_name(void) 4291077f50bSThomas Huth { 4301077f50bSThomas Huth return TARGET_NAME; 4311077f50bSThomas Huth } 4321077f50bSThomas Huth 433d9f24bf5SPaolo Bonzini void page_size_init(void) 434d9f24bf5SPaolo Bonzini { 435d9f24bf5SPaolo Bonzini /* NOTE: we can always suppose that qemu_host_page_size >= 436d9f24bf5SPaolo Bonzini TARGET_PAGE_SIZE */ 437d9f24bf5SPaolo Bonzini if (qemu_host_page_size == 0) { 4388e3b0cbbSMarc-André Lureau qemu_host_page_size = qemu_real_host_page_size(); 439d9f24bf5SPaolo Bonzini } 440d9f24bf5SPaolo Bonzini if (qemu_host_page_size < TARGET_PAGE_SIZE) { 441d9f24bf5SPaolo Bonzini qemu_host_page_size = TARGET_PAGE_SIZE; 442d9f24bf5SPaolo Bonzini } 443d9f24bf5SPaolo Bonzini qemu_host_page_mask = -(intptr_t)qemu_host_page_size; 444d9f24bf5SPaolo Bonzini } 445