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:
benpicco 2019-12-18 12:08:12 +01:00 committed by GitHub
commit f7cb0a096e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 149 additions and 98 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -100,81 +100,12 @@ SECTIONS
{ {
*(.configmem) *(.configmem)
. = ALIGN(256); . = ALIGN(256);
} >infomem } > infomem
/************************************************************************** /**************************************************************************
* 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
} }

View File

@ -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