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,24 +124,14 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
124 return cpu_ppc_get_tb(env) >> 32; 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 uint32_t cpu_ppc601_load_rtcu (CPUState *env) 137 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
hw/ppc.c
@@ -408,6 +408,7 @@ void ppc405_irq_init (CPUState *env) @@ -408,6 +408,7 @@ void ppc405_irq_init (CPUState *env)
408 struct ppc_tb_t { 408 struct ppc_tb_t {
409 /* Time base management */ 409 /* Time base management */
410 int64_t tb_offset; /* Compensation */ 410 int64_t tb_offset; /* Compensation */
  411 + int64_t atb_offset; /* Compensation */
411 uint32_t tb_freq; /* TB frequency */ 412 uint32_t tb_freq; /* TB frequency */
412 /* Decrementer management */ 413 /* Decrementer management */
413 uint64_t decr_next; /* Tick for next decr interrupt */ 414 uint64_t decr_next; /* Tick for next decr interrupt */
@@ -422,7 +423,7 @@ struct ppc_tb_t { @@ -422,7 +423,7 @@ struct ppc_tb_t {
422 void *opaque; 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 /* TB time in tb periods */ 428 /* TB time in tb periods */
428 return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset, 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,19 +435,10 @@ uint32_t cpu_ppc_load_tbl (CPUState *env)
434 ppc_tb_t *tb_env = env->tb_env; 435 ppc_tb_t *tb_env = env->tb_env;
435 uint64_t tb; 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 #endif 443 #endif
452 444
@@ -458,7 +450,7 @@ uint32_t cpu_ppc_load_tbu (CPUState *env) @@ -458,7 +450,7 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
458 ppc_tb_t *tb_env = env->tb_env; 450 ppc_tb_t *tb_env = env->tb_env;
459 uint64_t tb; 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 #if defined(PPC_DEBUG_TB) 454 #if defined(PPC_DEBUG_TB)
463 if (loglevel != 0) { 455 if (loglevel != 0) {
464 fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb); 456 fprintf(logfile, "%s: tb=0x%016lx\n", __func__, tb);
@@ -468,32 +460,89 @@ uint32_t cpu_ppc_load_tbu (CPUState *env) @@ -468,32 +460,89 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
468 return tb >> 32; 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 - qemu_get_clock(vm_clock); 467 - qemu_get_clock(vm_clock);
475 #ifdef PPC_DEBUG_TB 468 #ifdef PPC_DEBUG_TB
476 if (loglevel != 0) { 469 if (loglevel != 0) {
477 fprintf(logfile, "%s: tb=0x%016lx offset=%08lx\n", __func__, value, 470 fprintf(logfile, "%s: tb=0x%016lx offset=%08lx\n", __func__, value,
478 - tb_env->tb_offset); 471 + *tb_offsetp);
479 } 472 }
480 #endif 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 void cpu_ppc_store_tbu (CPUState *env, uint32_t value) 486 void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
484 { 487 {
485 ppc_tb_t *tb_env = env->tb_env; 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 ppc_tb_t *tb_env = env->tb_env; 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 static inline uint32_t _cpu_ppc_load_decr (CPUState *env, uint64_t *next) 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,7 +664,6 @@ void cpu_loop (CPUSPARCState *env)
664 #endif 664 #endif
665 665
666 #ifdef TARGET_PPC 666 #ifdef TARGET_PPC
667 -  
668 static inline uint64_t cpu_ppc_get_tb (CPUState *env) 667 static inline uint64_t cpu_ppc_get_tb (CPUState *env)
669 { 668 {
670 /* TO FIX */ 669 /* TO FIX */
@@ -681,32 +680,19 @@ uint32_t cpu_ppc_load_tbu (CPUState *env) @@ -681,32 +680,19 @@ uint32_t cpu_ppc_load_tbu (CPUState *env)
681 return cpu_ppc_get_tb(env) >> 32; 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 uint32_t cpu_ppc601_load_rtcu (CPUState *env) 693 uint32_t cpu_ppc601_load_rtcu (CPUState *env)
703 __attribute__ (( alias ("cpu_ppc_load_tbu") )); 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 uint32_t cpu_ppc601_load_rtcl (CPUState *env) 696 uint32_t cpu_ppc601_load_rtcl (CPUState *env)
711 { 697 {
712 return cpu_ppc_load_tbl(env) & 0x3FFFFF80; 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,6 +625,10 @@ uint32_t cpu_ppc_load_tbl (CPUPPCState *env);
625 uint32_t cpu_ppc_load_tbu (CPUPPCState *env); 625 uint32_t cpu_ppc_load_tbu (CPUPPCState *env);
626 void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value); 626 void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value);
627 void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value); 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 uint32_t cpu_ppc_load_decr (CPUPPCState *env); 632 uint32_t cpu_ppc_load_decr (CPUPPCState *env);
629 void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value); 633 void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
630 #if defined(TARGET_PPC64H) 634 #if defined(TARGET_PPC64H)
@@ -798,8 +802,8 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val); @@ -798,8 +802,8 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
798 #define SPR_BOOKE_SPEFSCR (0x200) 802 #define SPR_BOOKE_SPEFSCR (0x200)
799 #define SPR_E500_BBEAR (0x201) 803 #define SPR_E500_BBEAR (0x201)
800 #define SPR_E500_BBTAR (0x202) 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 #define SPR_IBAT0U (0x210) 807 #define SPR_IBAT0U (0x210)
804 #define SPR_BOOKE_IVOR32 (0x210) 808 #define SPR_BOOKE_IVOR32 (0x210)
805 #define SPR_IBAT0L (0x211) 809 #define SPR_IBAT0L (0x211)
target-ppc/op.c
@@ -423,6 +423,18 @@ void OPPROTO op_load_tbu (void) @@ -423,6 +423,18 @@ void OPPROTO op_load_tbu (void)
423 RETURN(); 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 #if !defined(CONFIG_USER_ONLY) 438 #if !defined(CONFIG_USER_ONLY)
427 void OPPROTO op_store_tbl (void) 439 void OPPROTO op_store_tbl (void)
428 { 440 {
@@ -436,6 +448,18 @@ void OPPROTO op_store_tbu (void) @@ -436,6 +448,18 @@ void OPPROTO op_store_tbu (void)
436 RETURN(); 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 void OPPROTO op_load_decr (void) 463 void OPPROTO op_load_decr (void)
440 { 464 {
441 T0 = cpu_ppc_load_decr(env); 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,6 +162,18 @@ static void spr_read_tbu (void *opaque, int sprn)
162 gen_op_load_tbu(); 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 #if !defined(CONFIG_USER_ONLY) 177 #if !defined(CONFIG_USER_ONLY)
166 static void spr_write_tbl (void *opaque, int sprn) 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,6 +184,18 @@ static void spr_write_tbu (void *opaque, int sprn)
172 { 184 {
173 gen_op_store_tbu(); 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 #endif 199 #endif
176 200
177 #if !defined(CONFIG_USER_ONLY) 201 #if !defined(CONFIG_USER_ONLY)