1 /* 2 * QEMU generic PowerPC hardware System Emulator 3 * 4 * Copyright (c) 2003-2007 Jocelyn Mayer 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 #include "hw/hw.h" 25 #include "hw/ppc/ppc.h" 26 #include "hw/ppc/ppc_e500.h" 27 #include "qemu/timer.h" 28 #include "sysemu/sysemu.h" 29 #include "sysemu/cpus.h" 30 #include "hw/timer/m48t59.h" 31 #include "qemu/log.h" 32 #include "hw/loader.h" 33 #include "sysemu/kvm.h" 34 #include "kvm_ppc.h" 35 36 //#define PPC_DEBUG_IRQ 37 //#define PPC_DEBUG_TB 38 39 #ifdef PPC_DEBUG_IRQ 40 # define LOG_IRQ(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__) 41 #else 42 # define LOG_IRQ(...) do { } while (0) 43 #endif 44 45 46 #ifdef PPC_DEBUG_TB 47 # define LOG_TB(...) qemu_log(__VA_ARGS__) 48 #else 49 # define LOG_TB(...) do { } while (0) 50 #endif 51 52 static void cpu_ppc_tb_stop (CPUPPCState *env); 53 static void cpu_ppc_tb_start (CPUPPCState *env); 54 55 void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level) 56 { 57 CPUState *cs = CPU(cpu); 58 CPUPPCState *env = &cpu->env; 59 unsigned int old_pending = env->pending_interrupts; 60 61 if (level) { 62 env->pending_interrupts |= 1 << n_IRQ; 63 cpu_interrupt(cs, CPU_INTERRUPT_HARD); 64 } else { 65 env->pending_interrupts &= ~(1 << n_IRQ); 66 if (env->pending_interrupts == 0) { 67 cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); 68 } 69 } 70 71 if (old_pending != env->pending_interrupts) { 72 #ifdef CONFIG_KVM 73 kvmppc_set_interrupt(cpu, n_IRQ, level); 74 #endif 75 } 76 77 LOG_IRQ("%s: %p n_IRQ %d level %d => pending %08" PRIx32 78 "req %08x\n", __func__, env, n_IRQ, level, 79 env->pending_interrupts, CPU(cpu)->interrupt_request); 80 } 81 82 /* PowerPC 6xx / 7xx internal IRQ controller */ 83 static void ppc6xx_set_irq(void *opaque, int pin, int level) 84 { 85 PowerPCCPU *cpu = opaque; 86 CPUPPCState *env = &cpu->env; 87 int cur_level; 88 89 LOG_IRQ("%s: env %p pin %d level %d\n", __func__, 90 env, pin, level); 91 cur_level = (env->irq_input_state >> pin) & 1; 92 /* Don't generate spurious events */ 93 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { 94 CPUState *cs = CPU(cpu); 95 96 switch (pin) { 97 case PPC6xx_INPUT_TBEN: 98 /* Level sensitive - active high */ 99 LOG_IRQ("%s: %s the time base\n", 100 __func__, level ? "start" : "stop"); 101 if (level) { 102 cpu_ppc_tb_start(env); 103 } else { 104 cpu_ppc_tb_stop(env); 105 } 106 case PPC6xx_INPUT_INT: 107 /* Level sensitive - active high */ 108 LOG_IRQ("%s: set the external IRQ state to %d\n", 109 __func__, level); 110 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); 111 break; 112 case PPC6xx_INPUT_SMI: 113 /* Level sensitive - active high */ 114 LOG_IRQ("%s: set the SMI IRQ state to %d\n", 115 __func__, level); 116 ppc_set_irq(cpu, PPC_INTERRUPT_SMI, level); 117 break; 118 case PPC6xx_INPUT_MCP: 119 /* Negative edge sensitive */ 120 /* XXX: TODO: actual reaction may depends on HID0 status 121 * 603/604/740/750: check HID0[EMCP] 122 */ 123 if (cur_level == 1 && level == 0) { 124 LOG_IRQ("%s: raise machine check state\n", 125 __func__); 126 ppc_set_irq(cpu, PPC_INTERRUPT_MCK, 1); 127 } 128 break; 129 case PPC6xx_INPUT_CKSTP_IN: 130 /* Level sensitive - active low */ 131 /* XXX: TODO: relay the signal to CKSTP_OUT pin */ 132 /* XXX: Note that the only way to restart the CPU is to reset it */ 133 if (level) { 134 LOG_IRQ("%s: stop the CPU\n", __func__); 135 cs->halted = 1; 136 } 137 break; 138 case PPC6xx_INPUT_HRESET: 139 /* Level sensitive - active low */ 140 if (level) { 141 LOG_IRQ("%s: reset the CPU\n", __func__); 142 cpu_interrupt(cs, CPU_INTERRUPT_RESET); 143 } 144 break; 145 case PPC6xx_INPUT_SRESET: 146 LOG_IRQ("%s: set the RESET IRQ state to %d\n", 147 __func__, level); 148 ppc_set_irq(cpu, PPC_INTERRUPT_RESET, level); 149 break; 150 default: 151 /* Unknown pin - do nothing */ 152 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); 153 return; 154 } 155 if (level) 156 env->irq_input_state |= 1 << pin; 157 else 158 env->irq_input_state &= ~(1 << pin); 159 } 160 } 161 162 void ppc6xx_irq_init(CPUPPCState *env) 163 { 164 PowerPCCPU *cpu = ppc_env_get_cpu(env); 165 166 env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, cpu, 167 PPC6xx_INPUT_NB); 168 } 169 170 #if defined(TARGET_PPC64) 171 /* PowerPC 970 internal IRQ controller */ 172 static void ppc970_set_irq(void *opaque, int pin, int level) 173 { 174 PowerPCCPU *cpu = opaque; 175 CPUPPCState *env = &cpu->env; 176 int cur_level; 177 178 LOG_IRQ("%s: env %p pin %d level %d\n", __func__, 179 env, pin, level); 180 cur_level = (env->irq_input_state >> pin) & 1; 181 /* Don't generate spurious events */ 182 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { 183 CPUState *cs = CPU(cpu); 184 185 switch (pin) { 186 case PPC970_INPUT_INT: 187 /* Level sensitive - active high */ 188 LOG_IRQ("%s: set the external IRQ state to %d\n", 189 __func__, level); 190 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); 191 break; 192 case PPC970_INPUT_THINT: 193 /* Level sensitive - active high */ 194 LOG_IRQ("%s: set the SMI IRQ state to %d\n", __func__, 195 level); 196 ppc_set_irq(cpu, PPC_INTERRUPT_THERM, level); 197 break; 198 case PPC970_INPUT_MCP: 199 /* Negative edge sensitive */ 200 /* XXX: TODO: actual reaction may depends on HID0 status 201 * 603/604/740/750: check HID0[EMCP] 202 */ 203 if (cur_level == 1 && level == 0) { 204 LOG_IRQ("%s: raise machine check state\n", 205 __func__); 206 ppc_set_irq(cpu, PPC_INTERRUPT_MCK, 1); 207 } 208 break; 209 case PPC970_INPUT_CKSTP: 210 /* Level sensitive - active low */ 211 /* XXX: TODO: relay the signal to CKSTP_OUT pin */ 212 if (level) { 213 LOG_IRQ("%s: stop the CPU\n", __func__); 214 cs->halted = 1; 215 } else { 216 LOG_IRQ("%s: restart the CPU\n", __func__); 217 cs->halted = 0; 218 qemu_cpu_kick(cs); 219 } 220 break; 221 case PPC970_INPUT_HRESET: 222 /* Level sensitive - active low */ 223 if (level) { 224 cpu_interrupt(cs, CPU_INTERRUPT_RESET); 225 } 226 break; 227 case PPC970_INPUT_SRESET: 228 LOG_IRQ("%s: set the RESET IRQ state to %d\n", 229 __func__, level); 230 ppc_set_irq(cpu, PPC_INTERRUPT_RESET, level); 231 break; 232 case PPC970_INPUT_TBEN: 233 LOG_IRQ("%s: set the TBEN state to %d\n", __func__, 234 level); 235 /* XXX: TODO */ 236 break; 237 default: 238 /* Unknown pin - do nothing */ 239 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); 240 return; 241 } 242 if (level) 243 env->irq_input_state |= 1 << pin; 244 else 245 env->irq_input_state &= ~(1 << pin); 246 } 247 } 248 249 void ppc970_irq_init(CPUPPCState *env) 250 { 251 PowerPCCPU *cpu = ppc_env_get_cpu(env); 252 253 env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, cpu, 254 PPC970_INPUT_NB); 255 } 256 257 /* POWER7 internal IRQ controller */ 258 static void power7_set_irq(void *opaque, int pin, int level) 259 { 260 PowerPCCPU *cpu = opaque; 261 CPUPPCState *env = &cpu->env; 262 263 LOG_IRQ("%s: env %p pin %d level %d\n", __func__, 264 env, pin, level); 265 266 switch (pin) { 267 case POWER7_INPUT_INT: 268 /* Level sensitive - active high */ 269 LOG_IRQ("%s: set the external IRQ state to %d\n", 270 __func__, level); 271 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); 272 break; 273 default: 274 /* Unknown pin - do nothing */ 275 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); 276 return; 277 } 278 if (level) { 279 env->irq_input_state |= 1 << pin; 280 } else { 281 env->irq_input_state &= ~(1 << pin); 282 } 283 } 284 285 void ppcPOWER7_irq_init(CPUPPCState *env) 286 { 287 PowerPCCPU *cpu = ppc_env_get_cpu(env); 288 289 env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, cpu, 290 POWER7_INPUT_NB); 291 } 292 #endif /* defined(TARGET_PPC64) */ 293 294 /* PowerPC 40x internal IRQ controller */ 295 static void ppc40x_set_irq(void *opaque, int pin, int level) 296 { 297 PowerPCCPU *cpu = opaque; 298 CPUPPCState *env = &cpu->env; 299 int cur_level; 300 301 LOG_IRQ("%s: env %p pin %d level %d\n", __func__, 302 env, pin, level); 303 cur_level = (env->irq_input_state >> pin) & 1; 304 /* Don't generate spurious events */ 305 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { 306 CPUState *cs = CPU(cpu); 307 308 switch (pin) { 309 case PPC40x_INPUT_RESET_SYS: 310 if (level) { 311 LOG_IRQ("%s: reset the PowerPC system\n", 312 __func__); 313 ppc40x_system_reset(cpu); 314 } 315 break; 316 case PPC40x_INPUT_RESET_CHIP: 317 if (level) { 318 LOG_IRQ("%s: reset the PowerPC chip\n", __func__); 319 ppc40x_chip_reset(cpu); 320 } 321 break; 322 case PPC40x_INPUT_RESET_CORE: 323 /* XXX: TODO: update DBSR[MRR] */ 324 if (level) { 325 LOG_IRQ("%s: reset the PowerPC core\n", __func__); 326 ppc40x_core_reset(cpu); 327 } 328 break; 329 case PPC40x_INPUT_CINT: 330 /* Level sensitive - active high */ 331 LOG_IRQ("%s: set the critical IRQ state to %d\n", 332 __func__, level); 333 ppc_set_irq(cpu, PPC_INTERRUPT_CEXT, level); 334 break; 335 case PPC40x_INPUT_INT: 336 /* Level sensitive - active high */ 337 LOG_IRQ("%s: set the external IRQ state to %d\n", 338 __func__, level); 339 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); 340 break; 341 case PPC40x_INPUT_HALT: 342 /* Level sensitive - active low */ 343 if (level) { 344 LOG_IRQ("%s: stop the CPU\n", __func__); 345 cs->halted = 1; 346 } else { 347 LOG_IRQ("%s: restart the CPU\n", __func__); 348 cs->halted = 0; 349 qemu_cpu_kick(cs); 350 } 351 break; 352 case PPC40x_INPUT_DEBUG: 353 /* Level sensitive - active high */ 354 LOG_IRQ("%s: set the debug pin state to %d\n", 355 __func__, level); 356 ppc_set_irq(cpu, PPC_INTERRUPT_DEBUG, level); 357 break; 358 default: 359 /* Unknown pin - do nothing */ 360 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); 361 return; 362 } 363 if (level) 364 env->irq_input_state |= 1 << pin; 365 else 366 env->irq_input_state &= ~(1 << pin); 367 } 368 } 369 370 void ppc40x_irq_init(CPUPPCState *env) 371 { 372 PowerPCCPU *cpu = ppc_env_get_cpu(env); 373 374 env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq, 375 cpu, PPC40x_INPUT_NB); 376 } 377 378 /* PowerPC E500 internal IRQ controller */ 379 static void ppce500_set_irq(void *opaque, int pin, int level) 380 { 381 PowerPCCPU *cpu = opaque; 382 CPUPPCState *env = &cpu->env; 383 int cur_level; 384 385 LOG_IRQ("%s: env %p pin %d level %d\n", __func__, 386 env, pin, level); 387 cur_level = (env->irq_input_state >> pin) & 1; 388 /* Don't generate spurious events */ 389 if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) { 390 switch (pin) { 391 case PPCE500_INPUT_MCK: 392 if (level) { 393 LOG_IRQ("%s: reset the PowerPC system\n", 394 __func__); 395 qemu_system_reset_request(); 396 } 397 break; 398 case PPCE500_INPUT_RESET_CORE: 399 if (level) { 400 LOG_IRQ("%s: reset the PowerPC core\n", __func__); 401 ppc_set_irq(cpu, PPC_INTERRUPT_MCK, level); 402 } 403 break; 404 case PPCE500_INPUT_CINT: 405 /* Level sensitive - active high */ 406 LOG_IRQ("%s: set the critical IRQ state to %d\n", 407 __func__, level); 408 ppc_set_irq(cpu, PPC_INTERRUPT_CEXT, level); 409 break; 410 case PPCE500_INPUT_INT: 411 /* Level sensitive - active high */ 412 LOG_IRQ("%s: set the core IRQ state to %d\n", 413 __func__, level); 414 ppc_set_irq(cpu, PPC_INTERRUPT_EXT, level); 415 break; 416 case PPCE500_INPUT_DEBUG: 417 /* Level sensitive - active high */ 418 LOG_IRQ("%s: set the debug pin state to %d\n", 419 __func__, level); 420 ppc_set_irq(cpu, PPC_INTERRUPT_DEBUG, level); 421 break; 422 default: 423 /* Unknown pin - do nothing */ 424 LOG_IRQ("%s: unknown IRQ pin %d\n", __func__, pin); 425 return; 426 } 427 if (level) 428 env->irq_input_state |= 1 << pin; 429 else 430 env->irq_input_state &= ~(1 << pin); 431 } 432 } 433 434 void ppce500_irq_init(CPUPPCState *env) 435 { 436 PowerPCCPU *cpu = ppc_env_get_cpu(env); 437 438 env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq, 439 cpu, PPCE500_INPUT_NB); 440 } 441 442 /* Enable or Disable the E500 EPR capability */ 443 void ppce500_set_mpic_proxy(bool enabled) 444 { 445 CPUState *cs; 446 447 CPU_FOREACH(cs) { 448 PowerPCCPU *cpu = POWERPC_CPU(cs); 449 450 cpu->env.mpic_proxy = enabled; 451 if (kvm_enabled()) { 452 kvmppc_set_mpic_proxy(cpu, enabled); 453 } 454 } 455 } 456 457 /*****************************************************************************/ 458 /* PowerPC time base and decrementer emulation */ 459 460 uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset) 461 { 462 /* TB time in tb periods */ 463 return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset; 464 } 465 466 uint64_t cpu_ppc_load_tbl (CPUPPCState *env) 467 { 468 ppc_tb_t *tb_env = env->tb_env; 469 uint64_t tb; 470 471 if (kvm_enabled()) { 472 return env->spr[SPR_TBL]; 473 } 474 475 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); 476 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); 477 478 return tb; 479 } 480 481 static inline uint32_t _cpu_ppc_load_tbu(CPUPPCState *env) 482 { 483 ppc_tb_t *tb_env = env->tb_env; 484 uint64_t tb; 485 486 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); 487 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); 488 489 return tb >> 32; 490 } 491 492 uint32_t cpu_ppc_load_tbu (CPUPPCState *env) 493 { 494 if (kvm_enabled()) { 495 return env->spr[SPR_TBU]; 496 } 497 498 return _cpu_ppc_load_tbu(env); 499 } 500 501 static inline void cpu_ppc_store_tb(ppc_tb_t *tb_env, uint64_t vmclk, 502 int64_t *tb_offsetp, uint64_t value) 503 { 504 *tb_offsetp = value - muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()); 505 LOG_TB("%s: tb %016" PRIx64 " offset %08" PRIx64 "\n", 506 __func__, value, *tb_offsetp); 507 } 508 509 void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value) 510 { 511 ppc_tb_t *tb_env = env->tb_env; 512 uint64_t tb; 513 514 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); 515 tb &= 0xFFFFFFFF00000000ULL; 516 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 517 &tb_env->tb_offset, tb | (uint64_t)value); 518 } 519 520 static inline void _cpu_ppc_store_tbu(CPUPPCState *env, uint32_t value) 521 { 522 ppc_tb_t *tb_env = env->tb_env; 523 uint64_t tb; 524 525 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); 526 tb &= 0x00000000FFFFFFFFULL; 527 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 528 &tb_env->tb_offset, ((uint64_t)value << 32) | tb); 529 } 530 531 void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value) 532 { 533 _cpu_ppc_store_tbu(env, value); 534 } 535 536 uint64_t cpu_ppc_load_atbl (CPUPPCState *env) 537 { 538 ppc_tb_t *tb_env = env->tb_env; 539 uint64_t tb; 540 541 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); 542 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); 543 544 return tb; 545 } 546 547 uint32_t cpu_ppc_load_atbu (CPUPPCState *env) 548 { 549 ppc_tb_t *tb_env = env->tb_env; 550 uint64_t tb; 551 552 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); 553 LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb); 554 555 return tb >> 32; 556 } 557 558 void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value) 559 { 560 ppc_tb_t *tb_env = env->tb_env; 561 uint64_t tb; 562 563 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); 564 tb &= 0xFFFFFFFF00000000ULL; 565 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 566 &tb_env->atb_offset, tb | (uint64_t)value); 567 } 568 569 void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value) 570 { 571 ppc_tb_t *tb_env = env->tb_env; 572 uint64_t tb; 573 574 tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); 575 tb &= 0x00000000FFFFFFFFULL; 576 cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 577 &tb_env->atb_offset, ((uint64_t)value << 32) | tb); 578 } 579 580 static void cpu_ppc_tb_stop (CPUPPCState *env) 581 { 582 ppc_tb_t *tb_env = env->tb_env; 583 uint64_t tb, atb, vmclk; 584 585 /* If the time base is already frozen, do nothing */ 586 if (tb_env->tb_freq != 0) { 587 vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 588 /* Get the time base */ 589 tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset); 590 /* Get the alternate time base */ 591 atb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->atb_offset); 592 /* Store the time base value (ie compute the current offset) */ 593 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb); 594 /* Store the alternate time base value (compute the current offset) */ 595 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb); 596 /* Set the time base frequency to zero */ 597 tb_env->tb_freq = 0; 598 /* Now, the time bases are frozen to tb_offset / atb_offset value */ 599 } 600 } 601 602 static void cpu_ppc_tb_start (CPUPPCState *env) 603 { 604 ppc_tb_t *tb_env = env->tb_env; 605 uint64_t tb, atb, vmclk; 606 607 /* If the time base is not frozen, do nothing */ 608 if (tb_env->tb_freq == 0) { 609 vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 610 /* Get the time base from tb_offset */ 611 tb = tb_env->tb_offset; 612 /* Get the alternate time base from atb_offset */ 613 atb = tb_env->atb_offset; 614 /* Restore the tb frequency from the decrementer frequency */ 615 tb_env->tb_freq = tb_env->decr_freq; 616 /* Store the time base value */ 617 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->tb_offset, tb); 618 /* Store the alternate time base value */ 619 cpu_ppc_store_tb(tb_env, vmclk, &tb_env->atb_offset, atb); 620 } 621 } 622 623 static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next) 624 { 625 ppc_tb_t *tb_env = env->tb_env; 626 uint32_t decr; 627 int64_t diff; 628 629 diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 630 if (diff >= 0) { 631 decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec()); 632 } else if (tb_env->flags & PPC_TIMER_BOOKE) { 633 decr = 0; 634 } else { 635 decr = -muldiv64(-diff, tb_env->decr_freq, get_ticks_per_sec()); 636 } 637 LOG_TB("%s: %08" PRIx32 "\n", __func__, decr); 638 639 return decr; 640 } 641 642 uint32_t cpu_ppc_load_decr (CPUPPCState *env) 643 { 644 ppc_tb_t *tb_env = env->tb_env; 645 646 if (kvm_enabled()) { 647 return env->spr[SPR_DECR]; 648 } 649 650 return _cpu_ppc_load_decr(env, tb_env->decr_next); 651 } 652 653 uint32_t cpu_ppc_load_hdecr (CPUPPCState *env) 654 { 655 ppc_tb_t *tb_env = env->tb_env; 656 657 return _cpu_ppc_load_decr(env, tb_env->hdecr_next); 658 } 659 660 uint64_t cpu_ppc_load_purr (CPUPPCState *env) 661 { 662 ppc_tb_t *tb_env = env->tb_env; 663 uint64_t diff; 664 665 diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start; 666 667 return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec()); 668 } 669 670 /* When decrementer expires, 671 * all we need to do is generate or queue a CPU exception 672 */ 673 static inline void cpu_ppc_decr_excp(PowerPCCPU *cpu) 674 { 675 /* Raise it */ 676 LOG_TB("raise decrementer exception\n"); 677 ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 1); 678 } 679 680 static inline void cpu_ppc_hdecr_excp(PowerPCCPU *cpu) 681 { 682 /* Raise it */ 683 LOG_TB("raise decrementer exception\n"); 684 ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1); 685 } 686 687 static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, 688 QEMUTimer *timer, 689 void (*raise_excp)(PowerPCCPU *), 690 uint32_t decr, uint32_t value, 691 int is_excp) 692 { 693 CPUPPCState *env = &cpu->env; 694 ppc_tb_t *tb_env = env->tb_env; 695 uint64_t now, next; 696 697 LOG_TB("%s: %08" PRIx32 " => %08" PRIx32 "\n", __func__, 698 decr, value); 699 700 if (kvm_enabled()) { 701 /* KVM handles decrementer exceptions, we don't need our own timer */ 702 return; 703 } 704 705 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 706 next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq); 707 if (is_excp) { 708 next += *nextp - now; 709 } 710 if (next == now) { 711 next++; 712 } 713 *nextp = next; 714 /* Adjust timer */ 715 timer_mod(timer, next); 716 717 /* If we set a negative value and the decrementer was positive, raise an 718 * exception. 719 */ 720 if ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) 721 && (value & 0x80000000) 722 && !(decr & 0x80000000)) { 723 (*raise_excp)(cpu); 724 } 725 } 726 727 static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, uint32_t decr, 728 uint32_t value, int is_excp) 729 { 730 ppc_tb_t *tb_env = cpu->env.tb_env; 731 732 __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer, 733 &cpu_ppc_decr_excp, decr, value, is_excp); 734 } 735 736 void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value) 737 { 738 PowerPCCPU *cpu = ppc_env_get_cpu(env); 739 740 _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value, 0); 741 } 742 743 static void cpu_ppc_decr_cb(void *opaque) 744 { 745 PowerPCCPU *cpu = opaque; 746 747 _cpu_ppc_store_decr(cpu, 0x00000000, 0xFFFFFFFF, 1); 748 } 749 750 static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, uint32_t hdecr, 751 uint32_t value, int is_excp) 752 { 753 ppc_tb_t *tb_env = cpu->env.tb_env; 754 755 if (tb_env->hdecr_timer != NULL) { 756 __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer, 757 &cpu_ppc_hdecr_excp, hdecr, value, is_excp); 758 } 759 } 760 761 void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value) 762 { 763 PowerPCCPU *cpu = ppc_env_get_cpu(env); 764 765 _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value, 0); 766 } 767 768 static void cpu_ppc_hdecr_cb(void *opaque) 769 { 770 PowerPCCPU *cpu = opaque; 771 772 _cpu_ppc_store_hdecr(cpu, 0x00000000, 0xFFFFFFFF, 1); 773 } 774 775 static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value) 776 { 777 ppc_tb_t *tb_env = cpu->env.tb_env; 778 779 tb_env->purr_load = value; 780 tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 781 } 782 783 static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq) 784 { 785 CPUPPCState *env = opaque; 786 PowerPCCPU *cpu = ppc_env_get_cpu(env); 787 ppc_tb_t *tb_env = env->tb_env; 788 789 tb_env->tb_freq = freq; 790 tb_env->decr_freq = freq; 791 /* There is a bug in Linux 2.4 kernels: 792 * if a decrementer exception is pending when it enables msr_ee at startup, 793 * it's not ready to handle it... 794 */ 795 _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 0); 796 _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 0); 797 cpu_ppc_store_purr(cpu, 0x0000000000000000ULL); 798 } 799 800 /* Set up (once) timebase frequency (in Hz) */ 801 clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq) 802 { 803 PowerPCCPU *cpu = ppc_env_get_cpu(env); 804 ppc_tb_t *tb_env; 805 806 tb_env = g_malloc0(sizeof(ppc_tb_t)); 807 env->tb_env = tb_env; 808 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED; 809 /* Create new timer */ 810 tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu); 811 if (0) { 812 /* XXX: find a suitable condition to enable the hypervisor decrementer 813 */ 814 tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb, 815 cpu); 816 } else { 817 tb_env->hdecr_timer = NULL; 818 } 819 cpu_ppc_set_tb_clk(env, freq); 820 821 return &cpu_ppc_set_tb_clk; 822 } 823 824 /* Specific helpers for POWER & PowerPC 601 RTC */ 825 #if 0 826 static clk_setup_cb cpu_ppc601_rtc_init (CPUPPCState *env) 827 { 828 return cpu_ppc_tb_init(env, 7812500); 829 } 830 #endif 831 832 void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value) 833 { 834 _cpu_ppc_store_tbu(env, value); 835 } 836 837 uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env) 838 { 839 return _cpu_ppc_load_tbu(env); 840 } 841 842 void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value) 843 { 844 cpu_ppc_store_tbl(env, value & 0x3FFFFF80); 845 } 846 847 uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env) 848 { 849 return cpu_ppc_load_tbl(env) & 0x3FFFFF80; 850 } 851 852 /*****************************************************************************/ 853 /* PowerPC 40x timers */ 854 855 /* PIT, FIT & WDT */ 856 typedef struct ppc40x_timer_t ppc40x_timer_t; 857 struct ppc40x_timer_t { 858 uint64_t pit_reload; /* PIT auto-reload value */ 859 uint64_t fit_next; /* Tick for next FIT interrupt */ 860 QEMUTimer *fit_timer; 861 uint64_t wdt_next; /* Tick for next WDT interrupt */ 862 QEMUTimer *wdt_timer; 863 864 /* 405 have the PIT, 440 have a DECR. */ 865 unsigned int decr_excp; 866 }; 867 868 /* Fixed interval timer */ 869 static void cpu_4xx_fit_cb (void *opaque) 870 { 871 PowerPCCPU *cpu; 872 CPUPPCState *env; 873 ppc_tb_t *tb_env; 874 ppc40x_timer_t *ppc40x_timer; 875 uint64_t now, next; 876 877 env = opaque; 878 cpu = ppc_env_get_cpu(env); 879 tb_env = env->tb_env; 880 ppc40x_timer = tb_env->opaque; 881 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 882 switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) { 883 case 0: 884 next = 1 << 9; 885 break; 886 case 1: 887 next = 1 << 13; 888 break; 889 case 2: 890 next = 1 << 17; 891 break; 892 case 3: 893 next = 1 << 21; 894 break; 895 default: 896 /* Cannot occur, but makes gcc happy */ 897 return; 898 } 899 next = now + muldiv64(next, get_ticks_per_sec(), tb_env->tb_freq); 900 if (next == now) 901 next++; 902 timer_mod(ppc40x_timer->fit_timer, next); 903 env->spr[SPR_40x_TSR] |= 1 << 26; 904 if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) { 905 ppc_set_irq(cpu, PPC_INTERRUPT_FIT, 1); 906 } 907 LOG_TB("%s: ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__, 908 (int)((env->spr[SPR_40x_TCR] >> 23) & 0x1), 909 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]); 910 } 911 912 /* Programmable interval timer */ 913 static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp) 914 { 915 ppc40x_timer_t *ppc40x_timer; 916 uint64_t now, next; 917 918 ppc40x_timer = tb_env->opaque; 919 if (ppc40x_timer->pit_reload <= 1 || 920 !((env->spr[SPR_40x_TCR] >> 26) & 0x1) || 921 (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) { 922 /* Stop PIT */ 923 LOG_TB("%s: stop PIT\n", __func__); 924 timer_del(tb_env->decr_timer); 925 } else { 926 LOG_TB("%s: start PIT %016" PRIx64 "\n", 927 __func__, ppc40x_timer->pit_reload); 928 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 929 next = now + muldiv64(ppc40x_timer->pit_reload, 930 get_ticks_per_sec(), tb_env->decr_freq); 931 if (is_excp) 932 next += tb_env->decr_next - now; 933 if (next == now) 934 next++; 935 timer_mod(tb_env->decr_timer, next); 936 tb_env->decr_next = next; 937 } 938 } 939 940 static void cpu_4xx_pit_cb (void *opaque) 941 { 942 PowerPCCPU *cpu; 943 CPUPPCState *env; 944 ppc_tb_t *tb_env; 945 ppc40x_timer_t *ppc40x_timer; 946 947 env = opaque; 948 cpu = ppc_env_get_cpu(env); 949 tb_env = env->tb_env; 950 ppc40x_timer = tb_env->opaque; 951 env->spr[SPR_40x_TSR] |= 1 << 27; 952 if ((env->spr[SPR_40x_TCR] >> 26) & 0x1) { 953 ppc_set_irq(cpu, ppc40x_timer->decr_excp, 1); 954 } 955 start_stop_pit(env, tb_env, 1); 956 LOG_TB("%s: ar %d ir %d TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx " " 957 "%016" PRIx64 "\n", __func__, 958 (int)((env->spr[SPR_40x_TCR] >> 22) & 0x1), 959 (int)((env->spr[SPR_40x_TCR] >> 26) & 0x1), 960 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR], 961 ppc40x_timer->pit_reload); 962 } 963 964 /* Watchdog timer */ 965 static void cpu_4xx_wdt_cb (void *opaque) 966 { 967 PowerPCCPU *cpu; 968 CPUPPCState *env; 969 ppc_tb_t *tb_env; 970 ppc40x_timer_t *ppc40x_timer; 971 uint64_t now, next; 972 973 env = opaque; 974 cpu = ppc_env_get_cpu(env); 975 tb_env = env->tb_env; 976 ppc40x_timer = tb_env->opaque; 977 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 978 switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) { 979 case 0: 980 next = 1 << 17; 981 break; 982 case 1: 983 next = 1 << 21; 984 break; 985 case 2: 986 next = 1 << 25; 987 break; 988 case 3: 989 next = 1 << 29; 990 break; 991 default: 992 /* Cannot occur, but makes gcc happy */ 993 return; 994 } 995 next = now + muldiv64(next, get_ticks_per_sec(), tb_env->decr_freq); 996 if (next == now) 997 next++; 998 LOG_TB("%s: TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx "\n", __func__, 999 env->spr[SPR_40x_TCR], env->spr[SPR_40x_TSR]); 1000 switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) { 1001 case 0x0: 1002 case 0x1: 1003 timer_mod(ppc40x_timer->wdt_timer, next); 1004 ppc40x_timer->wdt_next = next; 1005 env->spr[SPR_40x_TSR] |= 1 << 31; 1006 break; 1007 case 0x2: 1008 timer_mod(ppc40x_timer->wdt_timer, next); 1009 ppc40x_timer->wdt_next = next; 1010 env->spr[SPR_40x_TSR] |= 1 << 30; 1011 if ((env->spr[SPR_40x_TCR] >> 27) & 0x1) { 1012 ppc_set_irq(cpu, PPC_INTERRUPT_WDT, 1); 1013 } 1014 break; 1015 case 0x3: 1016 env->spr[SPR_40x_TSR] &= ~0x30000000; 1017 env->spr[SPR_40x_TSR] |= env->spr[SPR_40x_TCR] & 0x30000000; 1018 switch ((env->spr[SPR_40x_TCR] >> 28) & 0x3) { 1019 case 0x0: 1020 /* No reset */ 1021 break; 1022 case 0x1: /* Core reset */ 1023 ppc40x_core_reset(cpu); 1024 break; 1025 case 0x2: /* Chip reset */ 1026 ppc40x_chip_reset(cpu); 1027 break; 1028 case 0x3: /* System reset */ 1029 ppc40x_system_reset(cpu); 1030 break; 1031 } 1032 } 1033 } 1034 1035 void store_40x_pit (CPUPPCState *env, target_ulong val) 1036 { 1037 ppc_tb_t *tb_env; 1038 ppc40x_timer_t *ppc40x_timer; 1039 1040 tb_env = env->tb_env; 1041 ppc40x_timer = tb_env->opaque; 1042 LOG_TB("%s val" TARGET_FMT_lx "\n", __func__, val); 1043 ppc40x_timer->pit_reload = val; 1044 start_stop_pit(env, tb_env, 0); 1045 } 1046 1047 target_ulong load_40x_pit (CPUPPCState *env) 1048 { 1049 return cpu_ppc_load_decr(env); 1050 } 1051 1052 static void ppc_40x_set_tb_clk (void *opaque, uint32_t freq) 1053 { 1054 CPUPPCState *env = opaque; 1055 ppc_tb_t *tb_env = env->tb_env; 1056 1057 LOG_TB("%s set new frequency to %" PRIu32 "\n", __func__, 1058 freq); 1059 tb_env->tb_freq = freq; 1060 tb_env->decr_freq = freq; 1061 /* XXX: we should also update all timers */ 1062 } 1063 1064 clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq, 1065 unsigned int decr_excp) 1066 { 1067 ppc_tb_t *tb_env; 1068 ppc40x_timer_t *ppc40x_timer; 1069 1070 tb_env = g_malloc0(sizeof(ppc_tb_t)); 1071 env->tb_env = tb_env; 1072 tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED; 1073 ppc40x_timer = g_malloc0(sizeof(ppc40x_timer_t)); 1074 tb_env->tb_freq = freq; 1075 tb_env->decr_freq = freq; 1076 tb_env->opaque = ppc40x_timer; 1077 LOG_TB("%s freq %" PRIu32 "\n", __func__, freq); 1078 if (ppc40x_timer != NULL) { 1079 /* We use decr timer for PIT */ 1080 tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, env); 1081 ppc40x_timer->fit_timer = 1082 timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, env); 1083 ppc40x_timer->wdt_timer = 1084 timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, env); 1085 ppc40x_timer->decr_excp = decr_excp; 1086 } 1087 1088 return &ppc_40x_set_tb_clk; 1089 } 1090 1091 /*****************************************************************************/ 1092 /* Embedded PowerPC Device Control Registers */ 1093 typedef struct ppc_dcrn_t ppc_dcrn_t; 1094 struct ppc_dcrn_t { 1095 dcr_read_cb dcr_read; 1096 dcr_write_cb dcr_write; 1097 void *opaque; 1098 }; 1099 1100 /* XXX: on 460, DCR addresses are 32 bits wide, 1101 * using DCRIPR to get the 22 upper bits of the DCR address 1102 */ 1103 #define DCRN_NB 1024 1104 struct ppc_dcr_t { 1105 ppc_dcrn_t dcrn[DCRN_NB]; 1106 int (*read_error)(int dcrn); 1107 int (*write_error)(int dcrn); 1108 }; 1109 1110 int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp) 1111 { 1112 ppc_dcrn_t *dcr; 1113 1114 if (dcrn < 0 || dcrn >= DCRN_NB) 1115 goto error; 1116 dcr = &dcr_env->dcrn[dcrn]; 1117 if (dcr->dcr_read == NULL) 1118 goto error; 1119 *valp = (*dcr->dcr_read)(dcr->opaque, dcrn); 1120 1121 return 0; 1122 1123 error: 1124 if (dcr_env->read_error != NULL) 1125 return (*dcr_env->read_error)(dcrn); 1126 1127 return -1; 1128 } 1129 1130 int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val) 1131 { 1132 ppc_dcrn_t *dcr; 1133 1134 if (dcrn < 0 || dcrn >= DCRN_NB) 1135 goto error; 1136 dcr = &dcr_env->dcrn[dcrn]; 1137 if (dcr->dcr_write == NULL) 1138 goto error; 1139 (*dcr->dcr_write)(dcr->opaque, dcrn, val); 1140 1141 return 0; 1142 1143 error: 1144 if (dcr_env->write_error != NULL) 1145 return (*dcr_env->write_error)(dcrn); 1146 1147 return -1; 1148 } 1149 1150 int ppc_dcr_register (CPUPPCState *env, int dcrn, void *opaque, 1151 dcr_read_cb dcr_read, dcr_write_cb dcr_write) 1152 { 1153 ppc_dcr_t *dcr_env; 1154 ppc_dcrn_t *dcr; 1155 1156 dcr_env = env->dcr_env; 1157 if (dcr_env == NULL) 1158 return -1; 1159 if (dcrn < 0 || dcrn >= DCRN_NB) 1160 return -1; 1161 dcr = &dcr_env->dcrn[dcrn]; 1162 if (dcr->opaque != NULL || 1163 dcr->dcr_read != NULL || 1164 dcr->dcr_write != NULL) 1165 return -1; 1166 dcr->opaque = opaque; 1167 dcr->dcr_read = dcr_read; 1168 dcr->dcr_write = dcr_write; 1169 1170 return 0; 1171 } 1172 1173 int ppc_dcr_init (CPUPPCState *env, int (*read_error)(int dcrn), 1174 int (*write_error)(int dcrn)) 1175 { 1176 ppc_dcr_t *dcr_env; 1177 1178 dcr_env = g_malloc0(sizeof(ppc_dcr_t)); 1179 dcr_env->read_error = read_error; 1180 dcr_env->write_error = write_error; 1181 env->dcr_env = dcr_env; 1182 1183 return 0; 1184 } 1185 1186 /*****************************************************************************/ 1187 /* Debug port */ 1188 void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val) 1189 { 1190 addr &= 0xF; 1191 switch (addr) { 1192 case 0: 1193 printf("%c", val); 1194 break; 1195 case 1: 1196 printf("\n"); 1197 fflush(stdout); 1198 break; 1199 case 2: 1200 printf("Set loglevel to %04" PRIx32 "\n", val); 1201 qemu_set_log(val | 0x100); 1202 break; 1203 } 1204 } 1205 1206 /*****************************************************************************/ 1207 /* NVRAM helpers */ 1208 static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr) 1209 { 1210 return (*nvram->read_fn)(nvram->opaque, addr); 1211 } 1212 1213 static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val) 1214 { 1215 (*nvram->write_fn)(nvram->opaque, addr, val); 1216 } 1217 1218 static void NVRAM_set_byte(nvram_t *nvram, uint32_t addr, uint8_t value) 1219 { 1220 nvram_write(nvram, addr, value); 1221 } 1222 1223 static uint8_t NVRAM_get_byte(nvram_t *nvram, uint32_t addr) 1224 { 1225 return nvram_read(nvram, addr); 1226 } 1227 1228 static void NVRAM_set_word(nvram_t *nvram, uint32_t addr, uint16_t value) 1229 { 1230 nvram_write(nvram, addr, value >> 8); 1231 nvram_write(nvram, addr + 1, value & 0xFF); 1232 } 1233 1234 static uint16_t NVRAM_get_word(nvram_t *nvram, uint32_t addr) 1235 { 1236 uint16_t tmp; 1237 1238 tmp = nvram_read(nvram, addr) << 8; 1239 tmp |= nvram_read(nvram, addr + 1); 1240 1241 return tmp; 1242 } 1243 1244 static void NVRAM_set_lword(nvram_t *nvram, uint32_t addr, uint32_t value) 1245 { 1246 nvram_write(nvram, addr, value >> 24); 1247 nvram_write(nvram, addr + 1, (value >> 16) & 0xFF); 1248 nvram_write(nvram, addr + 2, (value >> 8) & 0xFF); 1249 nvram_write(nvram, addr + 3, value & 0xFF); 1250 } 1251 1252 uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr) 1253 { 1254 uint32_t tmp; 1255 1256 tmp = nvram_read(nvram, addr) << 24; 1257 tmp |= nvram_read(nvram, addr + 1) << 16; 1258 tmp |= nvram_read(nvram, addr + 2) << 8; 1259 tmp |= nvram_read(nvram, addr + 3); 1260 1261 return tmp; 1262 } 1263 1264 static void NVRAM_set_string(nvram_t *nvram, uint32_t addr, const char *str, 1265 uint32_t max) 1266 { 1267 int i; 1268 1269 for (i = 0; i < max && str[i] != '\0'; i++) { 1270 nvram_write(nvram, addr + i, str[i]); 1271 } 1272 nvram_write(nvram, addr + i, str[i]); 1273 nvram_write(nvram, addr + max - 1, '\0'); 1274 } 1275 1276 int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max) 1277 { 1278 int i; 1279 1280 memset(dst, 0, max); 1281 for (i = 0; i < max; i++) { 1282 dst[i] = NVRAM_get_byte(nvram, addr + i); 1283 if (dst[i] == '\0') 1284 break; 1285 } 1286 1287 return i; 1288 } 1289 1290 static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value) 1291 { 1292 uint16_t tmp; 1293 uint16_t pd, pd1, pd2; 1294 1295 tmp = prev >> 8; 1296 pd = prev ^ value; 1297 pd1 = pd & 0x000F; 1298 pd2 = ((pd >> 4) & 0x000F) ^ pd1; 1299 tmp ^= (pd1 << 3) | (pd1 << 8); 1300 tmp ^= pd2 | (pd2 << 7) | (pd2 << 12); 1301 1302 return tmp; 1303 } 1304 1305 static uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count) 1306 { 1307 uint32_t i; 1308 uint16_t crc = 0xFFFF; 1309 int odd; 1310 1311 odd = count & 1; 1312 count &= ~1; 1313 for (i = 0; i != count; i++) { 1314 crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i)); 1315 } 1316 if (odd) { 1317 crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8); 1318 } 1319 1320 return crc; 1321 } 1322 1323 #define CMDLINE_ADDR 0x017ff000 1324 1325 int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size, 1326 const char *arch, 1327 uint32_t RAM_size, int boot_device, 1328 uint32_t kernel_image, uint32_t kernel_size, 1329 const char *cmdline, 1330 uint32_t initrd_image, uint32_t initrd_size, 1331 uint32_t NVRAM_image, 1332 int width, int height, int depth) 1333 { 1334 uint16_t crc; 1335 1336 /* Set parameters for Open Hack'Ware BIOS */ 1337 NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16); 1338 NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */ 1339 NVRAM_set_word(nvram, 0x14, NVRAM_size); 1340 NVRAM_set_string(nvram, 0x20, arch, 16); 1341 NVRAM_set_lword(nvram, 0x30, RAM_size); 1342 NVRAM_set_byte(nvram, 0x34, boot_device); 1343 NVRAM_set_lword(nvram, 0x38, kernel_image); 1344 NVRAM_set_lword(nvram, 0x3C, kernel_size); 1345 if (cmdline) { 1346 /* XXX: put the cmdline in NVRAM too ? */ 1347 pstrcpy_targphys("cmdline", CMDLINE_ADDR, RAM_size - CMDLINE_ADDR, cmdline); 1348 NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR); 1349 NVRAM_set_lword(nvram, 0x44, strlen(cmdline)); 1350 } else { 1351 NVRAM_set_lword(nvram, 0x40, 0); 1352 NVRAM_set_lword(nvram, 0x44, 0); 1353 } 1354 NVRAM_set_lword(nvram, 0x48, initrd_image); 1355 NVRAM_set_lword(nvram, 0x4C, initrd_size); 1356 NVRAM_set_lword(nvram, 0x50, NVRAM_image); 1357 1358 NVRAM_set_word(nvram, 0x54, width); 1359 NVRAM_set_word(nvram, 0x56, height); 1360 NVRAM_set_word(nvram, 0x58, depth); 1361 crc = NVRAM_compute_crc(nvram, 0x00, 0xF8); 1362 NVRAM_set_word(nvram, 0xFC, crc); 1363 1364 return 0; 1365 } 1366 1367 /* CPU device-tree ID helpers */ 1368 int ppc_get_vcpu_dt_id(PowerPCCPU *cpu) 1369 { 1370 return cpu->cpu_dt_id; 1371 } 1372 1373 PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id) 1374 { 1375 CPUState *cs; 1376 1377 CPU_FOREACH(cs) { 1378 PowerPCCPU *cpu = POWERPC_CPU(cs); 1379 1380 if (cpu->cpu_dt_id == cpu_dt_id) { 1381 return cpu; 1382 } 1383 } 1384 1385 return NULL; 1386 } 1387