diff --git a/arch/arm/src/armv7-a/arm.h b/arch/arm/src/armv7-a/arm.h index 3257f4de686..e6784f2b7cf 100644 --- a/arch/arm/src/armv7-a/arm.h +++ b/arch/arm/src/armv7-a/arm.h @@ -111,6 +111,22 @@ extern "C" { #define EXTERN extern #endif +/**************************************************************************** + * Name: arm_data_initialize + * + * Description: + * Clear all of .bss to zero; set .data to the correct initial values + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +void arm_data_initialize(void); + #undef EXTERN #ifdef __cplusplus } diff --git a/arch/arm/src/armv7-a/arm_head.S b/arch/arm/src/armv7-a/arm_head.S index bce82d50b58..8f64bdc2f29 100644 --- a/arch/arm/src/armv7-a/arm_head.S +++ b/arch/arm/src/armv7-a/arm_head.S @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/armv7-a/arm_head.S * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -70,8 +70,6 @@ */ #ifdef CONFIG_BOOT_RUNFROMFLASH -# define DO_SDRAM_INIT 1 - /* Check for the identity mapping: For this configuration, this would be * the case where the virtual beginning of FLASH is the same as the physical * beginning of FLASH. @@ -98,7 +96,6 @@ #elif defined(CONFIG_BOOT_COPYTORAM) # error "configuration not implemented -# define DO_SDRAM_INIT 1 /* Check for the identity mapping: For this configuration, this would be * the case where the virtual beginning of FLASH is the same as the physical @@ -193,18 +190,6 @@ __start: mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) msr cpsr_c, r0 - /* Initialize DRAM using a macro provided by board-specific logic. - * - * This must be done in two cases: - * 1. CONFIG_BOOT_RUNFROMFLASH. The system is running from FLASH - * 2. CONFIG_BOOT_COPYTORAM. The system booted from FLASH but - * will copy itself to SDRAM. - */ - -#ifdef DO_SDRAM_INIT - config_sdram -#endif - /* Clear the 16K level 1 page table */ ldr r5, .LCppgtable /* r5=phys. page table */ @@ -626,19 +611,70 @@ __start: str r3, [r5, r3, lsr #18] /* identity mapping */ #endif /* !CONFIG_ARCH_ROMPGTABLE && !CONFIG_IDENTITY_TEXTMAP */ - /* Zero BSS and set up the stack pointer */ + /* Set up the stack pointer and clear the frame pointer */ + + ldr sp, .Lstackpointer + mov fp, #0 + + /* Initialize .bss and .data ONLY if .bss and .data lie in SRAM that is + * ready to use. Other memory, such as SDRAM, must be initialized before + * it can be used. up_boot() will perform that memory initialization and + * .bss and .data can be initialized after up_boot() returns. + */ + +#ifndef CONFIG_BOOT_SDRAM_DATA + bl arm_data_initialize +#endif + + /* Perform early C-level, platform-specific initialization. Logic + * within up_boot() must configure SDRAM and call arm_ram_initailize. + */ + + bl up_boot + +#ifdef CONFIG_DEBUG_STACK + /* Write a known value to the IDLE thread stack to support stack + * monitoring logic + */ + + adr r3, .Lstkinit + ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ + +1: /* Top of the loop */ + sub r1, r1, #1 /* R1 = Number of words remaining */ + cmp r1, #0 /* Check (nwords == 0) */ + str r2, [r0], #4 /* Save stack color word, increment stack address */ + bne 1b /* Bottom of the loop */ +#endif + + /* Finally branch to the OS entry point */ + + mov lr, #0 /* LR = return address (none) */ + b os_start /* Branch to os_start */ + .size .Lvstart, .-.Lvstart + +/*************************************************************************** + * Name: arm_data_initialize + ***************************************************************************/ + + .global arm_data_initialize + .type arm_data_initialize, #function + +arm_data_initialize: + + /* zero BSS and set up the stack pointer */ adr r0, .Linitparms - ldmia r0, {r0, r1, sp} + ldmia r0, {r0, r1} /* Clear the frame pointer and .bss */ mov fp, #0 -.Lbssinit: +1: cmp r0, r1 /* Clear up to _bss_end_ */ strcc fp, [r0],#4 - bcc .Lbssinit + bcc 1b /* If the .data section is in a separate, uninitialized address space, * then we will also need to copy the initial values of of the .data @@ -653,45 +689,34 @@ __start: adr r3, .Ldatainit ldmia r3, {r0, r1, r2} -1: ldmia r0!, {r3 - r10} +2: + ldmia r0!, {r3 - r10} stmia r1!, {r3 - r10} cmp r1, r2 - blt 1b + blt 2b #endif - /* Perform early C-level, platform-specific initialization */ + /* And return to the caller */ - bl up_boot + bx lr + .size arm_data_initialize, . - arm_data_initialize -#ifdef CONFIG_DEBUG_STACK - /* Write a known value to the IDLE thread stack to support stack - * monitoring logic - */ - - adr r3, .Lstkinit - ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ - -2: /* Top of the loop */ - sub r1, r1, #1 /* R1 = Number of words remaining */ - cmp r1, #0 /* Check (nwords == 0) */ - str r2, [r0], #4 /* Save stack color word, increment stack address */ - bne 2b /* Bottom of the loop */ - -#endif - - /* Finally branch to the OS entry point */ - - mov lr, #0 /* LR = return address (none) */ - b os_start /* Branch to os_start */ +/*************************************************************************** + * Text-section constants + ***************************************************************************/ /* Text-section constants: * * _sbss is the start of the BSS region (see ld.script) - * _ebss is the end of the BSS regsion (see ld.script) + * _ebss is the end of the BSS region (see ld.script) * - * The idle task stack starts at the end of BSS and is of size + * The idle task stack usually starts at the end of BSS and is of size * CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the * end of memory. See g_idle_topstack below. + * + * In the case where CONFIG_BOOT_SDRAM_DATA is defined, the IDLE stack is + * in ISRAM, but the heap is in SDRAM beginning at _ebss and extending + * to the end of SDRAM. */ #ifndef CONFIG_ARCH_ROMPGTABLE @@ -708,9 +733,16 @@ __start: .Linitparms: .long _sbss .long _ebss - .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 .size .Linitparms, . -.Linitparms +.Lstackpointer: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE-4 +#else + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 +#endif + .size .Lstackpointer, . -.Lstackpointer + #ifdef CONFIG_BOOT_RUNFROMFLASH .type .Ldatainit, %object .Ldatainit: @@ -723,14 +755,19 @@ __start: #ifdef CONFIG_DEBUG_STACK .type .Lstkinit, %object .Lstkinit: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */ +#else .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ +#endif .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) .long STACK_COLOR /* Stack coloration word */ .size .Lstkinit, . -.Lstkinit #endif - .size .Lvstart, .-.Lvstart - /* Data section variables */ +/*************************************************************************** + * Data section variables + ***************************************************************************/ /* This global variable is unsigned long g_idle_topstack and is * exported from here only because of its coupling to .Linitparms @@ -741,7 +778,13 @@ __start: .align 4 .globl g_idle_topstack .type g_idle_topstack, object + g_idle_topstack: + +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE +#else .long _ebss+CONFIG_IDLETHREAD_STACKSIZE +#endif .size g_idle_topstack, .-g_idle_topstack .end diff --git a/arch/arm/src/armv7-a/arm_pghead.S b/arch/arm/src/armv7-a/arm_pghead.S index 36497e75520..7321f2f214f 100644 --- a/arch/arm/src/armv7-a/arm_pghead.S +++ b/arch/arm/src/armv7-a/arm_pghead.S @@ -80,8 +80,6 @@ */ #ifdef CONFIG_BOOT_RUNFROMFLASH -# define DO_SDRAM_INIT 1 - /* Check for the identity mapping: For this configuration, this would be * the case where the virtual beginning of FLASH is the same as the physical * beginning of FLASH. @@ -108,7 +106,6 @@ #elif defined(CONFIG_BOOT_COPYTORAM) # error "configuration not implemented -# define DO_SDRAM_INIT 1 /* Check for the identity mapping: For this configuration, this would be * the case where the virtual beginning of FLASH is the same as the physical @@ -221,18 +218,6 @@ __start: mov r0, #(PSR_MODE_SVC | PSR_I_BIT | PSR_F_BIT) msr cpsr_c, r0 - /* Initialize DRAM using a macro provided by board-specific logic. - * - * This must be done in two cases: - * 1. CONFIG_BOOT_RUNFROMFLASH. The system is running from FLASH - * 2. CONFIG_BOOT_COPYTORAM. The system booted from FLASH but - * will copy itself to SDRAM. - */ - -#ifdef DO_SDRAM_INIT - config_sdram -#endif - /* Clear the 16K level 1 page table */ ldr r4, .LCppgtable /* r4=phys. page table */ @@ -665,38 +650,30 @@ __start: #endif /* CONFIG_BOOT_RUNFROMFLASH */ - /* Zero BSS and set up the stack pointer */ - - adr r0, .Linitparms - ldmia r0, {r0, r1, sp} - - /* Clear the frame pointer and .bss */ - - mov fp, #0 - -.Lbssinit: - cmp r0, r1 /* Clear up to _bss_end_ */ - strcc fp, [r0],#4 - bcc .Lbssinit - - /* If the .data section is in a separate, unitialized address space, - * then we will also need to copy the initial values of of the .data - * section from the .text region into that .data region. This would - * be the case if we are executing from FLASH and the .data section - * lies in a different physical address region OR if we are support - * on-demand paging and the .data section lies in a different virtual - * address region. + /* Initialize .bss and .data ONLY if .bss and .data lie in SRAM that is + * ready to use. Other memory, such as SDRAM, must be initialized before + * it can be used. up_boot() will perform that memory initialization and + * .bss and .data can be initialized after up_boot() returns. */ - adr r3, .Ldatainit - ldmia r3, {r0, r1, r2} + /* Set up the stack pointer and clear the frame pointer */ -1: ldmia r0!, {r3 - r10} - stmia r1!, {r3 - r10} - cmp r1, r2 - blt 1b + ldr sp, .Lstackpointer + mov fp, #0 - /* Perform early C-level, platform-specific initialization */ + /* Initialize .bss and .data ONLY if .bss and .data lie in SRAM that is + * ready to use. Other memory, such as SDRAM, must be initialized before + * it can be used. up_boot() will perform that memory initialization and + * .bss and .data can be initialized after up_boot() returns. + */ + +#ifndef CONFIG_BOOT_SDRAM_DATA + bl arm_data_initialize +#endif + + /* Perform early C-level, platform-specific initialization. Logic + * within up_boot() must configure SDRAM and call arm_ram_initailize. + */ bl up_boot @@ -708,36 +685,99 @@ __start: adr r3, .Lstkinit ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */ -2: /* Top of the loop */ +1: /* Top of the loop */ sub r1, r1, #1 /* R1 = Number of words remaining */ cmp r1, #0 /* Check (nwords == 0) */ str r2, [r0], #4 /* Save stack color word, increment stack address */ - bne 2b /* Bottom of the loop */ - + bne 1b /* Bottom of the loop */ #endif /* Finally branch to the OS entry point */ mov lr, #0 /* LR = return address (none) */ b os_start /* Branch to os_start */ + .size .Lvstart, .-.Lvstart + +/*************************************************************************** + * Name: arm_data_initialize + ***************************************************************************/ + + .global arm_data_initialize + .type arm_data_initialize, #function + +arm_data_initialize: + + /* zero BSS and set up the stack pointer */ + + adr r0, .Linitparms + ldmia r0, {r0, r1} + + /* Clear the frame pointer and .bss */ + + mov fp, #0 + +1: + cmp r0, r1 /* Clear up to _bss_end_ */ + strcc fp, [r0],#4 + bcc 1b + + /* If the .data section is in a separate, uninitialized address space, + * then we will also need to copy the initial values of of the .data + * section from the .text region into that .data region. This would + * be the case if we are executing from FLASH and the .data section + * lies in a different physical address region OR if we are support + * on-demand paging and the .data section lies in a different virtual + * address region. + */ + +#if defined(CONFIG_BOOT_RUNFROMFLASH) + adr r3, .Ldatainit + ldmia r3, {r0, r1, r2} + +2: + ldmia r0!, {r3 - r10} + stmia r1!, {r3 - r10} + cmp r1, r2 + blt 2b +#endif + + /* And return to the caller */ + + bx lr + .size arm_data_initialize, . - arm_data_initialize + +/*************************************************************************** + * Text-section constants + ***************************************************************************/ /* Text-section constants: * * _sbss is the start of the BSS region (see ld.script) * _ebss is the end of the BSS regsion (see ld.script) * - * The idle task stack starts at the end of BSS and is of size + * The idle task stack usually starts at the end of BSS and is of size * CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the * end of memory. See g_idle_topstack below. + * + * In the case where CONFIG_BOOT_SDRAM_DATA is defined, the IDLE stack is + * in ISRAM, but the heap is in SDRAM beginning at _ebss and extending + * to the end of SDRAM. */ .type .Linitparms, %object .Linitparms: .long _sbss .long _ebss - .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 .size .Linitparms, . -.Linitparms +.Lstackpointer: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE-4 +#else + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE-4 +#endif + .size .Lstackpointer, . -.Lstackpointer + .type .Ldataspan, %object .Ldataspan: .long PG_L1_DATA_VADDR /* Virtual address in the L1 table */ @@ -765,15 +805,19 @@ __start: #ifdef CONFIG_DEBUG_STACK .type .Lstkinit, %object .Lstkinit: +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */ +#else .long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */ +#endif .long (CONFIG_IDLETHREAD_STACKSIZE >> 2) .long STACK_COLOR /* Stack coloration word */ .size .Lstkinit, . -.Lstkinit #endif - .size .Lvstart, .-.Lvstart - - /* Data section variables */ +/*************************************************************************** + * Data section variables + ***************************************************************************/ /* This global variable is unsigned long g_idle_topstack and is * exported from here only because of its coupling to .Linitparms @@ -784,7 +828,13 @@ __start: .align 4 .globl g_idle_topstack .type g_idle_topstack, object + g_idle_topstack: + +#ifdef CONFIG_BOOT_SDRAM_DATA + .long IDLE_STACK_VBASE+CONFIG_IDLETHREAD_STACKSIZE +#else .long _ebss+CONFIG_IDLETHREAD_STACKSIZE +#endif .size g_idle_topstack, .-g_idle_topstack .end diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig index ea4b0b7295e..7ac338eca95 100644 --- a/arch/arm/src/sama5/Kconfig +++ b/arch/arm/src/sama5/Kconfig @@ -2969,6 +2969,7 @@ config SAMA5_DDRCS bool "External DDR-SDRAM Memory" default n depends on SAMA5_MPDDRC + select ARCH_HAVE_SDRAM ---help--- Build in support for DDR-SDRAM memory resources. diff --git a/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/arch/arm/src/sama5/chip/sama5d3x_memorymap.h index 6b7f57254d4..e80c58032e9 100644 --- a/arch/arm/src/sama5/chip/sama5d3x_memorymap.h +++ b/arch/arm/src/sama5/chip/sama5d3x_memorymap.h @@ -616,6 +616,10 @@ # endif # define PGTABLE_IN_HIGHSRAM 1 +# ifdef CONFIG_BOOT_SDRAM_DATA +# error CONFIG_BOOT_SDRAM_DATA not suupported in this configuration +# endif + # else /* CONFIG_BOOT_RUNFROMISRAM && CONFIG_ARCH_LOWVECTORS */ /* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps @@ -629,6 +633,11 @@ # endif # define PGTABLE_IN_LOWSRAM 1 +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (PGTABLE_BASE_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (PGTABLE_BASE_VADDR + PGTABLE_SIZE) +# endif + # endif /* CONFIG_BOOT_RUNFROMISRAM && CONFIG_ARCH_LOWVECTORS */ /* In either case, the page table lies in ISRAM. If ISRAM is not the @@ -640,6 +649,21 @@ # define ARMV7A_PGTABLE_MAPPING 1 # endif +#else /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ + + /* Sanity check.. if one is defined, both should be defined */ + +# if !defined(PGTABLE_BASE_PADDR) || !defined(PGTABLE_BASE_VADDR) +# error "One of PGTABLE_BASE_PADDR or PGTABLE_BASE_VADDR is undefined" +# endif + + /* If data is in SDRAM, then the IDLE stack at the beginning of ISRAM */ + +# ifdef CONFIG_BOOT_SDRAM_DATA +# define IDLE_STACK_PBASE (SAM_ISRAM0_PADDR + PGTABLE_SIZE) +# define IDLE_STACK_VBASE (SAM_ISRAM0_VADDR + PGTABLE_SIZE) +# endif + #endif /* !PGTABLE_BASE_PADDR || !PGTABLE_BASE_VADDR */ /* Level 2 Page table start addresses. diff --git a/arch/arm/src/sama5/sam_allocateheap.c b/arch/arm/src/sama5/sam_allocateheap.c index 0fab6de3360..63f1d5a9dc0 100644 --- a/arch/arm/src/sama5/sam_allocateheap.c +++ b/arch/arm/src/sama5/sam_allocateheap.c @@ -72,7 +72,7 @@ * start would exclude, for example, any memory at the bottom of the RAM * region used for the 16KB page table. If we are also executing from this * same RAM region then CONFIG_RAM_START is not used. Instead, the value of - * g_idle_stack is the used; this variable holds the first avaiable byte of + * g_idle_stack is the used; this variable holds the first available byte of * memory after the .text, .data, .bss, and IDLE stack allocations. * * CONFIG_RAM_VEND is defined in the configuration it is the usable top of @@ -94,7 +94,8 @@ # undef CONFIG_SAMA5_ISRAM_HEAP #endif -#if !defined(CONFIG_SAMA5_DDRCS) || defined(CONFIG_SAMA5_BOOT_SDRAM) +#if !defined(CONFIG_SAMA5_DDRCS) || defined(CONFIG_SAMA5_BOOT_SDRAM) || \ + defined(CONFIG_BOOT_SDRAM_DATA) # undef CONFIG_SAMA5_DDRCS_HEAP #endif @@ -216,9 +217,20 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)ubase; *heap_size = usize; -#else - /* Return the heap settings */ +#elif defined(CONFIG_BOOT_SDRAM_DATA) + /* In this case, the IDLE stack is in ISRAM, but data is in SDRAM. The + * heap is at the end of BSS through the configured end of SDRAM. + */ + + board_led_on(LED_HEAPALLOCATE); + *heap_start = (FAR void*)&_ebss; + *heap_size = CONFIG_RAM_VEND - (size_t)&_ebss; + +#else + /* Both data and the heap are in ISRAM. The heap is then from the end of + * IDLE stack through the configured end of ISRAM. + */ board_led_on(LED_HEAPALLOCATE); *heap_start = (FAR void*)g_idle_topstack; diff --git a/arch/arm/src/sama5/sam_boot.c b/arch/arm/src/sama5/sam_boot.c index a2a7fc8628a..8b95c75380f 100644 --- a/arch/arm/src/sama5/sam_boot.c +++ b/arch/arm/src/sama5/sam_boot.c @@ -633,6 +633,35 @@ void up_boot(void) arm_fpuconfig(); #endif + /* Perform board-specific initialization, This must include: + * + * - Initialization of board-specific memory resources (e.g., SDRAM) + * - Configuration of board specific resources (PIOs, LEDs, etc). + * + * NOTE: We must use caution prior to this point to make sure that + * the logic does not access any global variables that might lie + * in SDRAM. + */ + + sam_boardinitialize(); + + /* SDRAM was configured in a temporary state to support low-level + * initialization. Now that the SDRAM has been fully initialized, + * we can reconfigure the SDRAM in its final, fully cache-able state. + */ + +#ifdef NEED_SDRAM_REMAPPING + sam_remap(); +#endif + + /* If .data and .bss reside in SDRAM, then initialize the data sections + * now after SDRAM has been initialized. + */ + +#ifdef CONFIG_BOOT_SDRAM_DATA + arm_data_initialize(); +#endif + /* Perform common, low-level chip initialization (might do nothing) */ sam_lowsetup(); @@ -654,21 +683,4 @@ void up_boot(void) #ifdef CONFIG_NUTTX_KERNEL sam_userspace(); #endif - - /* Perform board-specific initialization, This must include: - * - * - Initialization of board-specific memory resources (e.g., SDRAM) - * - Configuration of board specific resources (PIOs, LEDs, etc). - */ - - sam_boardinitialize(); - - /* SDRAM was configured in a temporary state to support low-level - * ininitialization. Now that the SDRAM has been fully initialized, - * we can reconfigure the SDRAM in its final, fully cache-able state. - */ - -#ifdef NEED_SDRAM_REMAPPING - sam_remap(); -#endif }