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 [];
63static inline uint8_t ppc_read_byte(
const volatile void *src)
79static inline uint16_t ppc_read_half_word(
const volatile void *src)
95static inline uint32_t ppc_read_word(
const volatile void *src)
111static inline void ppc_write_byte(uint8_t value,
volatile void *dest)
116 :
"r" (value),
"b" (dest)
123static inline void ppc_write_half_word(uint16_t value,
volatile void *dest)
128 :
"r" (value),
"b" (dest)
135static inline void ppc_write_word(uint32_t value,
volatile void *dest)
139 :
"r" (value),
"b" (dest)
144static inline void *ppc_stack_pointer(
void)
156static inline void ppc_set_stack_pointer(
void *
sp)
165static inline void *ppc_link_register(
void)
177static inline void ppc_set_link_register(
void *lr)
186static inline uint32_t ppc_machine_state_register(
void)
198static inline void ppc_set_machine_state_register(uint32_t msr)
207static inline void ppc_synchronize_data(
void)
214static inline void ppc_light_weight_synchronize(
void)
221static inline void ppc_synchronize_instructions(
void)
228static inline void ppc_enforce_in_order_execution_of_io(
void)
235static inline void ppc_data_cache_block_flush(
void *addr)
245static inline void ppc_data_cache_block_flush_2(
253 :
"b" (base),
"r" (offset)
258static inline void ppc_data_cache_block_invalidate(
void *addr)
268static inline void ppc_data_cache_block_invalidate_2(
276 :
"b" (base),
"r" (offset)
281static inline void ppc_data_cache_block_store(
const void *addr)
290static inline void ppc_data_cache_block_store_2(
298 :
"b" (base),
"r" (offset)
302static inline void ppc_data_cache_block_touch(
const void *addr)
311static inline void ppc_data_cache_block_touch_2(
319 :
"b" (base),
"r" (offset)
323static inline void ppc_data_cache_block_touch_for_store(
const void *addr)
332static inline void ppc_data_cache_block_touch_for_store_2(
340 :
"b" (base),
"r" (offset)
344static inline void ppc_data_cache_block_clear_to_zero(
void *addr)
354static inline void ppc_data_cache_block_clear_to_zero_2(
362 :
"b" (base),
"r" (offset)
367static inline void ppc_instruction_cache_block_invalidate(
void *addr)
376static inline void ppc_instruction_cache_block_invalidate_2(
384 :
"b" (base),
"r" (offset)
394static 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)
416static inline void ppc_external_exceptions_disable(uint32_t msr)
418 ppc_set_machine_state_register(msr);
423static 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) )
500static 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 );
526static 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));
538static inline uint32_t ppc_decrementer_register(
void)
542 PPC_Get_decrementer(dec);
547static 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); \
759static inline uint32_t ppc_time_base(
void)
763 CPU_Get_timebase_low(val);
768static inline void ppc_set_time_base(uint32_t val)
773static inline uint32_t ppc_time_base_upper(
void)
778static inline void ppc_set_time_base_upper(uint32_t val)
783static inline uint64_t ppc_time_base_64(
void)
785 return PPC_Get_timebase_register();
788static inline void ppc_set_time_base_64(uint64_t val)
790 PPC_Set_timebase_register(val);
793static inline uint32_t ppc_alternate_time_base(
void)
798static inline uint32_t ppc_alternate_time_base_upper(
void)
803static 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);
818static inline uint32_t ppc_processor_id(
void)
823static inline void ppc_set_processor_id(uint32_t val)
828static inline uint32_t ppc_fsl_system_version(
void)
833static inline uint32_t ppc_fsl_system_version_cid(uint32_t svr)
835 return (svr >> 28) & 0xf;
838static inline uint32_t ppc_fsl_system_version_sid(uint32_t svr)
840 return (svr >> 16) & 0xfff;
843static inline uint32_t ppc_fsl_system_version_proc(uint32_t svr)
845 return (svr >> 12) & 0xf;
848static inline uint32_t ppc_fsl_system_version_mfg(uint32_t svr)
850 return (svr >> 8) & 0xf;
853static inline uint32_t ppc_fsl_system_version_mjrev(uint32_t svr)
855 return (svr >> 4) & 0xf;
858static inline uint32_t ppc_fsl_system_version_mnrev(uint32_t svr)
860 return (svr >> 0) & 0xf;
863void ppc_code_copy(
void *dest,
const void *src,
size_t n);
866void 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
891 ori \reg, \reg, (\addr)@
l
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
Interface to Kernel Print Methods.
uint32_t bsp_clicks_per_usec
Time base clicks per micro second.
Definition: bspstart.c:99
#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 PPC_SPECIAL_PURPOSE_REGISTER(spr)
Returns the value of the Special Purpose Register with number spr.
Definition: powerpc-utility.h:562
#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.
#define ra
return address */
Definition: regs.h:66
#define sp
stack-pointer */
Definition: regs.h:64
char _PPC_INTERRUPT_DISABLE_MASK[]
A global symbol used to disable interrupts in the MSR.
unsigned l
Definition: tte.h:13