Add addrenv.h; First cut at Cortex-A address environment structures; Add configuration options to setup address enviornment

This commit is contained in:
Gregory Nutt 2014-08-24 09:57:53 -06:00
parent aa48638d57
commit 2cb9d5c7b0
14 changed files with 300 additions and 25 deletions

View File

@ -2541,7 +2541,7 @@ config ARCH_SIM
</p>
<p>
Since timers are a limited resource, the use of two timers could be an issue on some systems.
The job could be done with a single timer if, for example, the single timer were kept in a free-running at all times. Some timer/counters have the capability to generate a compare interrupt when the timer matches a comparison value but also to continue counting without stopping. If your hardware supports such counters, one might used the <code>CONFIG_SCHED_TICKLESS_ALARM</code> option and be able to simply set the comparison count at the value of the free running timer <i>PLUS</i> the desired delay. Then you could have both with a single timer: An alarm and a free-running counter with the same timer!
The job could be done with a single timer if, for example, the single timer were kept in a free-running at all times. Some timer/counters have the capability to generate a compare interrupt when the timer matches a comparison value but also to continue counting without stopping. If your hardware supports such counters, one might used the <code>CONFIG_SCHED_TICKLESS_ALARM</code> option and be able to simply set the comparison count at the value of the free running timer <i>PLUS</i> the desired delay. Then you could have both with a single timer: An alarm and a free-running counter with the same timer!
</p>
<p>
In addition to these imported interfaces, the RTOS will export the following interfaces for use by the platform-specific interval timer implementation:
@ -3041,7 +3041,7 @@ VxWorks provides the following comparable interface:
<h3><a name="up_addrenv_select">4.4.4 <code>up_addrenv_select()</code></a></h3>
<p><b>Function Prototype</b>:<p>
<ul>
<code>int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv);</code>
<code>int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv);</code>
</ul>
<p><b>Description</b>:</p>
<ul>
@ -3054,7 +3054,7 @@ VxWorks provides the following comparable interface:
<li><code>oldenv</code>:
The address environment that was in place before <code>up_addrenv_select()</code> was called.
This may be used with <code>up_addrenv_restore()</code> to restore the original address environment that was in place before <code>up_addrenv_select()</code> was called.
Note that this may be a task agnostic, hardware representation that is different from <code>group_addrenv_t</code>.
Note that this may be a task agnostic, platform-specific representation that may or may not be different from <code>group_addrenv_t</code>.
</li>
</ul>
<p><b>Returned Value</b>:</p>
@ -3065,7 +3065,7 @@ VxWorks provides the following comparable interface:
<h3><a name="up_addrenv_restore">4.4.5 <code>up_addrenv_restore()</code></a></h3>
<p><b>Function Prototype</b>:<p>
<ul>
<code>int up_addrenv_restore(hw_addrenv_t oldenv);</code>
<code>int up_addrenv_restore(save_addrenv_t oldenv);</code>
</ul>
<p><b>Description</b>:</p>
<ul>
@ -3074,7 +3074,7 @@ VxWorks provides the following comparable interface:
</ul>
<p><b>Input Parameters</b>:</p>
<ul>
<li><code>oldenv</code>: The hardware representation of the address environment previously returned by <code>up_addrenv_select()</code>.</li>
<li><code>oldenv</code>: The platform-specific representation of the address environment previously returned by <code>up_addrenv_select()</code>.</li>
</ul>
<p><b>Returned Value</b>:</p>
<ul>

View File

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

View File

@ -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/<architecture>/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
****************************************************************************/

View File

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

View File

@ -70,6 +70,7 @@
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/addrenv.h>
#include <arch/arch.h>
#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;

View File

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

View File

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

View File

@ -88,7 +88,7 @@ static inline int exec_dtors(FAR struct binary_s *binp)
{
binfmt_dtor_t *dtor = binp->dtors;
#ifdef CONFIG_ARCH_ADDRENV
hw_addrenv_t oldenv;
save_addrenv_t oldenv;
int ret;
#endif
int i;

View File

@ -89,7 +89,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo, size_t envsize)
FAR struct dspace_s *dspace;
#ifdef CONFIG_ARCH_ADDRENV
FAR void *vaddr;
hw_addrenv_t oldenv;
save_addrenv_t oldenv;
int ret;
#endif

177
include/nuttx/addrenv.h Normal file
View File

