forked from rad1o/f1rmware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintrinsics.h
64 lines (53 loc) · 1.6 KB
/
intrinsics.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <libopencm3/cm3/cortex.h>
static inline uint32_t get_sp(void){
register uint32_t result;
__asm volatile ("MRS %0, msp\n" : "=r" (result) );
return result;
};
static inline void boot(const void * vtable){
// Set new Vtable
cm_disable_interrupts();
CREG_M4MEMMAP = (uintptr_t)vtable;
SCB_VTOR = (uintptr_t) vtable;
cm_enable_interrupts();
// Reset stack pointer & branch to the new reset vector.
__asm( "mov r0, %0\n"
"ldr sp, [r0]\n"
"ldr r0, [r0, #4]\n"
"bx r0\n"
:
: "r"(vtable)
: "%sp", "r0");
};
static inline uint32_t get_pc(void){
register uint32_t result;
__asm volatile ("mov %0, pc\n" : "=r" (result) );
return result;
};
extern void * _bin_size;
extern void * _reloc_ep;
extern void * _text_start;
extern unsigned _bss, _ebss;
int main(uint32_t);
void __attribute__ ((naked)) __attribute((section(".reset")))reset_handler(void) {
volatile unsigned *dest;
volatile uint32_t idx;
static uint32_t startloc=-1; /* initialize so it is not in BSS */
if ((void *)CREG_M4MEMMAP != &_reloc_ep){
/* Move ourselves to _reloc_ep and restart there */
for (idx=0; idx < ((uintptr_t)& _bin_size)/sizeof(uint32_t); idx++){
((uint32_t*)&_reloc_ep)[idx]= ((uint32_t *)&_text_start)[idx];
};
/* remember where we started. Needs to be done after the copy of data */
startloc=CREG_M4MEMMAP;
/* set shadow area to new code loction, so boot() still works */
CREG_M4MEMMAP = (uintptr_t)&_reloc_ep;
boot(&_reloc_ep);
};
/* Initialize BSS */
for (dest = &_bss; dest < &_ebss; ) {
*dest++ = 0;
}
/* Call the application's entry point. */
main(startloc);
}