From ed9fced470fe52c2e89a72ad3cde3f92363c6993 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 13 Sep 2014 12:25:32 -0600 Subject: [PATCH] Add a configuration option for dynamic stack management --- arch/Kconfig | 31 +++++++++++--- arch/arm/include/arch.h | 18 +++++---- arch/arm/src/armv7-a/arm_addrenv.c | 4 -- arch/arm/src/sama5/sam_pgalloc.c | 7 +++- configs/sama5d4-ek/elf/defconfig | 3 +- configs/sama5d4-ek/knsh/defconfig | 3 +- configs/sama5d4-ek/knsh/defconfig.ROMFS | 3 +- include/nuttx/addrenv.h | 54 ++++++++++++++----------- 8 files changed, 74 insertions(+), 49 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index e57d59c355f..9a7aa147630 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -199,11 +199,6 @@ config ARCH_HEAP_VBASE ---help--- The virtual address of the beginning of the heap region. -config ARCH_STACK_VBASE - hex "Virtual stack base" - ---help--- - The virtual address of the beginning the stack region - config ARCH_TEXT_NPAGES int "Max .text pages" default 1 @@ -228,6 +223,30 @@ config ARCH_HEAP_NPAGES This, along with knowledge of the page size, determines the size of the heap virtual address space. Default is 1. +config ARCH_STACK_DYNAMIC + bool "Dynamic stack" + default n if !BUILD_KERNEL || !LIBC_EXECFUNCS + default y if BUILD_KERNEL && LIBC_EXECFUNCS + ---help--- + Select this option if the user process stack resides in its own + address space. The naming of this selection implies that dynamic + stack allocation is supported. Certainly this option must be set if + dynamic stack allocation is supported by a platform. But the more + general meaning of this configuration environment is simply that the + stack has its own address space. + + NOTE: This options is also *required* if BUILD_KERNEL and + LIBC_EXECFUNCS are selected. Why? Because the caller's stack must + be preserved in its own address space when we instantiate the + environment of the new process in order to initialize it. + +if ARCH_STACK_DYNAMIC + +config ARCH_STACK_VBASE + hex "Virtual stack base" + ---help--- + The virtual address of the beginning the stack region + config ARCH_STACK_NPAGES int "Max. stack pages" default 1 @@ -236,6 +255,8 @@ config ARCH_STACK_NPAGES This, along with knowledge of the page size, determines the size of the stack virtual address space. Default is 1. +endif # ARCH_STACK_DYNAMIC + config ARCH_PGPOOL_MAPPING bool "Have page pool mapping" default n diff --git a/arch/arm/include/arch.h b/arch/arm/include/arch.h index 0e17ee79ce5..5b962f3fc00 100644 --- a/arch/arm/include/arch.h +++ b/arch/arm/include/arch.h @@ -99,17 +99,19 @@ do { \ /* Convert 4KiB pages to 1MiB sections */ -# define __PG2SECT_SHIFT (20 - MM_PGSHIFT) -# define __PG2SECT_MASK ((1 << __PG2SECT_SHIFT) - 1) +# define __PG2SECT_SHIFT (20 - MM_PGSHIFT) +# define __PG2SECT_MASK ((1 << __PG2SECT_SHIFT) - 1) -# define ARCH_PG2SECT(p) (((p) + __PG2SECT_MASK) >> __PG2SECT_SHIFT) -# define ARCH_SECT2PG(s) ((s) << __PG2SECT_SHIFT) +# define ARCH_PG2SECT(p) (((p) + __PG2SECT_MASK) >> __PG2SECT_SHIFT) +# define ARCH_SECT2PG(s) ((s) << __PG2SECT_SHIFT) -# define ARCH_TEXT_NSECTS ARCH_PG2SECT(CONFIG_ARCH_TEXT_NPAGES) -# define ARCH_DATA_NSECTS ARCH_PG2SECT(CONFIG_ARCH_DATA_NPAGES) -# define ARCH_HEAP_NSECTS ARCH_PG2SECT(CONFIG_ARCH_HEAP_NPAGES) -# define ARCH_STACK_NSECTS ARCH_PG2SECT(CONFIG_ARCH_STACK_NPAGES) +# define ARCH_TEXT_NSECTS ARCH_PG2SECT(CONFIG_ARCH_TEXT_NPAGES) +# define ARCH_DATA_NSECTS ARCH_PG2SECT(CONFIG_ARCH_DATA_NPAGES) +# define ARCH_HEAP_NSECTS ARCH_PG2SECT(CONFIG_ARCH_HEAP_NPAGES) +# ifdef CONFIG_ARCH_STACK_DYNAMIC +# define ARCH_STACK_NSECTS ARCH_PG2SECT(CONFIG_ARCH_STACK_NPAGES) +# endif #endif /**************************************************************************** diff --git a/arch/arm/src/armv7-a/arm_addrenv.c b/arch/arm/src/armv7-a/arm_addrenv.c index 5dc1652c933..c05f6b21ede 100644 --- a/arch/arm/src/armv7-a/arm_addrenv.c +++ b/arch/arm/src/armv7-a/arm_addrenv.c @@ -104,10 +104,6 @@ # error CONFIG_ARCH_HEAP_VBASE not aligned to section boundary #endif -#if (CONFIG_ARCH_STACK_VBASE & SECTION_MASK) != 0 -# error CONFIG_ARCH_STACK_VBASE not aligned to section boundary -#endif - /* Using a 4KiB page size, each 1MiB section maps to a PTE containing * 256*2KiB entries */ diff --git a/arch/arm/src/sama5/sam_pgalloc.c b/arch/arm/src/sama5/sam_pgalloc.c index b09c6cf62f6..b3f5c5f87b8 100644 --- a/arch/arm/src/sama5/sam_pgalloc.c +++ b/arch/arm/src/sama5/sam_pgalloc.c @@ -137,8 +137,11 @@ uintptr_t sam_physpgaddr(uintptr_t vaddr) if ((vaddr >= CONFIG_ARCH_TEXT_VBASE && vaddr < ARCH_TEXT_VEND) || (vaddr >= CONFIG_ARCH_DATA_VBASE && vaddr < ARCH_DATA_VEND) || - (vaddr >= CONFIG_ARCH_HEAP_VBASE && vaddr < ARCH_HEAP_VEND) || - (vaddr >= CONFIG_ARCH_STACK_VBASE && vaddr < ARCH_STACK_VEND)) + (vaddr >= CONFIG_ARCH_HEAP_VBASE && vaddr < ARCH_HEAP_VEND) +#ifdef CONFIG_ARCH_STACK_DYNAMIC + || (vaddr >= CONFIG_ARCH_STACK_VBASE && vaddr < ARCH_STACK_VEND) +#endif + ) { /* Yes.. Get Level 1 page table entry corresponding to this virtual * address. diff --git a/configs/sama5d4-ek/elf/defconfig b/configs/sama5d4-ek/elf/defconfig index 732c7f357aa..331f1865f20 100644 --- a/configs/sama5d4-ek/elf/defconfig +++ b/configs/sama5d4-ek/elf/defconfig @@ -266,11 +266,10 @@ CONFIG_ARCH_ADDRENV=y CONFIG_ARCH_TEXT_VBASE=0x80000000 CONFIG_ARCH_DATA_VBASE=0x80100000 CONFIG_ARCH_HEAP_VBASE=0x80200000 -CONFIG_ARCH_STACK_VBASE=0x80300000 CONFIG_ARCH_TEXT_NPAGES=256 CONFIG_ARCH_DATA_NPAGES=256 CONFIG_ARCH_HEAP_NPAGES=256 -CONFIG_ARCH_STACK_NPAGES=256 +# CONFIG_ARCH_STACK_DYNAMIC is not set CONFIG_ARCH_PGPOOL_MAPPING=y CONFIG_ARCH_PGPOOL_PBASE=0x28000000 CONFIG_ARCH_PGPOOL_VBASE=0x28000000 diff --git a/configs/sama5d4-ek/knsh/defconfig b/configs/sama5d4-ek/knsh/defconfig index b14852ea61f..f0b17178e13 100644 --- a/configs/sama5d4-ek/knsh/defconfig +++ b/configs/sama5d4-ek/knsh/defconfig @@ -277,11 +277,10 @@ CONFIG_ARCH_ADDRENV=y CONFIG_ARCH_TEXT_VBASE=0x80000000 CONFIG_ARCH_DATA_VBASE=0x80100000 CONFIG_ARCH_HEAP_VBASE=0x80200000 -CONFIG_ARCH_STACK_VBASE=0x80300000 CONFIG_ARCH_TEXT_NPAGES=256 CONFIG_ARCH_DATA_NPAGES=256 CONFIG_ARCH_HEAP_NPAGES=256 -CONFIG_ARCH_STACK_NPAGES=256 +# CONFIG_ARCH_STACK_DYNAMIC is not set CONFIG_ARCH_PGPOOL_MAPPING=y CONFIG_ARCH_PGPOOL_PBASE=0x28000000 CONFIG_ARCH_PGPOOL_VBASE=0x28000000 diff --git a/configs/sama5d4-ek/knsh/defconfig.ROMFS b/configs/sama5d4-ek/knsh/defconfig.ROMFS index 95f367a52d5..8b4cbe1b78f 100644 --- a/configs/sama5d4-ek/knsh/defconfig.ROMFS +++ b/configs/sama5d4-ek/knsh/defconfig.ROMFS @@ -261,11 +261,10 @@ CONFIG_ARCH_ADDRENV=y CONFIG_ARCH_TEXT_VBASE=0x80000000 CONFIG_ARCH_DATA_VBASE=0x80100000 CONFIG_ARCH_HEAP_VBASE=0x80200000 -CONFIG_ARCH_STACK_VBASE=0x80300000 CONFIG_ARCH_TEXT_NPAGES=256 CONFIG_ARCH_DATA_NPAGES=256 CONFIG_ARCH_HEAP_NPAGES=256 -CONFIG_ARCH_STACK_NPAGES=256 +# CONFIG_ARCH_STACK_DYNAMIC is not set CONFIG_ARCH_PGPOOL_MAPPING=y CONFIG_ARCH_PGPOOL_PBASE=0x28000000 CONFIG_ARCH_PGPOOL_VBASE=0x28000000 diff --git a/include/nuttx/addrenv.h b/include/nuttx/addrenv.h index 385bce32ef4..5f5ee5f1f9e 100644 --- a/include/nuttx/addrenv.h +++ b/include/nuttx/addrenv.h @@ -86,7 +86,7 @@ #ifndef CONFIG_ARCH_DATA_VBASE # error CONFIG_ARCH_DATA_VBASE not defined -# define CONFIG_ARCH_DATA_VBASE (CONFIG_ARCH_TEXT_VBASE + ARCH_TEXT_SIZE) +# define CONFIG_ARCH_DATA_VBASE ARCH_TEXT_VEND #endif #if (CONFIG_ARCH_DATA_VBASE & CONFIG_MM_MASK) != 0 @@ -123,7 +123,7 @@ #ifndef CONFIG_ARCH_HEAP_VBASE # error CONFIG_ARCH_HEAP_VBASE not defined -# define CONFIG_ARCH_HEAP_VBASE (CONFIG_ARCH_DATA_VBASE + ARCH_DATA_SIZE) +# define CONFIG_ARCH_HEAP_VBASE ARCH_DATA_VEND #endif #if (CONFIG_ARCH_HEAP_VBASE & CONFIG_MM_MASK) != 0 @@ -138,29 +138,35 @@ #define ARCH_HEAP_SIZE (CONFIG_ARCH_HEAP_NPAGES * CONFIG_MM_PGSIZE) #define ARCH_HEAP_VEND (CONFIG_ARCH_HEAP_VBASE + ARCH_HEAP_SIZE) -/* Stack region */ +#ifdef CONFIG_ARCH_STACK_DYNAMIC + /* Stack region */ -#ifndef CONFIG_ARCH_STACK_VBASE -# error CONFIG_ARCH_STACK_VBASE not defined -# define CONFIG_ARCH_STACK_VBASE (CONFIG_ARCH_HEAP_VBASE + ARCH_HEAP_SIZE) +# ifndef CONFIG_ARCH_STACK_VBASE +# error CONFIG_ARCH_STACK_VBASE not defined +# define CONFIG_ARCH_STACK_VBASE ARCH_HEAP_VEND +# endif + +# if (CONFIG_ARCH_STACK_VBASE & CONFIG_MM_MASK) != 0 +# error CONFIG_ARCH_STACK_VBASE not aligned to page boundary +# endif + +# ifndef CONFIG_ARCH_STACK_NPAGES +# warning CONFIG_ARCH_STACK_NPAGES not defined +# define CONFIG_ARCH_STACK_NPAGES 1 +# endif + +# define ARCH_STACK_SIZE (CONFIG_ARCH_STACK_NPAGES * CONFIG_MM_PGSIZE) +# define ARCH_STACK_VEND (CONFIG_ARCH_STACK_VBASE + ARCH_STACK_SIZE) + + /* A single page scratch region used for temporary mappings */ + +# define ARCH_SCRATCH_VBASE ARCH_STACK_VEND +#else + /* A single page scratch region used for temporary mappings */ + +# define ARCH_SCRATCH_VBASE ARCH_HEAP_VEND #endif -#if (CONFIG_ARCH_STACK_VBASE & CONFIG_MM_MASK) != 0 -# error CONFIG_ARCH_STACK_VBASE not aligned to page boundary -#endif - -#ifndef CONFIG_ARCH_STACK_NPAGES -# warning CONFIG_ARCH_STACK_NPAGES not defined -# define CONFIG_ARCH_STACK_NPAGES 1 -#endif - -#define ARCH_STACK_SIZE (CONFIG_ARCH_STACK_NPAGES * CONFIG_MM_PGSIZE) -#define ARCH_STACK_VEND (CONFIG_ARCH_STACK_VBASE + ARCH_STACK_SIZE) - -/* A single page scratch region used for temporary mappings */ - -#define ARCH_SCRATCH_VBASE (CONFIG_ARCH_STACK_VBASE + ARCH_STACK_SIZE) - /* There is no need to use the scratch memory region if the page pool memory * is statically mapped. */ @@ -263,9 +269,9 @@ struct addrenv_reserve_s * * up_addrenv_attach - Clone the address environment assigned to one TCB * to another. This operation is done when a pthread - * is created that share's the same address + * is created that share's the same group address * environment. - * up_addrenv_detach - Release the threads reference to an address + * up_addrenv_detach - Release the thread's reference to an address * environment when a task/thread exits. * ****************************************************************************/