More ARMv7-A files that are just copies of the ARMv4/5 files for now
This commit is contained in:
parent
15ae557793
commit
c294e9b374
@ -274,6 +274,9 @@ config ARCH_HAVE_VFORK
|
||||
bool
|
||||
default n
|
||||
|
||||
config ARCH_HAVE_MMU
|
||||
bool
|
||||
|
||||
config ARCH_STACKDUMP
|
||||
bool "Dump stack on assertions"
|
||||
default n
|
||||
@ -334,6 +337,7 @@ config ARCH_CALIBRATION
|
||||
|
||||
config DRAM_START
|
||||
hex "DRAM start physical address"
|
||||
default 0x0
|
||||
help
|
||||
The physical start address of installed RAM. Despite the naming,
|
||||
this may be SDRAM or SRAM or any other RAM technology that support
|
||||
@ -341,6 +345,7 @@ config DRAM_START
|
||||
|
||||
config DRAM_VSTART
|
||||
hex "DRAM start virtual address"
|
||||
default 0x0
|
||||
depends on ARCH_HAVE_MMU
|
||||
help
|
||||
The virtual start address of installed RAM. Despite the naming,
|
||||
@ -349,6 +354,7 @@ config DRAM_VSTART
|
||||
|
||||
config DRAM_SIZE
|
||||
int "DRAM size"
|
||||
default 0
|
||||
help
|
||||
The size in bytes of the installed RAM. Despite the naming,
|
||||
this may be SDRAM or SRAM or any other RAM technology that support
|
||||
|
@ -29,7 +29,6 @@ config ARCH_CHIP_DM320
|
||||
bool "TMS320 DM320"
|
||||
select ARCH_ARM926EJS
|
||||
select ARCH_HAVE_LOWVECTORS
|
||||
select ARCH_HAVE_MMU
|
||||
---help---
|
||||
TI DMS320 DM320 (ARM926EJS)
|
||||
|
||||
@ -38,7 +37,6 @@ config ARCH_CHIP_IMX
|
||||
select ARCH_ARM920T
|
||||
select ARCH_HAVE_HEAP2
|
||||
select ARCH_HAVE_LOWVECTORS
|
||||
select ARCH_HAVE_MMU
|
||||
---help---
|
||||
Freescale iMX architectures (ARM920T)
|
||||
|
||||
@ -91,7 +89,6 @@ config ARCH_CHIP_LPC31XX
|
||||
bool "NXP LPC31XX"
|
||||
select ARCH_ARM926EJS
|
||||
select ARCH_HAVE_LOWVECTORS
|
||||
select ARCH_HAVE_MMU
|
||||
---help---
|
||||
NPX LPC31XX architectures (ARM926EJS).
|
||||
|
||||
@ -143,10 +140,12 @@ config ARCH_ARM7TDMI
|
||||
config ARCH_ARM926EJS
|
||||
bool
|
||||
default n
|
||||
select ARCH_HAVE_MMU
|
||||
|
||||
config ARCH_ARM920T
|
||||
bool
|
||||
default n
|
||||
select ARCH_HAVE_MMU
|
||||
|
||||
config ARCH_CORTEXM0
|
||||
bool
|
||||
@ -169,6 +168,7 @@ config ARCH_CORTEXA5
|
||||
bool
|
||||
default n
|
||||
select ARCH_IRQPRIO
|
||||
select ARCH_HAVE_MMU
|
||||
|
||||
config ARCH_FAMILY
|
||||
string
|
||||
@ -261,11 +261,9 @@ config ARCH_LOWVECTORS
|
||||
---help---
|
||||
Support ARM vectors in low memory.
|
||||
|
||||
config ARCH_HAVE_MMU
|
||||
bool
|
||||
|
||||
config PGTABLE_VADDR
|
||||
hex "Page table virtual address"
|
||||
default 0x0
|
||||
depends on ARCH_HAVE_MMU
|
||||
---help---
|
||||
Page table virtual address (might be defined in the board.h file). Not
|
||||
|
@ -61,7 +61,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_undefinedinsn
|
||||
* Name: up_copystate
|
||||
****************************************************************************/
|
||||
|
||||
/* A little faster than most memcpy's */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/src/up_prefetchabort.c
|
||||
* arch/arm/src/arm/up_prefetchabort.c
|
||||
*
|
||||
* Copyright (C) 2007-2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/src/up_vectoraddrexceptn.S
|
||||
* arch/arm/src/arm/up_vectoraddrexceptn.S
|
||||
*
|
||||
* Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
|
243
arch/arm/src/armv7-a/arm_allocpage.c
Normal file
243
arch/arm/src/armv7-a/arm_allocpage.c
Normal file
@ -0,0 +1,243 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_allocpage.c
|
||||
* Allocate a new page and map it to the fault address of a task.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
|
||||
#include <nuttx/page.h>
|
||||
|
||||
#include "pg_macros.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_PAGING_NPPAGED < 256
|
||||
typedef uint8_t pgndx_t;
|
||||
#elif CONFIG_PAGING_NPPAGED < 65536
|
||||
typedef uint16_t pgndx_t;
|
||||
#else
|
||||
typedef uint32_t pgndx_t;
|
||||
#endif
|
||||
|
||||
#if PG_POOL_MAXL1NDX < 256
|
||||
typedef uint8_t L1ndx_t;
|
||||
#elif PG_POOL_MAXL1NDX < 65536
|
||||
typedef uint16_t L1ndx_t;
|
||||
#else
|
||||
typedef uint32_t L1ndx_t;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Free pages in memory are managed by indices ranging from up to
|
||||
* CONFIG_PAGING_NPAGED. Initially all pages are free so the page can be
|
||||
* simply allocated in order: 0, 1, 2, ... . After all CONFIG_PAGING_NPAGED
|
||||
* pages have be filled, then they are blindly freed and re-used in the
|
||||
* same order 0, 1, 2, ... because we don't know any better. No smart "least
|
||||
* recently used" kind of logic is supported.
|
||||
*/
|
||||
|
||||
static pgndx_t g_pgndx;
|
||||
|
||||
/* After CONFIG_PAGING_NPAGED have been allocated, the pages will be re-used.
|
||||
* In order to re-used the page, we will have un-map the page from its previous
|
||||
* mapping. In order to that, we need to be able to map a physical address to
|
||||
* to an index into the PTE where it was mapped. The following table supports
|
||||
* this backward lookup - it is indexed by the page number index, and holds
|
||||
* another index to the mapped virtual page.
|
||||
*/
|
||||
|
||||
static L1ndx_t g_ptemap[CONFIG_PAGING_NPPAGED];
|
||||
|
||||
/* The contents of g_ptemap[] are not valid until g_pgndx has wrapped at
|
||||
* least one time.
|
||||
*/
|
||||
|
||||
static bool g_pgwrap;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_allocpage()
|
||||
*
|
||||
* Description:
|
||||
* This architecture-specific function will set aside page in memory and map
|
||||
* the page to its correct virtual address. Architecture-specific context
|
||||
* information saved within the TCB will provide the function with the
|
||||
* information needed to identify the virtual miss address.
|
||||
*
|
||||
* This function will return the allocated physical page address in vpage.
|
||||
* The size of the underlying physical page is determined by the
|
||||
* configuration setting CONFIG_PAGING_PAGESIZE.
|
||||
*
|
||||
* NOTE 1: This function must always return a page allocation. If all
|
||||
* available pages are in-use (the typical case), then this function will
|
||||
* select a page in-use, un-map it, and make it available.
|
||||
*
|
||||
* NOTE 2: If an in-use page is un-mapped, it may be necessary to flush the
|
||||
* instruction cache in some architectures.
|
||||
*
|
||||
* NOTE 3: Allocating and filling a page is a two step process. up_allocpage()
|
||||
* allocates the page, and up_fillpage() fills it with data from some non-
|
||||
* volatile storage device. This distinction is made because up_allocpage()
|
||||
* can probably be implemented in board-independent logic whereas up_fillpage()
|
||||
* probably must be implemented as board-specific logic.
|
||||
*
|
||||
* NOTE 4: The initial mapping of vpage should be read-able and write-
|
||||
* able (but not cached). No special actions will be required of
|
||||
* up_fillpage() in order to write into this allocated page.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - A reference to the task control block of the task that needs to
|
||||
* have a page fill. Architecture-specific logic can retrieve page
|
||||
* fault information from the architecture-specific context
|
||||
* information in this TCB to perform the mapping.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function will return zero (OK) if the allocation was successful.
|
||||
* A negated errno value may be returned if an error occurs. All errors,
|
||||
* however, are fatal.
|
||||
*
|
||||
* Assumptions:
|
||||
* - This function is called from the normal tasking context (but with
|
||||
* interrupts disabled). The implementation must take whatever actions
|
||||
* are necessary to assure that the operation is safe within this
|
||||
* context.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_allocpage(FAR struct tcb_s *tcb, FAR void **vpage)
|
||||
{
|
||||
uintptr_t vaddr;
|
||||
uintptr_t paddr;
|
||||
uint32_t *pte;
|
||||
unsigned int pgndx;
|
||||
|
||||
/* Since interrupts are disabled, we don't need to anything special. */
|
||||
|
||||
DEBUGASSERT(tcb && vpage);
|
||||
|
||||
/* Get the virtual address that caused the fault */
|
||||
|
||||
vaddr = tcb->xcp.far;
|
||||
DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND);
|
||||
|
||||
/* Allocate page memory to back up the mapping. Start by getting the
|
||||
* index of the next page that we are going to allocate.
|
||||
*/
|
||||
|
||||
pgndx = g_pgndx++;
|
||||
if (g_pgndx >= CONFIG_PAGING)
|
||||
{
|
||||
g_pgndx = 0;
|
||||
g_pgwrap = true;
|
||||
}
|
||||
|
||||
/* Was this physical page previously mapped? If so, then we need to un-map
|
||||
* it.
|
||||
*/
|
||||
|
||||
if (g_pgwrap)
|
||||
{
|
||||
/* Yes.. Get a pointer to the L2 entry corresponding to the previous
|
||||
* mapping -- then zero it!
|
||||
*/
|
||||
|
||||
uintptr_t oldvaddr = PG_POOL_NDX2VA(g_ptemap[pgndx]);
|
||||
pte = up_va2pte(oldvaddr);
|
||||
*pte = 0;
|
||||
|
||||
/* Invalidate the instruction TLB corresponding to the virtual address */
|
||||
|
||||
tlb_inst_invalidate_single(oldvaddr);
|
||||
|
||||
/* I do not believe that it is necessary to flush the I-Cache in this
|
||||
* case: The I-Cache uses a virtual address index and, hence, since the
|
||||
* NuttX address space is flat, the cached instruction value should be
|
||||
* correct even if the page mapping is no longer in place.
|
||||
*/
|
||||
}
|
||||
|
||||
/* Then convert the index to a (physical) page address. */
|
||||
|
||||
paddr = PG_POOL_PGPADDR(pgndx);
|
||||
|
||||
/* Now setup up the new mapping. Get a pointer to the L2 entry
|
||||
* corresponding to the new mapping. Then set it map to the newly
|
||||
* allocated page address. The inital mapping is read/write but
|
||||
* non-cached (MMU_L2_ALLOCFLAGS)
|
||||
*/
|
||||
|
||||
pte = up_va2pte(vaddr);
|
||||
*pte = (paddr | MMU_L2_ALLOCFLAGS);
|
||||
|
||||
/* And save the new L1 index */
|
||||
|
||||
g_ptemap[pgndx] = PG_POOL_VA2L2NDX(vaddr);
|
||||
|
||||
/* Finally, return the virtual address of allocated page */
|
||||
|
||||
*vpage = (void*)(vaddr & ~PAGEMASK);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PAGING */
|
304
arch/arm/src/armv7-a/arm_assert.c
Normal file
304
arch/arm/src/armv7-a/arm_assert.c
Normal file
@ -0,0 +1,304 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_assert.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 <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Output debug info if stack dump is selected -- even if
|
||||
* debug is not selected.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
# undef lldbg
|
||||
# define lldbg lowsyslog
|
||||
#endif
|
||||
|
||||
/* The following is just intended to keep some ugliness out of the mainline
|
||||
* code. We are going to print the task name if:
|
||||
*
|
||||
* CONFIG_TASK_NAME_SIZE > 0 && <-- The task has a name
|
||||
* (defined(CONFIG_DEBUG) || <-- And the debug is enabled (lldbg used)
|
||||
* defined(CONFIG_ARCH_STACKDUMP) <-- Or lowsyslog() is used
|
||||
*/
|
||||
|
||||
#undef CONFIG_PRINT_TASKNAME
|
||||
#if CONFIG_TASK_NAME_SIZE > 0 && (defined(CONFIG_DEBUG) || defined(CONFIG_ARCH_STACKDUMP))
|
||||
# define CONFIG_PRINT_TASKNAME 1
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_getsp
|
||||
****************************************************************************/
|
||||
|
||||
/* I don't know if the builtin to get SP is enabled */
|
||||
|
||||
static inline uint32_t up_getsp(void)
|
||||
{
|
||||
uint32_t sp;
|
||||
__asm__
|
||||
(
|
||||
"\tmov %0, sp\n\t"
|
||||
: "=r"(sp)
|
||||
);
|
||||
return sp;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_stackdump
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
static void up_stackdump(uint32_t sp, uint32_t stack_base)
|
||||
{
|
||||
uint32_t stack ;
|
||||
|
||||
for (stack = sp & ~0x1f; stack < stack_base; stack += 32)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t*)stack;
|
||||
lldbg("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
stack, ptr[0], ptr[1], ptr[2], ptr[3],
|
||||
ptr[4], ptr[5], ptr[6], ptr[7]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define up_stackdump()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_registerdump
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
static inline void up_registerdump(void)
|
||||
{
|
||||
/* Are user registers available from interrupt processing? */
|
||||
|
||||
if (current_regs)
|
||||
{
|
||||
int regs;
|
||||
|
||||
/* Yes.. dump the interrupt registers */
|
||||
|
||||
for (regs = REG_R0; regs <= REG_R15; regs += 8)
|
||||
{
|
||||
uint32_t *ptr = (uint32_t*)¤t_regs[regs];
|
||||
lldbg("R%d: %08x %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
regs, ptr[0], ptr[1], ptr[2], ptr[3],
|
||||
ptr[4], ptr[5], ptr[6], ptr[7]);
|
||||
}
|
||||
|
||||
lldbg("CPSR: %08x\n", current_regs[REG_CPSR]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define up_registerdump()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_dumpstate
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
static void up_dumpstate(void)
|
||||
{
|
||||
struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
uint32_t sp = up_getsp();
|
||||
uint32_t ustackbase;
|
||||
uint32_t ustacksize;
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
uint32_t istackbase;
|
||||
uint32_t istacksize;
|
||||
#endif
|
||||
|
||||
/* Get the limits on the user stack memory */
|
||||
|
||||
if (rtcb->pid == 0)
|
||||
{
|
||||
ustackbase = g_idle_topstack - 4;
|
||||
ustacksize = CONFIG_IDLETHREAD_STACKSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ustackbase = (uint32_t)rtcb->adj_stack_ptr;
|
||||
ustacksize = (uint32_t)rtcb->adj_stack_size;
|
||||
}
|
||||
|
||||
/* Get the limits on the interrupt stack memory */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
istackbase = (uint32_t)&g_userstack;
|
||||
istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4;
|
||||
|
||||
/* Show interrupt stack info */
|
||||
|
||||
lldbg("sp: %08x\n", sp);
|
||||
lldbg("IRQ stack:\n");
|
||||
lldbg(" base: %08x\n", istackbase);
|
||||
lldbg(" size: %08x\n", istacksize);
|
||||
|
||||
/* Does the current stack pointer lie within the interrupt
|
||||
* stack?
|
||||
*/
|
||||
|
||||
if (sp <= istackbase && sp > istackbase - istacksize)
|
||||
{
|
||||
/* Yes.. dump the interrupt stack */
|
||||
|
||||
up_stackdump(sp, istackbase);
|
||||
|
||||
/* Extract the user stack pointer which should lie
|
||||
* at the base of the interrupt stack.
|
||||
*/
|
||||
|
||||
sp = g_userstack;
|
||||
lldbg("sp: %08x\n", sp);
|
||||
}
|
||||
|
||||
/* Show user stack info */
|
||||
|
||||
lldbg("User stack:\n");
|
||||
lldbg(" base: %08x\n", ustackbase);
|
||||
lldbg(" size: %08x\n", ustacksize);
|
||||
#else
|
||||
lldbg("sp: %08x\n", sp);
|
||||
lldbg("stack base: %08x\n", ustackbase);
|
||||
lldbg("stack size: %08x\n", ustacksize);
|
||||
#endif
|
||||
|
||||
/* Dump the user stack if the stack pointer lies within the allocated user
|
||||
* stack memory.
|
||||
*/
|
||||
|
||||
if (sp > ustackbase || sp <= ustackbase - ustacksize)
|
||||
{
|
||||
#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4
|
||||
lldbg("ERROR: Stack pointer is not within allocated stack\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
up_stackdump(sp, ustackbase);
|
||||
}
|
||||
|
||||
/* Then dump the registers (if available) */
|
||||
|
||||
up_registerdump();
|
||||
}
|
||||
#else
|
||||
# define up_dumpstate()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: _up_assert
|
||||
****************************************************************************/
|
||||
|
||||
static void _up_assert(int errorcode) noreturn_function;
|
||||
static void _up_assert(int errorcode)
|
||||
{
|
||||
/* Are we in an interrupt handler or the idle task? */
|
||||
|
||||
if (current_regs || ((struct tcb_s*)g_readytorun.head)->pid == 0)
|
||||
{
|
||||
(void)irqsave();
|
||||
for(;;)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
up_ledon(LED_PANIC);
|
||||
up_mdelay(250);
|
||||
up_ledoff(LED_PANIC);
|
||||
up_mdelay(250);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exit(errorcode);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_assert
|
||||
****************************************************************************/
|
||||
|
||||
void up_assert(const uint8_t *filename, int lineno)
|
||||
{
|
||||
#ifdef CONFIG_PRINT_TASKNAME
|
||||
struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
#endif
|
||||
|
||||
up_ledon(LED_ASSERTION);
|
||||
|
||||
#ifdef CONFIG_PRINT_TASKNAME
|
||||
lldbg("Assertion failed at file:%s line: %d task: %s\n",
|
||||
filename, lineno, rtcb->name);
|
||||
#else
|
||||
lldbg("Assertion failed at file:%s line: %d\n",
|
||||
filename, lineno);
|
||||
#endif
|
||||
up_dumpstate();
|
||||
_up_assert(EXIT_FAILURE);
|
||||
}
|
162
arch/arm/src/armv7-a/arm_blocktask.c
Normal file
162
arch/arm/src/armv7-a/arm_blocktask.c
Normal file
@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/up_blocktask.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 <stdbool.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_block_task
|
||||
*
|
||||
* Description:
|
||||
* The currently executing task at the head of
|
||||
* the ready to run list must be stopped. Save its context
|
||||
* and move it to the inactive list specified by task_state.
|
||||
*
|
||||
* Inputs:
|
||||
* tcb: Refers to a task in the ready-to-run list (normally
|
||||
* the task at the head of the list). It most be
|
||||
* stopped, its context saved and moved into one of the
|
||||
* waiting task lists. It it was the task at the head
|
||||
* of the ready-to-run list, then a context to the new
|
||||
* ready to run task must be performed.
|
||||
* task_state: Specifies which waiting task list should be
|
||||
* hold the blocked task TCB.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_block_task(struct tcb_s *tcb, tstate_t task_state)
|
||||
{
|
||||
struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
bool switch_needed;
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
|
||||
ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) &&
|
||||
(tcb->task_state <= LAST_READY_TO_RUN_STATE));
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we
|
||||
* are blocking the task at the head of the task list (the
|
||||
* most likely case), then a context switch to the next
|
||||
* ready-to-run task is needed. In this case, it should
|
||||
* also be true that rtcb == tcb.
|
||||
*/
|
||||
|
||||
switch_needed = sched_removereadytorun(tcb);
|
||||
|
||||
/* Add the task to the specified blocked task list */
|
||||
|
||||
sched_addblocked(tcb, (tstate_t)task_state);
|
||||
|
||||
/* If there are any pending tasks, then add them to the g_readytorun
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
{
|
||||
switch_needed |= sched_mergepending();
|
||||
}
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the user C context into the TCB at the (old) head of the
|
||||
* g_readytorun Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
}
|
123
arch/arm/src/armv7-a/arm_checkmapping.c
Normal file
123
arch/arm/src/armv7-a/arm_checkmapping.c
Normal file
@ -0,0 +1,123 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_checkmapping.c
|
||||
* Check if the current task's fault address has been mapped into the virtual
|
||||
* address space.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/page.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_checkmapping()
|
||||
*
|
||||
* Description:
|
||||
* The function up_checkmapping() returns an indication if the page fill
|
||||
* still needs to performed or not. In certain conditions, the page fault
|
||||
* may occur on several threads and be queued multiple times. This function
|
||||
* will prevent the same page from be filled multiple times.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - A reference to the task control block of the task that we believe
|
||||
* needs to have a page fill. Architecture-specific logic can
|
||||
* retrieve page fault information from the architecture-specific
|
||||
* context information in this TCB and can consult processor resources
|
||||
* (page tables or TLBs or ???) to determine if the fill still needs
|
||||
* to be performed or not.
|
||||
*
|
||||
* Returned Value:
|
||||
* This function will return true if the mapping is in place and false
|
||||
* if the mapping is still needed. Errors encountered should be
|
||||
* interpreted as fatal.
|
||||
*
|
||||
* Assumptions:
|
||||
* - This function is called from the normal tasking context (but with
|
||||
* interrupts disabled). The implementation must take whatever actions
|
||||
* are necessary to assure that the operation is safe within this
|
||||
* context.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool up_checkmapping(FAR struct tcb_s *tcb)
|
||||
{
|
||||
uintptr_t vaddr;
|
||||
uint32_t *pte;
|
||||
|
||||
/* Since interrupts are disabled, we don't need to anything special. */
|
||||
|
||||
DEBUGASSERT(tcb);
|
||||
|
||||
/* Get the virtual address that caused the fault */
|
||||
|
||||
vaddr = tcb->xcp.far;
|
||||
DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND);
|
||||
|
||||
/* Get the PTE associated with this virtual address */
|
||||
|
||||
pte = up_va2pte(vaddr);
|
||||
|
||||
/* Return true if this virtual address is mapped. */
|
||||
|
||||
return (*pte != 0);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PAGING */
|
82
arch/arm/src/armv7-a/arm_copystate.c
Normal file
82
arch/arm/src/armv7-a/arm_copystate.c
Normal file
@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_copystate.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 <stdint.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_copystate
|
||||
****************************************************************************/
|
||||
|
||||
/* A little faster than most memcpy's */
|
||||
|
||||
void up_copystate(uint32_t *dest, uint32_t *src)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* In the current ARM model, the state is always copied to and from the
|
||||
* stack and TCB.
|
||||
*/
|
||||
|
||||
for (i = 0; i < XCPTCONTEXT_REGS; i++)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
}
|
||||
|
201
arch/arm/src/armv7-a/arm_dataabort.c
Normal file
201
arch/arm/src/armv7-a/arm_dataabort.c
Normal file
@ -0,0 +1,201 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_dataabort.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 <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
# include <nuttx/page.h>
|
||||
# include "arm.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Output debug info if stack dump is selected -- even if
|
||||
* debug is not selected.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
# undef lldbg
|
||||
# define lldbg lowsyslog
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_dataabort
|
||||
*
|
||||
* Input parameters:
|
||||
* regs - The standard, ARM register save array.
|
||||
*
|
||||
* If CONFIG_PAGING is selected in the NuttX configuration file, then these
|
||||
* additional input values are expected:
|
||||
*
|
||||
* far - Fault address register. On a data abort, the ARM MMU places the
|
||||
* miss virtual address (MVA) into the FAR register. This is the address
|
||||
* of the data which, when accessed, caused the fault.
|
||||
* fsr - Fault status register. On a data a abort, the ARM MMU places an
|
||||
* encoded four-bit value, the fault status, along with the four-bit
|
||||
* encoded domain number, in the data FSR
|
||||
*
|
||||
* Description:
|
||||
* This is the data abort exception handler. The ARM data abort exception
|
||||
* occurs when a memory fault is detected during a data transfer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
void arm_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr)
|
||||
{
|
||||
FAR struct tcb_s *tcb = (FAR struct tcb_s *)g_readytorun.head;
|
||||
#ifdef CONFIG_PAGING
|
||||
uint32_t *savestate;
|
||||
|
||||
/* Save the saved processor context in current_regs where it can be accessed
|
||||
* for register dumps and possibly context switching.
|
||||
*/
|
||||
|
||||
|
||||
savestate = (uint32_t*)current_regs;
|
||||
#endif
|
||||
current_regs = regs;
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
/* In the NuttX on-demand paging implementation, only the read-only, .text
|
||||
* section is paged. However, the ARM compiler generated PC-relative data
|
||||
* fetches from within the .text sections. Also, it is customary to locate
|
||||
* read-only data (.rodata) within the same section as .text so that it
|
||||
* does not require copying to RAM. Misses in either of these case should
|
||||
* cause a data abort.
|
||||
*
|
||||
* We are only interested in data aborts due to page translations faults.
|
||||
* Sections should already be in place and permissions should already be
|
||||
* be set correctly (to read-only) so any other data abort reason is a
|
||||
* fatal error.
|
||||
*/
|
||||
|
||||
pglldbg("FSR: %08x FAR: %08x\n", fsr, far);
|
||||
if ((fsr & FSR_MASK) != FSR_PAGE)
|
||||
{
|
||||
goto segfault;
|
||||
}
|
||||
|
||||
/* Check the (virtual) address of data that caused the data abort. When
|
||||
* the exception occurred, this address was provided in the FAR register.
|
||||
* (It has not yet been saved in the register context save area).
|
||||
*/
|
||||
|
||||
pgllvdbg("VBASE: %08x VEND: %08x\n", PG_PAGED_VBASE, PG_PAGED_VEND);
|
||||
if (far < PG_PAGED_VBASE || far >= PG_PAGED_VEND)
|
||||
{
|
||||
goto segfault;
|
||||
}
|
||||
|
||||
/* Save the offending data address as the fault address in the TCB of
|
||||
* the currently task. This fault address is also used by the prefetch
|
||||
* abort handling; this will allow common paging logic for both
|
||||
* prefetch and data aborts.
|
||||
*/
|
||||
|
||||
tcb->xcp.far = regs[REG_R15];
|
||||
|
||||
/* Call pg_miss() to schedule the page fill. A consequences of this
|
||||
* call are:
|
||||
*
|
||||
* (1) The currently executing task will be blocked and saved on
|
||||
* on the g_waitingforfill task list.
|
||||
* (2) An interrupt-level context switch will occur so that when
|
||||
* this function returns, it will return to a different task,
|
||||
* most likely the page fill worker thread.
|
||||
* (3) The page fill worker task has been signalled and should
|
||||
* execute immediately when we return from this exception.
|
||||
*/
|
||||
|
||||
pg_miss();
|
||||
|
||||
/* Restore the previous value of current_regs. NULL would indicate that
|
||||
* we are no longer in an interrupt handler. It will be non-NULL if we
|
||||
* are returning from a nested interrupt.
|
||||
*/
|
||||
|
||||
current_regs = savestate;
|
||||
return;
|
||||
|
||||
segfault:
|
||||
#endif
|
||||
lldbg("Data abort. PC: %08x FAR: %08x FSR: %08x\n", regs[REG_PC], far, fsr);
|
||||
PANIC();
|
||||
}
|
||||
|
||||
#else /* CONFIG_PAGING */
|
||||
|
||||
void arm_dataabort(uint32_t *regs)
|
||||
{
|
||||
/* Save the saved processor context in current_regs where it can be accessed
|
||||
* for register dumps and possibly context switching.
|
||||
*/
|
||||
|
||||
current_regs = regs;
|
||||
|
||||
/* Crash -- possibly showing diagnost debug information. */
|
||||
|
||||
lldbg("Data abort. PC: %08x\n", regs[REG_PC]);
|
||||
PANIC();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PAGING */
|
116
arch/arm/src/armv7-a/arm_doirq.c
Normal file
116
arch/arm/src/armv7-a/arm_doirq.c
Normal file
@ -0,0 +1,116 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_doirq.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 <stdint.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void up_doirq(int irq, uint32_t *regs)
|
||||
{
|
||||
up_ledon(LED_INIRQ);
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
PANIC();
|
||||
#else
|
||||
uint32_t *savestate;
|
||||
|
||||
/* Nested interrupts are not supported in this implementation. If you want
|
||||
* to implement nested interrupts, you would have to (1) change the way that
|
||||
* current_regs is handled and (2) the design associated with
|
||||
* CONFIG_ARCH_INTERRUPTSTACK. The savestate variable will not work for
|
||||
* that purpose as implemented here because only the outermost nested
|
||||
* interrupt can result in a context switch (it can probably be deleted).
|
||||
*/
|
||||
|
||||
/* Current regs non-zero indicates that we are processing an interrupt;
|
||||
* current_regs is also used to manage interrupt level context switches.
|
||||
*/
|
||||
|
||||
savestate = (uint32_t*)current_regs;
|
||||
current_regs = regs;
|
||||
|
||||
/* Mask and acknowledge the interrupt */
|
||||
|
||||
up_maskack_irq(irq);
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
/* Restore the previous value of current_regs. NULL would indicate that
|
||||
* we are no longer in an interrupt handler. It will be non-NULL if we
|
||||
* are returning from a nested interrupt.
|
||||
*/
|
||||
|
||||
current_regs = savestate;
|
||||
|
||||
/* Unmask the last interrupt (global interrupts are still disabled) */
|
||||
|
||||
up_enable_irq(irq);
|
||||
#endif
|
||||
up_ledoff(LED_INIRQ);
|
||||
}
|
257
arch/arm/src/armv7-a/arm_elf.c
Normal file
257
arch/arm/src/armv7-a/arm_elf.c
Normal file
@ -0,0 +1,257 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv-7a/arm_elf.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 <stdlib.h>
|
||||
#include <elf32.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/elf.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/binfmt/elf.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arch_checkarch
|
||||
*
|
||||
* Description:
|
||||
* Given the ELF header in 'hdr', verify that the ELF file is appropriate
|
||||
* for the current, configured architecture. Every architecture that uses
|
||||
* the ELF loader must provide this function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* hdr - The ELF header read from the ELF file.
|
||||
*
|
||||
* Returned Value:
|
||||
* True if the architecture supports this ELF file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool arch_checkarch(FAR const Elf32_Ehdr *ehdr)
|
||||
{
|
||||
/* Make sure it's an ARM executable */
|
||||
|
||||
if (ehdr->e_machine != EM_ARM)
|
||||
{
|
||||
bdbg("Not for ARM: e_machine=%04x\n", ehdr->e_machine);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* Make sure that 32-bit objects are supported */
|
||||
|
||||
if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
|
||||
{
|
||||
bdbg("Need 32-bit objects: e_ident[EI_CLASS]=%02x\n", ehdr->e_ident[EI_CLASS]);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* Verify endian-ness */
|
||||
|
||||
#ifdef CONFIG_ENDIAN_BIG
|
||||
if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
|
||||
#else
|
||||
if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
|
||||
#endif
|
||||
{
|
||||
bdbg("Wrong endian-ness: e_ident[EI_DATA]=%02x\n", ehdr->e_ident[EI_DATA]);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* Make sure the entry point address is properly aligned */
|
||||
|
||||
if ((ehdr->e_entry & 3) != 0)
|
||||
{
|
||||
bdbg("Entry point is not properly aligned: %08x\n", ehdr->e_entry);
|
||||
return -ENOEXEC
|
||||
}
|
||||
|
||||
/* TODO: Check ABI here. */
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arch_relocate and arch_relocateadd
|
||||
*
|
||||
* Description:
|
||||
* Perform on architecture-specific ELF relocation. Every architecture
|
||||
* that uses the ELF loader must provide this function.
|
||||
*
|
||||
* Input Parameters:
|
||||
* rel - The relocation type
|
||||
* sym - The ELF symbol structure containing the fully resolved value.
|
||||
* addr - The address that requires the relocation.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if the relocation was successful. Otherwise, a negated errno
|
||||
* value indicating the cause of the relocation failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int arch_relocate(FAR const Elf32_Rel *rel, FAR const Elf32_Sym *sym,
|
||||
uintptr_t addr)
|
||||
{
|
||||
int32_t offset;
|
||||
|
||||
switch (ELF32_R_TYPE(rel->r_info))
|
||||
{
|
||||
case R_ARM_NONE:
|
||||
{
|
||||
/* No relocation */
|
||||
}
|
||||
break;
|
||||
|
||||
case R_ARM_PC24:
|
||||
case R_ARM_CALL:
|
||||
case R_ARM_JUMP24:
|
||||
{
|
||||
bvdbg("Performing PC24 [%d] link at addr %08lx [%08lx] to sym '%s' st_value=%08lx\n",
|
||||
ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t*)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
offset = (*(uint32_t*)addr & 0x00ffffff) << 2;
|
||||
if (offset & 0x02000000)
|
||||
{
|
||||
offset -= 0x04000000;
|
||||
}
|
||||
|
||||
offset += sym->st_value - addr;
|
||||
if (offset & 3 || offset <= (int32_t) 0xfe000000 || offset >= (int32_t) 0x02000000)
|
||||
{
|
||||
bdbg(" ERROR: PC24 [%d] relocation out of range, offset=%08lx\n",
|
||||
ELF32_R_TYPE(rel->r_info), offset);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
offset >>= 2;
|
||||
|
||||
*(uint32_t*)addr &= 0xff000000;
|
||||
*(uint32_t*)addr |= offset & 0x00ffffff;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_ARM_ABS32:
|
||||
case R_ARM_TARGET1: /* New ABI: TARGET1 always treated as ABS32 */
|
||||
{
|
||||
bvdbg("Performing ABS32 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
|
||||
(long)addr, (long)(*(uint32_t*)addr), sym, (long)sym->st_value);
|
||||
|
||||
*(uint32_t*)addr += sym->st_value;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_ARM_V4BX:
|
||||
{
|
||||
bvdbg("Performing V4BX link at addr=%08lx [%08lx]\n",
|
||||
(long)addr, (long)(*(uint32_t*)addr));
|
||||
|
||||
/* Preserve only Rm and the condition code */
|
||||
|
||||
*(uint32_t*)addr &= 0xf000000f;
|
||||
|
||||
/* Change instruction to 'mov pc, Rm' */
|
||||
|
||||
*(uint32_t*)addr |= 0x01a0f000;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_ARM_PREL31:
|
||||
{
|
||||
bvdbg("Performing PREL31 link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
|
||||
(long)addr, (long)(*(uint32_t*)addr), sym, (long)sym->st_value);
|
||||
|
||||
offset = *(uint32_t*)addr + sym->st_value - addr;
|
||||
*(uint32_t*)addr = offset & 0x7fffffff;
|
||||
}
|
||||
break;
|
||||
|
||||
case R_ARM_MOVW_ABS_NC:
|
||||
case R_ARM_MOVT_ABS:
|
||||
{
|
||||
bvdbg("Performing MOVx_ABS [%d] link at addr=%08lx [%08lx] to sym=%p st_value=%08lx\n",
|
||||
ELF32_R_TYPE(rel->r_info), (long)addr, (long)(*(uint32_t*)addr),
|
||||
sym, (long)sym->st_value);
|
||||
|
||||
offset = *(uint32_t*)addr;
|
||||
offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
|
||||
offset = (offset ^ 0x8000) - 0x8000;
|
||||
|
||||
offset += sym->st_value;
|
||||
if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
|
||||
{
|
||||
offset >>= 16;
|
||||
}
|
||||
|
||||
*(uint32_t*)addr &= 0xfff0f000;
|
||||
*(uint32_t*)addr |= ((offset & 0xf000) << 4) | (offset & 0x0fff);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
bdbg("Unsupported relocation: %d\n", ELF32_R_TYPE(rel->r_info));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int arch_relocateadd(FAR const Elf32_Rela *rel, FAR const Elf32_Sym *sym,
|
||||
uintptr_t addr)
|
||||
{
|
||||
bdbg("RELA relocation not supported\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
117
arch/arm/src/armv7-a/arm_fullcontextrestore.S
Normal file
117
arch/arm/src/armv7-a/arm_fullcontextrestore.S
Normal file
@ -0,0 +1,117 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_fullcontextrestore.S
|
||||
*
|
||||
* 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/irq.h>
|
||||
#include "up_internal.h"
|
||||
|
||||
.file "arm_fullcontextrestore.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fullcontextrestore
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fullcontextrestore
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_fullcontextrestore
|
||||
.type up_fullcontextrestore, function
|
||||
up_fullcontextrestore:
|
||||
|
||||
/* On entry, a1 (r0) holds address of the register save area */
|
||||
|
||||
/* Recover all registers except for r0, r1, R15, and CPSR */
|
||||
|
||||
add r1, r0, #(4*REG_R2) /* Offset to REG_R2 storage */
|
||||
ldmia r1, {r2-r14} /* Recover registers */
|
||||
|
||||
/* Create a stack frame to hold the PC */
|
||||
|
||||
sub sp, sp, #(3*4) /* Frame for three registers */
|
||||
ldr r1, [r0, #(4*REG_R0)] /* Fetch the stored r0 value */
|
||||
str r1, [sp] /* Save it at the top of the stack */
|
||||
ldr r1, [r0, #(4*REG_R1)] /* Fetch the stored r1 value */
|
||||
str r1, [sp, #4] /* Save it in the stack */
|
||||
ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */
|
||||
str r1, [sp, #8] /* Save it at the bottom of the frame */
|
||||
|
||||
/* Now we can restore the CPSR. We wait until we are completely
|
||||
* finished with the context save data to do this. Restore the CPSR
|
||||
* may re-enable and interrupts and we could be in a context
|
||||
* where the save structure is only protected by interrupts being
|
||||
* disabled.
|
||||
*/
|
||||
|
||||
ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
|
||||
msr cpsr, r1 /* Set the CPSR */
|
||||
|
||||
/* Now recover r0 and r1 */
|
||||
|
||||
ldr r0, [sp]
|
||||
ldr r1, [sp, #4]
|
||||
add sp, sp, #(2*4)
|
||||
|
||||
/* Then return to the address at the stop of the stack,
|
||||
* destroying the stack frame
|
||||
*/
|
||||
|
||||
ldr pc, [sp], #4
|
||||
.size up_fullcontextrestore, . - up_fullcontextrestore
|
@ -46,6 +46,7 @@
|
||||
|
||||
#include "arm.h"
|
||||
#include "cp15.h"
|
||||
#include "sctlr.h"
|
||||
|
||||
/**********************************************************************************
|
||||
* Configuration
|
||||
@ -355,77 +356,105 @@ __start:
|
||||
|
||||
ldr lr, .LCvstart /* Abs. virtual address */
|
||||
|
||||
/* Configure the domain access register (see mmu.h) */
|
||||
|
||||
mov r0, #0x1f /* Domains 0, 1 = client */
|
||||
mcr p15, 0, r0, c3, c0 /* Load domain access register */
|
||||
mrc p15, 0, r0, c1, c0 /* Get control register */
|
||||
mcr CP15_DACR(r0) /* Load domain access register */
|
||||
|
||||
/* Clear bits (see arm.h)
|
||||
/* Configure the system control register (see sctrl.h) */
|
||||
|
||||
mrc CP15_SCTLR(r0) /* Get control register */
|
||||
|
||||
/* Clear bits to reset values. This is only necessary in situations like, for
|
||||
* example, we get here via a bootloader and the control register is in some
|
||||
* unknown state.
|
||||
*
|
||||
* CR_R - ROM MMU protection
|
||||
* CR_F - Implementation defined
|
||||
* CR_Z - Implementation defined
|
||||
* SCTLR_A Bit 1: Strict alignment disabled (reset value)
|
||||
* SCTLR_C Bit 2: DCache disabled (reset value)
|
||||
*
|
||||
* CR_A - Alignment abort enable
|
||||
* CR_C - Dcache enable
|
||||
* CR_W - Write buffer enable
|
||||
* SCTLR_SW Bit 10: SWP/SWPB not enabled (reset value)
|
||||
* SCTLR_I Bit 12: ICache disabled (reset value)
|
||||
* SCTLR_V Bit 13: Assume low vectors (reset value)
|
||||
* SCTLR_RR Bit 14: The Cortex-A5 processor only supports a fixed random
|
||||
* replacement strategy.
|
||||
* SCTLR_HA Bit 17: Not supported by A5
|
||||
*
|
||||
* CR_I - Icache enable
|
||||
* SCTLR_EE Bit 25: Little endian (reset value).
|
||||
* SCTLR_TRE Bit 28: No memory region remapping (reset value)
|
||||
* SCTLR_AFE Bit 29: Full, legacy access permissions behavior (reset value).
|
||||
* SCTLR_TE Bit 30: All exceptions handled in ARM state (reset value).
|
||||
*/
|
||||
|
||||
bic r0, r0, #(CR_R|CR_F|CR_Z)
|
||||
bic r0, r0, #(CR_A|CR_C|CR_W)
|
||||
bic r0, r0, #(CR_I)
|
||||
bic r0, r0, #(SCTLR_A | SCTLR_C)
|
||||
bic r0, r0, #(SCTLR_SW | SCTLR_I | SCTLR_V | SCTLR_RR | SCTLR_HA)
|
||||
bic r0, r0, #(SCTLR_EE | SCTLR_TRE | SCTLR_AFE | SCTLR_TE)
|
||||
|
||||
/* Set bits (see arm.h)
|
||||
/* Set bits to enable the MMU
|
||||
*
|
||||
* CR_M - MMU enable
|
||||
* CR_P - 32-bit exception handler
|
||||
* CR_D - 32-bit data address range
|
||||
* SCTLR_M Bit 0: Enable the MMU
|
||||
* SCTLR_Z Bit 11: Program flow prediction control always enabled on A5
|
||||
*/
|
||||
|
||||
orr r0, r0, #(CR_M|CR_P|CR_D)
|
||||
orr r0, r0, #(SCTLR_M /* | SCTLR_Z */)
|
||||
|
||||
/* In most architectures, vectors are relocated to 0xffff0000.
|
||||
* -- but not all
|
||||
/* Position vectors to 0xffff0000 if so configured.
|
||||
*
|
||||
* CR_S - System MMU protection
|
||||
* CR_V - Vectors relocated to 0xffff0000
|
||||
* SCTLR_V Bit 13: High vectors
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_ARCH_LOWVECTORS
|
||||
orr r0, r0, #(CR_S|CR_V)
|
||||
#else
|
||||
orr r0, r0, #(CR_S)
|
||||
orr r0, r0, #(SCTLR_V)
|
||||
#endif
|
||||
/* CR_RR - Round Robin cache replacement */
|
||||
|
||||
#ifdef CPU_CACHE_ROUND_ROBIN
|
||||
orr r0, r0, #(CR_RR)
|
||||
/* CR_RR - Round Robin cache replacement
|
||||
*
|
||||
* SCTLR_RR Bit 14: The Cortex-A5 processor only supports a fixed random
|
||||
* replacement strategy.
|
||||
*/
|
||||
|
||||
#ifndef CPU_CACHE_ROUND_ROBIN
|
||||
#endif
|
||||
/* CR_C - Dcache enable */
|
||||
|
||||
/* CR_C - Dcache enable
|
||||
*
|
||||
* SCTLR_C Bit 2: DCache enable
|
||||
*/
|
||||
|
||||
#ifndef CPU_DCACHE_DISABLE
|
||||
orr r0, r0, #(CR_C)
|
||||
orr r0, r0, #(SCTLR_C)
|
||||
#endif
|
||||
/* CR_C - Dcache enable */
|
||||
|
||||
/* CR_C - Icache enable
|
||||
*
|
||||
* SCTLR_I Bit 12: ICache enable
|
||||
*/
|
||||
|
||||
#ifndef CPU_ICACHE_DISABLE
|
||||
orr r0, r0, #(CR_I)
|
||||
orr r0, r0, #(SCTLR_I)
|
||||
#endif
|
||||
/* CR_A - Alignment abort enable */
|
||||
|
||||
/* CR_A - Alignment abort enable
|
||||
*
|
||||
* SCTLR_A Bit 1: Strict alignment enabled
|
||||
*/
|
||||
|
||||
#ifdef ALIGNMENT_TRAP
|
||||
orr r0, r0, #(CR_A)
|
||||
orr r0, r0, #(SCTLR_A)
|
||||
#endif
|
||||
mcr p15, 0, r0, c1, c0, 0 /* write control reg */
|
||||
|
||||
/* Get TMP=2 Processor ID register */
|
||||
/* Then write the configured control register */
|
||||
|
||||
mrc p15, 0, r1, c0, c0, 0 /* read id reg */
|
||||
mov r1,r1 /* Null-avoiding nop */
|
||||
mov r1,r1 /* Null-avoiding nop */
|
||||
mcr CP15_SCTLR(r0) /* Write control reg */
|
||||
|
||||
/* And "jump" to .Lvstart */
|
||||
/* Read the Main ID register. This will be available in R1 after
|
||||
* MMU trampoline (not currently used)
|
||||
*/
|
||||
|
||||
mrc CP15_MIDR(r1) /* Read main id reg */
|
||||
mov r1, r1 /* Null-avoiding nop */
|
||||
mov r1, r1 /* Null-avoiding nop */
|
||||
|
||||
/* And "jump" to .Lvstart in the newly mapped virtual address space */
|
||||
|
||||
mov pc, lr
|
||||
|
||||
@ -433,7 +462,7 @@ __start:
|
||||
* PC_Relative Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Most addresses are all virtual address */
|
||||
/* Most addresses are virtual address */
|
||||
|
||||
.type .LCvstart, %object
|
||||
.LCvstart:
|
||||
|
146
arch/arm/src/armv7-a/arm_initialstate.c
Normal file
146
arch/arm/src/armv7-a/arm_initialstate.c
Normal file
@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_initialstate.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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "up_internal.h"
|
||||
#include "up_arch.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_initial_state
|
||||
*
|
||||
* Description:
|
||||
* A new thread is being started and a new TCB
|
||||
* has been created. This function is called to initialize
|
||||
* the processor specific portions of the new TCB.
|
||||
*
|
||||
* This function must setup the intial architecture registers
|
||||
* and/or stack so that execution will begin at tcb->start
|
||||
* on the next context switch.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_initial_state(struct tcb_s *tcb)
|
||||
{
|
||||
struct xcptcontext *xcp = &tcb->xcp;
|
||||
uint32_t cpsr;
|
||||
|
||||
/* Initialize the initial exception register context structure */
|
||||
|
||||
memset(xcp, 0, sizeof(struct xcptcontext));
|
||||
|
||||
/* Save the initial stack pointer */
|
||||
|
||||
xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr;
|
||||
|
||||
/* Save the task entry point */
|
||||
|
||||
xcp->regs[REG_PC] = (uint32_t)tcb->start;
|
||||
|
||||
/* If this task is running PIC, then set the PIC base register to the
|
||||
* address of the allocated D-Space region.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PIC
|
||||
if (tcb->dspace != NULL)
|
||||
{
|
||||
/* Set the PIC base register (probably R10) to the address of the
|
||||
* alloacated D-Space region.
|
||||
*/
|
||||
|
||||
xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set supervisor- or user-mode, depending on how NuttX is configured and
|
||||
* what kind of thread is being started. Disable FIQs in any event
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NUTTX_KERNEL
|
||||
if ((tcb->flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
|
||||
{
|
||||
/* It is a kernel thread.. set supervisor mode */
|
||||
|
||||
cpsr = PSR_MODE_SUPER | PSR_F_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is a normal task or a pthread. Set user mode */
|
||||
|
||||
cpsr = PSR_MODE_USER | PSR_F_BIT;
|
||||
}
|
||||
#else
|
||||
/* If the kernel build is not selected, then all threads run in
|
||||
* supervisor-mode.
|
||||
*/
|
||||
|
||||
cpsr = PSR_MODE_SUPER | PSR_F_BIT;
|
||||
#endif
|
||||
|
||||
/* Enable or disable interrupts, based on user configuration */
|
||||
|
||||
# ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
cpsr |= PSR_I_BIT;
|
||||
# endif
|
||||
|
||||
xcp->regs[REG_CPSR] = cpsr;
|
||||
}
|
||||
|
96
arch/arm/src/armv7-a/arm_pginitialize.c
Normal file
96
arch/arm/src/armv7-a/arm_pginitialize.c
Normal file
@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_pginitialize.c
|
||||
* Initialize the MMU for on-demand paging support.
|
||||
*
|
||||
* 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 <debug.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/page.h>
|
||||
|
||||
#include "up_internal.h"
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_pginitialize()
|
||||
*
|
||||
* Description:
|
||||
* Initialize the MMU for on-demand paging support..
|
||||
*
|
||||
* Input Parameters:
|
||||
* None.
|
||||
*
|
||||
* Returned Value:
|
||||
* None. This function will crash if any errors are detected during MMU
|
||||
* initialization
|
||||
*
|
||||
* Assumptions:
|
||||
* - Called early in the platform initialization sequence so that no special
|
||||
* concurrency protection is required.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_pginitialize(void)
|
||||
{
|
||||
/* None needed at present. This file is just retained in case the need
|
||||
* arises in the future. Nothing calls up_pginitialize() now. If needed,
|
||||
* if should be called early in up_boot.c to assure that all paging is
|
||||
* ready.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PAGING */
|
154
arch/arm/src/armv7-a/arm_prefetchabort.c
Normal file
154
arch/arm/src/armv7-a/arm_prefetchabort.c
Normal file
@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_prefetchabort.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 <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#ifdef CONFIG_PAGING
|
||||
# include <nuttx/page.h>
|
||||
#endif
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
/* Output debug info if stack dump is selected -- even if
|
||||
* debug is not selected.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
# undef lldbg
|
||||
# define lldbg lowsyslog
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_prefetchabort
|
||||
*
|
||||
* Description;
|
||||
* This is the prefetch abort exception handler. The ARM prefetch abort
|
||||
* exception occurs when a memory fault is detected during an an
|
||||
* instruction fetch.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void arm_prefetchabort(uint32_t *regs)
|
||||
{
|
||||
#ifdef CONFIG_PAGING
|
||||
uint32_t *savestate;
|
||||
|
||||
/* Save the saved processor context in current_regs where it can be accessed
|
||||
* for register dumps and possibly context switching.
|
||||
*/
|
||||
|
||||
savestate = (uint32_t*)current_regs;
|
||||
#endif
|
||||
current_regs = regs;
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
/* Get the (virtual) address of instruction that caused the prefetch abort.
|
||||
* When the exception occurred, this address was provided in the lr register
|
||||
* and this value was saved in the context save area as the PC at the
|
||||
* REG_R15 index.
|
||||
*
|
||||
* Check to see if this miss address is within the configured range of
|
||||
* virtual addresses.
|
||||
*/
|
||||
|
||||
pglldbg("VADDR: %08x VBASE: %08x VEND: %08x\n",
|
||||
regs[REG_PC], PG_PAGED_VBASE, PG_PAGED_VEND);
|
||||
|
||||
if (regs[REG_R15] >= PG_PAGED_VBASE && regs[REG_R15] < PG_PAGED_VEND)
|
||||
{
|
||||
/* Save the offending PC as the fault address in the TCB of the currently
|
||||
* executing task. This value is, of course, already known in regs[REG_R15],
|
||||
* but saving it in this location will allow common paging logic for both
|
||||
* prefetch and data aborts.
|
||||
*/
|
||||
|
||||
FAR struct tcb_s *tcb = (FAR struct tcb_s *)g_readytorun.head;
|
||||
tcb->xcp.far = regs[REG_R15];
|
||||
|
||||
/* Call pg_miss() to schedule the page fill. A consequences of this
|
||||
* call are:
|
||||
*
|
||||
* (1) The currently executing task will be blocked and saved on
|
||||
* on the g_waitingforfill task list.
|
||||
* (2) An interrupt-level context switch will occur so that when
|
||||
* this function returns, it will return to a different task,
|
||||
* most likely the page fill worker thread.
|
||||
* (3) The page fill worker task has been signalled and should
|
||||
* execute immediately when we return from this exception.
|
||||
*/
|
||||
|
||||
pg_miss();
|
||||
|
||||
/* Restore the previous value of current_regs. NULL would indicate that
|
||||
* we are no longer in an interrupt handler. It will be non-NULL if we
|
||||
* are returning from a nested interrupt.
|
||||
*/
|
||||
|
||||
current_regs = savestate;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
lldbg("Prefetch abort. PC: %08x\n", regs[REG_PC]);
|
||||
PANIC();
|
||||
}
|
||||
}
|
132
arch/arm/src/armv7-a/arm_releasepending.c
Normal file
132
arch/arm/src/armv7-a/arm_releasepending.c
Normal file
@ -0,0 +1,132 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_releasepending.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 <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_release_pending
|
||||
*
|
||||
* Description:
|
||||
* Release and ready-to-run tasks that have
|
||||
* collected in the pending task list. This can call a
|
||||
* context switch if a new task is placed at the head of
|
||||
* the ready to run list.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_release_pending(void)
|
||||
{
|
||||
struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
|
||||
slldbg("From TCB=%p\n", rtcb);
|
||||
|
||||
/* Merge the g_pendingtasks list into the g_readytorun task list */
|
||||
|
||||
/* sched_lock(); */
|
||||
if (sched_mergepending())
|
||||
{
|
||||
/* The currently active task has changed! We will need to
|
||||
* switch contexts. First check if we are operating in
|
||||
* interrupt context:
|
||||
*/
|
||||
|
||||
if (current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
slldbg("New Active Task TCB=%p\n", rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the exception context into the TCB of the task that
|
||||
* was currently active. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task
|
||||
* restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
slldbg("New Active Task TCB=%p\n", rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
}
|
187
arch/arm/src/armv7-a/arm_reprioritizertr.c
Normal file
187
arch/arm/src/armv7-a/arm_reprioritizertr.c
Normal file
@ -0,0 +1,187 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_reprioritizertr.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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_reprioritize_rtr
|
||||
*
|
||||
* Description:
|
||||
* Called when the priority of a running or
|
||||
* ready-to-run task changes and the reprioritization will
|
||||
* cause a context switch. Two cases:
|
||||
*
|
||||
* 1) The priority of the currently running task drops and the next
|
||||
* task in the ready to run list has priority.
|
||||
* 2) An idle, ready to run task's priority has been raised above the
|
||||
* the priority of the current, running task and it now has the
|
||||
* priority.
|
||||
*
|
||||
* Inputs:
|
||||
* tcb: The TCB of the task that has been reprioritized
|
||||
* priority: The new task priority
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority)
|
||||
{
|
||||
/* Verify that the caller is sane */
|
||||
|
||||
if (tcb->task_state < FIRST_READY_TO_RUN_STATE ||
|
||||
tcb->task_state > LAST_READY_TO_RUN_STATE
|
||||
#if SCHED_PRIORITY_MIN > 0
|
||||
|| priority < SCHED_PRIORITY_MIN
|
||||
#endif
|
||||
#if SCHED_PRIORITY_MAX < UINT8_MAX
|
||||
|| priority > SCHED_PRIORITY_MAX
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PANIC();
|
||||
}
|
||||
else
|
||||
{
|
||||
struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
bool switch_needed;
|
||||
|
||||
slldbg("TCB=%p PRI=%d\n", tcb, priority);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list.
|
||||
* sched_removereadytorun will return true if we just
|
||||
* remove the head of the ready to run list.
|
||||
*/
|
||||
|
||||
switch_needed = sched_removereadytorun(tcb);
|
||||
|
||||
/* Setup up the new task priority */
|
||||
|
||||
tcb->sched_priority = (uint8_t)priority;
|
||||
|
||||
/* Return the task to the specified blocked task list.
|
||||
* sched_addreadytorun will return true if the task was
|
||||
* added to the new list. We will need to perform a context
|
||||
* switch only if the EXCLUSIVE or of the two calls is non-zero
|
||||
* (i.e., one and only one the calls changes the head of the
|
||||
* ready-to-run list).
|
||||
*/
|
||||
|
||||
switch_needed ^= sched_addreadytorun(tcb);
|
||||
|
||||
/* Now, perform the context switch if one is needed */
|
||||
|
||||
if (switch_needed)
|
||||
{
|
||||
/* If we are going to do a context switch, then now is the right
|
||||
* time to add any pending tasks back into the ready-to-run list.
|
||||
* task list now
|
||||
*/
|
||||
|
||||
if (g_pendingtasks.head)
|
||||
{
|
||||
sched_mergepending();
|
||||
}
|
||||
|
||||
/* Are we in an interrupt handler? */
|
||||
|
||||
if (current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
slldbg("New Active Task TCB=%p\n", rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* Copy the exception context into the TCB at the (old) head of the
|
||||
* g_readytorun Task list. if up_saveusercontext returns a non-zero
|
||||
* value, then this is really the previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
slldbg("New Active Task TCB=%p\n", rtcb);
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
118
arch/arm/src/armv7-a/arm_saveusercontext.S
Normal file
118
arch/arm/src/armv7-a/arm_saveusercontext.S
Normal file
@ -0,0 +1,118 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_saveusercontext.S
|
||||
*
|
||||
* 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/irq.h>
|
||||
#include "up_internal.h"
|
||||
|
||||
.file "arm_saveusercontext.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_saveusercontext
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_saveusercontext
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
.globl up_saveusercontext
|
||||
.type up_saveusercontext, function
|
||||
up_saveusercontext:
|
||||
/* On entry, a1 (r0) holds address of struct xcptcontext.
|
||||
* Offset to the user region.
|
||||
*/
|
||||
|
||||
/* Make sure that the return value will be non-zero (the
|
||||
* value of the other volatile registers don't matter --
|
||||
* r1-r3, ip). This function is called throught the
|
||||
* normal C calling conventions and the values of these
|
||||
* registers cannot be assumed at the point of setjmp
|
||||
* return.
|
||||
*/
|
||||
|
||||
mov ip, #1
|
||||
str ip, [r0, #(4*REG_R0)]
|
||||
|
||||
/* Save the volatile registers (plus r12 which really
|
||||
* doesn't need to be saved)
|
||||
*/
|
||||
|
||||
add r1, r0, #(4*REG_R4)
|
||||
stmia r1, {r4-r14}
|
||||
|
||||
/* Save the current cpsr */
|
||||
|
||||
mrs r2, cpsr /* R3 = CPSR value */
|
||||
add r1, r0, #(4*REG_CPSR)
|
||||
str r2, [r1]
|
||||
|
||||
/* Finally save the return address as the PC so that we
|
||||
* return to the exit from this function.
|
||||
*/
|
||||
|
||||
add r1, r0, #(4*REG_PC)
|
||||
str lr, [r1]
|
||||
|
||||
/* Return 0 */
|
||||
|
||||
mov r0, #0 /* Return value == 0 */
|
||||
mov pc, lr /* Return */
|
||||
.size up_saveusercontext, . - up_saveusercontext
|
204
arch/arm/src/armv7-a/arm_schedulesigaction.c
Normal file
204
arch/arm/src/armv7-a/arm_schedulesigaction.c
Normal file
@ -0,0 +1,204 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_schedulesigaction.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 <stdint.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
#include "up_arch.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_schedule_sigaction
|
||||
*
|
||||
* Description:
|
||||
* This function is called by the OS when one or more
|
||||
* signal handling actions have been queued for execution.
|
||||
* The architecture specific code must configure things so
|
||||
* that the 'igdeliver' callback is executed on the thread
|
||||
* specified by 'tcb' as soon as possible.
|
||||
*
|
||||
* This function may be called from interrupt handling logic.
|
||||
*
|
||||
* This operation should not cause the task to be unblocked
|
||||
* nor should it cause any immediate execution of sigdeliver.
|
||||
* Typically, a few cases need to be considered:
|
||||
*
|
||||
* (1) This function may be called from an interrupt handler
|
||||
* During interrupt processing, all xcptcontext structures
|
||||
* should be valid for all tasks. That structure should
|
||||
* be modified to invoke sigdeliver() either on return
|
||||
* from (this) interrupt or on some subsequent context
|
||||
* switch to the recipient task.
|
||||
* (2) If not in an interrupt handler and the tcb is NOT
|
||||
* the currently executing task, then again just modify
|
||||
* the saved xcptcontext structure for the recipient
|
||||
* task so it will invoke sigdeliver when that task is
|
||||
* later resumed.
|
||||
* (3) If not in an interrupt handler and the tcb IS the
|
||||
* currently executing task -- just call the signal
|
||||
* handler now.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
|
||||
{
|
||||
/* Refuse to handle nested signal actions */
|
||||
|
||||
sdbg("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
|
||||
|
||||
if (!tcb->xcp.sigdeliver)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* Make sure that interrupts are disabled */
|
||||
|
||||
flags = irqsave();
|
||||
|
||||
/* First, handle some special cases when the signal is
|
||||
* being delivered to the currently executing task.
|
||||
*/
|
||||
|
||||
sdbg("rtcb=0x%p current_regs=0x%p\n", g_readytorun.head, current_regs);
|
||||
|
||||
if (tcb == (struct tcb_s*)g_readytorun.head)
|
||||
{
|
||||
/* CASE 1: We are not in an interrupt handler and
|
||||
* a task is signalling itself for some reason.
|
||||
*/
|
||||
|
||||
if (!current_regs)
|
||||
{
|
||||
/* In this case just deliver the signal now. */
|
||||
|
||||
sigdeliver(tcb);
|
||||
}
|
||||
|
||||
/* CASE 2: We are in an interrupt handler AND the
|
||||
* interrupted task is the same as the one that
|
||||
* must receive the signal, then we will have to modify
|
||||
* the return state as well as the state in the TCB.
|
||||
*
|
||||
* Hmmm... there looks like a latent bug here: The following
|
||||
* logic would fail in the strange case where we are in an
|
||||
* interrupt handler, the thread is signalling itself, but
|
||||
* a context switch to another task has occurred so that
|
||||
* current_regs does not refer to the thread at g_readytorun.head!
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Save the return lr and cpsr and one scratch register
|
||||
* These will be restored by the signal trampoline after
|
||||
* the signals have been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_pc = current_regs[REG_PC];
|
||||
tcb->xcp.saved_cpsr = current_regs[REG_CPSR];
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
|
||||
current_regs[REG_PC] = (uint32_t)up_sigdeliver;
|
||||
current_regs[REG_CPSR] = PSR_MODE_SUPER | PSR_I_BIT | PSR_F_BIT;
|
||||
|
||||
/* And make sure that the saved context in the TCB
|
||||
* is the same as the interrupt return context.
|
||||
*/
|
||||
|
||||
up_savestate(tcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, we are (1) signaling a task is not running
|
||||
* from an interrupt handler or (2) we are not in an
|
||||
* interrupt handler and the running task is signalling
|
||||
* some non-running task.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* Save the return lr and cpsr and one scratch register
|
||||
* These will be restored by the signal trampoline after
|
||||
* the signals have been delivered.
|
||||
*/
|
||||
|
||||
tcb->xcp.sigdeliver = sigdeliver;
|
||||
tcb->xcp.saved_pc = tcb->xcp.regs[REG_PC];
|
||||
tcb->xcp.saved_cpsr = tcb->xcp.regs[REG_CPSR];
|
||||
|
||||
/* Then set up to vector to the trampoline with interrupts
|
||||
* disabled
|
||||
*/
|
||||
|
||||
tcb->xcp.regs[REG_PC] = (uint32_t)up_sigdeliver;
|
||||
tcb->xcp.regs[REG_CPSR] = PSR_MODE_SUPER | PSR_I_BIT | PSR_F_BIT;
|
||||
}
|
||||
|
||||
irqrestore(flags);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_DISABLE_SIGNALS */
|
139
arch/arm/src/armv7-a/arm_sigdeliver.c
Normal file
139
arch/arm/src/armv7-a/arm_sigdeliver.c
Normal file
@ -0,0 +1,139 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_sigdeliver.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 <stdint.h>
|
||||
#include <sched.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
#include "up_arch.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_SIGNALS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_sigdeliver
|
||||
*
|
||||
* Description:
|
||||
* This is the a signal handling trampoline. When a signal action was
|
||||
* posted. The task context was mucked with and forced to branch to this
|
||||
* location with interrupts disabled.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_sigdeliver(void)
|
||||
{
|
||||
struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
uint32_t regs[XCPTCONTEXT_REGS];
|
||||
sig_deliver_t sigdeliver;
|
||||
|
||||
/* Save the errno. This must be preserved throughout the signal handling
|
||||
* so that the user code final gets the correct errno value (probably
|
||||
* EINTR).
|
||||
*/
|
||||
|
||||
int saved_errno = rtcb->pterrno;
|
||||
|
||||
up_ledon(LED_SIGNAL);
|
||||
|
||||
sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
|
||||
rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
|
||||
ASSERT(rtcb->xcp.sigdeliver != NULL);
|
||||
|
||||
/* Save the real return state on the stack. */
|
||||
|
||||
up_copystate(regs, rtcb->xcp.regs);
|
||||
regs[REG_PC] = rtcb->xcp.saved_pc;
|
||||
regs[REG_CPSR] = rtcb->xcp.saved_cpsr;
|
||||
|
||||
/* Get a local copy of the sigdeliver function pointer. we do this so that
|
||||
* we can nullify the sigdeliver function pointer in the TCB and accept
|
||||
* more signal deliveries while processing the current pending signals.
|
||||
*/
|
||||
|
||||
sigdeliver = rtcb->xcp.sigdeliver;
|
||||
rtcb->xcp.sigdeliver = NULL;
|
||||
|
||||
/* Then restore the task interrupt state */
|
||||
|
||||
irqrestore(regs[REG_CPSR]);
|
||||
|
||||
/* Deliver the signals */
|
||||
|
||||
sigdeliver(rtcb);
|
||||
|
||||
/* Output any debug messages BEFORE restoring errno (because they may
|
||||
* alter errno), then disable interrupts again and restore the original
|
||||
* errno that is needed by the user logic (it is probably EINTR).
|
||||
*/
|
||||
|
||||
sdbg("Resuming\n");
|
||||
(void)irqsave();
|
||||
rtcb->pterrno = saved_errno;
|
||||
|
||||
/* Then restore the correct state for this thread of execution. */
|
||||
|
||||
up_ledoff(LED_SIGNAL);
|
||||
up_fullcontextrestore(regs);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_DISABLE_SIGNALS */
|
||||
|
96
arch/arm/src/armv7-a/arm_syscall.c
Normal file
96
arch/arm/src/armv7-a/arm_syscall.c
Normal file
@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_syscall.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 <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Output debug info if stack dump is selected -- even if
|
||||
* debug is not selected.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
# undef lldbg
|
||||
# define lldbg lowsyslog
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* vectors
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_syscall
|
||||
*
|
||||
* Description:
|
||||
* SWI interrupts will vection here with insn=the SWI
|
||||
* instruction and xcp=the interrupt context
|
||||
*
|
||||
* The handler may get the SWI number be de-referencing
|
||||
* the return address saved in the xcp and decoding
|
||||
* the SWI instruction
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_syscall(uint32_t *regs)
|
||||
{
|
||||
lldbg("Syscall from 0x%x\n", regs[REG_PC]);
|
||||
current_regs = regs;
|
||||
PANIC();
|
||||
}
|
154
arch/arm/src/armv7-a/arm_unblocktask.c
Normal file
154
arch/arm/src/armv7-a/arm_unblocktask.c
Normal file
@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_unblocktask.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 <sched.h>
|
||||
#include <debug.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "clock_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_unblock_task
|
||||
*
|
||||
* Description:
|
||||
* A task is currently in an inactive task list
|
||||
* but has been prepped to execute. Move the TCB to the
|
||||
* ready-to-run list, restore its context, and start execution.
|
||||
*
|
||||
* Inputs:
|
||||
* tcb: Refers to the tcb to be unblocked. This tcb is
|
||||
* in one of the waiting tasks lists. It must be moved to
|
||||
* the ready-to-run list and, if it is the highest priority
|
||||
* ready to run taks, executed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_unblock_task(struct tcb_s *tcb)
|
||||
{
|
||||
struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
|
||||
/* Verify that the context switch can be performed */
|
||||
|
||||
ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) &&
|
||||
(tcb->task_state <= LAST_BLOCKED_STATE));
|
||||
|
||||
/* Remove the task from the blocked task list */
|
||||
|
||||
sched_removeblocked(tcb);
|
||||
|
||||
/* Reset its timeslice. This is only meaningful for round
|
||||
* robin tasks but it doesn't here to do it for everything
|
||||
*/
|
||||
|
||||
#if CONFIG_RR_INTERVAL > 0
|
||||
tcb->timeslice = CONFIG_RR_INTERVAL / MSEC_PER_TICK;
|
||||
#endif
|
||||
|
||||
/* Add the task in the correct location in the prioritized
|
||||
* g_readytorun task list
|
||||
*/
|
||||
|
||||
if (sched_addreadytorun(tcb))
|
||||
{
|
||||
/* The currently active task has changed! We need to do
|
||||
* a context switch to the new task.
|
||||
*
|
||||
* Are we in an interrupt handler?
|
||||
*/
|
||||
|
||||
if (current_regs)
|
||||
{
|
||||
/* Yes, then we have to do things differently.
|
||||
* Just copy the current_regs into the OLD rtcb.
|
||||
*/
|
||||
|
||||
up_savestate(rtcb->xcp.regs);
|
||||
|
||||
/* Restore the exception context of the rtcb at the (new) head
|
||||
* of the g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_restorestate(rtcb->xcp.regs);
|
||||
}
|
||||
|
||||
/* We are not in an interrupt handler. Copy the user C context
|
||||
* into the TCB of the task that was previously active. if
|
||||
* up_saveusercontext returns a non-zero value, then this is really the
|
||||
* previously running task restarting!
|
||||
*/
|
||||
|
||||
else if (!up_saveusercontext(rtcb->xcp.regs))
|
||||
{
|
||||
/* Restore the exception context of the new task that is ready to
|
||||
* run (probably tcb). This is the new rtcb at the head of the
|
||||
* g_readytorun task list.
|
||||
*/
|
||||
|
||||
rtcb = (struct tcb_s*)g_readytorun.head;
|
||||
|
||||
/* Then switch contexts */
|
||||
|
||||
up_fullcontextrestore(rtcb->xcp.regs);
|
||||
}
|
||||
}
|
||||
}
|
81
arch/arm/src/armv7-a/arm_undefinedinsn.c
Normal file
81
arch/arm/src/armv7-a/arm_undefinedinsn.c
Normal file
@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7/arm_undefinedinsn.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 <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "os_internal.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Output debug info if stack dump is selected -- even if
|
||||
* debug is not selected.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_STACKDUMP
|
||||
# undef lldbg
|
||||
# define lldbg lowsyslog
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_undefinedinsn
|
||||
****************************************************************************/
|
||||
|
||||
void arm_undefinedinsn(uint32_t *regs)
|
||||
{
|
||||
lldbg("Undefined instruction at 0x%x\n", regs[REG_PC]);
|
||||
current_regs = regs;
|
||||
PANIC();
|
||||
}
|
121
arch/arm/src/armv7-a/arm_va2pte.c
Normal file
121
arch/arm/src/armv7-a/arm_va2pte.c
Normal file
@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_va2pte.c
|
||||
* Utility to map a virtual address to a L2 page table entry.
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/page.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "pg_macros.h"
|
||||
#include "up_internal.h"
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_va2pte
|
||||
*
|
||||
* Description:
|
||||
* Convert a virtual address within the paged text region into a pointer to
|
||||
* the corresponding page table entry.
|
||||
*
|
||||
* Input Parameters:
|
||||
* vaddr - The virtual address within the paged text region.
|
||||
*
|
||||
* Returned Value:
|
||||
* A pointer to the corresponding page table entry.
|
||||
*
|
||||
* Assumptions:
|
||||
* - This function is called from the normal tasking context (but with
|
||||
* interrupts disabled). The implementation must take whatever actions
|
||||
* are necessary to assure that the operation is safe within this
|
||||
* context.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t *up_va2pte(uintptr_t vaddr)
|
||||
{
|
||||
uint32_t L1;
|
||||
uint32_t *L2;
|
||||
unsigned int ndx;
|
||||
|
||||
/* The virtual address is expected to lie in the paged text region */
|
||||
|
||||
DEBUGASSERT(vaddr >= PG_PAGED_VBASE && vaddr < PG_PAGED_VEND);
|
||||
|
||||
/* Get the L1 table entry associated with this virtual address */
|
||||
|
||||
L1 = *(uint32_t*)PG_POOL_VA2L1VADDR(vaddr);
|
||||
|
||||
/* Get the address of the L2 page table from the L1 entry */
|
||||
|
||||
L2 = (uint32_t*)PG_POOL_L12VPTABLE(L1);
|
||||
|
||||
/* Get the index into the L2 page table. Each L1 entry maps
|
||||
* 256 x 4Kb or 1024 x 1Kb pages.
|
||||
*/
|
||||
|
||||
ndx = (vaddr & 0x000fffff) >> PAGESHIFT;
|
||||
|
||||
/* Return true if this virtual address is mapped. */
|
||||
|
||||
return &L2[ndx];
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PAGING */
|
87
arch/arm/src/armv7-a/arm_vectoraddrexcptn.S
Normal file
87
arch/arm/src/armv7-a/arm_vectoraddrexcptn.S
Normal file
@ -0,0 +1,87 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_vectoraddrexceptn.S
|
||||
*
|
||||
* 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 <nuttx/irq.h>
|
||||
#include "up_arch.h"
|
||||
|
||||
.file "arm_vectoraddrexcptn.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Preprocessor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_vectoraddrexcption
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Macros
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_vectoraddrexcption
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen. This exception handler is in a separate file from
|
||||
* other vector handlers because some processors (e.g., Cortex-A5) do not
|
||||
* support the the Address Exception vector.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_vectoraddrexcptn
|
||||
.type arm_vectoraddrexcptn, %function
|
||||
arm_vectoraddrexcptn:
|
||||
b arm_vectoraddrexcptn
|
||||
.size arm_vectoraddrexcptn, . - arm_vectoraddrexcptn
|
||||
.end
|
@ -78,71 +78,71 @@ g_aborttmp:
|
||||
.text
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_vectorirq
|
||||
* Name: arm_vectorirq
|
||||
*
|
||||
* Description:
|
||||
* Interrupt excetpion. Entered in IRQ mode with spsr = SVC CPSR, lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorirq
|
||||
.type up_vectorirq, %function
|
||||
up_vectorirq:
|
||||
.globl arm_vectorirq
|
||||
.type arm_vectorirq, %function
|
||||
arm_vectorirq:
|
||||
/* On entry, we are in IRQ mode. We are free to use
|
||||
* the IRQ mode r13 and r14.
|
||||
*/
|
||||
|
||||
ldr r13, .Lirqtmp
|
||||
sub lr, lr, #4
|
||||
str lr, [r13] @ save lr_IRQ
|
||||
str lr, [r13] /* Save lr_IRQ */
|
||||
mrs lr, spsr
|
||||
str lr, [r13, #4] @ save spsr_IRQ
|
||||
str lr, [r13, #4] /* Save spsr_IRQ */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
ldr r0, .Lirqtmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
ldr r0, .Lirqtmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
/* Then call the IRQ handler with interrupts disabled. */
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
ldr sp, .Lirqstackbase /* SP = interrupt stack base */
|
||||
str r0, [sp] /* Save the user stack pointer */
|
||||
bl up_decodeirq /* Call the handler */
|
||||
ldr sp, [sp] /* Restore the user stack pointer */
|
||||
ldr sp, .Lirqstackbase /* SP = interrupt stack base */
|
||||
str r0, [sp] /* Save the user stack pointer */
|
||||
bl up_decodeirq /* Call the handler */
|
||||
ldr sp, [sp] /* Restore the user stack pointer */
|
||||
#else
|
||||
bl up_decodeirq /* Call the handler */
|
||||
bl up_decodeirq /* Call the handler */
|
||||
#endif
|
||||
|
||||
/* Restore the CPSR, SVC modr registers and return */
|
||||
.Lnoirqset:
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
.Lirqtmp:
|
||||
.word g_irqtmp
|
||||
@ -150,58 +150,58 @@ up_vectorirq:
|
||||
.Lirqstackbase:
|
||||
.word up_stackbase
|
||||
#endif
|
||||
.size up_vectorirq, . - up_vectorirq
|
||||
.size arm_vectorirq, . - arm_vectorirq
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
* Function: up_vectorswi
|
||||
* Function: arm_vectorswi
|
||||
*
|
||||
* Description:
|
||||
* SWI interrupt. We enter the SWI in SVC mode.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorswi
|
||||
.type up_vectorswi, %function
|
||||
up_vectorswi:
|
||||
.globl arm_vectorswi
|
||||
.type arm_vectorswi, %function
|
||||
arm_vectorswi:
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp), r14(lr), r15(pc)
|
||||
* and CPSR in r1-r4 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14 /* R14 is altered on return from SWI */
|
||||
mov r3, r14 /* Save r14 as the PC as well */
|
||||
mrs r4, spsr /* Get the saved CPSR */
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14 /* R14 is altered on return from SWI */
|
||||
mov r3, r14 /* Save r14 as the PC as well */
|
||||
mrs r4, spsr /* Get the saved CPSR */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
/* Then call the SWI handler with interrupts disabled.
|
||||
* void up_syscall(struct xcptcontext *xcp)
|
||||
*/
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl up_syscall /* Call the handler */
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl up_syscall /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC modr registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
.size up_vectorswi, . - up_vectorswi
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
.size arm_vectorswi, . - arm_vectorswi
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_vectordata
|
||||
* Name: arm_vectordata
|
||||
*
|
||||
* Description:
|
||||
* This is the data abort exception dispatcher. The ARM data abort exception occurs
|
||||
@ -210,72 +210,72 @@ up_vectorswi:
|
||||
* is entered in ABORT mode with spsr = SVC CPSR, lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectordata
|
||||
.type up_vectordata, %function
|
||||
up_vectordata:
|
||||
|
||||
.globl arm_vectordata
|
||||
.type arm_vectordata, %function
|
||||
arm_vectordata:
|
||||
/* On entry we are free to use the ABORT mode registers
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
ldr r13, .Ldaborttmp /* Points to temp storage */
|
||||
sub lr, lr, #8 /* Fixup return */
|
||||
str lr, [r13] /* Save in temp storage */
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
ldr r13, .Ldaborttmp /* Points to temp storage */
|
||||
sub lr, lr, #8 /* Fixup return */
|
||||
str lr, [r13] /* Save in temp storage */
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
ldr r0, .Ldaborttmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
ldr r0, .Ldaborttmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
/* Then call the data abort handler with interrupts disabled.
|
||||
* void up_dataabort(struct xcptcontext *xcp)
|
||||
* void arm_dataabort(struct xcptcontext *xcp)
|
||||
*/
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
#ifdef CONFIG_PAGING
|
||||
mrc p15, 0, r2, c5, c0, 0 /* Get r2=FSR */
|
||||
mrc p15, 0, r1, c6, c0, 0 /* Get R1=FAR */
|
||||
mrc p15, 0, r2, c5, c0, 0 /* Get r2=FSR */
|
||||
mrc p15, 0, r1, c6, c0, 0 /* Get R1=FAR */
|
||||
#endif
|
||||
bl up_dataabort /* Call the handler */
|
||||
bl arm_dataabort /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC modr registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
.Ldaborttmp:
|
||||
.word g_aborttmp
|
||||
.size up_vectordata, . - up_vectordata
|
||||
.size arm_vectordata, . - arm_vectordata
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_vectorprefetch
|
||||
* Name: arm_vectorprefetch
|
||||
*
|
||||
* Description:
|
||||
* This is the prefetch abort exception dispatcher. The ARM prefetch abort exception
|
||||
@ -284,146 +284,146 @@ up_vectordata:
|
||||
* handler. This function is entered in ABT mode with spsr = SVC CPSR, lr = SVC PC.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorprefetch
|
||||
.type up_vectorprefetch, %function
|
||||
up_vectorprefetch:
|
||||
|
||||
.globl arm_vectorprefetch
|
||||
.type arm_vectorprefetch, %function
|
||||
arm_vectorprefetch:
|
||||
/* On entry we are free to use the ABORT mode registers
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
ldr r13, .Lpaborttmp /* Points to temp storage */
|
||||
sub lr, lr, #4 /* Fixup return */
|
||||
str lr, [r13] /* Save in temp storage */
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
ldr r13, .Lpaborttmp /* Points to temp storage */
|
||||
sub lr, lr, #4 /* Fixup return */
|
||||
str lr, [r13] /* Save in temp storage */
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
ldr r0, .Lpaborttmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
ldr r0, .Lpaborttmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
/* Then call the prefetch abort handler with interrupts disabled.
|
||||
* void up_prefetchabort(struct xcptcontext *xcp)
|
||||
* void arm_prefetchabort(struct xcptcontext *xcp)
|
||||
*/
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl up_prefetchabort /* Call the handler */
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_prefetchabort /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC modr registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
.Lpaborttmp:
|
||||
.word g_aborttmp
|
||||
.size up_vectorprefetch, . - up_vectorprefetch
|
||||
.size arm_vectorprefetch, . - arm_vectorprefetch
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_vectorundefinsn
|
||||
* Name: arm_vectorundefinsn
|
||||
*
|
||||
* Description:
|
||||
* Undefined instruction entry exception. Entered in UND mode, spsr = SVC CPSR,
|
||||
* lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorundefinsn
|
||||
.type up_vectorundefinsn, %function
|
||||
up_vectorundefinsn:
|
||||
|
||||
.globl arm_vectorundefinsn
|
||||
.type arm_vectorundefinsn, %function
|
||||
arm_vectorundefinsn:
|
||||
/* On entry we are free to use the UND mode registers
|
||||
* r13 and r14
|
||||
*/
|
||||
|
||||
ldr r13, .Lundeftmp /* Points to temp storage */
|
||||
str lr, [r13] /* Save in temp storage */
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
ldr r13, .Lundeftmp /* Points to temp storage */
|
||||
str lr, [r13] /* Save in temp storage */
|
||||
mrs lr, spsr /* Get SPSR */
|
||||
str lr, [r13, #4] /* Save in temp storage */
|
||||
|
||||
/* Then switch back to SVC mode */
|
||||
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
bic lr, lr, #PSR_MODE_MASK /* Keep F and T bits */
|
||||
orr lr, lr, #(PSR_MODE_SUPER | PSR_I_BIT)
|
||||
msr cpsr_c, lr /* Switch to SVC mode */
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
* and store r0-r12 into the frame.
|
||||
*/
|
||||
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
sub sp, sp, #XCPTCONTEXT_SIZE
|
||||
stmia sp, {r0-r12} /* Save the SVC mode regs */
|
||||
|
||||
/* Get the correct values of r13(sp) and r14(lr) in r1 and r2 */
|
||||
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
add r1, sp, #XCPTCONTEXT_SIZE
|
||||
mov r2, r14
|
||||
|
||||
/* Get the values for r15(pc) and CPSR in r3 and r4 */
|
||||
|
||||
ldr r0, .Lundeftmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
ldr r0, .Lundeftmp /* Points to temp storage */
|
||||
ldmia r0, {r3, r4} /* Recover r1=lr_IRQ, r2=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
|
||||
/* Then call the undef insn handler with interrupts disabled.
|
||||
* void up_undefinedinsn(struct xcptcontext *xcp)
|
||||
* void arm_undefinedinsn(struct xcptcontext *xcp)
|
||||
*/
|
||||
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl up_undefinedinsn /* Call the handler */
|
||||
mov fp, #0 /* Init frame pointer */
|
||||
mov r0, sp /* Get r0=xcp */
|
||||
bl arm_undefinedinsn /* Call the handler */
|
||||
|
||||
/* Restore the CPSR, SVC modr registers and return */
|
||||
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
ldr r0, [sp, #(4*REG_CPSR)] /* Setup the SVC mode SPSR */
|
||||
msr spsr_cxsf, r0
|
||||
ldmia sp, {r0-r15}^ /* Return */
|
||||
|
||||
.Lundeftmp:
|
||||
.word g_undeftmp
|
||||
.size up_vectorundefinsn, . - up_vectorundefinsn
|
||||
.size arm_vectorundefinsn, . - arm_vectorundefinsn
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_vectorfiq
|
||||
* Name: arm_vectorfiq
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
.globl up_vectorfiq
|
||||
.type up_vectorfiq, %function
|
||||
up_vectorfiq:
|
||||
.globl arm_vectorfiq
|
||||
.type arm_vectorfiq, %function
|
||||
arm_vectorfiq:
|
||||
subs pc, lr, #4
|
||||
.size up_vectorfiq, . - up_vectorfiq
|
||||
.size arm_vectorfiq, . - arm_vectorfiq
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_interruptstack/g_userstack
|
||||
|
@ -63,40 +63,40 @@
|
||||
/* These will be relocated to VECTOR_BASE. */
|
||||
|
||||
_vector_start:
|
||||
ldr pc, .Lresethandler /* 0x00: Reset */
|
||||
ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */
|
||||
ldr pc, .Lswihandler /* 0x08: Software interrupt */
|
||||
ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */
|
||||
ldr pc, .Ldataaborthandler /* 0x10: Data abort */
|
||||
ldr pc, .Laddrexcptnhandler /* 0x14: Address exception (reserved) */
|
||||
ldr pc, .Lirqhandler /* 0x18: IRQ */
|
||||
ldr pc, .Lfiqhandler /* 0x1c: FIQ */
|
||||
ldr pc, .Lresethandler /* 0x00: Reset */
|
||||
ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */
|
||||
ldr pc, .Lswihandler /* 0x08: Software interrupt */
|
||||
ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */
|
||||
ldr pc, .Ldataaborthandler /* 0x10: Data abort */
|
||||
ldr pc, .Laddrexcptnhandler /* 0x14: Address exception (reserved) */
|
||||
ldr pc, .Lirqhandler /* 0x18: IRQ */
|
||||
ldr pc, .Lfiqhandler /* 0x1c: FIQ */
|
||||
|
||||
.globl __start
|
||||
.globl up_vectorundefinsn
|
||||
.globl up_vectorswi
|
||||
.globl up_vectorprefetch
|
||||
.globl up_vectordata
|
||||
.globl up_vectoraddrexcptn
|
||||
.globl up_vectorirq
|
||||
.globl up_vectorfiq
|
||||
.globl arm_vectorundefinsn
|
||||
.globl arm_vectorswi
|
||||
.globl arm_vectorprefetch
|
||||
.globl arm_vectordata
|
||||
.globl arm_vectoraddrexcptn
|
||||
.globl arm_vectorirq
|
||||
.globl arm_vectorfiq
|
||||
|
||||
.Lresethandler:
|
||||
.long __start
|
||||
.long __start
|
||||
.Lundefinedhandler:
|
||||
.long up_vectorundefinsn
|
||||
.long arm_vectorundefinsn
|
||||
.Lswihandler:
|
||||
.long up_vectorswi
|
||||
.long arm_vectorswi
|
||||
.Lprefetchaborthandler:
|
||||
.long up_vectorprefetch
|
||||
.long arm_vectorprefetch
|
||||
.Ldataaborthandler:
|
||||
.long up_vectordata
|
||||
.long arm_vectordata
|
||||
.Laddrexcptnhandler:
|
||||
.long up_vectoraddrexcptn
|
||||
.long arm_vectoraddrexcptn
|
||||
.Lirqhandler:
|
||||
.long up_vectorirq
|
||||
.long arm_vectorirq
|
||||
.Lfiqhandler:
|
||||
.long up_vectorfiq
|
||||
.long arm_vectorfiq
|
||||
|
||||
.globl _vector_end
|
||||
_vector_end:
|
||||
|
140
arch/arm/src/armv7-a/arm_vfork.S
Normal file
140
arch/arm/src/armv7-a/arm_vfork.S
Normal file
@ -0,0 +1,140 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-a/arm_vfork.S
|
||||
*
|
||||
* 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 "up_vfork.h"
|
||||
|
||||
.file "vfork.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_vfork
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vfork
|
||||
*
|
||||
* Description:
|
||||
* The vfork() function has the same effect as fork(), except that the
|
||||
* behavior is undefined if the process created by vfork() either modifies
|
||||
* any data other than a variable of type pid_t used to store the return
|
||||
* value from vfork(), or returns from the function in which vfork() was
|
||||
* called, or calls any other function before successfully calling _exit()
|
||||
* or one of the exec family of functions.
|
||||
*
|
||||
* This thin layer implements vfork by simply calling up_vfork() with the
|
||||
* vfork() context as an argument. The overall sequence is:
|
||||
*
|
||||
* 1) User code calls vfork(). vfork() collects context information and
|
||||
* transfers control up up_vfork().
|
||||
* 2) up_vfork()and calls task_vforksetup().
|
||||
* 3) task_vforksetup() allocates and configures the child task's TCB.
|
||||
* This consists of:
|
||||
* - Allocation of the child task's TCB.
|
||||
* - Initialization of file descriptors and streams
|
||||
* - Configuration of environment variables
|
||||
* - Setup the intput parameters for the task.
|
||||
* - Initialization of the TCB (including call to up_initial_state()
|
||||
* 4) up_vfork() provides any additional operating context. up_vfork must:
|
||||
* - Allocate and initialize the stack
|
||||
* - Initialize special values in any CPU registers that were not
|
||||
* already configured by up_initial_state()
|
||||
* 5) up_vfork() then calls task_vforkstart()
|
||||
* 6) task_vforkstart() then executes the child thread.
|
||||
*
|
||||
* Input Paremeters:
|
||||
* None
|
||||
*
|
||||
* Return:
|
||||
* Upon successful completion, vfork() returns 0 to the child process and
|
||||
* returns the process ID of the child process to the parent process.
|
||||
* Otherwise, -1 is returned to the parent, no child process is created,
|
||||
* and errno is set to indicate the error.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl vfork
|
||||
.type vfork, function
|
||||
vfork:
|
||||
/* Create a stack frame */
|
||||
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
|
||||
|
||||
/* CPU registers */
|
||||
/* Save the volatile registers */
|
||||
|
||||
str r4, [sp, #VFORK_R4_OFFSET]
|
||||
str r5, [sp, #VFORK_R5_OFFSET]
|
||||
str r6, [sp, #VFORK_R6_OFFSET]
|
||||
str r7, [sp, #VFORK_R7_OFFSET]
|
||||
str r8, [sp, #VFORK_R8_OFFSET]
|
||||
str r9, [sp, #VFORK_R9_OFFSET]
|
||||
str r10, [sp, #VFORK_R10_OFFSET]
|
||||
|
||||
/* Save the frame pointer, stack pointer, and return address */
|
||||
|
||||
str fp, [sp, #VFORK_FP_OFFSET]
|
||||
str r0, [sp, #VFORK_SP_OFFSET]
|
||||
str lr, [sp, #VFORK_LR_OFFSET]
|
||||
|
||||
/* Floating point registers (not yet) */
|
||||
|
||||
/* Then, call up_vfork(), passing it a pointer to the stack structure */
|
||||
|
||||
mov r0, sp
|
||||
bl up_vfork
|
||||
|
||||
/* Release the stack data and return the value returned by up_vfork */
|
||||
|
||||
ldr lr, [sp, #VFORK_LR_OFFSET]
|
||||
add sp, sp, #VFORK_SIZEOF
|
||||
mov pc, lr
|
||||
.size vfork, .-vfork
|
||||
.end
|
@ -194,7 +194,7 @@
|
||||
#define CP15_IDATAR(r) _CP15(3, r, c15, c4, 1) /* Instruction Cache Data Read Operation Register */
|
||||
#define CP15_TLBR(r) _CP15(3, r, c15, c4, 2) /* TLB Data Read Operation Register */
|
||||
#define CP15_CBADDR(r) _CP15(4, r, c15, c0, 0) /* Configuration Base Address Register */
|
||||
#define CP15_TLBHITMAP(r) _CP15(5, r, c15, c0, 0) /* TLB access and attributes
|
||||
#define CP15_TLBHITMAP(r) _CP15(5, r, c15, c0, 0) /* TLB access and attributes */
|
||||
|
||||
/* System control register descriptions.
|
||||
*
|
||||
|
@ -60,8 +60,8 @@
|
||||
* implement this feature, so this register always RAZ.
|
||||
*/
|
||||
|
||||
/* System Control Register (SCTRL). see sctrl.h */
|
||||
/* Non-secure Access Control Register (NSACR). See sctrl.h */
|
||||
/* System Control Register (SCTLR). see cstlr.h */
|
||||
/* Non-secure Access Control Register (NSACR). See cstlr.h */
|
||||
|
||||
/* Translation Table Base Register 0 (TTBR0)*/
|
||||
|
||||
@ -205,7 +205,7 @@
|
||||
#define TLBHR_16MB (1 << 3) /* Bit 3: 16MB supersections are present in the TLB */
|
||||
/* Bits 4-31: Reserved */
|
||||
|
||||
/* Context ID Register (CONTEXTIDR). See sctrl.h */
|
||||
/* Context ID Register (CONTEXTIDR). See cstlr.h */
|
||||
|
||||
/************************************************************************************
|
||||
* Assemby Macros
|
||||
|
@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/armv7-a/sctrl.h
|
||||
* arch/arm/src/armv7-a/sctlr.h
|
||||
* CP15 System Control Registers
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
@ -41,8 +41,8 @@
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_ARMV7_A_CPSR_H
|
||||
#define __ARCH_ARM_SRC_ARMV7_A_CPSR_H
|
||||
#ifndef __ARCH_ARM_SRC_ARMV7_A_SCTLR_H
|
||||
#define __ARCH_ARM_SRC_ARMV7_A_SCTLR_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
@ -124,14 +124,14 @@
|
||||
#define SCTLR_C (1 << 2) /* Bit 2: Determines if data can be cached */
|
||||
/* Bits 3-9: Reserved */
|
||||
#define SCTLR_SW (1 << 10) /* Bit 10: SWP/SWPB Enable bit */
|
||||
#define SCTLR_A (1 << 11) /* Bit 11: Program flow prediction control (1) */
|
||||
#define SCTLR_Z (1 << 11) /* Bit 11: Program flow prediction control (1) */
|
||||
#define SCTLR_I (1 << 12) /* Bit 12: Determines if instructions can be cached */
|
||||
#define SCTLR_V (1 << 13) /* Bit 13: Vectors bit */
|
||||
#define SCTLR_RR (1 << 14) /* Bit 14: Cache replacement strategy (2) */
|
||||
/* Bits 15-16: Reserved */
|
||||
#define SCTLR_HA (1 << 17) /* Bit 17: Hardware management access disabled (2) */
|
||||
/* Bits 18-24: Reserved */
|
||||
#define SCTLR_EE (1 << 25) /* Bit 15: Determines the value the CPSR.E */
|
||||
#define SCTLR_EE (1 << 25) /* Bit 25: Determines the value the CPSR.E */
|
||||
/* Bits 26-27: Reserved */
|
||||
#define SCTLR_TRE (1 << 28) /* Bit 28: TEX remap */
|
||||
#define SCTLR_AFE (1 << 29) /* Bit 29: Access Flag Enable bit */
|
||||
@ -237,14 +237,14 @@
|
||||
mrc p15, 0, \id, c0, c0, 0
|
||||
.endm
|
||||
|
||||
/* Read/write the system control register (SCTRL) */
|
||||
/* Read/write the system control register (SCTLR) */
|
||||
|
||||
.macro cp15_rdsctrl, sctrl
|
||||
mrc p15, 0, \sctrl, c1, c0, 0
|
||||
.macro cp15_rdsctlr, sctlr
|
||||
mrc p15, 0, \sctlr, c1, c0, 0
|
||||
.endm
|
||||
|
||||
.macro cp15_wrsctrl, sctrl
|
||||
mcr p15, 0, \sctrl, c1, c0, 0
|
||||
.macro cp15_wrsctlr, sctlr
|
||||
mcr p15, 0, \sctlr, c1, c0, 0
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
@ -278,23 +278,23 @@ static inline unsigned int cp15_rdid(void)
|
||||
return id;
|
||||
}
|
||||
|
||||
/* Read/write the system control register (SCTRL) */
|
||||
/* Read/write the system control register (SCTLR) */
|
||||
|
||||
static inline unsigned int cp15_rdsctrl(void)
|
||||
static inline unsigned int cp15_rdsctlr(void)
|
||||
{
|
||||
unsigned int sctrl;
|
||||
unsigned int sctlr;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"\tmrc p15, 0, %0, c1, c0, 0"
|
||||
: "=r" (sctrl)
|
||||
: "=r" (sctlr)
|
||||
:
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return sctrl;
|
||||
return sctlr;
|
||||
}
|
||||
|
||||
static inline void cp15_wrsctrl(unsigned int sctrl)
|
||||
static inline void cp15_wrsctlr(unsigned int sctlr)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
@ -308,7 +308,7 @@ static inline void cp15_wrsctrl(unsigned int sctrl)
|
||||
"\tnop\n"
|
||||
"\tnop\n"
|
||||
:
|
||||
: "r" (sctrl)
|
||||
: "r" (sctlr)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
@ -337,4 +337,4 @@ extern "C" {
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_ARMV7_A_CPSR_H */
|
||||
#endif /* __ARCH_ARM_SRC_ARMV7_A_SCTLR_H */
|
Loading…
Reference in New Issue
Block a user