summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-31 12:50:05 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-31 12:50:05 -0600
commit17b1bd4cdab460251d12b7a68954486798c17a2e (patch)
treed993e8b8130f9b29ab6a98c5ff67c56a5ff0d200
parent085bc3e78cd5de4a900b00531bb47535d4872924 (diff)
downloadpx4-nuttx-17b1bd4cdab460251d12b7a68954486798c17a2e.tar.gz
px4-nuttx-17b1bd4cdab460251d12b7a68954486798c17a2e.tar.bz2
px4-nuttx-17b1bd4cdab460251d12b7a68954486798c17a2e.zip
Clean up some kernel build heap allocation issues. The Cortex-A kernel build now compiles without errors (but cannot link until brk() and sbrk() are implemented).
-rw-r--r--nuttx/arch/arm/src/sama5/sam_allocateheap.c162
-rw-r--r--nuttx/include/nuttx/arch.h9
-rw-r--r--nuttx/include/nuttx/kmalloc.h6
-rw-r--r--nuttx/include/nuttx/mm.h23
-rw-r--r--nuttx/sched/init/os_start.c6
-rw-r--r--nuttx/sched/sched/sched_free.c5
6 files changed, 75 insertions, 136 deletions
diff --git a/nuttx/arch/arm/src/sama5/sam_allocateheap.c b/nuttx/arch/arm/src/sama5/sam_allocateheap.c
index 44c32fcd4..616b6f0fd 100644
--- a/nuttx/arch/arm/src/sama5/sam_allocateheap.c
+++ b/nuttx/arch/arm/src/sama5/sam_allocateheap.c
@@ -57,6 +57,30 @@
/****************************************************************************
* Private Definitions
****************************************************************************/
+/* Configuration ************************************************************/
+/* Terminology. In the flat build (CONFIG_BUILD_FLAT=y), there is only a
+ * single heap access with the standard allocations (malloc/free). This
+ * heap is referred to as the user heap. In the protected build
+ * (CONFIG_BUILD_PROTECTED=y) where an MPU is used to protect a region of
+ * otherwise flat memory, there will be two allocators: One that allocates
+ * protected (kernel) memory and one that allocates unprotected (user)
+ * memory. These are referred to as the kernel and user heaps,
+ * respectively.
+ *
+ * The ARMv7 has no MPU but does have an MMU. With this MMU, it can support
+ * the kernel build (CONFIG_BUILD_KERNEL=y). In this configuration, there
+ * is again only one heap but, retaining the terminology, this is the kernel
+ * heap.
+ */
+
+#if defined(CONFIG_MM_USER_HEAP) && defined(CONFIG_MM_KERNEL_HEAP)
+# error "Cannot support both user and kernel heaps"
+#elif defined(CONFIG_MM_KERNEL_HEAP)
+# define MM_ADDREGION kmm_addregion
+#else
+# define MM_ADDREGION umm_addregion
+#endif
+
/* The Primary Heap *********************************************************/
/* The physical address of the primary heap is defined by CONFIG_RAM_START,
* CONFIG_RAM_SIZE, and CONFIG_RAM_END where:
@@ -213,60 +237,23 @@
****************************************************************************/
/****************************************************************************
- * Name: up_allocate_heap
+ * Name: up_allocate_heap/up_allocate_kheap
*
* Description:
* This function will be called to dynamically set aside the heap region.
- *
- * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and
- * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the
- * size of the unprotected, user-space heap.
- *
- * If a protected kernel-space heap is provided, the kernel heap must be
- * allocated by an analogous up_allocate_kheap(). A custom version of this
- * file is needed if memory protection of the kernel heap is required.
- *
- * The following memory map is assumed for the flat build:
- *
- * .data region. Size determined at link time.
- * .bss region Size determined at link time.
- * IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE.
- * Heap. Extends to the end of SRAM.
- *
- * The following memory map is assumed for the kernel build:
- *
- * Kernel .data region. Size determined at link time.
- * Kernel .bss region Size determined at link time.
- * Kernel IDLE thread stack. Size determined by CONFIG_IDLETHREAD_STACKSIZE.
- * Padding for alignment
- * User .data region. Size determined at link time.
- * User .bss region Size determined at link time.
- * Kernel heap. Size determined by CONFIG_MM_KERNEL_HEAPSIZE.
- * User heap. Extends to the end of SRAM.
+ * For the flat build, this heap is referred to as the user heap (for
+ * compatibility with other platforms). For the kernel build
+ * (CONFIG_BUILD_KERNEL=y) this is referred to a the kernel heap.
*
****************************************************************************/
+#if defined(CONFIG_MM_USER_HEAP)
void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+#elif defined(CONFIG_MM_KERNEL_HEAP)
+void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
+#endif
{
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
- /* Get the unaligned size and position of the user-space heap.
- * This heap begins after the user-space .bss section at an offset
- * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
- */
-
- uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE;
- size_t usize = SAMA5_PRIMARY_HEAP_END - ubase;
- int log2;
-
- DEBUGASSERT(ubase < (uintptr_t)SAMA5_PRIMARY_HEAP_END);
-
- /* Return the user-space heap settings */
-
- board_led_on(LED_HEAPALLOCATE);
- *heap_start = (FAR void*)ubase;
- *heap_size = usize;
-
-#elif defined(CONFIG_BOOT_SDRAM_DATA)
+#if 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.
*/
@@ -287,40 +274,6 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
}
/****************************************************************************
- * Name: up_allocate_kheap
- *
- * Description:
- * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and
- * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
- * the kernel-space heap. A custom version of this function is need if
- * memory protection of the kernel heap is required.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
-void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
-{
- /* Get the unaligned size and position of the user-space heap.
- * This heap begins after the user-space .bss section at an offset
- * of CONFIG_MM_KERNEL_HEAPSIZE (subject to alignment).
- */
-
- uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE;
- size_t usize = SAMA5_PRIMARY_HEAP_END - ubase;
- int log2;
-
- DEBUGASSERT(ubase < (uintptr_t)SAMA5_PRIMARY_HEAP_END);
-
- /* Return the kernel heap settings (i.e., the part of the heap region
- * that was not dedicated to the user heap).
- */
-
- *heap_start = (FAR void*)USERSPACE->us_bssend;
- *heap_size = ubase - (uintptr_t)USERSPACE->us_bssend;
-}
-#endif
-
-/****************************************************************************
* Name: up_addregion
*
* Description:
@@ -340,16 +293,9 @@ void up_addregion(void)
vaddr = (uintptr_t)SAM_ISRAM0_VADDR
size = SAM_ISRAM0_SIZE + SAM_ISRAM1_SIZE;
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
- /* Allow user-mode access to the ISRAM heap */
-
- sam_uheap(vaddr, size);
-
-#endif
-
/* Add the ISRAM user heap region. */
- kumm_addregion((void *)vaddr, size);
+ MM_ADDREGION((void *)vaddr, size);
nregions--;
#endif
@@ -359,15 +305,9 @@ void up_addregion(void)
vaddr = (uintptr_t)SAM_DDRCS_VSECTION + SAMA5_DDRCS_HEAP_OFFSET;
size = SAMA5_DDRCS_HEAP_SIZE;
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
- /* Allow user-mode access to the DDR-SDRAM heap */
-
- sam_uheap(vaddr, size);
-#endif
-
/* Add the DDR-SDRAM user heap region. */
- kumm_addregion((void *)vaddr, size);
+ MM_ADDREGION((void *)vaddr, size);
nregions--;
}
else
@@ -384,15 +324,9 @@ void up_addregion(void)
vaddr = (uintptr_t)SAM_EBICS0_VSECTION + SAMA5_EBICS0_HEAP_OFFSET;
size = SAMA5_EBICS0_HEAP_SIZE;
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
- /* Allow user-mode access to the EBICS0 heap */
-
- sam_uheap(vaddr, size);
-#endif
-
/* Add the EBICS0 user heap region. */
- kumm_addregion((void *)vaddr, size);
+ MM_ADDREGION((void *)vaddr, size);
nregions--;
}
else
@@ -409,15 +343,9 @@ void up_addregion(void)
vaddr = (uintptr_t)SAM_EBICS1_VSECTION + SAMA5_EBICS1_HEAP_OFFSET;
size = SAMA5_EBICS1_HEAP_SIZE;
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
- /* Allow user-mode access to the EBICS1 heap */
-
- sam_uheap(vaddr, size);
-#endif
-
/* Add the EBICS1 user heap region. */
- kumm_addregion((void *)vaddr, size);
+ MM_ADDREGION((void *)vaddr, size);
nregions--;
}
else
@@ -434,15 +362,9 @@ void up_addregion(void)
vaddr = (uintptr_t)SAM_EBICS2_VSECTION + SAMA5_EBICS2_HEAP_OFFSET;
size = SAMA5_EBICS2_HEAP_SIZE;
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
- /* Allow user-mode access to the EBICS2 heap */
-
- sam_uheap(vaddr, size);
-#endif
-
/* Add the EBICS2 user heap region. */
- kumm_addregion((void *)vaddr, size);
+ MM_ADDREGION((void *)vaddr, size);
nregions--;
}
else
@@ -459,15 +381,9 @@ void up_addregion(void)
vaddr = (uintptr_t)SAM_EBICS3_VSECTION + SAMA5_EBICS3_HEAP_OFFSET;
size = SAMA5_EBICS3_HEAP_SIZE;
-#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP)
- /* Allow user-mode access to the EBICS3 heap */
-
- sam_uheap(vaddr, size);
-#endif
-
/* Add the EBICS3 user heap region. */
- kumm_addregion(vaddr, size);
+ MM_ADDREGION(vaddr, size);
nregions--;
}
else
diff --git a/nuttx/include/nuttx/arch.h b/nuttx/include/nuttx/arch.h
index 63670d27c..0393f6619 100644
--- a/nuttx/include/nuttx/arch.h
+++ b/nuttx/include/nuttx/arch.h
@@ -645,13 +645,14 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size);
* Name: up_allocate_kheap
*
* Description:
- * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and
- * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function allocates
- * (and protects) the kernel-space heap.
+ * For the kernel builds (CONFIG_BUILD_PROTECTED=y or
+ * CONFIG_BUILD_KERNEL=y) there may be both kernel- and user-space heaps
+ * as determined by CONFIG_MM_KERNEL_HEAP=y. This function allocates (and
+ * protects) the kernel-space heap.
*
****************************************************************************/
-#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
+#ifdef CONFIG_MM_KERNEL_HEAP
void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
#endif
diff --git a/nuttx/include/nuttx/kmalloc.h b/nuttx/include/nuttx/kmalloc.h
index 50aa80207..c26fb521e 100644
--- a/nuttx/include/nuttx/kmalloc.h
+++ b/nuttx/include/nuttx/kmalloc.h
@@ -135,7 +135,7 @@ extern "C"
#elif !defined(CONFIG_MM_KERNEL_HEAP)
/* If this the kernel phase of a kernel build, and there are only user-space
* allocators, then the following are defined in userspace.h as macros that
- * call into user-space via a header at the begining of the user-space blob.
+ * call into user-space via a header at the beginning of the user-space blob.
*/
# define kmm_initialize(h,s) /* Initialization done by kumm_initialize */
@@ -178,9 +178,11 @@ bool kmm_heapmember(FAR void *mem);
* sched_garbagecollection().
*/
+#ifdef CONFIG_MM_USER_HEAP
void sched_ufree(FAR void *address);
+#endif
-#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
+#if defined(CONFIG_MM_KERNEL_HEAP) && defined(__KERNEL__)
void sched_kfree(FAR void *address);
#else
# define sched_kfree(a) sched_ufree(a)
diff --git a/nuttx/include/nuttx/mm.h b/nuttx/include/nuttx/mm.h
index de217e550..cfafc8381 100644
--- a/nuttx/include/nuttx/mm.h
+++ b/nuttx/include/nuttx/mm.h
@@ -65,10 +65,27 @@
# define CONFIG_MM_SMALL 1
#endif
+/* Decide if there is a user heap. CONFIG_MM_USER_HEAP=n does not not
+ * really that there is no user heap but, rather, that there is no
+ * user heap available from within the kernel. The user heap is
+ * Available if:
+ *
+ * 1. The code is begin build for kernel space and this is a FLAT build
+ * (CONFIG_BUILD_FLAT=y),
+ * 2. The code is begin build for kernel space and this is a protected
+ * build (CONFIG_BUILD_PROTECTED=y), OR
+ * 3. The code is begin build for user space.
+ */
+
#undef CONFIG_MM_USER_HEAP
-#if (!defined(CONFIG_BUILD_PROTECTED) || !defined(__KERNEL__)) && \
- !defined(CONFIG_BUILD_KERNEL)
-# define CONFIG_MM_USER_HEAP
+#if !defined(CONFIG_BUILD_KERNEL) || !defined(__KERNEL__)
+# define CONFIG_MM_USER_HEAP 1
+#endif
+
+/* The kernel heap is never accessible from user code */
+
+#ifndef __KERNEL__
+# undef CONFIG_MM_KERNEL_HEAP
#endif
/* Chunk Header Definitions *************************************************/
diff --git a/nuttx/sched/init/os_start.c b/nuttx/sched/init/os_start.c
index b1ac5af2f..4f6da4ea5 100644
--- a/nuttx/sched/init/os_start.c
+++ b/nuttx/sched/init/os_start.c
@@ -48,6 +48,7 @@
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
#include <nuttx/lib.h>
+#include <nuttx/mm.h>
#include <nuttx/kmalloc.h>
#include <nuttx/init.h>
@@ -346,15 +347,16 @@ void os_start(void)
FAR void *heap_start;
size_t heap_size;
+#ifdef CONFIG_MM_USER_HEAP
/* Get the user-mode heap from the platform specific code and configure
* the user-mode memory allocator.
*/
up_allocate_heap(&heap_start, &heap_size);
kumm_initialize(heap_start, heap_size);
+#endif
-#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
- defined(CONFIG_MM_KERNEL_HEAP)
+#ifdef CONFIG_MM_KERNEL_HEAP
/* Get the kernel-mode heap from the platform specific code and configure
* the kernel-mode memory allocator.
*/
diff --git a/nuttx/sched/sched/sched_free.c b/nuttx/sched/sched/sched_free.c
index 97f1429f6..6456d099b 100644
--- a/nuttx/sched/sched/sched_free.c
+++ b/nuttx/sched/sched/sched_free.c
@@ -82,6 +82,7 @@
*
************************************************************************/
+#ifdef CONFIG_MM_USER_HEAP
void sched_ufree(FAR void *address)
{
irqstate_t flags;
@@ -122,9 +123,9 @@ void sched_ufree(FAR void *address)
kumm_givesemaphore();
}
}
+#endif
-#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
- defined(CONFIG_MM_KERNEL_HEAP)
+#ifdef CONFIG_MM_KERNEL_HEAP
void sched_kfree(FAR void *address)
{
irqstate_t flags;