Loading...
Searching...
No Matches
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
41extern "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
83void cortexm_init(void);
84
94static inline void cortexm_init_fpu(void)
95{
96 /* initialize the FPU on Cortex-M4F CPUs */
97#if (defined(CPU_CORE_CORTEX_M33) || defined(CPU_CORE_CORTEX_M4F) || defined(CPU_CORE_CORTEX_M7)) && defined(MODULE_CORTEXM_FPU)
98 /* give full access to the FPU */
99 SCB->CPACR |= (uint32_t)CORTEXM_SCB_CPACR_FPU_ACCESS_FULL;
100#endif
101}
102
103#if defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN)
104
115
126
127#endif /* defined(CPU_CORTEXM_INIT_SUBFUNCTIONS) || defined(DOXYGEN) */
128
134static inline uintptr_t cpu_get_caller_pc(void)
135{
136 uintptr_t lr_ptr;
137 __asm__ __volatile__("mov %0, lr" : "=r"(lr_ptr));
138 return lr_ptr;
139}
140
147static inline void cortexm_sleep_until_event(void)
148{
149 __WFE();
150}
151
157static inline void cortexm_sleep(int deep)
158{
159 if (deep) {
160 SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
161 }
162 else {
163 SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
164 }
165
166 /* ensure that all memory accesses have completed and trigger sleeping */
167 unsigned state = irq_disable();
168 __DSB();
169 __WFI();
170 /* Some CPUs require an ISB after WFI to work around silicon bugs */
171#if CORTEXM_ISB_REQUIRED_AFTER_WFI
172 __ISB();
173#endif
174 irq_restore(state);
175}
176
182static inline void cortexm_isr_end(void)
183{
186 }
187}
188
196static inline void cpu_jump_to_image(uint32_t image_address)
197{
198 /* On Cortex-M platforms, the flash begins with:
199 *
200 * 1. 4 byte pointer to stack to be used at startup
201 * 2. 4 byte pointer to the reset vector function
202 *
203 * On powerup, the CPU sets the stack pointer and starts executing the
204 * reset vector.
205 *
206 * We're doing the same here, but we'd like to start at image_address.
207 *
208 * This function must be called while executing from MSP (Master Stack
209 * Pointer).
210 */
211
212 /* set MSP */
213 __set_MSP(*(uint32_t*)image_address);
214
215 /* skip stack pointer */
216 image_address += 4;
217
218 /* load the images reset_vector address */
219 uint32_t destination_address = *(uint32_t*)image_address;
220
221 /* Make sure the Thumb State bit is set. */
222 destination_address |= 0x1;
223
224 /* Branch execution */
225 __asm("BX %0" :: "r" (destination_address));
226}
227
228/* The following register is only present for
229 Cortex-M0+, -M23, -M3, -M33, -M4 and M7 CPUs */
230#if defined(CPU_CORE_CORTEX_M0PLUS) || defined(CPU_CORE_CORTEX_M23) || \
231 defined(CPU_CORE_CORTEX_M3) || defined(CPU_CORE_CORTEX_M33) || \
232 defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \
233 defined(CPU_CORE_CORTEX_M7)
234static inline uint32_t cpu_get_image_baseaddr(void)
235{
236 return SCB->VTOR;
237}
238#endif
239
249bool cpu_check_address(volatile const char *address);
250
251#ifdef __cplusplus
252}
253#endif
254
255#endif /* CPU_H */
static uinttxtptr_t cpu_get_caller_pc(void)
Get the last instruction's address.
Definition cpu.h:141
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.
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:157
static void cortexm_isr_end(void)
Trigger a conditional context scheduler run / context switch.
Definition cpu.h:182
static void cpu_jump_to_image(uint32_t image_address)
Jumps to another image in flash.
Definition cpu.h:196
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:67
static void cortexm_sleep_until_event(void)
Put the CPU into the 'wait for event' sleep mode.
Definition cpu.h:147
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:94
IRQ driver interface.
Scheduler API definition.
stdio wrapper to extend the C libs stdio