Revision a062e36c hw/ppc.c

b/hw/ppc.c
408 408
struct ppc_tb_t {
409 409
    /* Time base management */
410 410
    int64_t  tb_offset;    /* Compensation               */
411
    int64_t  atb_offset;   /* Compensation               */
411 412
    uint32_t tb_freq;      /* TB frequency               */
412 413
    /* Decrementer management */
413 414
    uint64_t decr_next;    /* Tick for next decr interrupt  */
......
422 423
    void *opaque;
423 424
};
424 425

  
425
static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
426
static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env, int64_t tb_offset)
426 427
{
427 428
    /* TB time in tb periods */
428 429
    return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
......
434 435
    ppc_tb_t *tb_env = env->tb_env;
435 436
    uint64_t tb;
436 437

  
437
    tb = cpu_ppc_get_tb(tb_env);
438
#ifdef PPC_DEBUG_TB
439
    {
440
        static int last_time;
441
        int now;
442
        now = time(NULL);
443
        if (last_time != now) {
444
            last_time = now;
445
            if (loglevel != 0) {
446
                fprintf(logfile, "%s: tb=0x%016lx %d %08lx\n",
447
                        __func__, tb, now, tb_env->tb_offset);
448
            }
449
        }
438
    tb = cpu_ppc_get_tb(tb_env, tb_env->tb_offset);
439
#if defined(PPC_DEBUG_TB)
440
    if (loglevel != 0) {
441
        fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
450 442
    }
451 443
#endif
452 444

  
......
458 450
    ppc_tb_t *tb_env = env->tb_env;
459 451
    uint64_t tb;
460 452

  
461
    tb = cpu_ppc_get_tb(tb_env);
453
    tb = cpu_ppc_get_tb(tb_env, tb_env->tb_offset);
462 454
#if defined(PPC_DEBUG_TB)
463 455
    if (loglevel != 0) {
464 456
        fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
......
468 460
    return tb >> 32;
469 461
}
470 462

  
471
static void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t value)
463
static inline void cpu_ppc_store_tb (ppc_tb_t *tb_env, int64_t *tb_offsetp,
464
                                     uint64_t value)
472 465
{
473
    tb_env->tb_offset = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
466
    *tb_offsetp = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
474 467
        - qemu_get_clock(vm_clock);
475 468
#ifdef PPC_DEBUG_TB
476 469
    if (loglevel != 0) {
477 470
        fprintf(logfile, "%s: tb=0x%016lx offset=%08lx\n", __func__, value,
478
                tb_env->tb_offset);
471
                *tb_offsetp);
479 472
    }
480 473
#endif
481 474
}
482 475

  
476
void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
477
{
478
    ppc_tb_t *tb_env = env->tb_env;
479
    uint64_t tb;
480

  
481
    tb = cpu_ppc_get_tb(tb_env, tb_env->tb_offset);
482
    tb &= 0xFFFFFFFF00000000ULL;
483
    cpu_ppc_store_tb(tb_env, &tb_env->tb_offset, tb | (uint64_t)value);
484
}
485

  
483 486
void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
484 487
{
485 488
    ppc_tb_t *tb_env = env->tb_env;
489
    uint64_t tb;
486 490

  
487
    cpu_ppc_store_tb(tb_env,
488
                     ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
491
    tb = cpu_ppc_get_tb(tb_env, tb_env->tb_offset);
492
    tb &= 0x00000000FFFFFFFFULL;
493
    cpu_ppc_store_tb(tb_env, &tb_env->tb_offset,
494
                     ((uint64_t)value << 32) | tb);
489 495
}
490 496

  
491
void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
497
uint32_t cpu_ppc_load_atbl (CPUState *env)
498
{
499
    ppc_tb_t *tb_env = env->tb_env;
500
    uint64_t tb;
501

  
502
    tb = cpu_ppc_get_tb(tb_env, tb_env->atb_offset);
503
#if defined(PPC_DEBUG_TB)
504
    if (loglevel != 0) {
505
        fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
506
    }
507
#endif
508

  
509
    return tb & 0xFFFFFFFF;
510
}
511

  
512
uint32_t cpu_ppc_load_atbu (CPUState *env)
513
{
514
    ppc_tb_t *tb_env = env->tb_env;
515
    uint64_t tb;
516

  
517
    tb = cpu_ppc_get_tb(tb_env, tb_env->atb_offset);
518
#if defined(PPC_DEBUG_TB)
519
    if (loglevel != 0) {
520
        fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
521
    }
522
#endif
523

  
524
    return tb >> 32;
525
}
526

  
527
void cpu_ppc_store_atbl (CPUState *env, uint32_t value)
528
{
529
    ppc_tb_t *tb_env = env->tb_env;
530
    uint64_t tb;
531

  
532
    tb = cpu_ppc_get_tb(tb_env, tb_env->atb_offset);
533
    tb &= 0xFFFFFFFF00000000ULL;
534
    cpu_ppc_store_tb(tb_env, &tb_env->atb_offset, tb | (uint64_t)value);
535
}
536

  
537
void cpu_ppc_store_atbu (CPUState *env, uint32_t value)
492 538
{
493 539
    ppc_tb_t *tb_env = env->tb_env;
540
    uint64_t tb;
494 541

  
495
    cpu_ppc_store_tb(tb_env,
496
                     ((uint64_t)cpu_ppc_load_tbu(env) << 32) | value);
542
    tb = cpu_ppc_get_tb(tb_env, tb_env->atb_offset);
543
    tb &= 0x00000000FFFFFFFFULL;
544
    cpu_ppc_store_tb(tb_env, &tb_env->atb_offset,
545
                     ((uint64_t)value << 32) | tb);
497 546
}
498 547

  
499 548
static inline uint32_t _cpu_ppc_load_decr (CPUState *env, uint64_t *next)

Also available in: Unified diff