cpu.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014-2015 Freie Universität Berlin
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
30 #ifndef CPU_H
31 #define CPU_H
32 
33 #include "irq.h"
34 #include "sched.h"
35 #include "thread.h"
36 #include "cpu_conf.h" /* IWYU pragma: export */
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
49 #define STACK_CANARY_WORD (0xE7FEE7FEu)
50 
57 #define PROVIDES_PM_SET_LOWEST
58 
65 #define CORTEXM_SCB_CPACR_FPU_ACCESS_FULL (0x00f00000)
66 
81 void cortexm_init(void);
82 
92 static inline void cortexm_init_fpu(void)
93 {
94  /* initialize the FPU on Cortex-M4F CPUs */
95 #if (defined(CPU_CORE_CORTEX_M33) || defined(CPU_CORE_CORTEX_M4F) || defined(CPU_CORE_CORTEX_M7)) && defined(MODULE_CORTEXM_FPU)
96  /* give full access to the FPU */
97  SCB->CPACR |= (uint32_t)CORTEXM_SCB_CPACR_FPU_ACCESS_FULL;
98 #endif
99 }
100 
101 #if defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN)
102 
113 
123 void cortexm_init_misc(void);
124 
125 #endif /* defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN) */
126 
132 static inline uintptr_t cpu_get_caller_pc(void)
133 {
134  uintptr_t lr_ptr;
135  __asm__ __volatile__("mov %0, lr" : "=r"(lr_ptr));
136  return lr_ptr;
137 }
138 
145 static inline void cortexm_sleep_until_event(void)
146 {
147  __WFE();
148 }
149 
155 static inline void cortexm_sleep(int deep)
156 {
157  if (deep) {
158  SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
159  }
160  else {
161  SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
162  }
163 
164  /* ensure that all memory accesses have completed and trigger sleeping */
165  unsigned state = irq_disable();
166  __DSB();
167  __WFI();
168  /* Some CPUs require an ISB after WFI to work around silicon bugs */
169 #if CORTEXM_ISB_REQUIRED_AFTER_WFI
170  __ISB();
171 #endif
172  irq_restore(state);
173 }
174 
180 static inline void cortexm_isr_end(void)
181 {
184  }
185 }
186 
194 static inline void cpu_jump_to_image(uint32_t image_address)
195 {
196  /* On Cortex-M platforms, the flash begins with:
197  *
198  * 1. 4 byte pointer to stack to be used at startup
199  * 2. 4 byte pointer to the reset vector function
200  *
201  * On powerup, the CPU sets the stack pointer and starts executing the
202  * reset vector.
203  *
204  * We're doing the same here, but we'd like to start at image_address.
205  *
206  * This function must be called while executing from MSP (Master Stack
207  * Pointer).
208  */
209 
210  /* set MSP */
211  __set_MSP(*(uint32_t*)image_address);
212 
213  /* skip stack pointer */
214  image_address += 4;
215 
216  /* load the images reset_vector address */
217  uint32_t destination_address = *(uint32_t*)image_address;
218 
219  /* Make sure the Thumb State bit is set. */
220  destination_address |= 0x1;
221 
222  /* Branch execution */
223  __asm("BX %0" :: "r" (destination_address));
224 }
225 
226 /* The following register is only present for
227  Cortex-M0+, -M23, -M3, -M33, -M4 and M7 CPUs */
228 #if defined(CPU_CORE_CORTEX_M0PLUS) || defined(CPU_CORE_CORTEX_M23) || \
229  defined(CPU_CORE_CORTEX_M3) || defined(CPU_CORE_CORTEX_M33) || \
230  defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \
231  defined(CPU_CORE_CORTEX_M7)
232 static inline uint32_t cpu_get_image_baseaddr(void)
233 {
234  return SCB->VTOR;
235 }
236 #endif
237 
247 bool cpu_check_address(volatile const char *address);
248 
249 #ifdef __cplusplus
250 }
251 #endif
252 
253 #endif /* CPU_H */
static uint32_t cpu_get_image_baseaddr(void)
Returns the address of running application in flash.
Definition: cpu.h:30
MAYBE_INLINE void irq_restore(unsigned state)
This function restores the IRQ disable bit in the status register to the value contained within passe...
MAYBE_INLINE unsigned irq_disable(void)
This function sets the IRQ disable bit in the status register.
volatile unsigned int sched_context_switch_request
Flag indicating whether a context switch is necessary after handling an interrupt.
THREAD_MAYBE_INLINE void thread_yield_higher(void)
Lets current thread yield in favor of a higher prioritized thread.
static uintptr_t cpu_get_caller_pc(void)
Returns the current content of the link register (lr)
Definition: cpu.h:132
void cortexm_init_misc(void)
Initialize Cortex-M misc functions.
static void cortexm_sleep(int deep)
Put the CPU into (deep) sleep mode, using the WFI instruction.
Definition: cpu.h:155
static void cortexm_isr_end(void)
Trigger a conditional context scheduler run / context switch.
Definition: cpu.h:180
static void cpu_jump_to_image(uint32_t image_address)
Jumps to another image in flash.
Definition: cpu.h:194
void cortexm_init(void)
Initialize Cortex-M specific core parts of the CPU.
void cortexm_init_isr_priorities(void)
Initialize Cortex-M interrupt priorities.
#define CORTEXM_SCB_CPACR_FPU_ACCESS_FULL
Pattern to write into the co-processor Access Control Register to allow full FPU access.
Definition: cpu.h:65
static void cortexm_sleep_until_event(void)
Put the CPU into the 'wait for event' sleep mode.
Definition: cpu.h:145
bool cpu_check_address(volatile const char *address)
Checks is memory address valid or not.
static void cortexm_init_fpu(void)
Initialize Cortex-M FPU.
Definition: cpu.h:92
IRQ driver interface.
Scheduler API definition.