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:
parent
09e7987121
commit
f4b82b6405
29 changed files with 213 additions and 424 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue