SAMA5: If the page table is in high memory, make sure that it is excluded from the heap

This commit is contained in:
Gregory Nutt 2013-07-26 09:16:46 -06:00
parent 0fb58d2cf1
commit ec8a56259c
3 changed files with 63 additions and 29 deletions

View file

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

View file

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

View file

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