From 5bf7890d32b26713d314a750e75e5cb71552fcf8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 28 Jan 2019 06:08:30 -0600 Subject: [PATCH] arch/arm/src/lpc17xx/lpc17_allocateheap.c: Correct some confusion in the memory layout introduced in commit 40d666f4406774c0b8ff47a9572583d840350bf3. The 'primary ram' may be either the internal SRAM or the external DRAM (in the case where an external bootloader has previously initialized the SDRAM). The primary ram is laid out as: .data, .bss, then the IDLE stack allocation. The global variable g_idlestack is the top of the IDLE stack and also the beginning of memory available for the heap in primary ram. With this change, a range comparison is used to determin if g_idlestack lies in SRAM or SDRAM. If so, then the remainder of the memory is available for HEAP usage. --- arch/arm/src/lpc17xx/lpc17_allocateheap.c | 90 ++++++++++++++++------- 1 file changed, 65 insertions(+), 25 deletions(-) diff --git a/arch/arm/src/lpc17xx/lpc17_allocateheap.c b/arch/arm/src/lpc17xx/lpc17_allocateheap.c index 99e0f55e4e6..0f1a96cff87 100644 --- a/arch/arm/src/lpc17xx/lpc17_allocateheap.c +++ b/arch/arm/src/lpc17xx/lpc17_allocateheap.c @@ -56,6 +56,7 @@ #include "lpc17_emacram.h" #include "lpc17_ohciram.h" #include "lpc17_mpuinit.h" +#include "lpc17_start.h" /**************************************************************************** * Pre-processor Definitions @@ -248,9 +249,43 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) /* Allow user-mode access to the user heap memory */ lpc17_mpu_uheap((uintptr_t)ubase, usize); + +#elif CONFIG_MM_REGIONS >= 3 && defined(CONFIG_LPC17_EXTDRAM) && \ + defined(CONFIG_LPC17_EXTDRAMHEAP) + /* We are going to allocate a DRAM heap. In the case where a bootloader + * is used (and has initialized SDRAM), it is possible that .data, .bss, + * and the IDLE stack reside in SDRAM. + */ + + uintptr_t sram_start = CONFIG_RAM_START; + + /* Is SRAM the primary RAM? I.e., do .data, .bss, and the IDLE thread + * stack lie in SRAM? + */ + + if (g_idlestack >= CONFIG_RAM_START && + g_idlestack < CONFIG_RAM_END) + { + /* Yes, then the SRAM heap starts in SRAM after the IDLE stack */ + + sram_start = g_idlestack; + } + else + { + /* Use the entire SRAM for heap */ + + sram_start = CONFIG_RAM_START; + } + + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)sram_start; + *heap_size = CONFIG_RAM_END - sram_start; + #else - /* Return the heap settings */ + /* Return the heap settings (assuming that .data, .bss, and the IDLE + * stack lie in SRAM). + */ board_autoled_on(LED_HEAPALLOCATE); *heap_start = (FAR void *)g_idle_topstack; @@ -266,6 +301,9 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates * (and protects) the kernel-space heap. * + * REVISIT: This does not account for the possibility that the kernel + * heap might lie in SDRAM. + * ****************************************************************************/ #if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) @@ -342,38 +380,40 @@ void up_addregion(void) #if CONFIG_MM_REGIONS >= 3 #if defined(CONFIG_LPC17_EXTDRAM) && defined(CONFIG_LPC17_EXTDRAMHEAP) -#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) - /* Allow user-mode access to external DRAM heap memory */ - - lpc17_mpu_uheap((uintptr_t)LPC17_EXTDRAM_CS0, CONFIG_LPC17_EXTDRAMSIZE); - -#endif - /* Add external DRAM heap memory to the user heap */ { - uint32_t *dram_start = (FAR void *)LPC17_EXTDRAM_CS0; - uint32_t *dram_end = dram_start + CONFIG_LPC17_EXTDRAMSIZE / 4; + uintptr_t dram_end = LPC17_EXTDRAM_CS0 + CONFIG_LPC17_EXTDRAMSIZE; + uintptr_t dram_start; + uintptr_t heap_size; - if (&_eronly >= dram_start && &_eronly <= dram_end) + /* Is SDRAM the primary RAM? I.e., do .data, .bss, and the IDLE thread + * stack lie in SDRAM? + */ + + if (g_idlestack >= LPC17_EXTDRAM_CS0 && + g_idlestack < dram_end) { - dram_start = (uint32_t *)&_eronly + 0x100; + /* Yes, then the SDRAM heap starts in SDRAM after the IDLE stack */ + + dram_start = g_idlestack; + } + else + { + /* Use the entire SDRAM for heap */ + + dram_start = LPC17_EXTDRAM_CS0; } - if (&_edata >= dram_start && &_edata <= dram_end) - { - dram_start = &_edata + 0x100; - } + heap_size = dram_end - dram_start; - if (&_ebss >= dram_start && &_ebss <= dram_end) - { - dram_start = &_ebss + 0x100; - } +#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP) + /* Allow user-mode access to the external DRAM heap memory */ - if (((uintptr_t)dram_start & 0xff) != 0) - { - dram_start = (uint32_t *)((uintptr_t)dram_start & ~0xff); - } + lpc17_mpu_uheap(dram_start, heap_size); +#endif - kumm_addregion(dram_start, (char *)dram_end - (char *)dram_start); + /* Add external DRAM heap memory to the user heap */ + + kumm_addregion(dram_start, heap_size); } #endif