intrinsics.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 barrier() asm volatile ("" ::: "memory")
  25. #define cpu_relax() asm volatile ("nop" ::: "memory")
  26. #if defined(CORTEX_M3) || defined(CORTEX_M7)
  27. #define illegal() asm volatile (".short 0xde00");
  28. #define cpu_sync() asm volatile("dsb; isb" ::: "memory")
  29. #define sv_call(imm) asm volatile ( "svc %0" : : "i" (imm) )
  30. #define read_special(reg) ({ \
  31. uint32_t __x; \
  32. asm volatile ("mrs %0,"#reg : "=r" (__x) ::); \
  33. __x; \
  34. })
  35. #define write_special(reg,val) ({ \
  36. uint32_t __x = (uint32_t)(val); \
  37. asm volatile ("msr "#reg",%0" :: "r" (__x) :); \
  38. })
  39. /* CONTROL[1] == 0 => running on Master Stack (Exception Handler mode). */
  40. #define CONTROL_SPSEL 2
  41. #define in_exception() (!(read_special(control) & CONTROL_SPSEL))
  42. #define global_disable_exceptions() \
  43. asm volatile ("cpsid f; cpsid i" ::: "memory")
  44. #define global_enable_exceptions() \
  45. asm volatile ("cpsie f; cpsie i" ::: "memory")
  46. /* NB. IRQ disable via CPSID/MSR is self-synchronising. No barrier needed. */
  47. #define IRQ_global_disable() asm volatile ("cpsid i" ::: "memory")
  48. #define IRQ_global_enable() asm volatile ("cpsie i" ::: "memory")
  49. #define IRQ_global_save(flags) ({ \
  50. (flags) = read_special(primask) & 1; \
  51. IRQ_global_disable(); })
  52. #define IRQ_global_restore(flags) ({ \
  53. if (flags == 0) IRQ_global_enable(); })
  54. /* Save/restore IRQ priority levels.
  55. * NB. IRQ disable via MSR is self-synchronising. I have confirmed this on
  56. * Cortex-M3: any pending IRQs are handled before they are disabled by
  57. * a BASEPRI update. Hence no barrier is needed here. */
  58. #define IRQ_save(newpri) ({ \
  59. uint8_t __newpri = (newpri)<<4; \
  60. uint8_t __oldpri = read_special(basepri); \
  61. if (!__oldpri || (__oldpri > __newpri)) \
  62. write_special(basepri, __newpri); \
  63. __oldpri; })
  64. /* NB. Same as CPSIE, any pending IRQ enabled by this BASEPRI update may
  65. * execute a couple of instructions after the MSR instruction. This has been
  66. * confirmed on Cortex-M3. */
  67. #define IRQ_restore(oldpri) write_special(basepri, (oldpri))
  68. /* Cortex initialisation */
  69. void cortex_init(void);
  70. #elif defined(RISCV)
  71. #define IRQ_save(newpri) 0
  72. #define IRQ_restore(oldpri) ((void)oldpri)
  73. #endif
  74. #if defined(CORTEX_M7)
  75. /* Cache operations */
  76. void icache_invalidate_all(void);
  77. void icache_enable(void);
  78. void dcache_invalidate_all(void);
  79. void dcache_clear_and_invalidate_all(void);
  80. void dcache_enable(void);
  81. void dcache_disable(void);
  82. #elif defined(CORTEX_M3)
  83. /* No caches in Cortex M3 */
  84. #define icache_invalidate_all() ((void)0)
  85. #define icache_enable() ((void)0)
  86. #define dcache_invalidate_all() ((void)0)
  87. #define dcache_clear_and_invalidate_all() ((void)0)
  88. #define dcache_enable() ((void)0)
  89. #define dcache_disable() ((void)0)
  90. #endif
  91. /*
  92. * Local variables:
  93. * mode: C
  94. * c-file-style: "Linux"
  95. * c-basic-offset: 4
  96. * tab-width: 4
  97. * indent-tabs-mode: nil
  98. * End:
  99. */