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 <stdio.h>
34 
35 #include "irq.h"
36 #include "sched.h"
37 #include "thread.h"
38 #include "cpu_conf.h"
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
51 #define STACK_CANARY_WORD (0xE7FEE7FEu)
52 
59 #define PROVIDES_PM_SET_LOWEST
60 
67 #define CORTEXM_SCB_CPACR_FPU_ACCESS_FULL (0x00f00000)
68 
72 void cpu_init(void);
73 
88 void cortexm_init(void);
89 
99 static inline void cortexm_init_fpu(void)
100 {
101  /* initialize the FPU on Cortex-M4F CPUs */
102 #if (defined(CPU_CORE_CORTEX_M33) || defined(CPU_CORE_CORTEX_M4F) || defined(CPU_CORE_CORTEX_M7)) && defined(MODULE_CORTEXM_FPU)
103  /* give full access to the FPU */
104  SCB->CPACR |= (uint32_t)CORTEXM_SCB_CPACR_FPU_ACCESS_FULL;
105 #endif
106 }
107 
108 #if defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN)
109 
119 void cortexm_init_isr_priorities(void);
120 
130 void cortexm_init_misc(void);
131 
132 #endif /* defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN) */
133 
137 static inline void cpu_print_last_instruction(void)
138 {
139  uint32_t *lr_ptr;
140  __asm__ __volatile__("mov %0, lr" : "=r"(lr_ptr));
141  printf("%p\n", (void*) lr_ptr);
142 }
143 
150 static inline void cortexm_sleep_until_event(void)
151 {
152  __WFE();
153 }
154 
160 static inline void cortexm_sleep(int deep)
161 {
162  if (deep) {
163  SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
164  }
165  else {
166  SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
167  }
168 
169  /* ensure that all memory accesses have completed and trigger sleeping */
170  unsigned state = irq_disable();
171  __DSB();
172  __WFI();
173  irq_restore(state);
174 }
175 
181 static inline void cortexm_isr_end(void)
182 {
185  }
186 }
187 
195 static inline void cpu_jump_to_image(uint32_t image_address)
196 {
197  /* On Cortex-M platforms, the flash begins with:
198  *
199  * 1. 4 byte pointer to stack to be used at startup
200  * 2. 4 byte pointer to the reset vector function
201  *
202  * On powerup, the CPU sets the stack pointer and starts executing the
203  * reset vector.
204  *
205  * We're doing the same here, but we'd like to start at image_address.
206  *
207  * This function must be called while executing from MSP (Master Stack
208  * Pointer).
209  */
210 
211  /* set MSP */
212  __set_MSP(*(uint32_t*)image_address);
213 
214  /* skip stack pointer */
215  image_address += 4;
216 
217  /* load the images reset_vector address */
218  uint32_t destination_address = *(uint32_t*)image_address;
219 
220  /* Make sure the Thumb State bit is set. */
221  destination_address |= 0x1;
222 
223  /* Branch execution */
224  __asm("BX %0" :: "r" (destination_address));
225 }
226 
227 /* The following register is only present for
228  Cortex-M0+, -M23, -M3, -M33, -M4 and M7 CPUs */
229 #if defined(CPU_CORE_CORTEX_M0PLUS) || defined(CPU_CORE_CORTEX_M23) || \
230  defined(CPU_CORE_CORTEX_M3) || defined(CPU_CORE_CORTEX_M33) || \
231  defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \
232  defined(CPU_CORE_CORTEX_M7)
233 static inline uint32_t cpu_get_image_baseaddr(void)
234 {
235  return SCB->VTOR;
236 }
237 #endif
238 
248 bool cpu_check_address(volatile const char *address);
249 
250 #ifdef __cplusplus
251 }
252 #endif
253 
254 #endif /* CPU_H */
255 
cortexm_init_fpu
static void cortexm_init_fpu(void)
Initialize Cortex-M FPU.
Definition: cpu.h:99
irq_disable
MAYBE_INLINE unsigned irq_disable(void)
This function sets the IRQ disable bit in the status register.
cortexm_sleep_until_event
static void cortexm_sleep_until_event(void)
Put the CPU into the 'wait for event' sleep mode.
Definition: cpu.h:150
thread_yield_higher
void thread_yield_higher(void)
Lets current thread yield in favor of a higher prioritized thread.
sched.h
Scheduler API definition.
cortexm_isr_end
static void cortexm_isr_end(void)
Trigger a conditional context scheduler run / context switch.
Definition: cpu.h:181
cpu_check_address
bool cpu_check_address(volatile const char *address)
Checks is memory address valid or not.
cortexm_init_isr_priorities
void cortexm_init_isr_priorities(void)
Initialize Cortex-M interrupt priorities.
irq_restore
MAYBE_INLINE void irq_restore(unsigned state)
This function restores the IRQ disable bit in the status register to the value contained within passe...
sched_context_switch_request
volatile unsigned int sched_context_switch_request
Flag indicating whether a context switch is necessary after handling an interrupt.
cpu_init
void cpu_init(void)
Initialization of the CPU.
cpu_print_last_instruction
static void cpu_print_last_instruction(void)
Prints the current content of the link register (lr)
Definition: cpu.h:137
irq.h
IRQ driver interface.
cortexm_init
void cortexm_init(void)
Initialize Cortex-M specific core parts of the CPU.
cortexm_sleep
static void cortexm_sleep(int deep)
Put the CPU into (deep) sleep mode, using the WFI instruction.
Definition: cpu.h:160
CORTEXM_SCB_CPACR_FPU_ACCESS_FULL
#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:67
cpu_jump_to_image
static void cpu_jump_to_image(uint32_t image_address)
Jumps to another image in flash.
Definition: cpu.h:195
cortexm_init_misc
void cortexm_init_misc(void)
Initialize Cortex-M misc functions.