armcm_boot: Avoid invoking functions in reset_handler_stage_two()
Avoid calling memset() and memcpy() prior to copying the ram and clearing the bss. Also, place both ResetHandler() and reset_handler_stage_two() in an explicit ".text.armcm_boot" linker section. These changes make it easier to support targets that want to run all code in ram. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
43a9685c58
commit
55e46aa625
|
@ -22,7 +22,31 @@ extern uint32_t _stack_end;
|
||||||
* Basic interrupt handlers
|
* Basic interrupt handlers
|
||||||
****************************************************************/
|
****************************************************************/
|
||||||
|
|
||||||
static void __noreturn
|
// Inlined version of memset (to avoid function calls during intial boot code)
|
||||||
|
static void __always_inline
|
||||||
|
boot_memset(void *s, int c, size_t n)
|
||||||
|
{
|
||||||
|
volatile uint32_t *p = s;
|
||||||
|
while (n) {
|
||||||
|
*p++ = c;
|
||||||
|
n -= sizeof(*p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inlined version of memcpy (to avoid function calls during intial boot code)
|
||||||
|
static void __always_inline
|
||||||
|
boot_memcpy(void *dest, const void *src, size_t n)
|
||||||
|
{
|
||||||
|
const uint32_t *s = src;
|
||||||
|
volatile uint32_t *d = dest;
|
||||||
|
while (n) {
|
||||||
|
*d++ = *s++;
|
||||||
|
n -= sizeof(*d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main initialization code (called from ResetHandler below)
|
||||||
|
static void __noreturn __section(".text.armcm_boot.stage_two")
|
||||||
reset_handler_stage_two(void)
|
reset_handler_stage_two(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -60,10 +84,10 @@ reset_handler_stage_two(void)
|
||||||
|
|
||||||
// Copy global variables from flash to ram
|
// Copy global variables from flash to ram
|
||||||
uint32_t count = (&_data_end - &_data_start) * 4;
|
uint32_t count = (&_data_end - &_data_start) * 4;
|
||||||
__builtin_memcpy(&_data_start, &_data_flash, count);
|
boot_memcpy(&_data_start, &_data_flash, count);
|
||||||
|
|
||||||
// Clear the bss segment
|
// Clear the bss segment
|
||||||
__builtin_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4);
|
boot_memset(&_bss_start, 0, (&_bss_end - &_bss_start) * 4);
|
||||||
|
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
|
@ -80,7 +104,7 @@ reset_handler_stage_two(void)
|
||||||
|
|
||||||
// Initial code entry point - invoked by the processor after a reset
|
// Initial code entry point - invoked by the processor after a reset
|
||||||
// Reset interrupts and stack to take control from bootloaders
|
// Reset interrupts and stack to take control from bootloaders
|
||||||
void
|
void __section(".text.armcm_boot.stage_one")
|
||||||
ResetHandler(void)
|
ResetHandler(void)
|
||||||
{
|
{
|
||||||
__disable_irq();
|
__disable_irq();
|
||||||
|
|
Loading…
Reference in New Issue