Add a up_stack_frame() interface to allocate a frame of data on a task's stack.

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5768 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2013-03-21 17:35:08 +00:00
parent cce585e320
commit 170952d6e8
23 changed files with 1554 additions and 101 deletions

View File

@ -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).

View File

@ -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>

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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)

View File

@ -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));
}

View File

@ -49,6 +49,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 */

View File

@ -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? */

View File

@ -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));
}

View File

@ -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;

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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;

View File

@ -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));
}

View File

@ -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;

View File

@ -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));
}

View File

@ -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;

View File

@ -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
@ -218,6 +219,42 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype);
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
*