addrenv interface changes: up_addrenv_create() may need to create .text and .bss/.data separately because of differing access privileges (read/execute vs read/write). And, as a consequence, up_addrenv_vaddr() needs to be split into up_addrenv_vtext(0 and up_addrenv_vdata().

This commit is contained in:
Gregory Nutt 2014-08-24 11:54:14 -06:00
parent 95c79c675c
commit dde84a0a20
2 changed files with 121 additions and 37 deletions

View File

@ -42,8 +42,10 @@
* *
* up_addrenv_create - Create an address environment * up_addrenv_create - Create an address environment
* up_addrenv_destroy - Destroy an address environment. * up_addrenv_destroy - Destroy an address environment.
* up_addrenv_vaddr - Returns the virtual base address of the address * up_addrenv_vtext - Returns the virtual base address of the .text
* environment * address environment
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
* address environment
* up_addrenv_select - Instantiate an address environment * up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment * up_addrenv_restore - Restore an address environment
* up_addrenv_assign - Assign an address environment to a group * up_addrenv_assign - Assign an address environment to a group
@ -67,6 +69,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
@ -102,8 +105,10 @@
* memory for the new task. * memory for the new task.
* *
* Input Parameters: * Input Parameters:
* envsize - The size (in bytes) of the address environment needed by the * textsize - The size (in bytes) of the .text address environment needed
* task. * by the task. This region may be read/execute only.
* datasize - The size (in bytes) of the .data/.bss address environment
* needed by the task. This region may be read/write only.
* addrenv - The location to return the representation of the task address * addrenv - The location to return the representation of the task address
* environment. * environment.
* *
@ -112,7 +117,8 @@
* *
****************************************************************************/ ****************************************************************************/
int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv) int up_addrenv_create(size_t textsize, size_t datasize,
FAR group_addrenv_t *addrenv)
{ {
#warning Missing logic #warning Missing logic
return -ENOSYS; return -ENOSYS;
@ -141,27 +147,62 @@ int up_addrenv_destroy(group_addrenv_t addrenv)
} }
/**************************************************************************** /****************************************************************************
* Name: up_addrenv_vaddr * Name: up_addrenv_vtext
* *
* Description: * Description:
* Return the virtual address associated with the newly create address * Return the virtual address associated with the newly create .text
* environment. This function is used by the binary loaders in order * address environment. This function is used by the binary loaders in
* get an address that can be used to initialize the new task. * order get an address that can be used to initialize the new task.
* *
* Input Parameters: * Input Parameters:
* addrenv - The representation of the task address environment previously * addrenv - The representation of the task address environment previously
* returned by up_addrenv_create. * returned by up_addrenv_create.
* vaddr - The location to return the virtual address. * vtext - The location to return the virtual address.
* *
* Returned Value: * Returned Value:
* Zero (OK) on success; a negated errno value on failure. * Zero (OK) on success; a negated errno value on failure.
* *
****************************************************************************/ ****************************************************************************/
int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr) int up_addrenv_vtext(FAR group_addrenv_t addrenv, FAR void **vtext)
{ {
#warning Missing logic /* Not much to do in this case */
return -ENOSYS;
DEBUGASSERT(addrenv && vtext);
*vtext = (FAR void *)CONFIG_ARCH_TEXT_VBASE;
return OK;
}
/****************************************************************************
* Name: up_addrenv_vdata
*
* Description:
* Return the virtual address associated with the newly create .text
* address environment. This function is used by the binary loaders in
* order get an address that can be used to initialize the new task.
*
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
* textsize - For some implementations, the text and data will be saved
* in the same memory region (read/write/execute) and, in this case,
* the virtual address of the data just lies at this offset into the
* common region.
* vdata - The location to return the virtual address.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_vdata(FAR group_addrenv_t addrenv, uintptr_t textsize,
FAR void **vdata)
{
/* Not much to do in this case */
DEBUGASSERT(addrenv && vdata);
*vdata = (FAR void *)CONFIG_ARCH_DATA_VBASE;
return OK;
} }
/**************************************************************************** /****************************************************************************
@ -181,8 +222,8 @@ int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr)
* The address environment that was in place before up_addrenv_select(). * The address environment that was in place before up_addrenv_select().
* This may be used with up_addrenv_restore() to restore the original * This may be used with up_addrenv_restore() to restore the original
* address environment that was in place before up_addrenv_select() was * address environment that was in place before up_addrenv_select() was
* called. Note that this may be a task agnostic, hardware * called. Note that this may be a task agnostic, platform-specific
* representation that is different from group_addrenv_t. * representation that may or may not be different from group_addrenv_t.
* *
* Returned Value: * Returned Value:
* Zero (OK) on success; a negated errno value on failure. * Zero (OK) on success; a negated errno value on failure.
@ -204,7 +245,7 @@ int up_addrenv_select(group_addrenv_t addrenv, save_addrenv_t *oldenv)
* original address environment. * original address environment.
* *
* Input Parameters: * 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. * previously returned by up_addrenv_select.
* *
* Returned Value: * Returned Value:
@ -234,10 +275,15 @@ int up_addrenv_restore(save_addrenv_t oldenv)
* *
****************************************************************************/ ****************************************************************************/
int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group) int up_addrenv_assign(FAR const group_addrenv_t *addrenv,
FAR struct task_group_s *group)
{ {
#warning Missing logic DEBUGASSERT(addrenv && group);
return -ENOSYS;
/* Just copy the addess environment into the group */
memcpy(&group->addrenv, addrenv, sizeof(group_addrenv_t));
return OK;
} }
/**************************************************************************** /****************************************************************************
@ -263,8 +309,9 @@ int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group)
int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb) int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
{ {
#warning Missing logic /* Nothing needs to be done in this implementation */
return -ENOSYS;
return OK;
} }
/**************************************************************************** /****************************************************************************
@ -293,8 +340,9 @@ int up_addrenv_attach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb) int up_addrenv_detach(FAR struct task_group_s *group, FAR struct tcb_s *tcb)
{ {
#warning Missing logic /* Nothing needs to be done in this implementation */
return -ENOSYS;
return OK;
} }
#endif /* CONFIG_ARCH_ADDRENV */ #endif /* CONFIG_ARCH_ADDRENV */

