37 #ifndef __LIBCPU_POWERPC_UTILITY_H 38 #define __LIBCPU_POWERPC_UTILITY_H 44 #include <rtems/score/cpu.h> 56 #include <libcpu/cpuIdent.h> 58 #define LINKER_SYMBOL(sym) extern char sym []; 63 static inline uint8_t ppc_read_byte(
const volatile void *src)
79 static inline uint16_t ppc_read_half_word(
const volatile void *src)
95 static inline uint32_t ppc_read_word(
const volatile void *src)
111 static inline void ppc_write_byte(uint8_t value,
volatile void *dest)
116 :
"r" (value),
"b" (dest)
123 static inline void ppc_write_half_word(uint16_t value,
volatile void *dest)
128 :
"r" (value),
"b" (dest)
135 static inline void ppc_write_word(uint32_t value,
volatile void *dest)
139 :
"r" (value),
"b" (dest)
144 static inline void *ppc_stack_pointer(
void)
156 static inline void ppc_set_stack_pointer(
void *
sp)
165 static inline void *ppc_link_register(
void)
177 static inline void ppc_set_link_register(
void *lr)
186 static inline uint32_t ppc_machine_state_register(
void)
198 static inline void ppc_set_machine_state_register(uint32_t msr)
207 static inline void ppc_synchronize_data(
void)
214 static inline void ppc_light_weight_synchronize(
void)
221 static inline void ppc_synchronize_instructions(
void)
228 static inline void ppc_enforce_in_order_execution_of_io(
void)
235 static inline void ppc_data_cache_block_flush(
void *addr)
245 static inline void ppc_data_cache_block_flush_2(
253 :
"b" (base),
"r" (offset)
258 static inline void ppc_data_cache_block_invalidate(
void *addr)
268 static inline void ppc_data_cache_block_invalidate_2(
276 :
"b" (base),
"r" (offset)
281 static inline void ppc_data_cache_block_store(
const void *addr)
290 static inline void ppc_data_cache_block_store_2(
298 :
"b" (base),
"r" (offset)
302 static inline void ppc_data_cache_block_touch(
const void *addr)
311 static inline void ppc_data_cache_block_touch_2(
319 :
"b" (base),
"r" (offset)
323 static inline void ppc_data_cache_block_touch_for_store(
const void *addr)
332 static inline void ppc_data_cache_block_touch_for_store_2(
340 :
"b" (base),
"r" (offset)
344 static inline void ppc_data_cache_block_clear_to_zero(
void *addr)
354 static inline void ppc_data_cache_block_clear_to_zero_2(
362 :
"b" (base),
"r" (offset)
367 static inline void ppc_instruction_cache_block_invalidate(
void *addr)
376 static inline void ppc_instruction_cache_block_invalidate_2(
384 :
"b" (base),
"r" (offset)
394 static inline uint32_t ppc_external_exceptions_enable(
void)
396 uint32_t current_msr;
403 "ori %1, %0, 0x8000;" 405 :
"=r" (current_msr),
"=r" (new_msr)
416 static inline void ppc_external_exceptions_disable(uint32_t msr)
418 ppc_set_machine_state_register(msr);
423 static inline uint32_t ppc_count_leading_zeros(uint32_t value)
441 #if defined(mpx8xx) || defined(mpc860) || defined(mpc821) 455 #define CPU_Get_timebase_low( _value ) \ 456 __asm__ volatile( "mftb %0" : "=r" (_value) ) 458 #define CPU_Get_timebase_low( _value ) \ 459 __asm__ volatile( "mfspr %0,268" : "=r" (_value) ) 465 #define rtems_bsp_delay( _microseconds ) \ 467 uint32_t start, ticks, now; \ 468 CPU_Get_timebase_low( start ) ; \ 469 ticks = (_microseconds) * bsp_clicks_per_usec; \ 471 CPU_Get_timebase_low( now ) ; \ 472 while (now - start < ticks); \ 475 #define rtems_bsp_delay_in_bus_cycles( _cycles ) \ 477 uint32_t start, now; \ 478 CPU_Get_timebase_low( start ); \ 480 CPU_Get_timebase_low( now ); \ 481 while (now - start < (_cycles)); \ 488 #define PPC_Set_decrementer( _clicks ) \ 490 __asm__ volatile( "mtdec %0" : : "r" ((_clicks)) ); \ 493 #define PPC_Get_decrementer( _clicks ) \ 494 __asm__ volatile( "mfdec %0" : "=r" (_clicks) ) 500 static inline uint64_t PPC_Get_timebase_register(
void )
504 uint32_t tbr_high_old;
508 #if defined(mpx8xx) || defined(mpc860) || defined(mpc821) 510 __asm__ volatile(
"mftbu %0" :
"=r" (tbr_high_old));
511 __asm__ volatile(
"mftb %0" :
"=r" (tbr_low));
512 __asm__ volatile(
"mftbu %0" :
"=r" (tbr_high));
514 __asm__ volatile(
"mfspr %0, 269" :
"=r" (tbr_high_old));
515 __asm__ volatile(
"mfspr %0, 268" :
"=r" (tbr_low));
516 __asm__ volatile(
"mfspr %0, 269" :
"=r" (tbr_high));
518 }
while ( tbr_high_old != tbr_high );
526 static inline void PPC_Set_timebase_register (uint64_t tbr)
531 tbr_low = (uint32_t) tbr;
532 tbr_high = (uint32_t) (tbr >> 32);
533 __asm__ volatile(
"mtspr 284, %0" : :
"r" (tbr_low));
534 __asm__ volatile(
"mtspr 285, %0" : :
"r" (tbr_high));
538 static inline uint32_t ppc_decrementer_register(
void)
542 PPC_Get_decrementer(dec);
547 static inline void ppc_set_decrementer_register(uint32_t dec)
549 PPC_Set_decrementer(dec);
555 #define PPC_STRINGOF(x) #x 562 #define PPC_SPECIAL_PURPOSE_REGISTER(spr) \ 566 "mfspr %0, " PPC_STRINGOF(spr) \ 576 #define PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val) \ 579 "mtspr " PPC_STRINGOF(spr) ", %0" \ 591 #define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \ 595 uint32_t mybits = bits; \ 596 _ISR_Local_disable(level); \ 597 val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \ 599 PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \ 600 _ISR_Local_enable(level); \ 610 #define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED(spr, bits, mask) \ 614 uint32_t mybits = bits; \ 615 uint32_t mymask = mask; \ 616 _ISR_Local_disable(level); \ 617 val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \ 620 PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \ 621 _ISR_Local_enable(level); \ 630 #define PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \ 634 uint32_t mybits = bits; \ 635 _ISR_Local_disable(level); \ 636 val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \ 638 PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \ 639 _ISR_Local_enable(level); \ 647 #define PPC_THREAD_MGMT_REGISTER(tmr) \ 651 "mftmr %0, " PPC_STRINGOF(tmr) \ 661 #define PPC_SET_THREAD_MGMT_REGISTER(tmr, val) \ 664 "mttmr " PPC_STRINGOF(tmr) ", %0" \ 677 #define PPC_DEVICE_CONTROL_REGISTER(dcr) \ 681 "mfdcr %0, " PPC_STRINGOF(dcr) \ 693 #define PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val) \ 696 "mtdcr " PPC_STRINGOF(dcr) ", %0" \ 708 #define PPC_SET_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \ 712 uint32_t mybits = bits; \ 713 _ISR_Local_disable(level); \ 714 val = PPC_DEVICE_CONTROL_REGISTER(dcr); \ 716 PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \ 717 _ISR_Local_enable(level); \ 727 #define PPC_SET_DEVICE_CONTROL_REGISTER_BITS_MASKED(dcr, bits, mask) \ 731 uint32_t mybits = bits; \ 732 uint32_t mymask = mask; \ 733 _ISR_Local_disable(level); \ 734 val = PPC_DEVICE_CONTROL_REGISTER(dcr); \ 737 PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \ 738 _ISR_Local_enable(level); \ 747 #define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \ 751 uint32_t mybits = bits; \ 752 _ISR_Local_disable(level); \ 753 val = PPC_DEVICE_CONTROL_REGISTER(dcr); \ 755 PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \ 756 _ISR_Local_enable(level); \ 759 static inline uint32_t ppc_time_base(
void)
763 CPU_Get_timebase_low(val);
768 static inline void ppc_set_time_base(uint32_t val)
773 static inline uint32_t ppc_time_base_upper(
void)
778 static inline void ppc_set_time_base_upper(uint32_t val)
783 static inline uint64_t ppc_time_base_64(
void)
785 return PPC_Get_timebase_register();
788 static inline void ppc_set_time_base_64(uint64_t val)
790 PPC_Set_timebase_register(val);
793 static inline uint32_t ppc_alternate_time_base(
void)
798 static inline uint32_t ppc_alternate_time_base_upper(
void)
803 static inline uint64_t ppc_alternate_time_base_64(
void)
810 atbu_0 = ppc_alternate_time_base_upper();
811 atbl = ppc_alternate_time_base();
812 atbu_1 = ppc_alternate_time_base_upper();
813 }
while (atbu_0 != atbu_1);
815 return (((uint64_t) atbu_1) << 32) | ((uint64_t) atbl);
818 static inline uint32_t ppc_processor_id(
void)
823 static inline void ppc_set_processor_id(uint32_t val)
828 static inline uint32_t ppc_fsl_system_version(
void)
833 static inline uint32_t ppc_fsl_system_version_cid(uint32_t svr)
835 return (svr >> 28) & 0xf;
838 static inline uint32_t ppc_fsl_system_version_sid(uint32_t svr)
840 return (svr >> 16) & 0xfff;
843 static inline uint32_t ppc_fsl_system_version_proc(uint32_t svr)
845 return (svr >> 12) & 0xf;
848 static inline uint32_t ppc_fsl_system_version_mfg(uint32_t svr)
850 return (svr >> 8) & 0xf;
853 static inline uint32_t ppc_fsl_system_version_mjrev(uint32_t svr)
855 return (svr >> 4) & 0xf;
858 static inline uint32_t ppc_fsl_system_version_mnrev(uint32_t svr)
860 return (svr >> 0) & 0xf;
863 void ppc_code_copy(
void *dest,
const void *src,
size_t n);
866 void printBAT(
int bat, uint32_t upper, uint32_t lower);
874 #include <rtems/asm.h> 877 #if defined(__powerpc64__) 878 lis \reg, (\addr)@highest
879 ori \reg, \reg, (\addr)@higher
880 rldicr \reg, \reg, 32, 31
881 oris \reg, \reg, (\addr)@h
882 ori \reg, \reg, (\addr)@
l 885 ori \reg, \reg, (\addr)@
l 889 .macro LA32 reg, addr
891 ori \reg, \reg, (\addr)@
l 894 .macro LWI reg, value
896 ori \reg, \reg, (\value)@
l 901 lwz \reg, \addr@
l(\reg)
909 .macro TSTBITS reg1, reg2, mask
911 and \reg1, \reg1, \reg2
915 .macro SETBITS reg1, reg2, mask
917 or \reg1, \reg1, \reg2
920 .macro CLRBITS reg1, reg2, mask
922 andc \reg1, \reg1, \reg2
925 .macro GLOBAL_FUNCTION name
927 .type \name, @function
934 .macro GET_INTERRUPT_MASK mask
943 .macro INTERRUPT_DISABLE level, mask
945 GET_INTERRUPT_MASK mask=\mask
946 andc \mask, \level, \mask
953 .macro INTERRUPT_ENABLE level
957 .macro SET_SELF_CPU_CONTROL reg_0, reg_1
958 #if defined(RTEMS_SMP) 961 slwi \reg_0, \reg_0, PER_CPU_CONTROL_SIZE_LOG2
962 #if defined(__powerpc64__) 963 LA \reg_1, _Per_CPU_Information
964 add \reg_0, \reg_0, \reg_1
966 addis \reg_0, \reg_0, _Per_CPU_Information@ha
967 addi \reg_0, \reg_0, _Per_CPU_Information@
l 969 mtspr PPC_PER_CPU_CONTROL_REGISTER, \reg_0
973 .macro GET_SELF_CPU_CONTROL reg
974 #if defined(RTEMS_SMP) 975 mfspr \reg, PPC_PER_CPU_CONTROL_REGISTER
977 lis \reg, _Per_CPU_Information@h
978 ori \reg, \reg, _Per_CPU_Information@
l 982 .macro SHIFT_RIGHT_IMMEDIATE rd, rs, imm
983 #if defined(__powerpc64__) 990 .macro COMPARE_LOGICAL cr,
ra, rb
991 #if defined(__powerpc64__) 998 .macro CLEAR_RIGHT_IMMEDIATE rd, rs, imm
999 #if defined(__powerpc64__) 1000 clrrdi \rd, \rs, \imm
1002 clrrwi \rd, \rs, \imm
1006 #define LINKER_SYMBOL(sym) .extern sym
#define sp
stack-pointer */
Definition: regs.h:64
#define PPC_SPECIAL_PURPOSE_REGISTER(spr)
Returns the value of the Special Purpose Register with number spr.
Definition: powerpc-utility.h:562
#define PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val)
Sets the Special Purpose Register with number spr to the value in val.
Definition: powerpc-utility.h:576
#define RTEMS_COMPILER_MEMORY_BARRIER()
Definition: basedefs.h:77
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
char _PPC_INTERRUPT_DISABLE_MASK[]
A global symbol used to disable interrupts in the MSR.
Interface to Kernel Print Methods.
unsigned l
Definition: tte.h:86
uint32_t bsp_clicks_per_usec
Time base clicks per micro second.
Definition: bspstart.c:99
#define ra
return address */
Definition: regs.h:66