Commit a062e36c58738321295e1031bebb1b89a0cdf01a

Authored by j_mayer
1 parent 4887d78b

Implement the PowerPC alternate time-base, following the 2.04 specification.

Share most code with the time-base management routines.
Remove time-base write routines from user-mode emulation environments.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3277 c046a42c-6fe2-441c-8c8c-71466251a162
darwin-user/main.c
... ... @@ -124,24 +124,14 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
124 124 return cpu_ppc_get_tb(env) >> 32;
125 125 }
126 126  
127   -static void cpu_ppc_store_tb (CPUState *env, uint64_t value)
  127 +uint32_t cpu_ppc_load_atbl (CPUState *env)
128 128 {
129   - /* TO FIX */
130   -}
131   -
132   -void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
133   -{
134   - cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
135   -}
136   -
137   -void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
138   -{
139   - cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
  129 + return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
140 130 }
141 131  
142   -void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
  132 +uint32_t cpu_ppc_load_atbu (CPUState *env)
143 133 {
144   - cpu_ppc_store_tbu( env, value );
  134 + return cpu_ppc_get_tb(env) >> 32;
145 135 }
146 136  
147 137 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
... ...
hw/ppc.c
... ... @@ -408,6 +408,7 @@ void ppc405_irq_init (CPUState *env)
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,7 +423,7 @@ struct ppc_tb_t {
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,19 +435,10 @@ uint32_t cpu_ppc_load_tbl (CPUState *env)
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,7 +450,7 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
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,32 +460,89 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
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)
... ...
linux-user/main.c
... ... @@ -664,7 +664,6 @@ void cpu_loop (CPUSPARCState *env)
664 664 #endif
665 665  
666 666 #ifdef TARGET_PPC
667   -
668 667 static inline uint64_t cpu_ppc_get_tb (CPUState *env)
669 668 {
670 669 /* TO FIX */
... ... @@ -681,32 +680,19 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
681 680 return cpu_ppc_get_tb(env) >> 32;
682 681 }
683 682  
684   -static void cpu_ppc_store_tb (CPUState *env, uint64_t value)
685   -{
686   - /* TO FIX */
687   -}
688   -
689   -void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
  683 +uint32_t cpu_ppc_load_atbl (CPUState *env)
690 684 {
691   - cpu_ppc_store_tb(env, ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
  685 + return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
692 686 }
693 687  
694   -void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
  688 +uint32_t cpu_ppc_load_atbu (CPUState *env)
695 689 {
696   - cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
  690 + return cpu_ppc_get_tb(env) >> 32;
697 691 }
698 692  
699   -void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
700   -__attribute__ (( alias ("cpu_ppc_store_tbu") ));
701   -
702 693 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
703 694 __attribute__ (( alias ("cpu_ppc_load_tbu") ));
704 695  
705   -void cpu_ppc601_store_rtcl (CPUState *env, uint32_t value)
706   -{
707   - cpu_ppc_store_tbl(env, value & 0x3FFFFF80);
708   -}
709   -
710 696 uint32_t cpu_ppc601_load_rtcl (CPUState *env)
711 697 {
712 698 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
... ...
target-ppc/cpu.h
... ... @@ -625,6 +625,10 @@ uint32_t cpu_ppc_load_tbl (CPUPPCState *env);
625 625 uint32_t cpu_ppc_load_tbu (CPUPPCState *env);
626 626 void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value);
627 627 void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value);
  628 +uint32_t cpu_ppc_load_atbl (CPUPPCState *env);
  629 +uint32_t cpu_ppc_load_atbu (CPUPPCState *env);
  630 +void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value);
  631 +void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value);
628 632 uint32_t cpu_ppc_load_decr (CPUPPCState *env);
629 633 void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
630 634 #if defined(TARGET_PPC64H)
... ... @@ -798,8 +802,8 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
798 802 #define SPR_BOOKE_SPEFSCR (0x200)
799 803 #define SPR_E500_BBEAR (0x201)
800 804 #define SPR_E500_BBTAR (0x202)
801   -#define SPR_BOOKE_ATBL (0x20E)
802   -#define SPR_BOOKE_ATBU (0x20F)
  805 +#define SPR_ATBL (0x20E)
  806 +#define SPR_ATBU (0x20F)
803 807 #define SPR_IBAT0U (0x210)
804 808 #define SPR_BOOKE_IVOR32 (0x210)
805 809 #define SPR_IBAT0L (0x211)
... ...
target-ppc/op.c
... ... @@ -423,6 +423,18 @@ void OPPROTO op_load_tbu (void)
423 423 RETURN();
424 424 }
425 425  
  426 +void OPPROTO op_load_atbl (void)
  427 +{
  428 + T0 = cpu_ppc_load_atbl(env);
  429 + RETURN();
  430 +}
  431 +
  432 +void OPPROTO op_load_atbu (void)
  433 +{
  434 + T0 = cpu_ppc_load_atbu(env);
  435 + RETURN();
  436 +}
  437 +
426 438 #if !defined(CONFIG_USER_ONLY)
427 439 void OPPROTO op_store_tbl (void)
428 440 {
... ... @@ -436,6 +448,18 @@ void OPPROTO op_store_tbu (void)
436 448 RETURN();
437 449 }
438 450  
  451 +void OPPROTO op_store_atbl (void)
  452 +{
  453 + cpu_ppc_store_atbl(env, T0);
  454 + RETURN();
  455 +}
  456 +
  457 +void OPPROTO op_store_atbu (void)
  458 +{
  459 + cpu_ppc_store_atbu(env, T0);
  460 + RETURN();
  461 +}
  462 +
439 463 void OPPROTO op_load_decr (void)
440 464 {
441 465 T0 = cpu_ppc_load_decr(env);
... ...
target-ppc/translate_init.c
... ... @@ -162,6 +162,18 @@ static void spr_read_tbu (void *opaque, int sprn)
162 162 gen_op_load_tbu();
163 163 }
164 164  
  165 +__attribute__ (( unused ))
  166 +static void spr_read_atbl (void *opaque, int sprn)
  167 +{
  168 + gen_op_load_atbl();
  169 +}
  170 +
  171 +__attribute__ (( unused ))
  172 +static void spr_read_atbu (void *opaque, int sprn)
  173 +{
  174 + gen_op_load_atbu();
  175 +}
  176 +
165 177 #if !defined(CONFIG_USER_ONLY)
166 178 static void spr_write_tbl (void *opaque, int sprn)
167 179 {
... ... @@ -172,6 +184,18 @@ static void spr_write_tbu (void *opaque, int sprn)
172 184 {
173 185 gen_op_store_tbu();
174 186 }
  187 +
  188 +__attribute__ (( unused ))
  189 +static void spr_write_atbl (void *opaque, int sprn)
  190 +{
  191 + gen_op_store_atbl();
  192 +}
  193 +
  194 +__attribute__ (( unused ))
  195 +static void spr_write_atbu (void *opaque, int sprn)
  196 +{
  197 + gen_op_store_atbu();
  198 +}
175 199 #endif
176 200  
177 201 #if !defined(CONFIG_USER_ONLY)
... ...