View File

@ -186,8 +186,10 @@ return g_physhandle ? OK : -ENOMEM;
* *
* up_addrenv_create - Create an address environment * up_addrenv_create - Create an address environment
* up_addrenv_destroy - Destroy an address environment. * up_addrenv_destroy - Destroy an address environment.
* up_addrenv_vaddr - Returns the virtual base address of the address * up_addrenv_vtext - Returns the virtual base address of the .text
* environment * address environment
* up_addrenv_vdata - Returns the virtual base address of the .bss/.data
* address environment
* up_addrenv_select - Instantiate an address environment * up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment * up_addrenv_restore - Restore an address environment
* up_addrenv_assign - Assign an address environment to a group * up_addrenv_assign - Assign an address environment to a group
@ -214,8 +216,10 @@ return g_physhandle ? OK : -ENOMEM;
* memory for the new task. * memory for the new task.
* *
* Input Parameters: * Input Parameters:
* envsize - The size (in bytes) of the address environment needed by the * textsize - The size (in bytes) of the .text address environment needed
* task. * by the task. This region may be read/execute only.
* datasize - The size (in bytes) of the .data/.bss address environment
* needed by the task. This region may be read/write only.
* addrenv - The location to return the representation of the task address * addrenv - The location to return the representation of the task address
* environment. * environment.
* *
@ -224,17 +228,20 @@ return g_physhandle ? OK : -ENOMEM;
* *
****************************************************************************/ ****************************************************************************/
int up_addrenv_create(size_t envsize, FAR group_addrenv_t *addrenv) int up_addrenv_create(size_t textsize, size_t datasize,
FAR group_addrenv_t *addrenv)
{ {
FAR struct z180_cbr_s *cbr; FAR struct z180_cbr_s *cbr;
irqstate_t flags; irqstate_t flags;
size_t envsize;
uintptr_t alloc; uintptr_t alloc;
unsigned int npages; unsigned int npages;
int ret; int ret;
/* Convert the size from bytes to numbers of pages */ /* Convert the size from bytes to numbers of pages */
npages = PHYS_ALIGNUP(envsize); envsize = textsize + datasize;
npages = PHYS_ALIGNUP(envsize);
if (npages < 1) if (npages < 1)
{ {
/* No address environment... but I suppose that is not an error */ /* No address environment... but I suppose that is not an error */
@ -331,28 +338,56 @@ int up_addrenv_destroy(group_addrenv_t addrenv)
} }
/**************************************************************************** /****************************************************************************
* Name: up_addrenv_vaddr * Name: up_addrenv_vtext
* *
* Description: * Description:
* Return the virtual address associated with the newly create address * Return the virtual address associated with the newly create .text
* environment. This function is used by the binary loaders in order * address environment. This function is used by the binary loaders in
* get an address that can be used to initialize the new task.. * order get an address that can be used to initialize the new task.
* *
* Input Parameters: * Input Parameters:
* addrenv - The representation of the task address environment previously * addrenv - The representation of the task address environment previously
* returned by up_addrenv_create. * returned by up_addrenv_create.
* vaddr - The location to return the virtual address. * vtext - The location to return the virtual address.
* *
* Returned Value: * Returned Value:
* Zero (OK) on success; a negated errno value on failure. * Zero (OK) on success; a negated errno value on failure.
* *
****************************************************************************/ ****************************************************************************/
int up_addrenv_vaddr(FAR group_addrenv_t addrenv, FAR void **vaddr) int up_addrenv_vtext(FAR group_addrenv_t addrenv, FAR void **vtext)
{ {
return CONFIG_Z180_COMMON1AREA_VIRTBASE; return CONFIG_Z180_COMMON1AREA_VIRTBASE;
} }
/****************************************************************************
* Name: up_addrenv_vdata
*
* Description:
* Return the virtual address associated with the newly create .text
* address environment. This function is used by the binary loaders in
* order get an address that can be used to initialize the new task.
*
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
* textsize - For some implementations, the text and data will be saved
* in the same memory region (read/write/execute) and, in this case,
* the virtual address of the data just lies at this offset into the
* common region.
* vdata - The location to return the virtual address.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_vdata(FAR group_addrenv_t addrenv, uintptr_t textsize,
FAR void **vdata)
{
return CONFIG_Z180_COMMON1AREA_VIRTBASE + textsize;
}
/**************************************************************************** /****************************************************************************
* Name: up_addrenv_select * Name: up_addrenv_select
* *
@ -436,7 +471,8 @@ int up_addrenv_restore(save_addrenv_t oldenv)
* *
****************************************************************************/ ****************************************************************************/
int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group) int up_addrenv_assign(FAR const group_addrenv_t *addrenv,
FAR struct task_group_s *group)
{ {
/* Make sure that there is no address environment in place on this TCB */ /* Make sure that there is no address environment in place on this TCB */
@ -446,7 +482,7 @@ int up_addrenv_assign(group_addrenv_t addrenv, FAR struct task_group_s *group)
* special precautions should be needed. * special precautions should be needed.
*/ */
group->addrenv = addrenv; group->addrenv = *addrenv;
return OK; return OK;
} }