summaryrefslogtreecommitdiff
path: root/nuttx/arch
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch')
-rw-r--r--nuttx/arch/arm/include/arch.h12
-rwxr-xr-xnuttx/arch/arm/include/armv7-a/irq.h4
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_addrenv.c90
-rw-r--r--nuttx/arch/z80/src/z180/z180_mmu.c64
4 files changed, 124 insertions, 46 deletions
diff --git a/nuttx/arch/arm/include/arch.h b/nuttx/arch/arm/include/arch.h
index 2f1991622..02e66aaf4 100644
--- a/nuttx/arch/arm/include/arch.h
+++ b/nuttx/arch/arm/include/arch.h
@@ -133,9 +133,19 @@ do { \
struct group_addrenv_s
{
+ /* Level 1 page table entries for each group section */
+
FAR uintptr_t *text[ARCH_TEXT_NSECTS];
FAR uintptr_t *data[ARCH_DATA_NSECTS];
FAR uintptr_t *heap[ARCH_HEAP_NSECTS];
+
+ /* Initial heap allocation (in bytes). This exists only provide an
+ * indirect path for passing the size of the initial heap to the heap
+ * initialization logic. These operations are separated in time and
+ * architecture. REVISIT: I would like a better way to do this.
+ */
+
+ size_t heapsize;
};
typedef struct group_addrenv_s group_addrenv_t;
@@ -153,9 +163,7 @@ struct save_addrenv_s
{
FAR uint32_t text[ARCH_TEXT_NSECTS];
FAR uint32_t data[ARCH_DATA_NSECTS];
-#if 0 /* Not yet implemented */
FAR uint32_t heap[ARCH_HEAP_NSECTS];
-#endif
};
typedef struct save_addrenv_s save_addrenv_t;
diff --git a/nuttx/arch/arm/include/armv7-a/irq.h b/nuttx/arch/arm/include/armv7-a/irq.h
index 00e7244ae..f9d5225b3 100755
--- a/nuttx/arch/arm/include/armv7-a/irq.h
+++ b/nuttx/arch/arm/include/armv7-a/irq.h
@@ -274,17 +274,15 @@ struct xcptcontext
struct xcpt_syscall_s syscall[CONFIG_SYS_NNEST];
#endif
-#ifdef CONFIG_ARCH_ADDRENV
+#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_ARCH_STACK_DYNAMIC)
/* This table holds the physical address of the level 2 page table used
* to map the thread's stack memory. This array will be initially of
* zeroed and would be back-up up with pages during page fault exception
* handling to support dynamically sized stacks for each thread.
*/
-#if 0 /* Not yet implemented */
FAR uintptr_t *stack[ARCH_STACK_NSECTS];
#endif
-#endif
};
#endif
diff --git a/nuttx/arch/arm/src/armv7-a/arm_addrenv.c b/nuttx/arch/arm/src/armv7-a/arm_addrenv.c
index 4d68fd655..aa28efbdb 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_addrenv.c
+++ b/nuttx/arch/arm/src/armv7-a/arm_addrenv.c
@@ -40,27 +40,28 @@
* is an abstract representation of a task group's address environment and
* must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined.
*
- * up_addrenv_create - Create an address environment
- * up_addrenv_destroy - Destroy an address environment.
- * up_addrenv_vtext - Returns the virtual base address of the .text
- * 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_restore - Restore an address environment
- * up_addrenv_clone - Copy an address environment from one location to
- * another.
+ * up_addrenv_create - Create an address environment
+ * up_addrenv_destroy - Destroy an address environment.
+ * up_addrenv_vtext - Returns the virtual base address of the .text
+ * address environment
+ * up_addrenv_vdata - Returns the virtual base address of the .bss/.data
+ * 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.
*
* Higher-level interfaces used by the tasking logic. These interfaces are
* used by the functions in sched/ and all operate on the thread which whose
* group been assigned an address environment by up_addrenv_clone().
*
- * up_addrenv_attach - Clone the address environment assigned to one TCB
- * to another. This operation is done when a pthread
- * is created that share's the same address
- * environment.
- * up_addrenv_detach - Release the threads reference to an address
- * environment when a task/thread exits.
+ * up_addrenv_attach - Clone the address environment assigned to one TCB
+ * to another. This operation is done when a pthread
+ * is created that share's the same address
+ * environment.
+ * up_addrenv_detach - Release the threads reference to an address
+ * environment when a task/thread exits.
*
****************************************************************************/
@@ -153,6 +154,10 @@ static void set_l2_entry(FAR uint32_t *l2table, uintptr_t paddr,
* Description:
* Create one memory region.
*
+ * Returned Value:
+ * On success, the number of pages allocated is returned. Otherwise, a
+ * negated errno value is returned.
+ *
****************************************************************************/
static int up_addrenv_create_region(FAR uintptr_t **list,
@@ -264,7 +269,7 @@ static int up_addrenv_create_region(FAR uintptr_t **list,
irqrestore(flags);
}
- return OK;
+ return npages;
}
/****************************************************************************
@@ -437,6 +442,8 @@ static void up_addrenv_destroy_region(FAR uintptr_t **list,
* actual size of the data region that is allocated will include a
* OS private reserved region at the beginning. The size of the
* private, reserved region is give by ARCH_DATA_RESERVE_SIZE.
+ * heapsize - The initial size (in bytes) of the heap address environment
+ * needed by the task. This region may be read/write only.
* addrenv - The location to return the representation of the task address
* environment.
*
@@ -445,7 +452,7 @@ static void up_addrenv_destroy_region(FAR uintptr_t **list,
*
****************************************************************************/
-int up_addrenv_create(size_t textsize, size_t datasize,
+int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize,
FAR group_addrenv_t *addrenv)
{
int ret;
@@ -503,8 +510,22 @@ int up_addrenv_create(size_t textsize, size_t datasize,
}
#endif
- /* Notice that no pages are yet allocated for the heap */
+ /* Allocate heap space pages */
+
+ ret = up_addrenv_create_region(addrenv->heap, ARCH_HEAP_NSECTS,
+ CONFIG_ARCH_HEAP_VBASE, heapsize,
+ MMU_L2_UDATAFLAGS);
+ if (ret < 0)
+ {
+ bdbg("ERROR: Failed to create heap region: %d\n", ret);
+ goto errout;
+ }
+ /* Save the initial heap size allocated. This will be needed when
+ * the heap data structures are initialized.
+ */
+
+ addrenv->heapsize = (size_t)ret << MM_PGSHIFT;
return OK;
errout:
@@ -543,12 +564,10 @@ int up_addrenv_destroy(FAR group_addrenv_t *addrenv)
up_addrenv_destroy_region(addrenv->data, ARCH_DATA_NSECTS,
CONFIG_ARCH_DATA_VBASE);
-#if 0 /* Not yet implemented */
/* Destroy the heap region */
up_addrenv_destroy_region(addrenv->heap, ARCH_HEAP_NSECTS,
CONFIG_ARCH_HEAP_VBASE);
-#endif
memset(addrenv, 0, sizeof(group_addrenv_t));
return OK;
@@ -617,6 +636,31 @@ int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize,
}
/****************************************************************************
+ * Name: up_addrenv_heapsize
+ *
+ * Description:
+ * Return the initial heap allocation size. That is the amount of memory
+ * allocated by up_addrenv_create() when the heap memory region was first
+ * created. This may or may not differ from the heapsize parameter that
+ * was passed to up_addrenv_create()
+ *
+ * Input Parameters:
+ * addrenv - The representation of the task address environment previously
+ * returned by up_addrenv_create.
+ *
+ * Returned Value:
+ * The initial heap size allocated is returned on success; a negated
+ * errno value on failure.
+ *
+ ****************************************************************************/
+
+ssize_t up_addrenv_heapsize(FAR const group_addrenv_t *addrenv)
+{
+ DEBUGASSERT(addrenv);
+ return (ssize_t)addrenv->heapsize;
+}
+
+/****************************************************************************
* Name: up_addrenv_select
*
* Description:
@@ -698,7 +742,6 @@ int up_addrenv_select(FAR const group_addrenv_t *addrenv,
}
}
-#if 0 /* Not yet implemented */
for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0;
i < ARCH_HEAP_NSECTS;
vaddr += SECTION_SIZE, i++)
@@ -722,7 +765,6 @@ int up_addrenv_select(FAR const group_addrenv_t *addrenv,
mmu_l1_clrentry(vaddr);
}
}
-#endif
return OK;
}
@@ -770,7 +812,6 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
mmu_l1_restore(vaddr, oldenv->data[i]);
}
-#if 0 /* Not yet implemented */
for (vaddr = CONFIG_ARCH_HEAP_VBASE, i = 0;
i < ARCH_HEAP_NSECTS;
vaddr += SECTION_SIZE, i++)
@@ -779,7 +820,6 @@ int up_addrenv_restore(FAR const save_addrenv_t *oldenv)
mmu_l1_restore(vaddr, oldenv->heap[i]);
}
-#endif
return OK;
}
diff --git a/nuttx/arch/z80/src/z180/z180_mmu.c b/nuttx/arch/z80/src/z180/z180_mmu.c
index e1373851d..e63e18403 100644
--- a/nuttx/arch/z80/src/z180/z180_mmu.c
+++ b/nuttx/arch/z80/src/z180/z180_mmu.c
@@ -184,15 +184,16 @@ return g_physhandle ? OK : -ENOMEM;
* is an abstract representation of a task group's address environment and
* must be defined in arch/arch.h if CONFIG_ARCH_ADDRENV is defined.
*
- * up_addrenv_create - Create an address environment
- * up_addrenv_destroy - Destroy an address environment.
- * up_addrenv_vtext - Returns the virtual base address of the .text
- * 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_restore - Restore an address environment
- * up_addrenv_clone - Copy an address environment from one location to
+ * up_addrenv_create - Create an address environment
+ * up_addrenv_destroy - Destroy an address environment.
+ * up_addrenv_vtext - Returns the virtual base address of the .text
+ * address environment
+ * up_addrenv_vdata - Returns the virtual base address of the .bss/.data
+ * 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.
*
* Higher-level interfaces used by the tasking logic. These interfaces are
@@ -200,11 +201,11 @@ return g_physhandle ? OK : -ENOMEM;
* group been assigned an address environment by up_addrenv_clone().
*
* up_addrenv_attach - Clone the address environment assigned to one TCB
- * to another. This operation is done when a pthread
- * is created that share's the same address
- * environment.
- * up_addrenv_detach - Release the threads reference to an address
- * environment when a task/thread exits.
+ * to another. This operation is done when a pthread
+ * is created that share's the same address
+ * environment.
+ * up_addrenv_detach - Release the threads reference to an address
+ * environment when a task/thread exits.
*
****************************************************************************/
/****************************************************************************
@@ -220,6 +221,11 @@ return g_physhandle ? OK : -ENOMEM;
* textsize - The size (in bytes) of the .text address environment needed
* 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. NOTE: The
+ * actual size of the data region that is allocated will include a
+ * OS private reserved region at the beginning. The size of the
+ * private, reserved region is give by ARCH_DATA_RESERVE_SIZE.
+ * heapsize - The initial size (in bytes) of the heap address environment
* needed by the task. This region may be read/write only.
* addrenv - The location to return the representation of the task address
* environment.
@@ -229,7 +235,7 @@ return g_physhandle ? OK : -ENOMEM;
*
****************************************************************************/
-int up_addrenv_create(size_t textsize, size_t datasize,
+int up_addrenv_create(size_t textsize, size_t datasize, size_t heapsize,
FAR group_addrenv_t *addrenv)
{
FAR struct z180_cbr_s *cbr;
@@ -241,7 +247,7 @@ int up_addrenv_create(size_t textsize, size_t datasize,
/* Convert the size from bytes to numbers of pages */
- envsize = textsize + datasize;
+ envsize = textsize + datasize + heapsize;
npages = PHYS_ALIGNUP(envsize);
if (npages < 1)
{
@@ -390,6 +396,32 @@ int up_addrenv_vdata(FAR group_addrenv_t *addrenv, uintptr_t textsize,
}
/****************************************************************************
+ * Name: up_addrenv_heapsize
+ *
+ * Description:
+ * Return the initial heap allocation size. That is the amount of memory
+ * allocated by up_addrenv_create() when the heap memory region was first
+ * created. This may or may not differ from the heapsize parameter that
+ * was passed to up_addrenv_create()
+ *
+ * Input Parameters:
+ * addrenv - The representation of the task address environment previously
+ * returned by up_addrenv_create.
+ *
+ * Returned Value:
+ * The initial heap size allocated is returned on success; a negated
+ * errno value on failure.
+ *
+ ****************************************************************************/
+
+ssize_t up_addrenv_heapsize(FAR const group_addrenv_t *addrenv)
+{
+ /* Not implemented */
+
+ return (ssize_t)-ENOSYS;
+}
+
+/****************************************************************************
* Name: up_addrenv_select
*
* Description: