diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-07-26 09:16:46 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-07-26 09:16:46 -0600 |
commit | 1e3a335beb36c0e88d75e449759d4fc54f4e299e (patch) | |
tree | 4fc509a23db8ff766dc2622b5bb4e9f9214e31fc | |
parent | 5170306806fc4b68047219f811e9fe00f7f030ca (diff) | |
download | nuttx-1e3a335beb36c0e88d75e449759d4fc54f4e299e.tar.gz nuttx-1e3a335beb36c0e88d75e449759d4fc54f4e299e.tar.bz2 nuttx-1e3a335beb36c0e88d75e449759d4fc54f4e299e.zip |
SAMA5: If the page table is in high memory, make sure that it is excluded from the heap
-rw-r--r-- | nuttx/arch/arm/src/armv7-a/mmu.h | 17 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h | 39 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sama5/sam_allocateheap.c | 36 |
3 files changed, 63 insertions, 29 deletions
diff --git a/nuttx/arch/arm/src/armv7-a/mmu.h b/nuttx/arch/arm/src/armv7-a/mmu.h index 7e684fe36..e69e8396c 100644 --- a/nuttx/arch/arm/src/armv7-a/mmu.h +++ b/nuttx/arch/arm/src/armv7-a/mmu.h @@ -539,12 +539,10 @@ /* We position the locked region PTEs at an offset into the first * L2 page table. The L1 entry points to an 1Mb aligned virtual * address. The actual L2 entry will be offset into the aligned - * L2 table. + * L2 table. For 4KB, "small" pages: * - * Coarse: PG_L1_PADDRMASK=0xfffffc00 - * OFFSET=(((a) & 0x000fffff) >> 12) << 2) - * Fine: PG_L1_PADDRMASK=0xfffff000 - * OFFSET=(((a) & 0x000fffff) >> 10) << 2) + * PG_L1_PADDRMASK=0xfffff000 + * OFFSET=(((a) & 0x000fffff) >> 10) << 2) */ #define PG_L1_LOCKED_PADDR (PGTABLE_BASE_PADDR + ((PG_LOCKED_VBASE >> 20) << 2)) @@ -866,10 +864,9 @@ * Name: pg_l1span * * Description: - * Write several, contiguous unmapped coarse L1 page table entries. As - * many entries will be written as many as needed to span npages. This - * macro is used when CONFIG_PAGING is enable. This case, it is used as - * follows: + * Write several, contiguous, unmapped, small L1 page table entries. As many + * entries will be written as many as needed to span npages. This macro is + * used when CONFIG_PAGING is enable. In this case, it is used as follows: * * ldr r0, =PG_L1_PGTABLE_PADDR <-- Address in the L1 table * ldr r1, =PG_L2_PGTABLE_PADDR <-- Physical address of L2 page table @@ -905,7 +902,7 @@ .macro pg_l1span, l1, l2, npages, ppage, mmuflags, tmp b 2f 1: - /* Write the L1 table entry that refers to this (unmapped) coarse page + /* Write the L1 table entry that refers to this (unmapped) small page * table. * * tmp = (l2table | mmuflags), the value to write into the page table diff --git a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h index a5d1065b5..a028b81a6 100644 --- a/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h +++ b/nuttx/arch/arm/src/sama5/chip/sama5d3x_memorymap.h @@ -371,10 +371,17 @@ /* MMU Page Table Location * - * Determine the address of the MMU page table. We will try to place that page - * table at the beginng of ISRAM0 if the vectors are at the high address, 0xffff:0000 - * or at the end of ISRAM1 (or ISRAM0 if ISRAM1 is not available in this architecture) - * if the vectors are at 0x0000:0000 + * Determine the address of the MMU page table. Regardless of the memory + * configuration, we will keep the page table in the SAMA5's internal SRAM. + * We will always attempt to use the bottom 16KB of internal SRAM for the + * page table, but there are a few conditions that affect this: + * + * 1) If CONFIG_ARCH_ROMPGTABLE, then the page table resides in ROM and we + * will not use any page table in RAM. + * 2) We are executing out of SRAM. In this case, vectors will reside at + * the bottom of SRAM, following by .text, .data, .bss, and heep. The + * page table will be squeezed into the end of internal SRAM in this + * case. * * Or... the user may specify the address of the page table explicitly be defining * CONFIG_PGTABLE_VADDR and CONFIG_PGTABLE_PADDR in the configuration or board.h file. @@ -407,11 +414,12 @@ * will probably be in error. In that case PGTABLE_BASE_VADDR is defined * in the file mmu.h * - * We must declare the page table in ISRAM0 or 1. We decide depending upon - * where the vector table was place. + * We must declare the page table at the bottom or at the top of internal + * SRAM. We pick the the bottom of internal SRAM *unless* there are vectors + * in the way at that position. */ -# ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */ +#if defined(CONFIG_BOOT_RUNFROMISRAM) && defined(CONFIG_ARCH_LOWVECTORS) /* In this case, table must lie at the top 16Kb of ISRAM1 (or ISRAM0 if ISRAM1 * is not available in this architecture) @@ -434,9 +442,8 @@ # define PGTABLE_IN_HIGHSRAM 1 # else - /* Otherwise, ISRAM1 (or ISRAM0 if ISRAM1 is not available in this - * architecture) will be mapped so that the end of the SRAM region will - * provide memory for the vectors. The page table will then be places at + /* Otherwise, the vectors lie at another location (perhaps in NOR FLASH, perhaps + * elsewhere in internal SRAM). The page table will then be positioned at * the first 16Kb of ISRAM0. */ @@ -459,7 +466,7 @@ * * That is the offset where the main L2 page table will be positioned. This * corresponds to page table offsets 0x000002000 through 0x000003c00. That - * is 1792 entries mapping 1MB of address each for a total of 1.75 GB of virtual + * is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual * address space) */ @@ -470,9 +477,13 @@ * * 0x00a00000-0x0fffffff: Undefined (246 MB) * - * This corresponds to page table offsets 0x000000028 through 0x00000400. That - * is 246 entries mapping 1MB of address each for a total of 246 MB of virtual - * address space) + * This corresponds to page table offsets 0x000000028 through 0x00000400. + * That is 246 entries each mapping 4KB of address each for a total of 984KB + * of virtual address space). For low vectors, this L2 page table can can + * span: 0x0000:0000 through 0x000f:6000 leaving up to the full 984KB for + * vector logic. For high vectors located at 0xffff:0000, this L2 page + * table can cover only 0xfff0:0000 through 0xffff:6000 which leaves 5KB for + * vectors. */ #define VECTOR_L2_OFFSET 0x000000028 diff --git a/nuttx/arch/arm/src/sama5/sam_allocateheap.c b/nuttx/arch/arm/src/sama5/sam_allocateheap.c index 0828f6d6a..ee0e02a4a 100644 --- a/nuttx/arch/arm/src/sama5/sam_allocateheap.c +++ b/nuttx/arch/arm/src/sama5/sam_allocateheap.c @@ -49,8 +49,10 @@ #include <arch/board/board.h> +#include "chip.h" #include "up_arch.h" #include "up_internal.h" +#include "mmu.h" /**************************************************************************** * Private Definitions @@ -95,6 +97,30 @@ # undef SAMA5_EBICS3_HEAP #endif +/* Adjust the size of the primary RAM region if (1) internal SRAM is the + * the primary RAM region, (2) other logic has positioned the MMU page + * table at the end of the internal SRAM, and (3) this is not a kernel + * build using a separate kernel heap. + * + * NOTES: + * - If this is a kernel build using a separate kernel heap, then the heap + * if defined by the userspace blob. + * + * - Internal SRAM is the "primary" RAM region in the case where we are + * executing from internal SRAM. In that case, g_idle_topstack points + * into internal SRAM and CONFIG_DRAM_END is the end of internal SRAM. + */ + +#if defined(CONFIG_BOOT_RUNFROMISRAM) && defined(PGTABLE_IN_HIGHSRAM) && \ + (!defined(CONFIG_NUTTX_KERNEL) || !defined(CONFIG_MM_KERNEL_HEAP)) +# define ADJUSTED_RAM_END (CONFIG_DRAM_END-PGTABLE_SIZE) + +/* Otherwise, the heap extends to the end of the primary RAM */ + +#else +# define ADJUSTED_RAM_END CONFIG_DRAM_END +#endif + /**************************************************************************** * Private Data ****************************************************************************/ @@ -150,10 +176,10 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) */ uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; - size_t usize = CONFIG_DRAM_END - ubase; + size_t usize = ADJUSTED_RAM_END - ubase; int log2; - DEBUGASSERT(ubase < (uintptr_t)CONFIG_DRAM_END); + DEBUGASSERT(ubase < (uintptr_t)ADJUSTED_RAM_END); /* Return the user-space heap settings */ @@ -166,7 +192,7 @@ void up_allocate_heap(FAR void **heap_start, size_t *heap_size) up_ledon(LED_HEAPALLOCATE); *heap_start = (FAR void*)g_idle_topstack; - *heap_size = CONFIG_DRAM_END - g_idle_topstack; + *heap_size = ADJUSTED_RAM_END - g_idle_topstack; #endif } @@ -190,10 +216,10 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size) */ uintptr_t ubase = (uintptr_t)USERSPACE->us_bssend + CONFIG_MM_KERNEL_HEAPSIZE; - size_t usize = CONFIG_DRAM_END - ubase; + size_t usize = ADJUSTED_RAM_END - ubase; int log2; - DEBUGASSERT(ubase < (uintptr_t)CONFIG_DRAM_END); + DEBUGASSERT(ubase < (uintptr_t)ADJUSTED_RAM_END); /* Return the kernel heap settings (i.e., the part of the heap region * that was not dedicated to the user heap). |