From 95c79c675cbd50192566109b69e6032a158d5478 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 24 Aug 2014 09:57:53 -0600 Subject: [PATCH] Add addrenv.h; First cut at Cortex-A address environment structures; Add configuration options to setup address enviornment --- arch/Kconfig | 58 +++++++++++++++++++++++++++++- arch/arm/include/arch.h | 32 ++++++++++++++++- arch/arm/include/armv7-a/irq.h | 10 ++++++ arch/arm/src/armv7-a/arm_addrenv.c | 8 +++-- arch/z80/include/z180/arch.h | 2 +- arch/z80/src/z180/z180_mmu.c | 6 ++-- 6 files changed, 107 insertions(+), 9 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 92bdb83429..4db654dd01 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -154,7 +154,7 @@ config ARCH_HAVE_EXTCLK bool default n -config ARCH_ADDRENV +menuconfig ARCH_ADDRENV bool "Address environments" default n depends on ARCH_HAVE_ADDRENV @@ -162,6 +162,62 @@ config ARCH_ADDRENV Support per-task address environments using the MMU... i.e., support "processes" +if ARCH_ADDRENV && ARCH_HAVE_MMU + +config ARCH_TEXT_VBASE + hex "Virtual .text base" + ---help--- + The virtual address of the beginning the .text region + +config ARCH_DATA_VBASE + hex "Virtual .bss/.data base" + ---help--- + The virtual address of the beginning of the .bss/.data region. + +config ARCH_HEAP_VBASE + hex "Virtual heap base" + ---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 + ---help--- + The maximum number of pages that can allocated for the .text region. + This, along with knowledge of the page size, determines the size of + the .text virtual address space. Default is 1. + +config ARCH_DATA_NPAGES + int "Max .bss/.data pages" + default 1 + ---help--- + The maximum number of pages that can allocated for the .bss/.data + region. This, along with knowledge of the page size, determines the + size of the .bss/.data virtual address space. Default is 1. + +config ARCH_HEAP_NPAGES + int "Max heap pages" + default 1 + ---help--- + The maximum number of pages that can allocated for the heap region. + This, along with knowledge of the page size, determines the size of + the heap virtual address space. Default is 1. + +config ARCH_STACK_NPAGES + int "Max. stack pages" + default 1 + ---help--- + The maximum number of pages that can allocated for the stack region. + This, along with knowledge of the page size, determines the size of + the stack virtual address space. Default is 1. + +endif # ARCH_ADDRENV && ARCH_HAVE_MMU + menuconfig PAGING bool "On-demand paging" default n diff --git a/arch/arm/include/arch.h b/arch/arm/include/arch.h index d0b2602eba..6495c52304 100644 --- a/arch/arm/include/arch.h +++ b/arch/arm/include/arch.h @@ -50,7 +50,7 @@ #endif /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ #ifdef CONFIG_PIC @@ -99,6 +99,36 @@ do { \ * Public Types ****************************************************************************/ +#ifdef CONFIG_ARCH_ADDRENV +/* The task group resources are retained in a single structure, task_group_s + * that is defined in the header file nuttx/include/nuttx/sched.h. The type + * group_addrenv_t must be defined by platform specific logic in + * nuttx/arch//include/arch.h. + * + * These tables would hold the physical address of the level 2 page tables. + * All would be initially NULL and would not be backed up with physical memory + * until mappings in the level 2 page table are required. + */ + +struct group_addrenv_s +{ + FAR uint32_t *text[CONFIG_ARCH_TEXT_NPAGES]; + FAR uint32_t *data[CONFIG_ARCH_DATA_NPAGES]; + FAR uint32_t *heap[CONFIG_ARCH_HEAP_NPAGES]; +}; + +typedef struct group_addrenv_s group_addrenv_t; + +/* This type is used when the OS needs to temporarily instantiate a + * different address environment. Used in the implementation of + * + * int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv); + * int up_addrenv_restore(save_addrenv_t oldenv); + */ + +typedef group_addrenv_t *save_addrenv_t; +#endif + /**************************************************************************** * Public Variables ****************************************************************************/ diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h index 0b7b0589ed..98fd8b154d 100755 --- a/arch/arm/include/armv7-a/irq.h +++ b/arch/arm/include/armv7-a/irq.h @@ -240,6 +240,16 @@ struct xcptcontext #ifdef CONFIG_PAGING uintptr_t far; #endif + +#ifdef CONFIG_ARCH_ADDRENV + /* This table holds the physical address of the level 2 page table used + * to map the thread's stack memory. This array will be initially of + * zeroed and would be back-up up with pages during page fault exception + * handling to support dynamically sized stacks for each thread. + */ + + FAR uint32_t *stack[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 335ab205a0..5aa21aa6c5 100644 --- a/arch/arm/src/armv7-a/arm_addrenv.c +++ b/arch/arm/src/armv7-a/arm_addrenv.c @@ -70,6 +70,7 @@ #include #include +#include #include #ifdef CONFIG_ARCH_ADDRENV @@ -77,6 +78,7 @@ /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ /**************************************************************************** * Private Data @@ -95,7 +97,7 @@ * * Description: * This function is called when a new task is created in order to - * instantiate an address environment for the new task group. + * instantiate an address environment for the new task group. * up_addrenv_create() is essentially the allocator of the physical * memory for the new task. * @@ -187,7 +189,7 @@ int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr) * ****************************************************************************/ -int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv) +int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv) { #warning Missing logic return -ENOSYS; @@ -210,7 +212,7 @@ int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv) * ****************************************************************************/ -int up_addrenv_restore(hw_addrenv_t oldenv) +int up_addrenv_restore(save_addrenv_t oldenv) { #warning Missing logic return -ENOSYS; diff --git a/arch/z80/include/z180/arch.h b/arch/z80/include/z180/arch.h index 85422fdca2..64e1112f52 100644 --- a/arch/z80/include/z180/arch.h +++ b/arch/z80/include/z180/arch.h @@ -65,7 +65,7 @@ */ #ifdef CONFIG_ARCH_ADDRENV -typedef uint8_t hw_addrenv_t; +typedef uint8_t save_addrenv_t; /* At the task-level, the z180 address environment is represented as struct * z180_cbr_s which is defined in irq.h. diff --git a/arch/z80/src/z180/z180_mmu.c b/arch/z80/src/z180/z180_mmu.c index 3289026f96..5f788859f1 100644 --- a/arch/z80/src/z180/z180_mmu.c +++ b/arch/z80/src/z180/z180_mmu.c @@ -378,7 +378,7 @@ int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr) * ****************************************************************************/ -int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv) +int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv) { FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv; irqstate_t flags; @@ -388,7 +388,7 @@ int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv) /* Return the current CBR value from the CBR register */ flags = irqsave(); - *oldenv = (hw_addrenv_t)inp(Z180_MMU_CBR); + *oldenv = (save_addrenv_t)inp(Z180_MMU_CBR); /* Write the new CBR value into CBR register */ @@ -414,7 +414,7 @@ int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv) * ****************************************************************************/ -int up_addrenv_restore(hw_addrenv_t oldenv) +int up_addrenv_restore(save_addrenv_t oldenv) { outp(Z180_MMU_CBR, (uint8_t)oldenv); return OK;