RTEMS  5.1
powerpc-utility.h
Go to the documentation of this file.
1 
10 /*
11  * Copyright (c) 2008-2015 embedded brains GmbH.
12  *
13  * embedded brains GmbH
14  * Dornierstr. 4
15  * 82178 Puchheim
16  * Germany
17  * <rtems@embedded-brains.de>
18  *
19  * access function for Device Control Registers inspired by "ppc405common.h"
20  * from Michael Hamel ADInstruments May 2008
21  *
22  * The license and distribution terms for this file may be
23  * found in the file LICENSE in this distribution or at
24  * http://www.rtems.org/license/LICENSE.
25  */
26 
37 #ifndef __LIBCPU_POWERPC_UTILITY_H
38 #define __LIBCPU_POWERPC_UTILITY_H
39 
40 #if !defined(ASM)
41  #include <rtems.h>
42 #endif
43 
44 #include <rtems/score/cpu.h>
46 #include <rtems/powerpc/powerpc.h>
47 
48 #ifdef __cplusplus
49 extern "C" {
50 #endif
51 
52 #if !defined(ASM)
53 
54 #include <rtems/bspIo.h>
55 
56 #include <libcpu/cpuIdent.h>
57 
58 #define LINKER_SYMBOL(sym) extern char sym [];
59 
63 static inline uint8_t ppc_read_byte(const volatile void *src)
64 {
65  uint8_t value;
66 
67  __asm__ volatile (
68  "lbz %0, 0(%1)"
69  : "=r" (value)
70  : "b" (src)
71  );
72 
73  return value;
74 }
75 
79 static inline uint16_t ppc_read_half_word(const volatile void *src)
80 {
81  uint16_t value;
82 
83  __asm__ volatile (
84  "lhz %0, 0(%1)"
85  : "=r" (value)
86  : "b" (src)
87  );
88 
89  return value;
90 }
91 
95 static inline uint32_t ppc_read_word(const volatile void *src)
96 {
97  uint32_t value;
98 
99  __asm__ volatile (
100  "lwz %0, 0(%1)"
101  : "=r" (value)
102  : "b" (src)
103  );
104 
105  return value;
106 }
107 
111 static inline void ppc_write_byte(uint8_t value, volatile void *dest)
112 {
113  __asm__ volatile (
114  "stb %0, 0(%1)"
115  :
116  : "r" (value), "b" (dest)
117  );
118 }
119 
123 static inline void ppc_write_half_word(uint16_t value, volatile void *dest)
124 {
125  __asm__ volatile (
126  "sth %0, 0(%1)"
127  :
128  : "r" (value), "b" (dest)
129  );
130 }
131 
135 static inline void ppc_write_word(uint32_t value, volatile void *dest)
136 {
137  __asm__ volatile (
138  "stw %0, 0(%1)" :
139  : "r" (value), "b" (dest)
140  );
141 }
142 
143 
144 static inline void *ppc_stack_pointer(void)
145 {
146  void *sp;
147 
148  __asm__ volatile (
149  "mr %0, 1"
150  : "=r" (sp)
151  );
152 
153  return sp;
154 }
155 
156 static inline void ppc_set_stack_pointer(void *sp)
157 {
158  __asm__ volatile (
159  "mr 1, %0"
160  :
161  : "r" (sp)
162  );
163 }
164 
165 static inline void *ppc_link_register(void)
166 {
167  void *lr;
168 
169  __asm__ volatile (
170  "mflr %0"
171  : "=r" (lr)
172  );
173 
174  return lr;
175 }
176 
177 static inline void ppc_set_link_register(void *lr)
178 {
179  __asm__ volatile (
180  "mtlr %0"
181  :
182  : "r" (lr)
183  );
184 }
185 
186 static inline uint32_t ppc_machine_state_register(void)
187 {
188  uint32_t msr;
189 
190  __asm__ volatile (
191  "mfmsr %0"
192  : "=r" (msr)
193  );
194 
195  return msr;
196 }
197 
198 static inline void ppc_set_machine_state_register(uint32_t msr)
199 {
200  __asm__ volatile (
201  "mtmsr %0"
202  :
203  : "r" (msr)
204  );
205 }
206 
207 static inline void ppc_synchronize_data(void)
208 {
210 
211  __asm__ volatile ("sync");
212 }
213 
214 static inline void ppc_light_weight_synchronize(void)
215 {
217 
218  __asm__ volatile ("lwsync");
219 }
220 
221 static inline void ppc_synchronize_instructions(void)
222 {
224 
225  __asm__ volatile ("isync");
226 }
227 
228 static inline void ppc_enforce_in_order_execution_of_io(void)
229 {
231 
232  __asm__ volatile ("eieio");
233 }
234 
235 static inline void ppc_data_cache_block_flush(void *addr)
236 {
237  __asm__ volatile (
238  "dcbf 0, %0"
239  :
240  : "r" (addr)
241  : "memory"
242  );
243 }
244 
245 static inline void ppc_data_cache_block_flush_2(
246  void *base,
247  uintptr_t offset
248 )
249 {
250  __asm__ volatile (
251  "dcbf %0, %1"
252  :
253  : "b" (base), "r" (offset)
254  : "memory"
255  );
256 }
257 
258 static inline void ppc_data_cache_block_invalidate(void *addr)
259 {
260  __asm__ volatile (
261  "dcbi 0, %0"
262  :
263  : "r" (addr)
264  : "memory"
265  );
266 }
267 
268 static inline void ppc_data_cache_block_invalidate_2(
269  void *base,
270  uintptr_t offset
271 )
272 {
273  __asm__ volatile (
274  "dcbi %0, %1"
275  :
276  : "b" (base), "r" (offset)
277  : "memory"
278  );
279 }
280 
281 static inline void ppc_data_cache_block_store(const void *addr)
282 {
283  __asm__ volatile (
284  "dcbst 0, %0"
285  :
286  : "r" (addr)
287  );
288 }
289 
290 static inline void ppc_data_cache_block_store_2(
291  const void *base,
292  uintptr_t offset
293 )
294 {
295  __asm__ volatile (
296  "dcbst %0, %1"
297  :
298  : "b" (base), "r" (offset)
299  );
300 }
301 
302 static inline void ppc_data_cache_block_touch(const void *addr)
303 {
304  __asm__ volatile (
305  "dcbt 0, %0"
306  :
307  : "r" (addr)
308  );
309 }
310 
311 static inline void ppc_data_cache_block_touch_2(
312  const void *base,
313  uintptr_t offset
314 )
315 {
316  __asm__ volatile (
317  "dcbt %0, %1"
318  :
319  : "b" (base), "r" (offset)
320  );
321 }
322 
323 static inline void ppc_data_cache_block_touch_for_store(const void *addr)
324 {
325  __asm__ volatile (
326  "dcbtst 0, %0"
327  :
328  : "r" (addr)
329  );
330 }
331 
332 static inline void ppc_data_cache_block_touch_for_store_2(
333  const void *base,
334  uintptr_t offset
335 )
336 {
337  __asm__ volatile (
338  "dcbtst %0, %1"
339  :
340  : "b" (base), "r" (offset)
341  );
342 }
343 
344 static inline void ppc_data_cache_block_clear_to_zero(void *addr)
345 {
346  __asm__ volatile (
347  "dcbz 0, %0"
348  :
349  : "r" (addr)
350  : "memory"
351  );
352 }
353 
354 static inline void ppc_data_cache_block_clear_to_zero_2(
355  void *base,
356  uintptr_t offset
357 )
358 {
359  __asm__ volatile (
360  "dcbz %0, %1"
361  :
362  : "b" (base), "r" (offset)
363  : "memory"
364  );
365 }
366 
367 static inline void ppc_instruction_cache_block_invalidate(void *addr)
368 {
369  __asm__ volatile (
370  "icbi 0, %0"
371  :
372  : "r" (addr)
373  );
374 }
375 
376 static inline void ppc_instruction_cache_block_invalidate_2(
377  void *base,
378  uintptr_t offset
379 )
380 {
381  __asm__ volatile (
382  "icbi %0, %1"
383  :
384  : "b" (base), "r" (offset)
385  );
386 }
387 
394 static inline uint32_t ppc_external_exceptions_enable(void)
395 {
396  uint32_t current_msr;
397  uint32_t new_msr;
398 
400 
401  __asm__ volatile (
402  "mfmsr %0;"
403  "ori %1, %0, 0x8000;"
404  "mtmsr %1"
405  : "=r" (current_msr), "=r" (new_msr)
406  );
407 
408  return current_msr;
409 }
410 
416 static inline void ppc_external_exceptions_disable(uint32_t msr)
417 {
418  ppc_set_machine_state_register(msr);
419 
421 }
422 
423 static inline uint32_t ppc_count_leading_zeros(uint32_t value)
424 {
425  uint32_t count;
426 
427  __asm__ (
428  "cntlzw %0, %1;"
429  : "=r" (count)
430  : "r" (value)
431  );
432 
433  return count;
434 }
435 
436 /*
437  * Simple spin delay in microsecond units for device drivers.
438  * This is very dependent on the clock speed of the target.
439  */
440 
441 #if defined(mpx8xx) || defined(mpc860) || defined(mpc821)
442 /* Wonderful bookE doesn't have mftb/mftbu; they only
443  * define the TBRU/TBRL SPRs so we use these. Luckily,
444  * we run in supervisory mode so that should work on
445  * all CPUs. In user mode we'd have a problem...
446  * 2007/11/30, T.S.
447  *
448  * OTOH, PSIM currently lacks support for reading
449  * SPRs 268/269. You need GDB patch sim/2376 to avoid
450  * a crash...
451  * OTOH, the MPC8xx do not allow to read the timebase registers via mfspr.
452  * we NEED a mftb to access the time base.
453  * 2009/10/30 Th. D.
454  */
455 #define CPU_Get_timebase_low( _value ) \
456  __asm__ volatile( "mftb %0" : "=r" (_value) )
457 #else
458 #define CPU_Get_timebase_low( _value ) \
459  __asm__ volatile( "mfspr %0,268" : "=r" (_value) )
460 #endif
461 
462 /* Must be provided for rtems_bsp_delay to work */
463 extern uint32_t bsp_clicks_per_usec;
464 
465 #define rtems_bsp_delay( _microseconds ) \
466  do { \
467  uint32_t start, ticks, now; \
468  CPU_Get_timebase_low( start ) ; \
469  ticks = (_microseconds) * bsp_clicks_per_usec; \
470  do \
471  CPU_Get_timebase_low( now ) ; \
472  while (now - start < ticks); \
473  } while (0)
474 
475 #define rtems_bsp_delay_in_bus_cycles( _cycles ) \
476  do { \
477  uint32_t start, now; \
478  CPU_Get_timebase_low( start ); \
479  do \
480  CPU_Get_timebase_low( now ); \
481  while (now - start < (_cycles)); \
482  } while (0)
483 
484 /*
485  * Routines to access the decrementer register
486  */
487 
488 #define PPC_Set_decrementer( _clicks ) \
489  do { \
490  __asm__ volatile( "mtdec %0" : : "r" ((_clicks)) ); \
491  } while (0)
492 
493 #define PPC_Get_decrementer( _clicks ) \
494  __asm__ volatile( "mfdec %0" : "=r" (_clicks) )
495 
496 /*
497  * Routines to access the time base register
498  */
499 
500 static inline uint64_t PPC_Get_timebase_register( void )
501 {
502  uint32_t tbr_low;
503  uint32_t tbr_high;
504  uint32_t tbr_high_old;
505  uint64_t tbr;
506 
507  do {
508 #if defined(mpx8xx) || defined(mpc860) || defined(mpc821)
509 /* See comment above (CPU_Get_timebase_low) */
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));
513 #else
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));
517 #endif
518  } while ( tbr_high_old != tbr_high );
519 
520  tbr = tbr_high;
521  tbr <<= 32;
522  tbr |= tbr_low;
523  return tbr;
524 }
525 
526 static inline void PPC_Set_timebase_register (uint64_t tbr)
527 {
528  uint32_t tbr_low;
529  uint32_t tbr_high;
530 
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));
535 
536 }
537 
538 static inline uint32_t ppc_decrementer_register(void)
539 {
540  uint32_t dec;
541 
542  PPC_Get_decrementer(dec);
543 
544  return dec;
545 }
546 
547 static inline void ppc_set_decrementer_register(uint32_t dec)
548 {
549  PPC_Set_decrementer(dec);
550 }
551 
555 #define PPC_STRINGOF(x) #x
556 
562 #define PPC_SPECIAL_PURPOSE_REGISTER(spr) \
563  ({ \
564  uint32_t val; \
565  __asm__ volatile (\
566  "mfspr %0, " PPC_STRINGOF(spr) \
567  : "=r" (val) \
568  ); \
569  val;\
570  } )
571 
576 #define PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val) \
577  do { \
578  __asm__ volatile (\
579  "mtspr " PPC_STRINGOF(spr) ", %0" \
580  : \
581  : "r" (val) \
582  ); \
583  } while (0)
584 
591 #define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
592  do { \
593  ISR_Level level; \
594  uint32_t val; \
595  uint32_t mybits = bits; \
596  _ISR_Local_disable(level); \
597  val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
598  val |= mybits; \
599  PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
600  _ISR_Local_enable(level); \
601  } while (0)
602 
610 #define PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS_MASKED(spr, bits, mask) \
611  do { \
612  ISR_Level level; \
613  uint32_t val; \
614  uint32_t mybits = bits; \
615  uint32_t mymask = mask; \
616  _ISR_Local_disable(level); \
617  val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
618  val &= ~mymask; \
619  val |= mybits; \
620  PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
621  _ISR_Local_enable(level); \
622  } while (0)
623 
630 #define PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(spr, bits) \
631  do { \
632  ISR_Level level; \
633  uint32_t val; \
634  uint32_t mybits = bits; \
635  _ISR_Local_disable(level); \
636  val = PPC_SPECIAL_PURPOSE_REGISTER(spr); \
637  val &= ~mybits; \
638  PPC_SET_SPECIAL_PURPOSE_REGISTER(spr, val); \
639  _ISR_Local_enable(level); \
640  } while (0)
641 
647 #define PPC_THREAD_MGMT_REGISTER(tmr) \
648  ({ \
649  uint32_t val; \
650  __asm__ volatile (\
651  "mftmr %0, " PPC_STRINGOF(tmr) \
652  : "=r" (val) \
653  ); \
654  val;\
655  } )
656 
661 #define PPC_SET_THREAD_MGMT_REGISTER(tmr, val) \
662  do { \
663  __asm__ volatile (\
664  "mttmr " PPC_STRINGOF(tmr) ", %0" \
665  : \
666  : "r" (val) \
667  ); \
668  } while (0)
669 
677 #define PPC_DEVICE_CONTROL_REGISTER(dcr) \
678  ({ \
679  uint32_t val; \
680  __asm__ volatile (\
681  "mfdcr %0, " PPC_STRINGOF(dcr) \
682  : "=r" (val) \
683  ); \
684  val;\
685  } )
686 
693 #define PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val) \
694  do { \
695  __asm__ volatile (\
696  "mtdcr " PPC_STRINGOF(dcr) ", %0" \
697  : \
698  : "r" (val) \
699  ); \
700  } while (0)
701 
708 #define PPC_SET_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
709  do { \
710  ISR_Level level; \
711  uint32_t val; \
712  uint32_t mybits = bits; \
713  _ISR_Local_disable(level); \
714  val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
715  val |= mybits; \
716  PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
717  _ISR_Local_enable(level); \
718  } while (0)
719 
727 #define PPC_SET_DEVICE_CONTROL_REGISTER_BITS_MASKED(dcr, bits, mask) \
728  do { \
729  ISR_Level level; \
730  uint32_t val; \
731  uint32_t mybits = bits; \
732  uint32_t mymask = mask; \
733  _ISR_Local_disable(level); \
734  val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
735  val &= ~mymask; \
736  val |= mybits; \
737  PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
738  _ISR_Local_enable(level); \
739  } while (0)
740 
747 #define PPC_CLEAR_DEVICE_CONTROL_REGISTER_BITS(dcr, bits) \
748  do { \
749  ISR_Level level; \
750  uint32_t val; \
751  uint32_t mybits = bits; \
752  _ISR_Local_disable(level); \
753  val = PPC_DEVICE_CONTROL_REGISTER(dcr); \
754  val &= ~mybits; \
755  PPC_SET_DEVICE_CONTROL_REGISTER(dcr, val); \
756  _ISR_Local_enable(level); \
757  } while (0)
758 
759 static inline uint32_t ppc_time_base(void)
760 {
761  uint32_t val;
762 
763  CPU_Get_timebase_low(val);
764 
765  return val;
766 }
767 
768 static inline void ppc_set_time_base(uint32_t val)
769 {
771 }
772 
773 static inline uint32_t ppc_time_base_upper(void)
774 {
775  return PPC_SPECIAL_PURPOSE_REGISTER(TBRU);
776 }
777 
778 static inline void ppc_set_time_base_upper(uint32_t val)
779 {
781 }
782 
783 static inline uint64_t ppc_time_base_64(void)
784 {
785  return PPC_Get_timebase_register();
786 }
787 
788 static inline void ppc_set_time_base_64(uint64_t val)
789 {
790  PPC_Set_timebase_register(val);
791 }
792 
793 static inline uint32_t ppc_alternate_time_base(void)
794 {
795  return PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_ATBL);
796 }
797 
798 static inline uint32_t ppc_alternate_time_base_upper(void)
799 {
800  return PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_ATBU);
801 }
802 
803 static inline uint64_t ppc_alternate_time_base_64(void)
804 {
805  uint32_t atbl;
806  uint32_t atbu_0;
807  uint32_t atbu_1;
808 
809  do {
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);
814 
815  return (((uint64_t) atbu_1) << 32) | ((uint64_t) atbl);
816 }
817 
818 static inline uint32_t ppc_processor_id(void)
819 {
820  return PPC_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR);
821 }
822 
823 static inline void ppc_set_processor_id(uint32_t val)
824 {
825  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR, val);
826 }
827 
828 static inline uint32_t ppc_fsl_system_version(void)
829 {
830  return PPC_SPECIAL_PURPOSE_REGISTER(FSL_EIS_SVR);
831 }
832 
833 static inline uint32_t ppc_fsl_system_version_cid(uint32_t svr)
834 {
835  return (svr >> 28) & 0xf;
836 }
837 
838 static inline uint32_t ppc_fsl_system_version_sid(uint32_t svr)
839 {
840  return (svr >> 16) & 0xfff;
841 }
842 
843 static inline uint32_t ppc_fsl_system_version_proc(uint32_t svr)
844 {
845  return (svr >> 12) & 0xf;
846 }
847 
848 static inline uint32_t ppc_fsl_system_version_mfg(uint32_t svr)
849 {
850  return (svr >> 8) & 0xf;
851 }
852 
853 static inline uint32_t ppc_fsl_system_version_mjrev(uint32_t svr)
854 {
855  return (svr >> 4) & 0xf;
856 }
857 
858 static inline uint32_t ppc_fsl_system_version_mnrev(uint32_t svr)
859 {
860  return (svr >> 0) & 0xf;
861 }
862 
863 void ppc_code_copy(void *dest, const void *src, size_t n);
864 
865 /* FIXME: Do not use this function */
866 void printBAT(int bat, uint32_t upper, uint32_t lower);
867 
868 /* FIXME: Do not use this function */
869 void ShowBATS(void);
870 
871 #endif /* ifndef ASM */
872 
873 #if defined(ASM)
874 #include <rtems/asm.h>
875 
876 .macro LA reg, addr
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
883 #else
884  lis \reg, (\addr)@h
885  ori \reg, \reg, (\addr)@l
886 #endif
887 .endm
888 
889 .macro LA32 reg, addr
890  lis \reg, (\addr)@h
891  ori \reg, \reg, (\addr)@l
892 .endm
893 
894 .macro LWI reg, value
895  lis \reg, (\value)@h
896  ori \reg, \reg, (\value)@l
897 .endm
898 
899 .macro LW reg, addr
900  lis \reg, \addr@ha
901  lwz \reg, \addr@l(\reg)
902 .endm
903 
904 /*
905  * Tests the bits in reg1 against the bits set in mask. A match is indicated
906  * by EQ = 0 in CR0. A mismatch is indicated by EQ = 1 in CR0. The register
907  * reg2 is used to load the mask.
908  */
909 .macro TSTBITS reg1, reg2, mask
910  LWI \reg2, \mask
911  and \reg1, \reg1, \reg2
912  cmplw \reg1, \reg2
913 .endm
914 
915 .macro SETBITS reg1, reg2, mask
916  LWI \reg2, \mask
917  or \reg1, \reg1, \reg2
918 .endm
919 
920 .macro CLRBITS reg1, reg2, mask
921  LWI \reg2, \mask
922  andc \reg1, \reg1, \reg2
923 .endm
924 
925 .macro GLOBAL_FUNCTION name
926  .global \name
927  .type \name, @function
928 \name:
929 .endm
930 
931 /*
932  * Obtain interrupt mask
933  */
934 .macro GET_INTERRUPT_MASK mask
935  lis \mask, _PPC_INTERRUPT_DISABLE_MASK@h
936  ori \mask, \mask, _PPC_INTERRUPT_DISABLE_MASK@l
937 .endm
938 
939 /*
940  * Disables all asynchronous exeptions (interrupts) which may cause a context
941  * switch.
942  */
943 .macro INTERRUPT_DISABLE level, mask
944  mfmsr \level
945  GET_INTERRUPT_MASK mask=\mask
946  andc \mask, \level, \mask
947  mtmsr \mask
948 .endm
949 
950 /*
951  * Restore previous machine state.
952  */
953 .macro INTERRUPT_ENABLE level
954  mtmsr \level
955 .endm
956 
957 .macro SET_SELF_CPU_CONTROL reg_0, reg_1
958 #if defined(RTEMS_SMP)
959  /* Use Book E Processor ID Register (PIR) */
960  mfspr \reg_0, 286
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
965 #else
966  addis \reg_0, \reg_0, _Per_CPU_Information@ha
967  addi \reg_0, \reg_0, _Per_CPU_Information@l
968 #endif
969  mtspr PPC_PER_CPU_CONTROL_REGISTER, \reg_0
970 #endif
971 .endm
972 
973 .macro GET_SELF_CPU_CONTROL reg
974 #if defined(RTEMS_SMP)
975  mfspr \reg, PPC_PER_CPU_CONTROL_REGISTER
976 #else
977  lis \reg, _Per_CPU_Information@h
978  ori \reg, \reg, _Per_CPU_Information@l
979 #endif
980 .endm
981 
982 .macro SHIFT_RIGHT_IMMEDIATE rd, rs, imm
983 #if defined(__powerpc64__)
984  srdi \rd, \rs, \imm
985 #else
986  srwi \rd, \rs, \imm
987 #endif
988 .endm
989 
990 .macro COMPARE_LOGICAL cr, ra, rb
991 #if defined(__powerpc64__)
992  cmpld \cr, \ra, \rb
993 #else
994  cmplw \cr, \ra, \rb
995 #endif
996 .endm
997 
998 .macro CLEAR_RIGHT_IMMEDIATE rd, rs, imm
999 #if defined(__powerpc64__)
1000  clrrdi \rd, \rs, \imm
1001 #else
1002  clrrwi \rd, \rs, \imm
1003 #endif
1004 .endm
1005 
1006 #define LINKER_SYMBOL(sym) .extern sym
1007 
1008 #endif /* ASM */
1009 
1010 #ifdef __cplusplus
1011 }
1012 #endif
1013 
1016 #endif /* __LIBCPU_POWERPC_UTILITY_H */
#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