summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/ChangeLog6
-rw-r--r--nuttx/Documentation/NuttxPortingGuide.html155
-rw-r--r--nuttx/arch/arm/src/common/up_stackframe.c144
-rw-r--r--nuttx/arch/arm/src/lpc17xx/Make.defs2
-rw-r--r--nuttx/arch/arm/src/sam3u/Make.defs2
-rw-r--r--nuttx/arch/arm/src/stm32/stm32_otgfsdev.c1
-rw-r--r--nuttx/arch/avr/src/avr/up_stackframe.c117
-rw-r--r--nuttx/arch/avr/src/avr32/up_stackframe.c133
-rw-r--r--nuttx/arch/hc/src/common/up_stackframe.c133
-rw-r--r--nuttx/arch/mips/src/common/up_createstack.c6
-rw-r--r--nuttx/arch/mips/src/common/up_stackframe.c136
-rw-r--r--nuttx/arch/mips/src/common/up_usestack.c37
-rw-r--r--nuttx/arch/rgmp/src/nuttx.c25
-rw-r--r--nuttx/arch/sh/src/common/up_stackframe.c132
-rw-r--r--nuttx/arch/sh/src/common/up_usestack.c14
-rw-r--r--nuttx/arch/sim/src/up_stackframe.c133
-rw-r--r--nuttx/arch/x86/src/i486/up_stackframe.c134
-rw-r--r--nuttx/arch/z16/src/common/up_createstack.c14
-rw-r--r--nuttx/arch/z16/src/common/up_stackframe.c132
-rw-r--r--nuttx/arch/z16/src/common/up_usestack.c14
-rw-r--r--nuttx/arch/z80/src/common/up_stackframe.c132
-rw-r--r--nuttx/arch/z80/src/common/up_usestack.c14
-rw-r--r--nuttx/include/nuttx/arch.h39
23 files changed, 1554 insertions, 101 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 7f6a2b421..3c427ff29 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -4407,5 +4407,7 @@
thread, use the kernel allocator so that the kernel thread stacks
are protected from user application meddling (2013-03-20).
* arch/arm/src/armv[6|7]-m/up_scall.c: Fix parameter passing for
- all system call inline functions with > 3 parameters (2013-03-20)
-
+ all system call inline functions with > 3 parameters (2013-03-20)
+ * arch/*/src/common/up_stackframe.c and include/nuttx/arch.h: Add
+ and new interface to set aside memory on the stack. This will be
+ used at least in the kernel build to hold task arguments 2013-03-21).
diff --git a/nuttx/Documentation/NuttxPortingGuide.html b/nuttx/Documentation/NuttxPortingGuide.html
index 709c5a3a6..2fa0b2a71 100644
--- a/nuttx/Documentation/NuttxPortingGuide.html
+++ b/nuttx/Documentation/NuttxPortingGuide.html
@@ -78,22 +78,23 @@
<a href="#upinitialstate">4.1.3 <code>up_initial_state()</code></a><br>
<a href="#upcreatestack">4.1.4 <code>up_create_stack()</code></a><br>
<a href="#upusestack">4.1.5 <code>up_use_stack()</code></a><br>
- <a href="#upreleasestack">4.1.6 <code>up_release_stack()</code></a><br>
- <a href="#upunblocktask">4.1.7 <code>up_unblock_task()</code></a><br>
- <a href="#upblocktask">4.1.8 <code>up_block_task()</code></a><br>
- <a href="#upreleasepending">4.1.9 <code>up_release_pending()</code></a><br>
- <a href="#upreprioritizertr">4.1.10 <code>up_reprioritize_rtr()</code></a><br>
- <a href="#_exit">4.1.11 <code>_exit()</code></a><br>
- <a href="#upassert">4.1.12 <code>up_assert()</code></a><br>
- <a href="#upschedulesigaction">4.1.13 <code>up_schedule_sigaction()</code></a><br>
- <a href="#upallocateheap">4.1.14 <code>up_allocate_heap()</code></a><br>
- <a href="#upinterruptcontext">4.1.15 <code>up_interrupt_context()</code></a><br>
- <a href="#updisableirq">4.1.16 <code>up_disable_irq()</code></a><br>
- <a href="#upenableirq">4.1.17 <code>up_enable_irq()</code></a><br>
- <a href="#upprioritizeirq">4.1.18 <code>up_prioritize_irq()</code></a></br>
- <a href="#upputc">4.1.19 <code>up_putc()</code></a></br>
- <a href="#systemtime">4.1.20 System Time and Clock</a><br>
- <a href="#addrenv">4.1.21 Address Environments</a>
+ <a href="#upstackframe">4.1.6 <code>up_stack_frame()</code></a><br>
+ <a href="#upreleasestack">4.1.7 <code>up_release_stack()</code></a><br>
+ <a href="#upunblocktask">4.1.8 <code>up_unblock_task()</code></a><br>
+ <a href="#upblocktask">4.1.9 <code>up_block_task()</code></a><br>
+ <a href="#upreleasepending">4.1.10 <code>up_release_pending()</code></a><br>
+ <a href="#upreprioritizertr">4.1.11 <code>up_reprioritize_rtr()</code></a><br>
+ <a href="#_exit">4.1.12 <code>_exit()</code></a><br>
+ <a href="#upassert">4.1.13 <code>up_assert()</code></a><br>
+ <a href="#upschedulesigaction">4.1.14 <code>up_schedule_sigaction()</code></a><br>
+ <a href="#upallocateheap">4.1.15 <code>up_allocate_heap()</code></a><br>
+ <a href="#upinterruptcontext">4.1.16 <code>up_interrupt_context()</code></a><br>
+ <a href="#updisableirq">4.1.17 <code>up_disable_irq()</code></a><br>
+ <a href="#upenableirq">4.1.18 <code>up_enable_irq()</code></a><br>
+ <a href="#upprioritizeirq">4.1.19 <code>up_prioritize_irq()</code></a></br>
+ <a href="#upputc">4.1.20 <code>up_putc()</code></a></br>
+ <a href="#systemtime">4.1.21 System Time and Clock</a><br>
+ <a href="#addrenv">4.1.22 Address Environments</a>
</ul>
<a href="#exports">4.2 APIs Exported by NuttX to Architecture-Specific Logic</a>
<ul>
@@ -1702,7 +1703,58 @@ The system can be re-made subsequently by just typing <code>make</code>.
The TCB flags will always be set to provide the task type to <code>up_use_stack()</code> if the information needs that information.
</p>
-<h3><a name="upreleasestack">4.1.6 <code>up_release_stack()</code></a></h3>
+
+<h3><a name="upstackframe">4.1.6 <code>up_stack_frame()</code></a></h3>
+<p><b>Prototype</b>: <code>FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size);</code></p>
+
+<p>
+ <b>Description</b>.
+ Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ This function may be called anytime after <code>up_create_stack()</code> or <code>up_use_stack()</code> have been called but before the task has been started.
+</p>
+<p>
+ Thread data may be kept in the stack (instead of in the TCB) if it is accessed by the user code directory.
+ This includes such things as <code>argv[]</code>.
+ The stack memory is guaranteed to be in the same protection domain as the thread.
+</p>
+<p>
+ The following TCB fields will be re-initialized:
+</p>
+<ul>
+ <li>
+ <code>adj_stack_size</code>: Stack size after removal of the stack frame from the stack.
+ </li>
+ <li>
+ <code>adj_stack_ptr</code>: Adjusted initial stack pointer after the frame has been removed from the stack.
+ This will still be the initial value of the stack pointer when the task is started.
+ </li>
+</ul>
+<p>
+ This API is <i>NOT</i> required if <code>CONFIG_NUTTX_KERNEL</code> is undefined or if <code>CONFIG_CUSTOM_STACK</code> is defined.
+</p>
+<p><b>Input Parameters:</b></p>
+<ul>
+ <li>
+ <p>
+ <code>tcb</code>:
+ The TCB of new task.
+ </p>
+ </li>
+ <li>
+ <p>
+ <code>frame_size</code>:
+ The size of the stack frame to allocate.
+ </p>
+ </li>
+</ul>
+<p>
+ <b>Returned Value:</b>
+ A pointer to bottom of the allocated stack frame.
+ NULL will be returned on any failures.
+ The alignment of the returned value is the same as the alignment of the stack itself
+</p>
+
+<h3><a name="upreleasestack">4.1.7 <code>up_release_stack()</code></a></h3>
<p><b>Prototype</b>: <code>void up_release_stack(FAR struct tcb_s *dtcb);</code></p>
<p><b>Description</b>.
@@ -1718,6 +1770,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
<p>
<code>dtcb</code>:
The TCB containing information about the stack to be released.
+ </p>
</li>
<li>
<p>
@@ -1740,7 +1793,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
</li>
</ul>
-<h3><a name="upunblocktask">4.1.7 <code>up_unblock_task()</code></a></h3>
+<h3><a name="upunblocktask">4.1.8 <code>up_unblock_task()</code></a></h3>
<p><b>Prototype</b>: <code>void up_unblock_task(FAR struct tcb_s *tcb);</code></p>
<p><b>Description</b>.
@@ -1763,7 +1816,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
</li>
</ul>
-<h3><a name="upblocktask">4.1.8 <code>up_block_task()</code></a></h3>
+<h3><a name="upblocktask">4.1.9 <code>up_block_task()</code></a></h3>
<p><b>Prototype</b>: <code>void up_block_task(FAR struct tcb_s *tcb, tstate_t task_state);</code></p>
<p><b>Description</b>.
@@ -1789,7 +1842,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
</li>
</ul>
-<h3><a name="upreleasepending">4.1.9 <code>up_release_pending()</code></a></h3>
+<h3><a name="upreleasepending">4.1.10 <code>up_release_pending()</code></a></h3>
<p><b>Prototype</b>: <code>void up_release_pending(void);</code></p>
<p><b>Description</b>.
@@ -1806,7 +1859,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
function is called.
</p>
-<h3><a name="upreprioritizertr">4.1.10 <code>up_reprioritize_rtr()</code></a></h3>
+<h3><a name="upreprioritizertr">4.1.11 <code>up_reprioritize_rtr()</code></a></h3>
<p><b>Prototype</b>: <code>void up_reprioritize_rtr(FAR struct tcb_s *tcb, uint8_t priority);</code></p>
<p><b>Description</b>.
@@ -1841,7 +1894,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
</li>
</ul>
-<h3><a name="_exit">4.1.11 <code>_exit()</code></a></h3>
+<h3><a name="_exit">4.1.12 <code>_exit()</code></a></h3>
<p><b>Prototype</b>: <code>void _exit(int status) noreturn_function;</code></p>
<p><b>Description</b>.
@@ -1855,7 +1908,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
before performing scheduling operations.
</p>
-<h3><a name="upassert">4.1.12 <code>up_assert()</code></a></h3>
+<h3><a name="upassert">4.1.13 <code>up_assert()</code></a></h3>
<p><b>Prototype</b>:<br>
<code>void up_assert(FAR const uint8_t *filename, int linenum);</code></br>
<code>void up_assert_code(FAR const uint8_t *filename, int linenum, int error_code);</code></br>
@@ -1866,7 +1919,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
way.
</p>
-<h3><a name="upschedulesigaction">4.1.13 <code>up_schedule_sigaction()</code></a></h3>
+<h3><a name="upschedulesigaction">4.1.14 <code>up_schedule_sigaction()</code></a></h3>
<p><b>Prototype</b>:
<code>void up_schedule_sigaction(FAR struct tcb_s *tcb, sig_deliver_t sigdeliver);</code>
</p>
@@ -1913,7 +1966,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
is defined.
</p>
-<h3><a name="upallocateheap">4.1.14 <code>up_allocate_heap()</code></a></h3>
+<h3><a name="upallocateheap">4.1.15 <code>up_allocate_heap()</code></a></h3>
<p><b>Prototype</b>: <code>void up_allocate_heap(FAR void **heap_start, size_t *heap_size);</code></p>
<p><b>Description</b>.
@@ -1924,14 +1977,14 @@ The system can be re-made subsequently by just typing <code>make</code>.
If a protected kernel-space heap is provided, the kernel heap must be allocated (and protected) by an analogous <code>up_allocate_kheap()</code>.
</p>
-<h3><a name="upinterruptcontext">4.1.15 <code>up_interrupt_context()</code></a></h3>
+<h3><a name="upinterruptcontext">4.1.16 <code>up_interrupt_context()</code></a></h3>
<p><b>Prototype</b>: <code>bool up_interrupt_context(void)</code></p>
<p><b>Description</b>.
Return true if we are currently executing in the interrupt handler context.
</p>
-<h3><a name="updisableirq">4.1.16 <code>up_disable_irq()</code></a></h3>
+<h3><a name="updisableirq">4.1.17 <code>up_disable_irq()</code></a></h3>
<p><b>Prototype</b>:</p>
<ul><pre>
#ifndef CONFIG_ARCH_NOINTC
@@ -1958,7 +2011,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
avoided in common implementations where possible.
</p>
-<h3><a name="upenableirq">4.1.17 <code>up_enable_irq()</code></a></h3>
+<h3><a name="upenableirq">4.1.18 <code>up_enable_irq()</code></a></h3>
<p><b>Prototype</b>:</p>
<ul><pre>
#ifndef CONFIG_ARCH_NOINTC
@@ -1979,7 +2032,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
avoided in common implementations where possible.
</p>
-<h3><a name="upprioritizeirq">4.1.18 <code>up_prioritize_irq()</code></a></h3>
+<h3><a name="upprioritizeirq">4.1.19 <code>up_prioritize_irq()</code></a></h3>
<p><b>Prototype</b>:</p>
<ul><pre>
#ifdef CONFIG_ARCH_IRQPRIO
@@ -1996,7 +2049,7 @@ The system can be re-made subsequently by just typing <code>make</code>.
avoided in common implementations where possible.
</p>
-<h3><a name="upputc">4.1.19 <code>up_putc()</code></a></h3>
+<h3><a name="upputc">4.1.20 <code>up_putc()</code></a></h3>
<p><b>Prototype</b>: <code>int up_putc(int ch);</code></p>
<p><b>Description</b>.
@@ -2004,9 +2057,9 @@ The system can be re-made subsequently by just typing <code>make</code>.
Output one character on the console
</p>
-<h3><a name="systemtime">4.1.20 System Time and Clock</a></h3>
+<h3><a name="systemtime">4.1.21 System Time and Clock</a></h3>
-<h4>4.1.20.1 Basic System Timer</h4>
+<h4>4.1.21.1 Basic System Timer</h4>
<p><b>System Timer</b>
In most implementations, system time is provided by a timer interrupt.
@@ -2089,7 +2142,7 @@ else
In this way, the timer interval is controlled from interrupt-to-interrupt to produce an average frequency of exactly 100Hz.
</p>
-<h4>4.1.20.1 Hardware</h4>
+<h4>4.1.21.2 Hardware</h4>
<p>
To enable hardware module use the following configuration options:
<p>
@@ -2144,7 +2197,7 @@ else
</li>
</ul>
-<h4>4.1.20.2 System Tick and Time</h4>
+<h4>4.1.21.3 System Tick and Time</h4>
<p>
The system tick is represented by::
</p>
@@ -2167,7 +2220,7 @@ else
To retrieve that variable use:
</p>
-<h3><a name="addrenv">4.1.21 Address Environments</a></h3>
+<h3><a name="addrenv">4.1.22 Address Environments</a></h3>
<p>
CPUs that support memory management units (MMUs) may provide <i>address environments</i> within which tasks and their child threads execute.
@@ -2191,27 +2244,27 @@ else
</p>
<ul>
<li>
- <a href="#up_addrenv_create">4.1.21.1 <code>up_addrenv_create()</code></a>:
+ <a href="#up_addrenv_create">4.1.22.1 <code>up_addrenv_create()</code></a>:
Create an address environment.
</li>
<li>
- <a href="#up_addrenv_vaddr">4.1.21.2 <code>up_addrenv_vaddr()</code></a>:
+ <a href="#up_addrenv_vaddr">4.1.22.2 <code>up_addrenv_vaddr()</code></a>:
Returns the virtual base address of the address environment.
</li>
<li>
- <a href="#up_addrenv_select">4.1.21.3 <code>up_addrenv_select()</code></a>:
+ <a href="#up_addrenv_select">4.1.22.3 <code>up_addrenv_select()</code></a>:
Instantiate an address environment.
</li>
<li>
- <a href="#up_addrenv_restore">4.1.21.4 <code>up_addrenv_restore()</code></a>:
+ <a href="#up_addrenv_restore">4.1.22.4 <code>up_addrenv_restore()</code></a>:
Restore an address environment.
</li>
<li>
- <a href="#up_addrenv_destroy">4.1.21.5 <code>up_addrenv_destroy()</code></a>:
+ <a href="#up_addrenv_destroy">4.1.22.5 <code>up_addrenv_destroy()</code></a>:
Destroy an address environment.
</li>
<li>
- <a href="#up_addrenv_assign">4.1.21.6 <code>up_addrenv_assign()</code></a>:
+ <a href="#up_addrenv_assign">4.1.22.6 <code>up_addrenv_assign()</code></a>:
Assign an address environment to a TCB.
</li>
</ul>
@@ -2224,12 +2277,12 @@ else
</p>
<ul>
<li>
- <a href="#up_addrenv_share">4.1.21.7 <code>up_addrenv_share()</code></a>:
+ <a href="#up_addrenv_share">4.1.22.7 <code>up_addrenv_share()</code></a>:
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.
</li>
<li>
- <a href="#up_addrenv_release">4.1.21.8 <code>up_addrenv_release()</code></a>:
+ <a href="#up_addrenv_release">4.1.22.8 <code>up_addrenv_release()</code></a>:
Release the TCB's reference to an address environment when a task/thread exits.
</li>
</ul>
@@ -2237,7 +2290,7 @@ else
</ol>
-<h4><a name="up_addrenv_create">4.1.21.1 <code>up_addrenv_create()</code></a></h4>
+<h4><a name="up_addrenv_create">4.1.22.1 <code>up_addrenv_create()</code></a></h4>
<p><b>Prototype</b>:</p>
<ul>
<code>int up_addrenv_create(size_t envsize, FAR task_addrenv_t *addrenv);</code>
@@ -2257,7 +2310,7 @@ else
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
</ul>
-<h4><a name="up_addrenv_vaddr">4.1.21.2 <code>up_addrenv_vaddr()</code></a></h4>
+<h4><a name="up_addrenv_vaddr">4.1.22.2 <code>up_addrenv_vaddr()</code></a></h4>
<p><b>Prototype</b>:<p>
<ul>
<code>int up_addrenv_vaddr(FAR task_addrenv_t addrenv, FAR void **vaddr);</code>
@@ -2277,7 +2330,7 @@ else
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
</ul>
-<h4><a name="up_addrenv_select">4.1.21.3 <code>up_addrenv_select()</code></a></h4>
+<h4><a name="up_addrenv_select">4.1.22.3 <code>up_addrenv_select()</code></a></h4>
<p><b>Prototype</b>:<p>
<ul>
<code>int up_addrenv_select(task_addrenv_t addrenv, hw_addrenv_t *oldenv);</code>
@@ -2301,7 +2354,7 @@ else
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
</ul>
-<h4><a name="up_addrenv_restore">4.1.21.4 <code>up_addrenv_restore()</code></a></h4>
+<h4><a name="up_addrenv_restore">4.1.22.4 <code>up_addrenv_restore()</code></a></h4>
<p><b>Prototype</b>:<p>
<ul>
<code>int up_addrenv_restore(hw_addrenv_t oldenv);</code>
@@ -2320,7 +2373,7 @@ else
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
</ul>
-<h4><a name="up_addrenv_destroy">4.1.21.5 <code>up_addrenv_destroy()</code></a></h4>
+<h4><a name="up_addrenv_destroy">4.1.22.5 <code>up_addrenv_destroy()</code></a></h4>
<p><b>Prototype</b>:<p>
<ul>
<code>int up_addrenv_destroy(task_addrenv_t addrenv);</code>
@@ -2338,7 +2391,7 @@ else
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
</ul>
-<h4><a name="up_addrenv_assign">4.1.21.6 <code>up_addrenv_assign()</code></a></h4>
+<h4><a name="up_addrenv_assign">4.1.22.6 <code>up_addrenv_assign()</code></a></h4>
<p><b>Prototype</b>:<p>
<ul>
<code>int up_addrenv_assign(task_addrenv_t addrenv, FAR struct tcb_s *tcb);</code>
@@ -2357,7 +2410,7 @@ else
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
</ul>
-<h4><a name="up_addrenv_share">4.1.21.7 <code>up_addrenv_share()</code></a></h4>
+<h4><a name="up_addrenv_share">4.1.22.7 <code>up_addrenv_share()</code></a></h4>
<p><b>Prototype</b>:<p>
<ul>
<code>int up_addrenv_share(FAR const struct tcb_s *ptcb, FAR struct tcb_s *ctcb);</code>
@@ -2377,7 +2430,7 @@ else
Zero (<code>OK</code>) on success; a negated <code>errno</code> value on failure.
</ul>
-<h4><a name="up_addrenv_release">4.1.21.8 <code>up_addrenv_release()</code></a></h4>
+<h4><a name="up_addrenv_release">4.1.22.8 <code>up_addrenv_release()</code></a></h4>
<p><b>Prototype</b>:<p>
<ul>
<code>int up_addrenv_release(FAR struct tcb_s *tcb);</code>
diff --git a/nuttx/arch/arm/src/common/up_stackframe.c b/nuttx/arch/arm/src/common/up_stackframe.c
new file mode 100644
index 000000000..3720d334a
--- /dev/null
+++ b/nuttx/arch/arm/src/common/up_stackframe.c
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * arch/arm/src/common/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* ARM requires at least a 4-byte stack alignment. For use with EABI and
+ * floating point, the stack must be aligned to 8-byte addresses.
+ */
+
+#ifndef CONFIG_STACK_ALIGNMENT
+
+/* The symbol __ARM_EABI__ is defined by GCC if EABI is being used. If you
+ * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly!
+ */
+
+# ifdef __ARM_EABI__
+# define CONFIG_STACK_ALIGNMENT 8
+# else
+# define CONFIG_STACK_ALIGNMENT 4
+# endif
+#endif
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/arm/src/lpc17xx/Make.defs b/nuttx/arch/arm/src/lpc17xx/Make.defs
index 469165387..0fec22d12 100644
--- a/nuttx/arch/arm/src/lpc17xx/Make.defs
+++ b/nuttx/arch/arm/src/lpc17xx/Make.defs
@@ -68,7 +68,7 @@ CMN_ASRCS += up_memcpy.S
endif
ifeq ($(CONFIG_NUTTX_KERNEL),y)
-CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c
+CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c up_stackframe.c
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CMN_CSRCS += up_signal_handler.c
endif
diff --git a/nuttx/arch/arm/src/sam3u/Make.defs b/nuttx/arch/arm/src/sam3u/Make.defs
index 16ca22401..4abca3b2c 100644
--- a/nuttx/arch/arm/src/sam3u/Make.defs
+++ b/nuttx/arch/arm/src/sam3u/Make.defs
@@ -60,7 +60,7 @@ CMN_ASRCS += up_memcpy.S
endif
ifeq ($(CONFIG_NUTTX_KERNEL),y)
-CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c
+CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c up_stackframe.c
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
CMN_CSRCS += up_signal_handler.c
endif
diff --git a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
index 3986106d8..b8033fdd5 100644
--- a/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
+++ b/nuttx/arch/arm/src/stm32/stm32_otgfsdev.c
@@ -1517,7 +1517,6 @@ static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt)
DEBUGASSERT(privep && privep->ep.priv);
priv = (FAR struct stm32_usbdev_s *)privep->ep.priv;
- DEBUGASSERT(priv->ep0state == EP0STATE_SETUP_OUT);
ullvdbg("EP0: bcnt=%d\n", bcnt);
usbtrace(TRACE_READ(EP0), bcnt);
diff --git a/nuttx/arch/avr/src/avr/up_stackframe.c b/nuttx/arch/avr/src/avr/up_stackframe.c
new file mode 100644
index 000000000..39253e2b5
--- /dev/null
+++ b/nuttx/arch/avr/src/avr/up_stackframe.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * arch/avr/src/avr/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint8_t));
+}
diff --git a/nuttx/arch/avr/src/avr32/up_stackframe.c b/nuttx/arch/avr/src/avr32/up_stackframe.c
new file mode 100644
index 000000000..08c4cf51e
--- /dev/null
+++ b/nuttx/arch/avr/src/avr32/up_stackframe.c
@@ -0,0 +1,133 @@
+/****************************************************************************
+ * arch/avr/src/avr32/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* The AVR32 stack must be aligned at word (4 byte) boundaries. If necessary
+ * frame_size must be rounded up to the next boundary
+ */
+
+#define STACK_ALIGNMENT 4
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/hc/src/common/up_stackframe.c b/nuttx/arch/hc/src/common/up_stackframe.c
new file mode 100644
index 000000000..0daa4f7da
--- /dev/null
+++ b/nuttx/arch/hc/src/common/up_stackframe.c
@@ -0,0 +1,133 @@
+/****************************************************************************
+ * arch/hc/src/common/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* The CPU12 stack should be aligned at half-word (2 byte) boundaries. If
+ * necessary frame_size must be rounded up to the next boundary
+ */
+
+#define STACK_ALIGNMENT 2
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/mips/src/common/up_createstack.c b/nuttx/arch/mips/src/common/up_createstack.c
index 6109797a3..e2a73fc7d 100644
--- a/nuttx/arch/mips/src/common/up_createstack.c
+++ b/nuttx/arch/mips/src/common/up_createstack.c
@@ -60,14 +60,14 @@
*/
#ifdef CONFIG_LIBC_FLOATINGPOINT
-# define CONFIG_STACK_ALIGNMENT 8
+# define STACK_ALIGNMENT 8
#else
-# define CONFIG_STACK_ALIGNMENT 4
+# define STACK_ALIGNMENT 4
#endif
/* Stack alignment macros */
-#define STACK_ALIGN_MASK (CONFIG_STACK_ALIGNMENT-1)
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
diff --git a/nuttx/arch/mips/src/common/up_stackframe.c b/nuttx/arch/mips/src/common/up_stackframe.c
new file mode 100644
index 000000000..9b473ecc6
--- /dev/null
+++ b/nuttx/arch/mips/src/common/up_stackframe.c
@@ -0,0 +1,136 @@
+/****************************************************************************
+ * arch/mips/src/common/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+/* MIPS requires at least a 4-byte stack alignment. For floating point use,
+ * however, the stack must be aligned to 8-byte addresses.
+ */
+
+#ifdef CONFIG_LIBC_FLOATINGPOINT
+# define STACK_ALIGNMENT 8
+#else
+# define STACK_ALIGNMENT 4
+#endif
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/mips/src/common/up_usestack.c b/nuttx/arch/mips/src/common/up_usestack.c
index b636a51d7..934ac8ed1 100644
--- a/nuttx/arch/mips/src/common/up_usestack.c
+++ b/nuttx/arch/mips/src/common/up_usestack.c
@@ -50,6 +50,26 @@
#include "up_internal.h"
/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* MIPS requires at least a 4-byte stack alignment. For floating point use,
+ * however, the stack must be aligned to 8-byte addresses.
+ */
+
+#ifdef CONFIG_LIBC_FLOATINGPOINT
+# define STACK_ALIGNMENT 8
+#else
+# define STACK_ALIGNMENT 4
+#endif
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
* Private Types
****************************************************************************/
@@ -107,21 +127,20 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
tcb->stack_alloc_ptr = stack;
- /* MIPS uses a push-down stack: the stack grows
- * toward loweraddresses in memory. The stack pointer
- * register, points to the lowest, valid work address
- * (the "top" of the stack). Items on the stack are
- * referenced as positive word offsets from sp.
+ /* MIPS uses a push-down stack: the stack grows toward loweraddresses in
+ * memory. The stack pointer register, points to the lowest, valid work
+ * address (the "top" of the stack). Items on the stack are referenced
+ * as positive word offsets from sp.
*/
top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
- /* The MIPS stack must be aligned at word (4 byte)
- * boundaries. If necessary top_of_stack must be rounded
- * down to the next boundary
+ /* The MIPS stack must be aligned at word (4 byte) or double word (8 byte)
+ * boundaries. If necessary top_of_stack must be rounded down to the
+ * next boundary
*/
- top_of_stack &= ~3;
+ top_of_stack = STACK_ALIGN_DOWN(top_of_stack);
size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4;
/* Save the adjusted stack values in the struct tcb_s */
diff --git a/nuttx/arch/rgmp/src/nuttx.c b/nuttx/arch/rgmp/src/nuttx.c
index 79f97fcfc..f218b3f18 100644
--- a/nuttx/arch/rgmp/src/nuttx.c
+++ b/nuttx/arch/rgmp/src/nuttx.c
@@ -168,6 +168,31 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
return OK;
}
+#ifdef CONFIG_NUTTX_KERNEL
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = (frame_size + 3) & ~3;
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
+#endif
+
void up_release_stack(struct tcb_s *dtcb, uint8_t ttype)
{
/* Is there a stack allocated? */
diff --git a/nuttx/arch/sh/src/common/up_stackframe.c b/nuttx/arch/sh/src/common/up_stackframe.c
new file mode 100644
index 000000000..b1ef4c6b4
--- /dev/null
+++ b/nuttx/arch/sh/src/common/up_stackframe.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * arch/sh/src/common/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+/* The SH stack must be aligned at word (4 byte) boundaries. If necessary
+ * frame_size must be rounded up to the next boundary
+ */
+
+#define STACK_ALIGNMENT 4
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/sh/src/common/up_usestack.c b/nuttx/arch/sh/src/common/up_usestack.c
index bcce3261c..e0f348045 100644
--- a/nuttx/arch/sh/src/common/up_usestack.c
+++ b/nuttx/arch/sh/src/common/up_usestack.c
@@ -107,18 +107,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
tcb->stack_alloc_ptr = stack;
- /* The Arm7Tdmi uses a push-down stack: the stack grows
- * toward loweraddresses in memory. The stack pointer
- * register, points to the lowest, valid work address
- * (the "top" of the stack). Items on the stack are
- * referenced as positive word offsets from sp.
+ /* The SH family uses a push-down stack: the stack grows toward lower
+ * addresses in memory. The stack pointer register, points to the
+ * lowest, valid work address (the "top" of the stack). Items on the
+ * stack are referenced as positive word offsets from sp.
*/
top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
- /* The Arm7Tdmi stack must be aligned at word (4 byte)
- * boundaries. If necessary top_of_stack must be rounded
- * down to the next boundary
+ /* The SH stack must be aligned at word (4 byte) boundaries. If necessary
+ * top_of_stack must be rounded down to the next boundary
*/
top_of_stack &= ~3;
diff --git a/nuttx/arch/sim/src/up_stackframe.c b/nuttx/arch/sim/src/up_stackframe.c
new file mode 100644
index 000000000..4d62e6ec0
--- /dev/null
+++ b/nuttx/arch/sim/src/up_stackframe.c
@@ -0,0 +1,133 @@
+/****************************************************************************
+ * arch/sim/src/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* Use a stack alignment of 4 bytes. If necessary frame_size must be rounded
+ * up to the next boundary
+ */
+
+#define STACK_ALIGNMENT 4
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/x86/src/i486/up_stackframe.c b/nuttx/arch/x86/src/i486/up_stackframe.c
new file mode 100644
index 000000000..ea4edc07a
--- /dev/null
+++ b/nuttx/arch/x86/src/i486/up_stackframe.c
@@ -0,0 +1,134 @@
+/****************************************************************************
+ * arch/x86/src/i486/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+
+/* The initial stack point is aligned at word (4 byte) boundaries. If
+ * necessary frame_size must be rounded up to the next boundary to retain
+ * this alignment.
+ */
+
+#define STACK_ALIGNMENT 4
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/z16/src/common/up_createstack.c b/nuttx/arch/z16/src/common/up_createstack.c
index 2bd3a8951..69a413bde 100644
--- a/nuttx/arch/z16/src/common/up_createstack.c
+++ b/nuttx/arch/z16/src/common/up_createstack.c
@@ -171,18 +171,16 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
memset(tcb->stack_alloc_ptr, 0xaa, stack_size);
#endif
- /* The ZNeo uses a push-down stack: the stack grows
- * toward loweraddresses in memory. The stack pointer
- * register, points to the lowest, valid work address
- * (the "top" of the stack). Items on the stack are
- * referenced as positive word offsets from sp.
+ /* The ZNeo uses a push-down stack: the stack grows toward lower
+ * addresses in memory. The stack pointer register, points to the
+ * lowest, valid work address (the "top" of the stack). Items on
+ * the stack are referenced as positive word offsets from sp.
*/
top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
- /* The ZNeo stack must be aligned at word (4 byte)
- * boundaries. If necessary top_of_stack must be rounded
- * down to the next boundary
+ /* Align the stack to word (4 byte) boundaries. This is probably
+ * a greater alignement than is required.
*/
top_of_stack &= ~3;
diff --git a/nuttx/arch/z16/src/common/up_stackframe.c b/nuttx/arch/z16/src/common/up_stackframe.c
new file mode 100644
index 000000000..c11106542
--- /dev/null
+++ b/nuttx/arch/z16/src/common/up_stackframe.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * arch/z16/src/common/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+/* Align the stack to word (4 byte) boundaries. This is probablya greater
+ * alignement than is required.
+ */
+
+#define STACK_ALIGNMENT 4
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/z16/src/common/up_usestack.c b/nuttx/arch/z16/src/common/up_usestack.c
index 7b5effc45..eb725b7fb 100644
--- a/nuttx/arch/z16/src/common/up_usestack.c
+++ b/nuttx/arch/z16/src/common/up_usestack.c
@@ -107,18 +107,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
tcb->stack_alloc_ptr = stack;
- /* The Arm7Tdmi uses a push-down stack: the stack grows
- * toward loweraddresses in memory. The stack pointer
- * register, points to the lowest, valid work address
- * (the "top" of the stack). Items on the stack are
- * referenced as positive word offsets from sp.
+ /* The ZNEO uses a push-down stack: the stack grows toward lower
+ * addresses in memory. The stack pointer register, points to the
+ * lowest, valid work address (the "top" of the stack). Items on
+ * the stack are referenced as positive word offsets from sp.
*/
top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
- /* The Arm7Tdmi stack must be aligned at word (4 byte)
- * boundaries. If necessary top_of_stack must be rounded
- * down to the next boundary
+ /* Align the stack to word (4 byte) boundaries. This is probably
+ * a greater alignement than is required.
*/
top_of_stack &= ~3;
diff --git a/nuttx/arch/z80/src/common/up_stackframe.c b/nuttx/arch/z80/src/common/up_stackframe.c
new file mode 100644
index 000000000..01a7b0881
--- /dev/null
+++ b/nuttx/arch/z80/src/common/up_stackframe.c
@@ -0,0 +1,132 @@
+/****************************************************************************
+ * arch/z80/src/common/up_stackframe.c
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <sched.h>
+#include <debug.h>
+
+#include <nuttx/arch.h>
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Macros
+ ****************************************************************************/
+/* The Z80 stack does not need to be aligned. Here is is aligned at word
+ * (4 byte) boundary.
+ */
+
+#define STACK_ALIGNMENT 4
+
+/* Stack alignment macros */
+
+#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1)
+#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
+#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Global Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size)
+{
+ uintptr_t topaddr;
+
+ /* Align the frame_size */
+
+ frame_size = STACK_ALIGN_UP(frame_size);
+
+ /* Is there already a stack allocated? Is it big enough? */
+
+ if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size)
+ {
+ return NULL;
+ }
+
+ /* Save the adjusted stack values in the struct tcb_s */
+
+ topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size;
+ tcb->adj_stack_ptr = (FAR void *)topaddr;
+ tcb->adj_stack_size -= frame_size;
+
+ return (FAR void *)(topaddr + sizeof(uint32_t));
+}
diff --git a/nuttx/arch/z80/src/common/up_usestack.c b/nuttx/arch/z80/src/common/up_usestack.c
index 095b4f5d5..414040ec2 100644
--- a/nuttx/arch/z80/src/common/up_usestack.c
+++ b/nuttx/arch/z80/src/common/up_usestack.c
@@ -106,18 +106,16 @@ int up_use_stack(struct tcb_s *tcb, void *stack, size_t stack_size)
tcb->stack_alloc_ptr = stack;
- /* The Arm7Tdmi uses a push-down stack: the stack grows
- * toward loweraddresses in memory. The stack pointer
- * register, points to the lowest, valid work address
- * (the "top" of the stack). Items on the stack are
- * referenced as positive word offsets from sp.
+ /* The Z80 uses a push-down stack: the stack grows toward lower
+ * addresses in memory. The stack pointer register, points to the
+ * lowest, valid work address (the "top" of the stack). Items on
+ * the stack are* referenced as positive word offsets from sp.
*/
top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4;
- /* The Arm7Tdmi stack must be aligned at word (4 byte)
- * boundaries. If necessary top_of_stack must be rounded
- * down to the next boundary
+ /* The Z80 stack does not need to be aligned. Here is is aligned at
+ * word (4 byte) boundary.
*/
top_of_stack &= ~3;
diff --git a/nuttx/include/nuttx/arch.h b/nuttx/include/nuttx/arch.h
index 18df38b52..6595b3911 100644
--- a/nuttx/include/nuttx/arch.h
+++ b/nuttx/include/nuttx/arch.h
@@ -204,7 +204,8 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype);
* initial value of the stack pointer.
*
* Inputs:
- * - tcb: The TCB of new task
+ * - tcb: The TCB of new task
+ * - stack: The new stack to be used.
* - stack_size: The allocated stack size.
*
* NOTE: Unlike up_stack_create() and up_stack_release, this function
@@ -219,6 +220,42 @@ int up_use_stack(FAR struct tcb_s *tcb, FAR void *stack, size_t stack_size);
#endif
/****************************************************************************
+ * Name: up_stack_frame
+ *
+ * Description:
+ * Allocate a stack frame in the TCB's stack to hold thread-specific data.
+ * This function may be called anytime after up_create_stack() or
+ * up_use_stack() have been called but before the task has been started.
+ *
+ * Thread data may be kept in the stack (instead of in the TCB) if it is
+ * accessed by the user code directory. This includes such things as
+ * argv[]. The stack memory is guaranteed to be in the same protection
+ * domain as the thread.
+ *
+ * The following TCB fields will be re-initialized:
+ *
+ * - adj_stack_size: Stack size after removal of the stack frame from
+ * the stack
+ * - adj_stack_ptr: Adjusted initial stack pointer after the frame has
+ * been removed from the stack. This will still be the initial value
+ * of the stack pointer when the task is started.
+ *
+ * Inputs:
+ * - tcb: The TCB of new task
+ * - frame_size: The size of the stack frame to allocate.
+ *
+ * Returned Value:
+ * - A pointer to bottom of the allocated stack frame. NULL will be
+ * returned on any failures. The alignment of the returned value is
+ * the same as the alignment of the stack itself.
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_CUSTOM_STACK) && defined(CONFIG_NUTTX_KERNEL)
+FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size);
+#endif
+
+/****************************************************************************
* Name: up_release_stack
*
* Description: