sched/addrenv: Remove up_addrenv_restore

The function is not relevant any longer, remove it. Also remove
save_addrenv_t, the parameter taken by up_addrenv_restore.

Implement addrenv_select() / addrenv_restore() to handle the temporary
instantiation of address environments, e.g. when a process is being
created.
This commit is contained in:
Ville Juven 2023-01-27 13:45:03 +02:00 committed by Xiang Xiao
parent 09e7987121
commit f4b82b6405
29 changed files with 213 additions and 424 deletions

View file

@ -34,7 +34,6 @@ The CPU-specific logic must provide two categories in interfaces:
- :c:func:`up_addrenv_vdata()`: Returns the virtual base address of the ``.bss``/``.data`` address environment.
- :c:func:`up_addrenv_heapsize()`: Return the initial heap size.
- :c:func:`up_addrenv_select()`: Instantiate an address environment.
- :c:func:`up_addrenv_restore()`: Restore an address environment.
- :c:func:`up_addrenv_clone()`: Copy an address environment from one location to another.
#. **Tasking Support**. Other interfaces must be provided to
@ -162,7 +161,7 @@ The CPU-specific logic must provide two categories in interfaces:
:return: The initial heap size allocated is returned on success;
a negated errno value on failure.
.. c:function:: int up_addrenv_select(arch_addrenv_t *addrenv, save_addrenv_t *oldenv)
.. c:function:: int up_addrenv_select(arch_addrenv_t *addrenv)
After an address environment has been established for a task
(via up_addrenv_create()), this function may be called to instantiate
@ -172,24 +171,6 @@ The CPU-specific logic must provide two categories in interfaces:
:param addrenv: The representation of the task address environment
previously returned by ``up_addrenv_create()``.
:param oldenv: The address environment that was in place before
``up_addrenv_select()`` was called. 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,
platform-specific representation that may or may not be
different from ``arch_addrenv_t``.
:return: Zero (OK) on success; a negated errno value on failure.
.. c:function:: int up_addrenv_restore(save_addrenv_t oldenv)
After an address environment has been temporarily instantiated
by up_addrenv_select, this function may be called to restore
the original address environment.
:param oldenv: The platform-specific representation of the address
environment previously returned by ``up_addrenv_select()``.
:return: Zero (OK) on success; a negated errno value on failure.

View file

@ -152,29 +152,6 @@ struct arch_addrenv_s
};
typedef struct arch_addrenv_s arch_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(arch_addrenv_t addrenv, save_addrenv_t *oldenv);
* int up_addrenv_restore(save_addrenv_t oldenv);
*
* In this case, the saved valued in the L1 page table are returned
*/
struct save_addrenv_s
{
uint32_t text[ARCH_TEXT_NSECTS];
uint32_t data[ARCH_DATA_NSECTS];
#ifdef CONFIG_BUILD_KERNEL
uint32_t heap[ARCH_HEAP_NSECTS];
#ifdef CONFIG_ARCH_VMA_MAPPING
uint32_t shm[ARCH_SHM_NSECTS];
#endif
#endif
};
typedef struct save_addrenv_s save_addrenv_t;
#endif
/****************************************************************************

View file

@ -34,7 +34,6 @@
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*
@ -489,39 +488,25 @@ ssize_t up_addrenv_heapsize(const arch_addrenv_t *addrenv)
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
* oldenv
* 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, platform-specific
* representation that may or may not be different from arch_addrenv_t.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_select(const arch_addrenv_t *addrenv,
save_addrenv_t *oldenv)
int up_addrenv_select(const arch_addrenv_t *addrenv)
{
uintptr_t vaddr;
uintptr_t paddr;
int i;
binfo("addrenv=%p oldenv=%p\n", addrenv, oldenv);
binfo("addrenv=%p\n", addrenv);
DEBUGASSERT(addrenv);
for (vaddr = CONFIG_ARCH_TEXT_VBASE, i = 0;
i < ARCH_TEXT_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Save the old L1 page table entry */
if (oldenv)
{
oldenv->text[i] = mmu_l1_getentry(vaddr);
}
/* Set (or clear) the new page table entry */
paddr = (uintptr_t)addrenv->text[i];
@ -541,13 +526,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
i < ARCH_DATA_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Save the old L1 page table entry */
if (oldenv)
{
oldenv->data[i] = mmu_l1_getentry(vaddr);
}
/* Set (or clear) the new page table entry */
paddr = (uintptr_t)addrenv->data[i];
@ -568,13 +546,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
i < ARCH_HEAP_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Save the old L1 page table entry */
if (oldenv)
{
oldenv->heap[i] = mmu_l1_getentry(vaddr);
}
/* Set (or clear) the new page table entry */
paddr = (uintptr_t)addrenv->heap[i];
@ -595,13 +566,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
i < ARCH_SHM_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Save the old L1 page table entry */
if (oldenv)
{
oldenv->shm[i] = mmu_l1_getentry(vaddr);
}
/* Set (or clear) the new page table entry */
paddr = (uintptr_t)addrenv->shm[i];
@ -621,75 +585,6 @@ int up_addrenv_select(const arch_addrenv_t *addrenv,
return OK;
}
/****************************************************************************
* Name: up_addrenv_restore
*
* Description:
* After an address environment has been temporarily instantiated by
* up_addrenv_select(), this function may be called to restore the
* original address environment.
*
* Input Parameters:
* oldenv - The platform-specific representation of the address environment
* previously returned by up_addrenv_select.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_restore(const save_addrenv_t *oldenv)
{
uintptr_t vaddr;
int i;
binfo("oldenv=%p\n", oldenv);
DEBUGASSERT(oldenv);
for (vaddr = CONFIG_ARCH_TEXT_VBASE, i = 0;
i < ARCH_TEXT_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Restore the L1 page table entry */
mmu_l1_restore(vaddr, oldenv->text[i]);
}
for (vaddr = CONFIG_ARCH_DATA_VBASE, i = 0;
i < ARCH_DATA_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Restore the L1 page table entry */
mmu_l1_restore(vaddr, oldenv->data[i]);
}
#ifdef CONFIG_BUILD_KERNEL
for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0;
i < ARCH_HEAP_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Restore the L1 page table entry */
mmu_l1_restore(vaddr, oldenv->heap[i]);
}
#ifdef CONFIG_ARCH_VMA_MAPPING
for (vaddr = CONFIG_ARCH_SHM_VBASE, i = 0;
i < ARCH_SHM_NSECTS;
vaddr += SECTION_SIZE, i++)
{
/* Restore the L1 page table entry */
mmu_l1_restore(vaddr, oldenv->shm[i]);
}
#endif
#endif
return OK;
}
/****************************************************************************
* Name: up_addrenv_coherent
*

View file

@ -34,7 +34,6 @@
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*

View file

@ -34,7 +34,6 @@
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*

View file

@ -136,7 +136,7 @@ static int get_pgtable(arch_addrenv_t *addrenv, uintptr_t vaddr)
/* And instantiate the modified environment */
up_addrenv_select(addrenv, NULL);
up_addrenv_select(addrenv);
}
}

View file

@ -30,6 +30,7 @@
#include <assert.h>
#include <debug.h>
#include <nuttx/addrenv.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
@ -202,12 +203,11 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
size_t size;
#ifdef CONFIG_ARCH_ADDRENV
save_addrenv_t oldenv;
bool saved = false;
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
if (tcb->addrenv_own != NULL)
{
up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
addrenv_select(tcb->addrenv_own);
saved = true;
}
#endif
@ -217,7 +217,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
#ifdef CONFIG_ARCH_ADDRENV
if (saved)
{
up_addrenv_restore(&oldenv);
addrenv_restore();
}
#endif

View file

@ -90,29 +90,6 @@ struct arch_addrenv_s
};
typedef struct arch_addrenv_s arch_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(arch_addrenv_t addrenv, save_addrenv_t *oldenv);
* int up_addrenv_restore(save_addrenv_t oldenv);
*
* In this case, the saved value in the L1 page table are returned
*/
struct save_addrenv_s
{
uint32_t text[ARCH_TEXT_NSECTS];
uint32_t data[ARCH_DATA_NSECTS];
#ifdef CONFIG_BUILD_KERNEL
uint32_t heap[ARCH_HEAP_NSECTS];
#ifdef CONFIG_ARCH_VMA_MAPPING
uint32_t shm[ARCH_SHM_NSECTS];
#endif
#endif
};
typedef struct save_addrenv_s save_addrenv_t;
#endif
/****************************************************************************

View file

@ -102,31 +102,6 @@ struct arch_addrenv_s
size_t heapsize;
#endif
};
typedef struct arch_addrenv_s arch_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(arch_addrenv_t addrenv, save_addrenv_t *oldenv);
* int up_addrenv_restore(save_addrenv_t oldenv);
*
* In this case, the saved valued in the L1 page table are returned
*/
struct save_addrenv_s
{
uint32_t text[ARCH_TEXT_NSECTS];
uint32_t data[ARCH_DATA_NSECTS];
#ifdef CONFIG_BUILD_KERNEL
uint32_t heap[ARCH_HEAP_NSECTS];
#ifdef CONFIG_ARCH_VMA_MAPPING
uint32_t shm[ARCH_SHM_NSECTS];
#endif
#endif
};
typedef struct save_addrenv_s save_addrenv_t;
#endif
/****************************************************************************

View file

@ -101,12 +101,6 @@ struct arch_addrenv_s
};
typedef struct arch_addrenv_s arch_addrenv_t;
/* If an address environment needs to be saved, saving the satp register
* will suffice. The register width is architecture dependent
*/
typedef uintptr_t save_addrenv_t;
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_ARCH_ADDRENV */

View file

@ -34,7 +34,6 @@
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*
@ -713,58 +712,19 @@ ssize_t up_addrenv_heapsize(const arch_addrenv_t *addrenv)
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
* oldenv
* 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 arch_addrenv_t.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_select(const arch_addrenv_t *addrenv,
save_addrenv_t *oldenv)
int up_addrenv_select(const arch_addrenv_t *addrenv)
{
DEBUGASSERT(addrenv && addrenv->satp);
if (oldenv)
{
/* Save the old environment */
uintptr_t satp_reg = mmu_read_satp();
*oldenv = (save_addrenv_t)satp_reg;
}
mmu_write_satp(addrenv->satp);
return OK;
}
/****************************************************************************
* Name: up_addrenv_restore
*
* Description:
* After an address environment has been temporarily instantiated by
* up_addrenv_select, this function may be called to restore the
* original address environment.
*
* Input Parameters:
* oldenv - The hardware representation of the address environment
* previously returned by up_addrenv_select.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_restore(const save_addrenv_t *oldenv)
{
DEBUGASSERT(oldenv);
mmu_write_satp((uintptr_t)*oldenv);
return OK;
}
/****************************************************************************
* Name: up_addrenv_coherent
*

View file

@ -30,6 +30,7 @@
#include <assert.h>
#include <debug.h>
#include <nuttx/addrenv.h>
#include <nuttx/arch.h>
#include "sched/sched.h"
@ -158,12 +159,11 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
size_t size;
#ifdef CONFIG_ARCH_ADDRENV
save_addrenv_t oldenv;
bool saved = false;
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
if (tcb->addrenv_own != NULL)
{
up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
addrenv_select(tcb->addrenv_own);
saved = true;
}
#endif
@ -174,7 +174,7 @@ size_t up_check_tcbstack(struct tcb_s *tcb)
#ifdef CONFIG_ARCH_ADDRENV
if (saved)
{
up_addrenv_restore(&oldenv);
addrenv_restore();
}
#endif

View file

@ -50,7 +50,6 @@
*/
#ifdef CONFIG_ARCH_ADDRENV
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

