1 /* 2 * QEMU S/390 CPU 3 * 4 * Copyright (c) 2009 Ulrich Hecht 5 * Copyright (c) 2011 Alexander Graf 6 * Copyright (c) 2012 SUSE LINUX Products GmbH 7 * Copyright (c) 2012 IBM Corp. 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, see 21 * <http://www.gnu.org/licenses/lgpl-2.1.html> 22 * Contributions after 2012-12-11 are licensed under the terms of the 23 * GNU GPL, version 2 or (at your option) any later version. 24 */ 25 26 #include "qemu/osdep.h" 27 #include "qapi/error.h" 28 #include "cpu.h" 29 #include "internal.h" 30 #include "kvm_s390x.h" 31 #include "sysemu/kvm.h" 32 #include "qemu-common.h" 33 #include "qemu/cutils.h" 34 #include "qemu/timer.h" 35 #include "qemu/error-report.h" 36 #include "trace.h" 37 #include "qapi/visitor.h" 38 #include "exec/exec-all.h" 39 #include "hw/qdev-properties.h" 40 #ifndef CONFIG_USER_ONLY 41 #include "hw/hw.h" 42 #include "sysemu/arch_init.h" 43 #include "sysemu/sysemu.h" 44 #include "hw/s390x/sclp.h" 45 #endif 46 47 #define CR0_RESET 0xE0UL 48 #define CR14_RESET 0xC2000000UL; 49 50 static void s390_cpu_set_pc(CPUState *cs, vaddr value) 51 { 52 S390CPU *cpu = S390_CPU(cs); 53 54 cpu->env.psw.addr = value; 55 } 56 57 static bool s390_cpu_has_work(CPUState *cs) 58 { 59 S390CPU *cpu = S390_CPU(cs); 60 CPUS390XState *env = &cpu->env; 61 62 return (cs->interrupt_request & CPU_INTERRUPT_HARD) && 63 (env->psw.mask & PSW_MASK_EXT); 64 } 65 66 #if !defined(CONFIG_USER_ONLY) 67 /* S390CPUClass::load_normal() */ 68 static void s390_cpu_load_normal(CPUState *s) 69 { 70 S390CPU *cpu = S390_CPU(s); 71 cpu->env.psw.addr = ldl_phys(s->as, 4) & PSW_MASK_ESA_ADDR; 72 cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64; 73 s390_cpu_set_state(CPU_STATE_OPERATING, cpu); 74 } 75 #endif 76 77 /* S390CPUClass::cpu_reset() */ 78 static void s390_cpu_reset(CPUState *s) 79 { 80 S390CPU *cpu = S390_CPU(s); 81 S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); 82 CPUS390XState *env = &cpu->env; 83 84 env->pfault_token = -1UL; 85 scc->parent_reset(s); 86 cpu->env.sigp_order = 0; 87 s390_cpu_set_state(CPU_STATE_STOPPED, cpu); 88 } 89 90 /* S390CPUClass::initial_reset() */ 91 static void s390_cpu_initial_reset(CPUState *s) 92 { 93 S390CPU *cpu = S390_CPU(s); 94 CPUS390XState *env = &cpu->env; 95 int i; 96 97 s390_cpu_reset(s); 98 /* initial reset does not clear everything! */ 99 memset(&env->start_initial_reset_fields, 0, 100 offsetof(CPUS390XState, end_reset_fields) - 101 offsetof(CPUS390XState, start_initial_reset_fields)); 102 103 /* architectured initial values for CR 0 and 14 */ 104 env->cregs[0] = CR0_RESET; 105 env->cregs[14] = CR14_RESET; 106 107 /* architectured initial value for Breaking-Event-Address register */ 108 env->gbea = 1; 109 110 env->pfault_token = -1UL; 111 env->ext_index = -1; 112 for (i = 0; i < ARRAY_SIZE(env->io_index); i++) { 113 env->io_index[i] = -1; 114 } 115 116 /* tininess for underflow is detected before rounding */ 117 set_float_detect_tininess(float_tininess_before_rounding, 118 &env->fpu_status); 119 120 /* Reset state inside the kernel that we cannot access yet from QEMU. */ 121 if (kvm_enabled()) { 122 kvm_s390_reset_vcpu(cpu); 123 } 124 } 125 126 /* CPUClass:reset() */ 127 static void s390_cpu_full_reset(CPUState *s) 128 { 129 S390CPU *cpu = S390_CPU(s); 130 S390CPUClass *scc = S390_CPU_GET_CLASS(cpu); 131 CPUS390XState *env = &cpu->env; 132 int i; 133 134 scc->parent_reset(s); 135 cpu->env.sigp_order = 0; 136 s390_cpu_set_state(CPU_STATE_STOPPED, cpu); 137 138 memset(env, 0, offsetof(CPUS390XState, end_reset_fields)); 139 140 /* architectured initial values for CR 0 and 14 */ 141 env->cregs[0] = CR0_RESET; 142 env->cregs[14] = CR14_RESET; 143 144 /* architectured initial value for Breaking-Event-Address register */ 145 env->gbea = 1; 146 147 env->pfault_token = -1UL; 148 env->ext_index = -1; 149 for (i = 0; i < ARRAY_SIZE(env->io_index); i++) { 150 env->io_index[i] = -1; 151 } 152 153 /* tininess for underflow is detected before rounding */ 154 set_float_detect_tininess(float_tininess_before_rounding, 155 &env->fpu_status); 156 157 /* Reset state inside the kernel that we cannot access yet from QEMU. */ 158 if (kvm_enabled()) { 159 kvm_s390_reset_vcpu(cpu); 160 } 161 } 162 163 #if !defined(CONFIG_USER_ONLY) 164 static void s390_cpu_machine_reset_cb(void *opaque) 165 { 166 S390CPU *cpu = opaque; 167 168 run_on_cpu(CPU(cpu), s390_do_cpu_full_reset, RUN_ON_CPU_NULL); 169 } 170 #endif 171 172 static void s390_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) 173 { 174 info->mach = bfd_mach_s390_64; 175 info->print_insn = print_insn_s390; 176 } 177 178 static void s390_cpu_realizefn(DeviceState *dev, Error **errp) 179 { 180 CPUState *cs = CPU(dev); 181 S390CPUClass *scc = S390_CPU_GET_CLASS(dev); 182 S390CPU *cpu = S390_CPU(dev); 183 CPUS390XState *env = &cpu->env; 184 Error *err = NULL; 185 186 /* the model has to be realized before qemu_init_vcpu() due to kvm */ 187 s390_realize_cpu_model(cs, &err); 188 if (err) { 189 goto out; 190 } 191 192 #if !defined(CONFIG_USER_ONLY) 193 if (cpu->env.core_id >= max_cpus) { 194 error_setg(&err, "Unable to add CPU with core-id: %" PRIu32 195 ", maximum core-id: %d", cpu->env.core_id, 196 max_cpus - 1); 197 goto out; 198 } 199 #else 200 /* implicitly set for linux-user only */ 201 cpu->env.core_id = scc->next_core_id; 202 scc->next_core_id++; 203 #endif 204 205 if (cpu_exists(cpu->env.core_id)) { 206 error_setg(&err, "Unable to add CPU with core-id: %" PRIu32 207 ", it already exists", cpu->env.core_id); 208 goto out; 209 } 210 211 /* sync cs->cpu_index and env->core_id. The latter is needed for TCG. */ 212 cs->cpu_index = env->core_id; 213 cpu_exec_realizefn(cs, &err); 214 if (err != NULL) { 215 goto out; 216 } 217 218 #if !defined(CONFIG_USER_ONLY) 219 qemu_register_reset(s390_cpu_machine_reset_cb, cpu); 220 #endif 221 s390_cpu_gdb_init(cs); 222 qemu_init_vcpu(cs); 223 #if !defined(CONFIG_USER_ONLY) 224 run_on_cpu(cs, s390_do_cpu_full_reset, RUN_ON_CPU_NULL); 225 #else 226 cpu_reset(cs); 227 #endif 228 229 scc->parent_realize(dev, &err); 230 231 #if !defined(CONFIG_USER_ONLY) 232 if (dev->hotplugged) { 233 raise_irq_cpu_hotplug(); 234 } 235 #endif 236 237 out: 238 error_propagate(errp, err); 239 } 240 241 static void s390_cpu_initfn(Object *obj) 242 { 243 CPUState *cs = CPU(obj); 244 S390CPU *cpu = S390_CPU(obj); 245 CPUS390XState *env = &cpu->env; 246 static bool inited; 247 #if !defined(CONFIG_USER_ONLY) 248 struct tm tm; 249 #endif 250 251 cs->env_ptr = env; 252 cs->halted = 1; 253 cs->exception_index = EXCP_HLT; 254 s390_cpu_model_register_props(obj); 255 #if !defined(CONFIG_USER_ONLY) 256 qemu_get_timedate(&tm, 0); 257 env->tod_offset = TOD_UNIX_EPOCH + 258 (time2tod(mktimegm(&tm)) * 1000000000ULL); 259 env->tod_basetime = 0; 260 env->tod_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu); 261 env->cpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu); 262 s390_cpu_set_state(CPU_STATE_STOPPED, cpu); 263 #endif 264 265 if (tcg_enabled() && !inited) { 266 inited = true; 267 s390x_translate_init(); 268 } 269 } 270 271 static void s390_cpu_finalize(Object *obj) 272 { 273 #if !defined(CONFIG_USER_ONLY) 274 S390CPU *cpu = S390_CPU(obj); 275 276 qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu); 277 g_free(cpu->irqstate); 278 #endif 279 } 280 281 #if !defined(CONFIG_USER_ONLY) 282 static bool disabled_wait(CPUState *cpu) 283 { 284 return cpu->halted && !(S390_CPU(cpu)->env.psw.mask & 285 (PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK)); 286 } 287 288 static unsigned s390_count_running_cpus(void) 289 { 290 CPUState *cpu; 291 int nr_running = 0; 292 293 CPU_FOREACH(cpu) { 294 uint8_t state = S390_CPU(cpu)->env.cpu_state; 295 if (state == CPU_STATE_OPERATING || 296 state == CPU_STATE_LOAD) { 297 if (!disabled_wait(cpu)) { 298 nr_running++; 299 } 300 } 301 } 302 303 return nr_running; 304 } 305 306 unsigned int s390_cpu_halt(S390CPU *cpu) 307 { 308 CPUState *cs = CPU(cpu); 309 trace_cpu_halt(cs->cpu_index); 310 311 if (!cs->halted) { 312 cs->halted = 1; 313 cs->exception_index = EXCP_HLT; 314 } 315 316 return s390_count_running_cpus(); 317 } 318 319 void s390_cpu_unhalt(S390CPU *cpu) 320 { 321 CPUState *cs = CPU(cpu); 322 trace_cpu_unhalt(cs->cpu_index); 323 324 if (cs->halted) { 325 cs->halted = 0; 326 cs->exception_index = -1; 327 } 328 } 329 330 unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu) 331 { 332 trace_cpu_set_state(CPU(cpu)->cpu_index, cpu_state); 333 334 switch (cpu_state) { 335 case CPU_STATE_STOPPED: 336 case CPU_STATE_CHECK_STOP: 337 /* halt the cpu for common infrastructure */ 338 s390_cpu_halt(cpu); 339 break; 340 case CPU_STATE_OPERATING: 341 case CPU_STATE_LOAD: 342 /* unhalt the cpu for common infrastructure */ 343 s390_cpu_unhalt(cpu); 344 break; 345 default: 346 error_report("Requested CPU state is not a valid S390 CPU state: %u", 347 cpu_state); 348 exit(1); 349 } 350 if (kvm_enabled() && cpu->env.cpu_state != cpu_state) { 351 kvm_s390_set_cpu_state(cpu, cpu_state); 352 } 353 cpu->env.cpu_state = cpu_state; 354 355 return s390_count_running_cpus(); 356 } 357 358 int s390_get_clock(uint8_t *tod_high, uint64_t *tod_low) 359 { 360 if (kvm_enabled()) { 361 return kvm_s390_get_clock(tod_high, tod_low); 362 } 363 /* Fixme TCG */ 364 *tod_high = 0; 365 *tod_low = 0; 366 return 0; 367 } 368 369 int s390_set_clock(uint8_t *tod_high, uint64_t *tod_low) 370 { 371 if (kvm_enabled()) { 372 return kvm_s390_set_clock(tod_high, tod_low); 373 } 374 /* Fixme TCG */ 375 return 0; 376 } 377 378 int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit) 379 { 380 if (kvm_enabled()) { 381 return kvm_s390_set_mem_limit(new_limit, hw_limit); 382 } 383 return 0; 384 } 385 386 void s390_cmma_reset(void) 387 { 388 if (kvm_enabled()) { 389 kvm_s390_cmma_reset(); 390 } 391 } 392 393 int s390_cpu_restart(S390CPU *cpu) 394 { 395 if (kvm_enabled()) { 396 return kvm_s390_cpu_restart(cpu); 397 } 398 return -ENOSYS; 399 } 400 401 int s390_get_memslot_count(void) 402 { 403 if (kvm_enabled()) { 404 return kvm_s390_get_memslot_count(); 405 } else { 406 return MAX_AVAIL_SLOTS; 407 } 408 } 409 410 int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id, 411 int vq, bool assign) 412 { 413 if (kvm_enabled()) { 414 return kvm_s390_assign_subch_ioeventfd(notifier, sch_id, vq, assign); 415 } else { 416 return 0; 417 } 418 } 419 420 void s390_crypto_reset(void) 421 { 422 if (kvm_enabled()) { 423 kvm_s390_crypto_reset(); 424 } 425 } 426 427 bool s390_get_squash_mcss(void) 428 { 429 if (object_property_get_bool(OBJECT(qdev_get_machine()), "s390-squash-mcss", 430 NULL)) { 431 return true; 432 } 433 434 return false; 435 } 436 437 void s390_enable_css_support(S390CPU *cpu) 438 { 439 if (kvm_enabled()) { 440 kvm_s390_enable_css_support(cpu); 441 } 442 } 443 #endif 444 445 static gchar *s390_gdb_arch_name(CPUState *cs) 446 { 447 return g_strdup("s390:64-bit"); 448 } 449 450 static Property s390x_cpu_properties[] = { 451 DEFINE_PROP_UINT32("core-id", S390CPU, env.core_id, 0), 452 DEFINE_PROP_END_OF_LIST() 453 }; 454 455 static void s390_cpu_class_init(ObjectClass *oc, void *data) 456 { 457 S390CPUClass *scc = S390_CPU_CLASS(oc); 458 CPUClass *cc = CPU_CLASS(scc); 459 DeviceClass *dc = DEVICE_CLASS(oc); 460 461 scc->parent_realize = dc->realize; 462 dc->realize = s390_cpu_realizefn; 463 dc->props = s390x_cpu_properties; 464 dc->user_creatable = true; 465 466 scc->parent_reset = cc->reset; 467 #if !defined(CONFIG_USER_ONLY) 468 scc->load_normal = s390_cpu_load_normal; 469 #endif 470 scc->cpu_reset = s390_cpu_reset; 471 scc->initial_cpu_reset = s390_cpu_initial_reset; 472 cc->reset = s390_cpu_full_reset; 473 cc->class_by_name = s390_cpu_class_by_name, 474 cc->has_work = s390_cpu_has_work; 475 #ifdef CONFIG_TCG 476 cc->do_interrupt = s390_cpu_do_interrupt; 477 #endif 478 cc->dump_state = s390_cpu_dump_state; 479 cc->set_pc = s390_cpu_set_pc; 480 cc->gdb_read_register = s390_cpu_gdb_read_register; 481 cc->gdb_write_register = s390_cpu_gdb_write_register; 482 #ifdef CONFIG_USER_ONLY 483 cc->handle_mmu_fault = s390_cpu_handle_mmu_fault; 484 #else 485 cc->get_phys_page_debug = s390_cpu_get_phys_page_debug; 486 cc->vmsd = &vmstate_s390_cpu; 487 cc->write_elf64_note = s390_cpu_write_elf64_note; 488 #ifdef CONFIG_TCG 489 cc->cpu_exec_interrupt = s390_cpu_exec_interrupt; 490 cc->debug_excp_handler = s390x_cpu_debug_excp_handler; 491 cc->do_unaligned_access = s390x_cpu_do_unaligned_access; 492 #endif 493 #endif 494 cc->disas_set_info = s390_cpu_disas_set_info; 495 496 cc->gdb_num_core_regs = S390_NUM_CORE_REGS; 497 cc->gdb_core_xml_file = "s390x-core64.xml"; 498 cc->gdb_arch_name = s390_gdb_arch_name; 499 500 s390_cpu_model_class_register_props(oc); 501 } 502 503 static const TypeInfo s390_cpu_type_info = { 504 .name = TYPE_S390_CPU, 505 .parent = TYPE_CPU, 506 .instance_size = sizeof(S390CPU), 507 .instance_init = s390_cpu_initfn, 508 .instance_finalize = s390_cpu_finalize, 509 .abstract = true, 510 .class_size = sizeof(S390CPUClass), 511 .class_init = s390_cpu_class_init, 512 }; 513 514 static void s390_cpu_register_types(void) 515 { 516 type_register_static(&s390_cpu_type_info); 517 } 518 519 type_init(s390_cpu_register_types) 520