Merge pull request #12899 from benpicco/lpc2387-micropython
cpu/lpc2387: align lpc2387.ld with cortexm_base.ld, provide thread_isr_stack_*() - enables MicroPython
This commit is contained in:
commit
f7cb0a096e
@ -31,10 +31,10 @@ static inline void _init_data(void)
|
|||||||
{
|
{
|
||||||
/* (linker script ensures that data is 32-bit aligned) */
|
/* (linker script ensures that data is 32-bit aligned) */
|
||||||
extern unsigned int _etext;
|
extern unsigned int _etext;
|
||||||
extern unsigned int _data;
|
extern unsigned int _srelocate; /* .data section */
|
||||||
extern unsigned int _edata;
|
extern unsigned int _erelocate;
|
||||||
extern unsigned int __bss_start;
|
extern unsigned int _szero; /* .bss section */
|
||||||
extern unsigned int __bss_end;
|
extern unsigned int _ezero;
|
||||||
|
|
||||||
/* Support for Battery Backup RAM */
|
/* Support for Battery Backup RAM */
|
||||||
#ifdef CPU_HAS_BACKUP_RAM
|
#ifdef CPU_HAS_BACKUP_RAM
|
||||||
@ -49,18 +49,38 @@ static inline void _init_data(void)
|
|||||||
register unsigned int *dst;
|
register unsigned int *dst;
|
||||||
register unsigned int *end;
|
register unsigned int *end;
|
||||||
|
|
||||||
|
#ifdef DEVELHELP
|
||||||
|
/* Fill user stack with canary values up until the current stack pointer */
|
||||||
|
/* Read current stack pointer from CPU register */
|
||||||
|
__asm__ volatile ("mov %[end], sp" : [end] "=r" (end) : : );
|
||||||
|
dst = &__stack_start;
|
||||||
|
while (dst < end) {
|
||||||
|
*(dst++) = STACK_CANARY_WORD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fill the interrupt stacks with canary values */
|
||||||
|
extern unsigned int __stack_usr_start;
|
||||||
|
extern unsigned int __stack_end;
|
||||||
|
|
||||||
|
dst = &__stack_usr_start;
|
||||||
|
end = &__stack_end;
|
||||||
|
while (dst < end) {
|
||||||
|
*(dst++) = STACK_CANARY_WORD;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* initialize data from flash */
|
/* initialize data from flash */
|
||||||
src = &_etext;
|
src = &_etext;
|
||||||
dst = &_data;
|
dst = &_srelocate;
|
||||||
end = &_edata;
|
end = &_erelocate;
|
||||||
|
|
||||||
while (dst < end) {
|
while (dst < end) {
|
||||||
*dst++ = *src++;
|
*dst++ = *src++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear bss */
|
/* clear bss */
|
||||||
dst = &__bss_start;
|
dst = &_szero;
|
||||||
end = &__bss_end;
|
end = &_ezero;
|
||||||
|
|
||||||
while (dst < end) {
|
while (dst < end) {
|
||||||
*dst++ = 0;
|
*dst++ = 0;
|
||||||
@ -99,9 +119,9 @@ void bootloader(void)
|
|||||||
_init_data();
|
_init_data();
|
||||||
|
|
||||||
#ifdef MODULE_PUF_SRAM
|
#ifdef MODULE_PUF_SRAM
|
||||||
/* uninitialized heap starts after bss section */
|
/* use uninitialized heap */
|
||||||
extern unsigned int __bss_end;
|
extern unsigned _sheap;
|
||||||
puf_sram_init((uint8_t *) __bss_end, SEED_RAM_LEN);
|
puf_sram_init((uint8_t *) &_sheap, SEED_RAM_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* cpu specific setup of clocks, peripherals */
|
/* cpu specific setup of clocks, peripherals */
|
||||||
|
|||||||
@ -94,3 +94,43 @@ void thread_print_stack(void)
|
|||||||
|
|
||||||
printf("STACK (%d)= %X \n", i, *s);
|
printf("STACK (%d)= %X \n", i, *s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *thread_isr_stack_start(void)
|
||||||
|
{
|
||||||
|
extern uintptr_t __stack_irq_start;
|
||||||
|
return (void *)&__stack_irq_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *thread_isr_stack_pointer(void)
|
||||||
|
{
|
||||||
|
void *_sp;
|
||||||
|
|
||||||
|
/* If we are not in interrupt mode, the interrupt stack pointer will
|
||||||
|
* always point to the start of the interrupt stack.
|
||||||
|
*/
|
||||||
|
if (irq_is_in()) {
|
||||||
|
/* read stack pointer */
|
||||||
|
__asm volatile ("mov %0, r13" : "=r" (_sp) );
|
||||||
|
} else {
|
||||||
|
_sp = thread_isr_stack_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _sp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function returns the number of bytes used on the ISR stack */
|
||||||
|
int thread_isr_stack_usage(void)
|
||||||
|
{
|
||||||
|
extern uintptr_t __stack_irq_start;
|
||||||
|
extern uintptr_t __stack_irq_size;
|
||||||
|
|
||||||
|
uintptr_t *ptr = &__stack_irq_start - (unsigned) &__stack_irq_size;
|
||||||
|
|
||||||
|
while(((*ptr) == STACK_CANARY_WORD) && (ptr < &__stack_irq_start)) {
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptrdiff_t num_used_words = &__stack_irq_start - ptr;
|
||||||
|
|
||||||
|
return num_used_words;
|
||||||
|
}
|
||||||
|
|||||||
@ -25,6 +25,16 @@ void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t *prescale);
|
|||||||
|
|
||||||
void arm_reset(void);
|
void arm_reset(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Interrupt stack canary value
|
||||||
|
*
|
||||||
|
* @note 0xeafffffe is the ARM machine code equivalent of asm("b #0") or
|
||||||
|
* 'while (1);', i.e. an infinite loop.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
#define STACK_CANARY_WORD (0xEAFFFFFEu)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -76,6 +76,14 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define PUF_SRAM_ATTRIBUTES __attribute__((used, section(".noinit")))
|
#define PUF_SRAM_ATTRIBUTES __attribute__((used, section(".noinit")))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Stack size used for the exception (ISR) stack
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
extern unsigned __stack_irq_size;
|
||||||
|
#define ISR_STACKSIZE ((unsigned) &__stack_irq_size)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -106,75 +106,6 @@ SECTIONS
|
|||||||
* RAM
|
* RAM
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
/*
|
|
||||||
* collect all zero initialized sections that go into RAM
|
|
||||||
*/
|
|
||||||
.bss (NOLOAD) :
|
|
||||||
{
|
|
||||||
. = ALIGN(4); /* ensure data is aligned so relocation can use 4-byte operations */
|
|
||||||
__bss_start = .; /* define a global symbol marking the start of the .bss section */
|
|
||||||
*(.bss*) /* all .bss sections */
|
|
||||||
*(COMMON)
|
|
||||||
} > ram /* put all the above in RAM (it will be cleared in the startup code */
|
|
||||||
. = ALIGN(4); /* ensure data is aligned so relocation can use 4-byte operations */
|
|
||||||
__bss_end = . ; /* define a global symbol marking the end of the .bss section */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* collect all initialized .data sections that go into RAM
|
|
||||||
* initial values get placed at the end of .text in flash
|
|
||||||
*/
|
|
||||||
.data :
|
|
||||||
{
|
|
||||||
. = ALIGN(4); /* ensure data is aligned so relocation can use 4-byte operations */
|
|
||||||
_data = .; /* create a global symbol marking the start of the .data section */
|
|
||||||
*(.data .data.*) /* all .data sections */
|
|
||||||
*(.gnu.linkonce.d*)
|
|
||||||
. = ALIGN(4);
|
|
||||||
/* preinit data */
|
|
||||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
|
||||||
KEEP(*(.preinit_array))
|
|
||||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
/* init data */
|
|
||||||
PROVIDE_HIDDEN (__init_array_start = .);
|
|
||||||
KEEP(*(SORT(.init_array.*)))
|
|
||||||
KEEP(*(.init_array))
|
|
||||||
PROVIDE_HIDDEN (__init_array_end = .);
|
|
||||||
|
|
||||||
. = ALIGN(4);
|
|
||||||
/* finit data */
|
|
||||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
|
||||||
KEEP(*(SORT(.fini_array.*)))
|
|
||||||
KEEP(*(.fini_array))
|
|
||||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
|
||||||
} >ram AT > rom /* put all the above into RAM (but load the LMA copy into FLASH) */
|
|
||||||
. = ALIGN(4); /* ensure data is aligned so relocation can use 4-byte operations */
|
|
||||||
_edata = .; /* define a global symbol marking the end of the .data section */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* collect all uninitialized sections that go into RAM
|
|
||||||
*/
|
|
||||||
.noinit (NOLOAD) :
|
|
||||||
{
|
|
||||||
__noinit_start = .;
|
|
||||||
PROVIDE(__fiq_handler = .);
|
|
||||||
*(.fiq)
|
|
||||||
*(.noinit)
|
|
||||||
} > ram
|
|
||||||
. = ALIGN(4);
|
|
||||||
__noinit_end = .;
|
|
||||||
|
|
||||||
_end = .; /* define a global symbol marking the end of application RAM */
|
|
||||||
|
|
||||||
__heap1_size = ORIGIN(ram) + LENGTH(ram) - . - __stack_size;
|
|
||||||
.heap1 (NOLOAD) :
|
|
||||||
{
|
|
||||||
PROVIDE(_sheap = .);
|
|
||||||
. = . + __heap1_size;
|
|
||||||
PROVIDE(_eheap = .);
|
|
||||||
} > ram
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stacks
|
* Stacks
|
||||||
*/
|
*/
|
||||||
@ -198,12 +129,56 @@ SECTIONS
|
|||||||
PROVIDE(__stack_end = .);
|
PROVIDE(__stack_end = .);
|
||||||
} > ram
|
} > ram
|
||||||
|
|
||||||
|
.relocate :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_srelocate = .;
|
||||||
|
*(.ramfunc .ramfunc.*);
|
||||||
|
*(.data .data.*);
|
||||||
|
KEEP (*(.openocd .openocd.*))
|
||||||
|
. = ALIGN(4);
|
||||||
|
_erelocate = .;
|
||||||
|
} > ram AT> rom
|
||||||
|
|
||||||
|
/* .bss section which is used for uninitialized data */
|
||||||
|
.bss (NOLOAD) :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = . ;
|
||||||
|
_szero = .;
|
||||||
|
*(.bss .bss.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = . ;
|
||||||
|
_ezero = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/*
|
||||||
|
* collect all uninitialized sections that go into RAM
|
||||||
|
*/
|
||||||
|
.noinit (NOLOAD) :
|
||||||
|
{
|
||||||
|
__noinit_start = .;
|
||||||
|
PROVIDE(__fiq_handler = .);
|
||||||
|
*(.fiq)
|
||||||
|
*(.noinit)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__noinit_end = .;
|
||||||
|
} > ram
|
||||||
|
|
||||||
|
/* heap section */
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sheap = . ;
|
||||||
|
_eheap = ORIGIN(ram) + LENGTH(ram);
|
||||||
|
|
||||||
|
/* Populate information about ram size */
|
||||||
|
_sram = ORIGIN(ram);
|
||||||
|
_eram = ORIGIN(ram) + LENGTH(ram);
|
||||||
|
|
||||||
__heap2_size = LENGTH(ram_ethernet);
|
__heap2_size = LENGTH(ram_ethernet);
|
||||||
.heap2 (NOLOAD) :
|
.heap2 (NOLOAD) :
|
||||||
{
|
{
|
||||||
PROVIDE(__heap2_start = . );
|
PROVIDE(__heap2_start = . );
|
||||||
. = . + __heap2_size;
|
|
||||||
PROVIDE(__heap2_max = .); /* _heap shall always be < _heap_max */
|
|
||||||
} > ram_ethernet
|
} > ram_ethernet
|
||||||
|
|
||||||
. = ORIGIN(ram_usb);
|
. = ORIGIN(ram_usb);
|
||||||
@ -216,19 +191,9 @@ SECTIONS
|
|||||||
{
|
{
|
||||||
__heap3_size = ORIGIN(ram_usb) + LENGTH(ram_usb) - ABSOLUTE(.);
|
__heap3_size = ORIGIN(ram_usb) + LENGTH(ram_usb) - ABSOLUTE(.);
|
||||||
PROVIDE(__heap3_start = . );
|
PROVIDE(__heap3_start = . );
|
||||||
. += __heap3_size;
|
|
||||||
PROVIDE(__heap3_max = .);
|
|
||||||
} > ram_usb
|
} > ram_usb
|
||||||
__heap_size = SIZEOF(.heap3);
|
__heap_size = SIZEOF(.heap3);
|
||||||
|
|
||||||
.backup.bss (NOLOAD) : ALIGN(4) {
|
|
||||||
_sbackup_bss = .;
|
|
||||||
*(.backup.bss)
|
|
||||||
_ebackup_bss = .;
|
|
||||||
/* Round size so that we can use 4 byte copy in init */
|
|
||||||
. = ALIGN(4);
|
|
||||||
} > ram_battery
|
|
||||||
|
|
||||||
_sbackup_data_load = LOADADDR(.backup.data);
|
_sbackup_data_load = LOADADDR(.backup.data);
|
||||||
.backup.data : ALIGN(4) {
|
.backup.data : ALIGN(4) {
|
||||||
_sbackup_data = .;
|
_sbackup_data = .;
|
||||||
@ -237,4 +202,12 @@ SECTIONS
|
|||||||
/* Round size so that we can use 4 byte copy in init */
|
/* Round size so that we can use 4 byte copy in init */
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} > ram_battery AT> rom
|
} > ram_battery AT> rom
|
||||||
|
|
||||||
|
.backup.bss (NOLOAD) : ALIGN(4) {
|
||||||
|
_sbackup_bss = .;
|
||||||
|
*(.backup.bss)
|
||||||
|
_ebackup_bss = .;
|
||||||
|
/* Round size so that we can use 4 byte copy in init */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > ram_battery
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ USEMODULE += stdin
|
|||||||
FEATURES_BLACKLIST += arch_8bit arch_16bit
|
FEATURES_BLACKLIST += arch_8bit arch_16bit
|
||||||
|
|
||||||
# This port currently requires ISR_STACKSIZE and thread_isr_stack_start
|
# This port currently requires ISR_STACKSIZE and thread_isr_stack_start
|
||||||
FEATURES_BLACKLIST += arch_arm7 arch_esp32 arch_esp8266 arch_riscv
|
FEATURES_BLACKLIST += arch_esp32 arch_esp8266 arch_riscv
|
||||||
|
|
||||||
# The port currently doesn't compile for mips
|
# The port currently doesn't compile for mips
|
||||||
FEATURES_BLACKLIST += arch_mips32r2
|
FEATURES_BLACKLIST += arch_mips32r2
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user