@ -174,7 +174,6 @@ int z80_mmu_initialize(void)
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*
@ -443,30 +442,20 @@ ssize_t up_addrenv_heapsize(FAR const arch_addrenv_t *addrenv)
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
* oldenv
* 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 arch_addrenv_t.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_select(FAR const arch_addrenv_t *addrenv,
FAR save_addrenv_t *oldenv)
int up_addrenv_select(FAR const arch_addrenv_t *addrenv)
{
FAR struct z180_cbr_s *cbr = (FAR struct z180_cbr_s *)addrenv;
irqstate_t flags;
DEBUGASSERT(cbr && oldenv);
/* Return the current CBR value from the CBR register */
DEBUGASSERT(cbr);
flags = enter_critical_section();
*oldenv = (save_addrenv_t)inp(Z180_MMU_CBR);
/* Write the new CBR value into CBR register */
@ -475,29 +464,6 @@ int up_addrenv_select(FAR const arch_addrenv_t *addrenv,
return OK;
}
/****************************************************************************
* Name: up_addrenv_restore
*
* Description:
* After an address environment has been temporarily instantiated by
* up_addrenv_select, this function may be called to restore the
* original address environment.
*
* Input Parameters:
* oldenv - The hardware representation of the address environment
* previously returned by up_addrenv_select.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
{
outp(Z180_MMU_CBR, (uint8_t)*oldenv);
return OK;
}
/****************************************************************************
* Name: up_addrenv_coherent
*

View file

@ -31,6 +31,7 @@
#include <debug.h>
#include <errno.h>
#include <nuttx/addrenv.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/sched.h>
@ -110,13 +111,13 @@ static void exec_ctors(FAR void *arg)
*
****************************************************************************/
int exec_module(FAR const struct binary_s *binp,
int exec_module(FAR struct binary_s *binp,
FAR const char *filename, FAR char * const *argv,
FAR char * const *envp)
{
FAR struct task_tcb_s *tcb;
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
save_addrenv_t oldenv;
FAR struct arch_addrenv_s *addrenv = &binp->addrenv.addrenv;
FAR void *vheap;
#endif
FAR void *stackaddr = NULL;
@ -164,14 +165,14 @@ int exec_module(FAR const struct binary_s *binp,
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
/* Instantiate the address environment containing the user heap */
ret = up_addrenv_select(&binp->addrenv, &oldenv);
ret = addrenv_select(&binp->addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_select() failed: %d\n", ret);
berr("ERROR: addrenv_select() failed: %d\n", ret);
goto errout_with_envp;
}
ret = up_addrenv_vheap(&binp->addrenv, &vheap);
ret = up_addrenv_vheap(addrenv, &vheap);
if (ret < 0)
{
berr("ERROR: up_addrenv_vheap() failed: %d\n", ret);
@ -179,8 +180,8 @@ int exec_module(FAR const struct binary_s *binp,
}
binfo("Initialize the user heap (heapsize=%zu)\n",
up_addrenv_heapsize(&binp->addrenv));
umm_initialize(vheap, up_addrenv_heapsize(&binp->addrenv));
up_addrenv_heapsize(addrenv));
umm_initialize(vheap, up_addrenv_heapsize(addrenv));
#endif
/* Note that tcb->flags are not modified. 0=normal task */
@ -272,10 +273,10 @@ int exec_module(FAR const struct binary_s *binp,
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
/* Restore the address environment of the caller */
ret = up_addrenv_restore(&oldenv);
ret = addrenv_restore();
if (ret < 0)
{
berr("ERROR: up_addrenv_restore() failed: %d\n", ret);
berr("ERROR: addrenv_restore() failed: %d\n", ret);
goto errout_with_tcbinit;
}
#endif
@ -291,7 +292,7 @@ errout_with_tcbinit:
errout_with_addrenv:
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_BUILD_KERNEL)
up_addrenv_restore(&oldenv);
addrenv_restore();
errout_with_envp:
#endif
binfmt_freeenv(envp);

View file

@ -30,6 +30,7 @@
#include <debug.h>
#include <errno.h>
#include <nuttx/addrenv.h>
#include <nuttx/kmalloc.h>
#include <nuttx/binfmt/binfmt.h>
@ -61,7 +62,6 @@ static inline int exec_dtors(FAR struct binary_s *binp)
{
binfmt_dtor_t *dtor = binp->dtors;
#ifdef CONFIG_ARCH_ADDRENV
save_addrenv_t oldenv;
int ret;
#endif
int i;
@ -69,10 +69,10 @@ static inline int exec_dtors(FAR struct binary_s *binp)
/* Instantiate the address environment containing the destructors */
#ifdef CONFIG_ARCH_ADDRENV
ret = up_addrenv_select(&binp->addrenv, &oldenv);
ret = addrenv_select(&binp->addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_select() failed: %d\n", ret);
berr("ERROR: addrenv_select() failed: %d\n", ret);
return ret;
}
#endif
@ -90,7 +90,7 @@ static inline int exec_dtors(FAR struct binary_s *binp)
/* Restore the address environment */
#ifdef CONFIG_ARCH_ADDRENV
return up_addrenv_restore(&oldenv);
return addrenv_restore();
#else
return OK;
#endif

View file

@ -271,7 +271,12 @@ static int elf_loadbinary(FAR struct binary_s *binp,
* needed when the module is executed.
*/
up_addrenv_clone(&loadinfo.addrenv, &binp->addrenv);
up_addrenv_clone(&loadinfo.addrenv.addrenv, &binp->addrenv.addrenv);
/* Take a reference to the address environment, so it won't get freed */
addrenv_take(&binp->addrenv);
#else
binp->alloc[0] = (FAR void *)loadinfo.textalloc;
binp->alloc[1] = (FAR void *)loadinfo.dataalloc;

View file

@ -27,6 +27,7 @@
#include <errno.h>
#include <debug.h>
#include <nuttx/addrenv.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
@ -83,33 +84,38 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,
size_t datasize, size_t heapsize)
{
#ifdef CONFIG_ARCH_ADDRENV
FAR struct arch_addrenv_s *addrenv = &loadinfo->addrenv.addrenv;
FAR void *vtext;
FAR void *vdata;
int ret;
/* Create an address environment for the new ELF task */
ret = up_addrenv_create(textsize, datasize, heapsize, &loadinfo->addrenv);
ret = up_addrenv_create(textsize, datasize, heapsize, addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_create failed: %d\n", ret);
return ret;
}
/* Take a reference to the address environment, so it won't get freed */
addrenv_take(&loadinfo->addrenv);
/* Get the virtual address associated with the start of the address
* environment. This is the base address that we will need to use to
* access the ELF image (but only if the address environment has been
* selected.
*/
ret = up_addrenv_vtext(&loadinfo->addrenv, &vtext);
ret = up_addrenv_vtext(addrenv, &vtext);
if (ret < 0)
{
berr("ERROR: up_addrenv_vtext failed: %d\n", ret);
return ret;
}
ret = up_addrenv_vdata(&loadinfo->addrenv, textsize, &vdata);
ret = up_addrenv_vdata(addrenv, textsize, &vdata);
if (ret < 0)
{
berr("ERROR: up_addrenv_vdata failed: %d\n", ret);
@ -171,16 +177,16 @@ int elf_addrenv_select(FAR struct elf_loadinfo_s *loadinfo)
/* Instantiate the new address environment */
ret = up_addrenv_select(&loadinfo->addrenv, &loadinfo->oldenv);
ret = addrenv_select(&loadinfo->addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_select failed: %d\n", ret);
berr("ERROR: addrenv_select failed: %d\n", ret);
return ret;
}
/* Allow write access to .text */
ret = up_addrenv_mprot(&loadinfo->addrenv, loadinfo->textalloc,
ret = up_addrenv_mprot(&loadinfo->addrenv.addrenv, loadinfo->textalloc,
loadinfo->textsize, ELF_TEXT_WRE);
if (ret < 0)
{
@ -213,7 +219,7 @@ int elf_addrenv_restore(FAR struct elf_loadinfo_s *loadinfo)
/* Remove write access to .text */
ret = up_addrenv_mprot(&loadinfo->addrenv, loadinfo->textalloc,
ret = up_addrenv_mprot(&loadinfo->addrenv.addrenv, loadinfo->textalloc,
loadinfo->textsize, ELF_TEXT_WRD);
if (ret < 0)
{
@ -223,10 +229,10 @@ int elf_addrenv_restore(FAR struct elf_loadinfo_s *loadinfo)
/* Restore the old address environment */
ret = up_addrenv_restore(&loadinfo->oldenv);
ret = addrenv_restore();
if (ret < 0)
{
berr("ERROR: up_addrenv_restore failed: %d\n", ret);
berr("ERROR: addrenv_restore failed: %d\n", ret);
return ret;
}
@ -259,7 +265,7 @@ void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
/* Free the address environment */
ret = up_addrenv_destroy(&loadinfo->addrenv);
ret = up_addrenv_destroy(&loadinfo->addrenv.addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_destroy failed: %d\n", ret);

View file

@ -643,7 +643,7 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
*/
#if 0 /* REVISIT... has some problems */
up_addrenv_coherent(&loadinfo->addrenv);
up_addrenv_coherent(&loadinfo->addrenv.addrenv);
#else
up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize);

View file

@ -76,26 +76,7 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
****************************************************************************/
#ifdef CONFIG_ARCH_ADDRENV
# define nxflat_addrenv_select(l) up_addrenv_select(&(l)->addrenv, &(l)->oldenv)
#endif
/****************************************************************************
* Name: nxflat_addrenv_restore
*
* Description:
* Restore the address environment before nxflat_addrenv_select() was
* called..
*
* Input Parameters:
* loadinfo - Load state information
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_ARCH_ADDRENV
# define nxflat_addrenv_restore(l) up_addrenv_restore(&(l)->oldenv)
# define nxflat_addrenv_select(l) addrenv_select(&(l)->addrenv)
#endif
/****************************************************************************

View file

@ -30,6 +30,7 @@
#include <errno.h>
#include <debug.h>
#include <nuttx/addrenv.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
@ -70,8 +71,8 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
{
FAR struct dspace_s *dspace;
#ifdef CONFIG_ARCH_ADDRENV
FAR struct arch_addrenv_s *addrenv = &loadinfo->addrenv.addrenv;
FAR void *vdata;
save_addrenv_t oldenv;
size_t heapsize;
int ret;
#endif
@ -101,20 +102,24 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
/* Create a D-Space address environment for the new NXFLAT task */
ret = up_addrenv_create(0, envsize, heapsize, &loadinfo->addrenv);
ret = up_addrenv_create(0, envsize, heapsize, addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_create failed: %d\n", ret);
goto errout_with_dspace;
}
/* Take a reference to the address environment, so it won't get freed */
addrenv_take(&loadinfo->addrenv);
/* Get the virtual address associated with the start of the address
* environment. This is the base address that we will need to use to
* access the D-Space region (but only if the address environment has been
* selected.
*/
ret = up_addrenv_vdata(&loadinfo->addrenv, 0, &vdata);
ret = up_addrenv_vdata(addrenv, 0, &vdata);
if (ret < 0)
{
berr("ERROR: up_addrenv_vdata failed: %d\n", ret);
@ -125,19 +130,19 @@ int nxflat_addrenv_alloc(FAR struct nxflat_loadinfo_s *loadinfo,
* selected the D-Space address environment to do this.
*/
ret = up_addrenv_select(loadinfo->addrenv, &oldenv);
ret = addrenv_select(&loadinfo->addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_select failed: %d\n", ret);
berr("ERROR: addrenv_select failed: %d\n", ret);
goto errout_with_addrenv;
}
memset(vdata, 0, envsize);
ret = up_addrenv_restore(oldenv);
ret = addrenv_restore();
if (ret < 0)
{
berr("ERROR: up_addrenv_restore failed: %d\n", ret);
berr("ERROR: addrenv_restore failed: %d\n", ret);
goto errout_with_addrenv;
}

View file

@ -202,7 +202,7 @@ static int nxflat_loadbinary(FAR struct binary_s *binp,
* needed when the module is executed.
*/
up_addrenv_clone(&loadinfo.addrenv, &binp->addrenv);
up_addrenv_clone(&loadinfo.addrenv.addrenv, &binp->addrenv.addrenv);
#endif
nxflat_dumpbuffer("Entry code", (FAR const uint8_t *)binp->entrypt,

View file

@ -365,7 +365,7 @@ int addrenv_switch(FAR struct tcb_s *tcb);
****************************************************************************/
int addrenv_attach(FAR struct tcb_s *tcb,
FAR const struct arch_addrenv_s *addrenv);
FAR const struct addrenv_s *addrenv);
/****************************************************************************
* Name: addrenv_join
@ -405,10 +405,11 @@ int addrenv_join(FAR struct tcb_s *ptcb, FAR struct tcb_s *tcb);
int addrenv_leave(FAR struct tcb_s *tcb);
/****************************************************************************
* Name: addrenv_take
* Name: addrenv_select
*
* Description:
* Take a reference to an address environment.
* Temporarily select a different address environment for the currently
* running process.
*
* Input Parameters:
* addrenv - The address environment.
@ -420,21 +421,54 @@ int addrenv_leave(FAR struct tcb_s *tcb);
*
****************************************************************************/
int addrenv_select(FAR struct addrenv_s *addrenv);
/****************************************************************************
* Name: addrenv_restore
*
* Description:
* Switch back to the procces's own address environment.
*
* Input Parameters:
* None
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int addrenv_restore(void);
/****************************************************************************
* Name: addrenv_take
*
* Description:
* Take a reference to an address environment.
*
* Input Parameters:
* addrenv - The address environment.
*
* Returned Value:
* None.
*
****************************************************************************/
void addrenv_take(FAR struct addrenv_s *addrenv);
/****************************************************************************
* Name: addrenv_give
*
* Description:
* Give back a reference to an address environment.
* Give back a reference to an address environment, obtaining the resulting
* reference counter as returned value.
*
* Input Parameters:
* addrenv - The address environment.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
* Remaining reference count.
*
****************************************************************************/
@ -452,9 +486,7 @@ int addrenv_give(FAR struct addrenv_s *addrenv);
* no: The address environment can be dropped at once
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
* None.
*
****************************************************************************/
@ -478,7 +510,6 @@ void addrenv_drop(FAR struct addrenv_s *addrenv, bool deferred);
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*

View file

@ -789,7 +789,6 @@ bool up_textheap_heapmember(FAR void *p);
* address environment
* up_addrenv_heapsize - Returns the size of the initial heap allocation.
* up_addrenv_select - Instantiate an address environment
* up_addrenv_restore - Restore an address environment
* up_addrenv_clone - Copy an address environment from one location to
* another.
*
@ -1006,12 +1005,6 @@ ssize_t up_addrenv_heapsize(FAR const arch_addrenv_t *addrenv);
* Input Parameters:
* addrenv - The representation of the task address environment previously
* returned by up_addrenv_create.
* oldenv
* 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, platform-specific
* representation that may or may not be different from arch_addrenv_t.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
@ -1019,29 +1012,7 @@ ssize_t up_addrenv_heapsize(FAR const arch_addrenv_t *addrenv);
****************************************************************************/
#ifdef CONFIG_ARCH_ADDRENV
int up_addrenv_select(FAR const arch_addrenv_t *addrenv,
FAR save_addrenv_t *oldenv);
#endif
/****************************************************************************
* Name: up_addrenv_restore
*
* Description:
* After an address environment has been temporarily instantiated by
* up_addrenv_select(), this function may be called to restore the
* original address environment.
*
* Input Parameters:
* oldenv - The platform-specific representation of the address environment
* previously returned by up_addrenv_select.
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_ARCH_ADDRENV
int up_addrenv_restore(FAR const save_addrenv_t *oldenv);
int up_addrenv_select(FAR const arch_addrenv_t *addrenv);
#endif
/****************************************************************************

View file

@ -86,7 +86,7 @@ struct binary_s
* used to manage the tasks address space.
*/
arch_addrenv_t addrenv; /* Task group address environment */
addrenv_t addrenv; /* Address environment */
#endif
size_t mapsize; /* Size of the mapped address region (needed for munmap) */
@ -261,7 +261,7 @@ int unload_module(FAR struct binary_s *bin);
*
****************************************************************************/
int exec_module(FAR const struct binary_s *binp,
int exec_module(FAR struct binary_s *binp,
FAR const char *filename, FAR char * const *argv,
FAR char * const *envp);

View file

@ -119,13 +119,10 @@ struct elf_loadinfo_s
*
* addrenv - This is the handle created by up_addrenv_create() that can be
* used to manage the tasks address space.
* oldenv - This is a value returned by up_addrenv_select() that must be
* used to restore the current address environment.
*/
#ifdef CONFIG_ARCH_ADDRENV
arch_addrenv_t addrenv; /* Task group address environment */
save_addrenv_t oldenv; /* Saved address environment */
addrenv_t addrenv; /* Address environment */
#endif
uint16_t symtabidx; /* Symbol table section index */

View file

@ -84,13 +84,10 @@ struct nxflat_loadinfo_s
*
* addrenv - This is the handle created by up_addrenv_create() that can be
* used to manage the tasks address space.
* oldenv - This is a value returned by up_addrenv_select() that must be
* used to restore the current address environment.
*/
#ifdef CONFIG_ARCH_ADDRENV
arch_addrenv_t addrenv; /* Task group address environment */
save_addrenv_t oldenv; /* Saved address environment */
addrenv_t addrenv; /* Address environment */
#endif
/* File descriptors */

View file

@ -86,6 +86,35 @@ static void addrenv_destroy(FAR void *arg)
kmm_free(addrenv);
}
/****************************************************************************
* Name: addrenv_clear_current
*
* Description:
* Clear the current addrenv from g_addrenv, if it matches the input.
*
* Input Parameters:
* addrenv - Pointer to the addrenv to free.
*
* Returned Value:
* None.
*
****************************************************************************/
static void addrenv_clear_current(FAR const addrenv_t *addrenv)
{
int i;
/* Mark no address environment */
for (i = 0; i < CONFIG_SMP_NCPUS; i++)
{
if (addrenv == g_addrenv[i])
{
g_addrenv[i] = NULL;
}
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -136,7 +165,7 @@ int addrenv_switch(FAR struct tcb_s *tcb)
}
DEBUGASSERT(tcb);
next = tcb->mm_curr;
next = tcb->addrenv_curr;
/* Does the group have an address environment? */
@ -179,7 +208,7 @@ int addrenv_switch(FAR struct tcb_s *tcb)
* instantiated.
*/
ret = up_addrenv_select(&next->addrenv, NULL);
ret = up_addrenv_select(&next->addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_select failed: %d\n", ret);
@ -285,13 +314,13 @@ int addrenv_free(FAR struct tcb_s *tcb)
****************************************************************************/
int addrenv_attach(FAR struct tcb_s *tcb,
FAR const struct arch_addrenv_s *addrenv)
FAR const struct addrenv_s *addrenv)
{
int ret;
/* Clone the address environment for us */
ret = up_addrenv_clone(addrenv, &tcb->addrenv_own->addrenv);
ret = up_addrenv_clone(&addrenv->addrenv, &tcb->addrenv_own->addrenv);
if (ret < 0)
{
berr("ERROR: up_addrenv_clone failed: %d\n", ret);
@ -378,6 +407,63 @@ int addrenv_leave(FAR struct tcb_s *tcb)
return ret;
}
/****************************************************************************
* Name: addrenv_select
*
* Description:
* Temporarily select a different address environment for the currently
* running process.
*
* Input Parameters:
* addrenv - The address environment.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int addrenv_select(FAR struct addrenv_s *addrenv)
{
FAR struct tcb_s *tcb = this_task();
addrenv_take(addrenv);
tcb->addrenv_curr = addrenv;
return addrenv_switch(tcb);
}
/****************************************************************************
* Name: addrenv_restore
*
* Description:
* Switch back to the procces's own address environment.
*
* Input Parameters:
* None
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
*
****************************************************************************/
int addrenv_restore(void)
{
FAR struct tcb_s *tcb = this_task();
addrenv_give(tcb->addrenv_curr);
if (tcb->addrenv_own == NULL)
{
/* Kernel thread, clear g_addrenv, as it is not valid any more */
addrenv_clear_current(tcb->addrenv_curr);
}
tcb->addrenv_curr = tcb->addrenv_own;
return addrenv_switch(tcb);
}
/****************************************************************************
* Name: addrenv_take
*
@ -388,9 +474,7 @@ int addrenv_leave(FAR struct tcb_s *tcb)
* addrenv - The address environment.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
* None.
*
****************************************************************************/
@ -405,15 +489,14 @@ void addrenv_take(FAR struct addrenv_s *addrenv)
* Name: addrenv_give
*
* Description:
* Give back a reference to an address environment.
* Give back a reference to an address environment, obtaining the resulting
* reference counter as returned value.
*
* Input Parameters:
* addrenv - The address environment.
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
* Remaining reference count.
*
****************************************************************************/
@ -441,9 +524,7 @@ int addrenv_give(FAR struct addrenv_s *addrenv)
* no: The address environment can be dropped at once
*
* Returned Value:
* This is a NuttX internal function so it follows the convention that
* 0 (OK) is returned on success and a negated errno is returned on
* failure.
* None.
*
****************************************************************************/

View file

@ -24,6 +24,7 @@
#include <nuttx/config.h>
#include <nuttx/addrenv.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <nuttx/irq.h>
@ -225,7 +226,6 @@ static void show_stacks(FAR struct tcb_s *rtcb)
static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
{
#ifdef CONFIG_ARCH_ADDRENV
save_addrenv_t oldenv;
bool saved = false;
#endif
@ -240,17 +240,9 @@ static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
}
#ifdef CONFIG_ARCH_ADDRENV
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL)
if (tcb->addrenv_own != NULL)
{
if (tcb->addrenv_own == NULL)
{
/* Process should have address environment, but doesn't */
*args = '\0';
return;
}
up_addrenv_select(&tcb->addrenv_own->addrenv, &oldenv);
addrenv_select(tcb->addrenv_own);
saved = true;
}
#endif
@ -277,7 +269,7 @@ static void get_argv_str(FAR struct tcb_s *tcb, FAR char *args, size_t size)
#ifdef CONFIG_ARCH_ADDRENV
if (saved)
{
up_addrenv_restore(&oldenv);
addrenv_restore();
}
#endif
}