50#ifndef __LIBCPU_POWERPC_UTILITY_H
51#define __LIBCPU_POWERPC_UTILITY_H
57#include <rtems/score/cpu.h>
69#include <libcpu/cpuIdent.h>
71#define LINKER_SYMBOL(sym) extern char sym [];
76static inline uint8_t ppc_read_byte(
const volatile void *src)
92static inline uint16_t ppc_read_half_word(
const volatile void *src)
108static inline uint32_t ppc_read_word(
const volatile void *src)
124static inline void ppc_write_byte(uint8_t value,
volatile void *dest)
129 :
"r" (value),
"b" (dest)
136static inline void ppc_write_half_word(uint16_t value,
volatile void *dest)
141 :
"r" (value),
"b" (dest)
148static inline void ppc_write_word(uint32_t value,
volatile void *dest)
152 :
"r" (value),
"b" (dest)
157static inline void *ppc_stack_pointer(
void)
169static inline void ppc_set_stack_pointer(
void *
sp)
178static inline void *ppc_link_register(
void)
190static inline void ppc_set_link_register(
void *lr)
199static inline uint32_t ppc_machine_state_register(
void)
211static inline void ppc_set_machine_state_register(uint32_t msr)
220static inline void ppc_synchronize_data(
void)
227static inline void ppc_light_weight_synchronize(
void)
234static inline void ppc_synchronize_instructions(
void)
241static inline void ppc_enforce_in_order_execution_of_io(
void)
246 ".machine \"push\"\n"
253static inline void ppc_data_cache_block_flush(
void *addr)
263static inline void ppc_data_cache_block_flush_2(
271 :
"b" (base),
"r" (offset)
276static inline void ppc_data_cache_block_invalidate(
void *addr)
286static inline void ppc_data_cache_block_invalidate_2(
294 :
"b" (base),
"r" (offset)
299static inline void ppc_data_cache_block_store(
const void *addr)
308static inline void ppc_data_cache_block_store_2(
316 :
"b" (base),
"r" (offset)
320static inline void ppc_data_cache_block_touch(
const void *addr)
329static inline void ppc_data_cache_block_touch_2(
337 :
"b" (base),
"r" (offset)
341static inline void ppc_data_cache_block_touch_for_store(
const void *addr)
350static inline void ppc_data_cache_block_touch_for_store_2(
358 :
"b" (base),
"r" (offset)
362static inline void ppc_data_cache_block_clear_to_zero(
void *addr)
372static inline void ppc_data_cache_block_clear_to_zero_2(
380 :
"b" (base),
"r" (offset)
385static inline void ppc_instruction_cache_block_invalidate(
void *addr)
394static inline void ppc_instruction_cache_block_invalidate_2(
402 :
"b" (base),
"r" (offset)
412static inline uint32_t ppc_external_exceptions_enable(
void)
414 uint32_t current_msr;
421 "ori %1, %0, 0x8000;"
423 :
"=r" (current_msr),
"=r" (new_msr)
434static inline void ppc_external_exceptions_disable(uint32_t msr)
436 ppc_set_machine_state_register(msr);
441static inline uint32_t ppc_count_leading_zeros(uint32_t value)
459#if defined(mpx8xx) || defined(mpc860) || defined(mpc821)
473#define CPU_Get_timebase_low( _value ) \
474 __asm__ volatile( "mftb %0" : "=r" (_value) )
476#define CPU_Get_timebase_low( _value ) \
477 __asm__ volatile( "mfspr %0,268" : "=r" (_value) )
483#define rtems_bsp_delay( _microseconds ) \
485 uint32_t start, ticks, now; \
486 CPU_Get_timebase_low( start ) ; \
487 ticks = (_microseconds) * bsp_clicks_per_usec; \
489 CPU_Get_timebase_low( now ) ; \
490 while (now - start < ticks); \
493#define rtems_bsp_delay_in_bus_cycles( _cycles ) \
495 uint32_t start, now; \
496 CPU_Get_timebase_low( start ); \
498 CPU_Get_timebase_low( now ); \
499 while (now - start < (_cycles)); \
506#define PPC_Set_decrementer( _clicks ) \
508 __asm__ volatile( "mtdec %0" : : "r" ((_clicks)) ); \
511#define PPC_Get_decrementer( _clicks ) \
512 __asm__ volatile( "mfdec %0" : "=r" (_clicks) )
518static inline uint64_t PPC_Get_timebase_register(
void )
522 uint32_t tbr_high_old;
526#if defined(mpx8xx) || defined(mpc860) || defined(mpc821)
528 __asm__ volatile(
"mftbu %0" :
"=r" (tbr_high_old));
529 __asm__ volatile(
"mftb %0" :
"=r" (tbr_low));
530 __asm__ volatile(
"mftbu %0" :
"=r" (tbr_high));
532 __asm__ volatile(
"mfspr %0, 269" :
"=r" (tbr_high_old));
533 __asm__ volatile(
"mfspr %0, 268" :
"=r" (tbr_low));
534 __asm__ volatile(
"mfspr %0, 269" :
"=r" (tbr_high));
536 }
while ( tbr_high_old != tbr_high );
544static inline void PPC_Set_timebase_register (uint64_t tbr)
549 tbr_low = (uint32_t) tbr;
550 tbr_high = (uint32_t) (tbr >> 32);
551 __asm__ volatile(
"mtspr 284, %0" : :
"r" (tbr_low));
552 __asm__ volatile(
"mtspr 285, %0" : :
"r" (tbr_high));
556static inline uint32_t ppc_decrementer_register(
void)
560 PPC_Get_decrementer(dec);
565static inline void ppc_set_decrementer_register(uint32_t dec)
567 PPC_Set_decrementer(dec);
573#define PPC_STRINGOF(x) #x
580#define PPC_SPECIAL_PURPOSE_REGISTER(spr, val) \
582 "mfspr %0, " PPC_STRINGOF(spr) \
590#define PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val) \
593 "mtspr " PPC_STRINGOF(spr) ", %0" \
605#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
609 uint32_t mybits = bits; \
610 _ISR_Local_disable(level); \
611 PPC_SPECIAL_PURPOSE_REGISTER(spr, val); \
613 PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
614 _ISR_Local_enable(level); \
624#define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED(spr, bits, mask) \
628 uint32_t mybits = bits; \
629 uint32_t mymask = mask; \
630 _ISR_Local_disable(level); \
631 PPC_SPECIAL_PURPOSE_REGISTER(spr, val); \
634 PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
635 _ISR_Local_enable(level); \
644#define PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
648 uint32_t mybits = bits; \
649 _ISR_Local_disable(level); \
650 PPC_SPECIAL_PURPOSE_REGISTER(spr, val); \
652 PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
653 _ISR_Local_enable(level); \
661#define PPC_THREAD_MGMT_REGISTER(tmr) \
665 "mftmr %0, " PPC_STRINGOF(tmr) \
675#define PPC_SET_THREAD_MGMT_REGISTER(tmr, val) \
678 "mttmr " PPC_STRINGOF(tmr) ", %0" \
691#define PPC_DEVICE_CONTROL_REGISTER(dcr) \
695 "mfdcr %0, " PPC_STRINGOF(dcr) \
707#define PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val) \
710 "mtdcr " PPC_STRINGOF(dcr) ", %0" \
722#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
726 uint32_t mybits = bits; \
727 _ISR_Local_disable(level); \
728 val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
730 PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
731 _ISR_Local_enable(level); \
741#define PPC_SET_DEVICE_CONTROL_REGISTER_BITS_MASKED(dcr, bits, mask) \
745 uint32_t mybits = bits; \
746 uint32_t mymask = mask; \
747 _ISR_Local_disable(level); \
748 val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
751 PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
752 _ISR_Local_enable(level); \
761#define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
765 uint32_t mybits = bits; \
766 _ISR_Local_disable(level); \
767 val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
769 PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
770 _ISR_Local_enable(level); \
773static inline uint32_t ppc_time_base(
void)
777 CPU_Get_timebase_low(val);
782static inline void ppc_set_time_base(uint32_t val)
787static inline uint32_t ppc_time_base_upper(
void)
794static inline void ppc_set_time_base_upper(uint32_t val)
799static inline uint64_t ppc_time_base_64(
void)
801 return PPC_Get_timebase_register();
804static inline void ppc_set_time_base_64(uint64_t val)
806 PPC_Set_timebase_register(val);
809static inline uint32_t ppc_alternate_time_base(
void)
816static inline uint32_t ppc_alternate_time_base_upper(
void)
823static inline uint64_t ppc_alternate_time_base_64(
void)
830 atbu_0 = ppc_alternate_time_base_upper();
831 atbl = ppc_alternate_time_base();
832 atbu_1 = ppc_alternate_time_base_upper();
833 }
while (atbu_0 != atbu_1);
835 return (((uint64_t) atbu_1) << 32) | ((uint64_t) atbl);
838static inline uint32_t ppc_processor_id(
void)
845static inline void ppc_set_processor_id(uint32_t val)
850static inline uint32_t ppc_fsl_system_version(
void)
857static inline uint32_t ppc_fsl_system_version_cid(uint32_t svr)
859 return (svr >> 28) & 0xf;
862static inline uint32_t ppc_fsl_system_version_sid(uint32_t svr)
864 return (svr >> 16) & 0xfff;
867static inline uint32_t ppc_fsl_system_version_proc(uint32_t svr)
869 return (svr >> 12) & 0xf;
872static inline uint32_t ppc_fsl_system_version_mfg(uint32_t svr)
874 return (svr >> 8) & 0xf;
877static inline uint32_t ppc_fsl_system_version_mjrev(uint32_t svr)
879 return (svr >> 4) & 0xf;
882static inline uint32_t ppc_fsl_system_version_mnrev(uint32_t svr)
884 return (svr >> 0) & 0xf;
887static inline void ppc_msync(
void)
900static inline void ppc_tlbre(
void)
913static inline void ppc_tlbwe(
void)
926static inline void ppc_tlbsx(
void *addr)
939static inline void ppc_mtivpr(
void *prefix)
951#define ppc_mtivor(x, vec) __asm__ volatile ( \
954 "mtivor" RTEMS_XSTRING(x) " %0\n" \
960void ppc_code_copy(
void *dest,
const void *src,
size_t n);
963void printBAT(
int bat, uint32_t upper, uint32_t lower);
971#include <rtems/asm.h>
974#if defined(__powerpc64__)
975 lis \reg, (\addr)@highest
976 ori \reg, \reg, (\addr)@higher
977 rldicr \reg, \reg, 32, 31
978 oris \reg, \reg, (\addr)@h
979 ori \reg, \reg, (\addr)@
l
982 ori \reg, \reg, (\addr)@
l
988 ori \reg, \reg, (\addr)@
l
993 ori \reg, \reg, (\value)@
l
998 lwz \reg, \addr@
l(\reg)
1006.macro TSTBITS reg1, reg2, mask
1008 and \reg1, \reg1, \reg2
1012.macro SETBITS reg1, reg2, mask
1014 or \reg1, \reg1, \reg2
1017.macro CLRBITS reg1, reg2, mask
1019 andc \reg1, \reg1, \reg2
1022.macro GLOBAL_FUNCTION name
1024 .type \name, @function
1031.macro GET_INTERRUPT_MASK mask
1040.macro INTERRUPT_DISABLE level, mask
1042 GET_INTERRUPT_MASK mask=\mask
1043 andc \mask, \level, \mask
1050.macro INTERRUPT_ENABLE level
1054.macro SET_SELF_CPU_CONTROL reg_0, reg_1
1055#if defined(RTEMS_SMP)
1058 slwi \reg_0, \reg_0, PER_CPU_CONTROL_SIZE_LOG2
1059#if defined(__powerpc64__)
1061 add \reg_0, \reg_0, \reg_1
1066 mtspr PPC_PER_CPU_CONTROL_REGISTER, \reg_0
1070.macro GET_SELF_CPU_CONTROL reg
1071#if defined(RTEMS_SMP)
1072 mfspr \reg, PPC_PER_CPU_CONTROL_REGISTER
1079.macro SHIFT_RIGHT_IMMEDIATE rd, rs, imm
1080#if defined(__powerpc64__)
1087.macro COMPARE_LOGICAL cr,
ra, rb
1088#if defined(__powerpc64__)
1095.macro CLEAR_RIGHT_IMMEDIATE rd, rs, imm
1096#if defined(__powerpc64__)
1097 clrrdi \rd, \rs, \imm
1099 clrrwi \rd, \rs, \imm
1103#define LINKER_SYMBOL(sym) .extern sym
This header file provides the kernel character input/output support API.
#define RTEMS_COMPILER_MEMORY_BARRIER()
This macro forbids the compiler to reorder read and write commands around it.
Definition: basedefs.h:258
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:590
#define PPC_SPECIAL_PURPOSE_REGISTER(spr, val)
Returns the value of the Special Purpose Register with number spr.
Definition: powerpc-utility.h:580
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
CPU_STRUCTURE_ALIGNMENT Per_CPU_Control_envelope _Per_CPU_Information[]
Set of Per CPU Core Information.
Definition: asm.h:171
#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.
This header file defines the RTEMS Classic API.
unsigned l
Definition: tte.h:13