@ -0,0 +1,177 @@
/****************************************************************************
* include/nuttx/addrenv.h
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_ADDRENV_H
#define __INCLUDE_NUTTX_ADDRENV_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_ARCH_ADDRENV
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Pre-requisites */
#ifndef CONFIG_MM_PGALLOC
# error CONFIG_MM_PGALLOC not defined
#endif
#ifndef CONFIG_MM_PGSIZE
# error CONFIG_MM_PGSIZE not defined
#endif
/* .text region */
#ifndef CONFIG_ARCH_TEXT_VBASE
# error CONFIG_ARCH_TEXT_VBASE not defined
# define CONFIG_ARCH_TEXT_VBASE 0
#endif
#if (CONFIG_ARCH_TEXT_VBASE & CONFIG_MM_MASK) != 0
# error CONFIG_ARCH_TEXT_VBASE not aligned to page boundary
#endif
#ifndef CONFIG_ARCH_TEXT_NPAGES
# warning CONFIG_ARCH_TEXT_NPAGES not defined
# define CONFIG_ARCH_TEXT_NPAGES 1
#endif
#define CONFIG_ARCH_TEXT_SIZE (CONFIG_ARCH_TEXT_NPAGES * CONFIG_MM_PGSIZE)
/* .bss/.data region */
#ifndef CONFIG_ARCH_DATA_VBASE
# error CONFIG_ARCH_DATA_VBASE not defined
# define CONFIG_ARCH_DATA_VBASE (CONFIG_ARCH_TEXT_VBASE + CONFIG_ARCH_TEXT_SIZE)
#endif
#if (CONFIG_ARCH_DATA_VBASE & CONFIG_MM_MASK) != 0
# error CONFIG_ARCH_DATA_VBASE not aligned to page boundary
#endif
#ifndef CONFIG_ARCH_DATA_NPAGES
# warning CONFIG_ARCH_DATA_NPAGES not defined
# define CONFIG_ARCH_DATA_NPAGES 1
#endif
#define CONFIG_ARCH_DATA_SIZE (CONFIG_ARCH_DATA_NPAGES * CONFIG_MM_PGSIZE)
/* Heap region */
#ifndef CONFIG_ARCH_HEAP_VBASE
# error CONFIG_ARCH_HEAP_VBASE not defined
# define CONFIG_ARCH_HEAP_VBASE (CONFIG_ARCH_DATA_VBASE + CONFIG_ARCH_DATA_SIZE)
#endif
#if (CONFIG_ARCH_HEAP_VBASE & CONFIG_MM_MASK) != 0
# error CONFIG_ARCH_HEAP_VBASE not aligned to page boundary
#endif
#ifndef CONFIG_ARCH_HEAP_NPAGES
# warning CONFIG_ARCH_HEAP_NPAGES not defined
# define CONFIG_ARCH_HEAP_NPAGES 1
#endif
#define CONFIG_ARCH_HEAP_SIZE (CONFIG_ARCH_HEAP_NPAGES * CONFIG_MM_PGSIZE)
/* Stack region */
#ifndef CONFIG_ARCH_STACK_VBASE
# error CONFIG_ARCH_STACK_VBASE not defined
# define CONFIG_ARCH_STACK_VBASE (CONFIG_ARCH_HEAP_VBASE + CONFIG_ARCH_HEAP_SIZE)
#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 CONFIG_ARCH_STACK_SIZE (CONFIG_ARCH_STACK_NPAGES * CONFIG_MM_PGSIZE)
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Address Environment Interfaces
*
* Low-level interfaces used in binfmt/ to instantiate tasks with address
* environments. These interfaces all operate on type group_addrenv_t which
* is an abstract representation of a task group's address environment and
* must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined.
*
* up_addrenv_create - Create an address environment
* up_addrenv_destroy - Destroy an address environment.
* up_addrenv_vaddr - Returns the virtual base address of the address
* environment
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_assign - Assign an address environment to a group
*
* Higher-level interfaces used by the tasking logic. These interfaces are
* used by the functions in sched/ and all operate on the thread which whose
* group been assigned an address environment by up_addrenv_assign().
*
* 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
* environment.
* up_addrenv_detach - Release the threads reference to an address
* environment when a task/thread exits.
*
****************************************************************************/
/* Prototyped in include/nuttx/arch.h as part of the OS/platform interface */
#endif /* CONFIG_ARCH_ADDRENV */
#endif /* __INCLUDE_NUTTX_ADDRENV_H */

View File

@ -698,7 +698,7 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size);
*
* 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.
*
@ -776,8 +776,8 @@ int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr);
* The address environment that was in place before up_addrenv_select().
* This may be used with up_addrenv_restore() to restore the original
* address environment that was in place before up_addrenv_select() was
* called. Note that this may be a task agnostic, hardware
* representation that is different from group_addrenv_t.
* called. Note that this may be a task agnostic, platform-specific
* representation that may or may not be different from group_addrenv_t.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
@ -785,7 +785,7 @@ int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr);
****************************************************************************/
#ifdef CONFIG_ARCH_ADDRENV
int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv);
int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv);
#endif
/****************************************************************************
@ -797,7 +797,7 @@ int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv);
* original address environment.
*
* Input Parameters:
* oldenv - The hardware representation of the address environment
* oldenv - The platform-specific representation of the address environment
* previously returned by up_addrenv_select.
*
* Returned Value:
@ -806,7 +806,7 @@ int up_addrenv_select(group_addrenv_t addrenv, hw_addrenv_t *oldenv);
****************************************************************************/
#ifdef CONFIG_ARCH_ADDRENV
int up_addrenv_restore(hw_addrenv_t oldenv);
int up_addrenv_restore(save_addrenv_t oldenv);
#endif
/****************************************************************************

View File

@ -132,7 +132,7 @@ struct elf_loadinfo_s
#ifdef CONFIG_ARCH_ADDRENV
group_addrenv_t addrenv; /* Task group address environment */
hw_addrenv_t oldenv; /* Saved hardware address environment */
save_addrenv_t oldenv; /* Saved hardware address environment */
#endif
uint16_t symtabidx; /* Symbol table section index */

View File

@ -104,7 +104,7 @@ struct nxflat_loadinfo_s
#ifdef CONFIG_ARCH_ADDRENV
group_addrenv_t addrenv; /* Task group address environment */
hw_addrenv_t oldenv; /* Saved hardware address environment */
save_addrenv_t oldenv; /* Saved hardware address environment */
#endif
/* File descriptors */

View File

@ -66,7 +66,7 @@
*
* Dependencies: CONFIG_ARCH_HAVE_MMU and CONFIG_GRAN
*/
#ifndef CONFIG_MM_PGALLOC_PGSIZE
# define CONFIG_MM_PGALLOC_PGSIZE 4096
#endif