Add support for .data and .bss in SDRAM

This commit is contained in:
Gregory Nutt 2014-01-28 14:35:03 -06:00
parent 4aee332cd1
commit c930554c2c
7 changed files with 279 additions and 121 deletions

View File

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

View File

@ -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 <gnutt@nuttx.org>
*
* 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

View File

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

View File

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

View File

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

View File

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

View File

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