intrinsics.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * intrinsics.h
  3. *
  4. * Compiler intrinsics for ARMv7-M core.
  5. *
  6. * Written & released by Keir Fraser <keir.xen@gmail.com>
  7. *
  8. * This is free and unencumbered software released into the public domain.
  9. * See the file COPYING for more details, or visit <http://unlicense.org>.
  10. */
  11. struct exception_frame {
  12. uint32_t r0, r1, r2, r3, r12, lr, pc, psr;
  13. };
  14. #define _STR(x) #x
  15. #define STR(x) _STR(x)
  16. /* Force a compilation error if condition is true */
  17. #define BUILD_BUG_ON(cond) ({ _Static_assert(!(cond), "!(" #cond ")"); })
  18. #define aligned(x) __attribute__((aligned(x)))
  19. #define packed __attribute((packed))
  20. #define always_inline __inline__ __attribute__((always_inline))
  21. #define noinline __attribute__((noinline))
  22. #define likely(x) __builtin_expect(!!(x),1)
  23. #define unlikely(x) __builtin_expect(!!(x),0)
  24. #define illegal() asm volatile (".short 0xde00");
  25. #define barrier() asm volatile ("" ::: "memory")
  26. #define cpu_sync() asm volatile("dsb; isb" ::: "memory")
  27. #define cpu_relax() asm volatile ("nop" ::: "memory")
  28. #define sv_call(imm) asm volatile ( "svc %0" : : "i" (imm) )
  29. #define read_special(reg) ({ \
  30. uint32_t __x; \
  31. asm volatile ("mrs %0,"#reg : "=r" (__x) ::); \
  32. __x; \
  33. })
  34. #define write_special(reg,val) ({ \
  35. uint32_t __x = (uint32_t)(val); \
  36. asm volatile ("msr "#reg",%0" :: "r" (__x) :); \
  37. })
  38. /* CONTROL[1] == 0 => running on Master Stack (Exception Handler mode). */
  39. #define CONTROL_SPSEL 2
  40. #define in_exception() (!(read_special(control) & CONTROL_SPSEL))
  41. #define global_disable_exceptions() \
  42. asm volatile ("cpsid f; cpsid i" ::: "memory")
  43. #define global_enable_exceptions() \
  44. asm volatile ("cpsie f; cpsie i" ::: "memory")
  45. /* NB. IRQ disable via CPSID/MSR is self-synchronising. No barrier needed. */
  46. #define IRQ_global_disable() asm volatile ("cpsid i" ::: "memory")
  47. #define IRQ_global_enable() asm volatile ("cpsie i" ::: "memory")
  48. #define IRQ_global_save(flags) ({ \
  49. (flags) = read_special(primask) & 1; \
  50. IRQ_global_disable(); })
  51. #define IRQ_global_restore(flags) ({ \
  52. if (flags == 0) IRQ_global_enable(); })
  53. /* Save/restore IRQ priority levels.
  54. * NB. IRQ disable via MSR is self-synchronising. I have confirmed this on
  55. * Cortex-M3: any pending IRQs are handled before they are disabled by
  56. * a BASEPRI update. Hence no barrier is needed here. */
  57. #define IRQ_save(newpri) ({ \
  58. uint8_t __newpri = (newpri)<<4; \
  59. uint8_t __oldpri = read_special(basepri); \
  60. if (!__oldpri || (__oldpri > __newpri)) \
  61. write_special(basepri, __newpri); \
  62. __oldpri; })
  63. /* NB. Same as CPSIE, any pending IRQ enabled by this BASEPRI update may
  64. * execute a couple of instructions after the MSR instruction. This has been
  65. * confirmed on Cortex-M3. */
  66. #define IRQ_restore(oldpri) write_special(basepri, (oldpri))
  67. /* Cortex initialisation */
  68. void cortex_init(void);
  69. #if defined(CORTEX_M7)
  70. /* Cache operations */
  71. void icache_invalidate_all(void);
  72. void icache_enable(void);
  73. void dcache_invalidate_all(void);
  74. void dcache_clear_and_invalidate_all(void);
  75. void dcache_enable(void);
  76. void dcache_disable(void);
  77. #elif defined(CORTEX_M3)
  78. /* No caches in Cortex M3 */
  79. #define icache_invalidate_all() ((void)0)
  80. #define icache_enable() ((void)0)
  81. #define dcache_invalidate_all() ((void)0)
  82. #define dcache_clear_and_invalidate_all() ((void)0)
  83. #define dcache_enable() ((void)0)
  84. #define dcache_disable() ((void)0)
  85. #endif
  86. /*
  87. * Local variables:
  88. * mode: C
  89. * c-file-style: "Linux"
  90. * c-basic-offset: 4
  91. * tab-width: 4
  92. * indent-tabs-mode: nil
  93. * End:
  94. */