From ecc3d23672afce147e4e629e3e7cc2562090f02e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 19 Jul 2013 11:43:04 -0600 Subject: More ARMv7-A files that are just copies of the ARMv4/5 files for now --- nuttx/arch/arm/src/arm/up_copystate.c | 2 +- nuttx/arch/arm/src/arm/up_prefetchabort.c | 2 +- nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S | 2 +- nuttx/arch/arm/src/armv7-a/arm_allocpage.c | 243 +++++++++++++++ nuttx/arch/arm/src/armv7-a/arm_assert.c | 304 ++++++++++++++++++ nuttx/arch/arm/src/armv7-a/arm_blocktask.c | 162 ++++++++++ nuttx/arch/arm/src/armv7-a/arm_checkmapping.c | 123 ++++++++ nuttx/arch/arm/src/armv7-a/arm_copystate.c | 82 +++++ nuttx/arch/arm/src/armv7-a/arm_dataabort.c | 201 ++++++++++++ nuttx/arch/arm/src/armv7-a/arm_doirq.c | 116 +++++++ nuttx/arch/arm/src/armv7-a/arm_elf.c | 257 ++++++++++++++++ .../arch/arm/src/armv7-a/arm_fullcontextrestore.S | 117 +++++++ nuttx/arch/arm/src/armv7-a/arm_head.S | 111 ++++--- nuttx/arch/arm/src/armv7-a/arm_initialstate.c | 146 +++++++++ nuttx/arch/arm/src/armv7-a/arm_pginitialize.c | 96 ++++++ nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c | 154 ++++++++++ nuttx/arch/arm/src/armv7-a/arm_releasepending.c | 132 ++++++++ nuttx/arch/arm/src/armv7-a/arm_reprioritizertr.c | 187 ++++++++++++ nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S | 118 +++++++ nuttx/arch/arm/src/armv7-a/arm_schedulesigaction.c | 204 +++++++++++++ nuttx/arch/arm/src/armv7-a/arm_sigdeliver.c | 139 +++++++++ nuttx/arch/arm/src/armv7-a/arm_syscall.c | 96 ++++++ nuttx/arch/arm/src/armv7-a/arm_unblocktask.c | 154 ++++++++++ nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c | 81 +++++ nuttx/arch/arm/src/armv7-a/arm_va2pte.c | 121 ++++++++ nuttx/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S | 87 ++++++ nuttx/arch/arm/src/armv7-a/arm_vectors.S | 270 ++++++++-------- nuttx/arch/arm/src/armv7-a/arm_vectortab.S | 46 +-- nuttx/arch/arm/src/armv7-a/arm_vfork.S | 140 +++++++++ nuttx/arch/arm/src/armv7-a/cp15.h | 2 +- nuttx/arch/arm/src/armv7-a/mmu.h | 6 +- nuttx/arch/arm/src/armv7-a/sctlr.h | 340 +++++++++++++++++++++ nuttx/arch/arm/src/armv7-a/sctrl.h | 340 --------------------- 33 files changed, 4035 insertions(+), 546 deletions(-) create mode 100644 nuttx/arch/arm/src/armv7-a/arm_allocpage.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_assert.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_blocktask.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_checkmapping.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_copystate.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_dataabort.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_doirq.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_elf.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_fullcontextrestore.S create mode 100644 nuttx/arch/arm/src/armv7-a/arm_initialstate.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_pginitialize.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_releasepending.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_reprioritizertr.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S create mode 100644 nuttx/arch/arm/src/armv7-a/arm_schedulesigaction.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_sigdeliver.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_syscall.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_unblocktask.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_va2pte.c create mode 100644 nuttx/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S create mode 100644 nuttx/arch/arm/src/armv7-a/arm_vfork.S create mode 100644 nuttx/arch/arm/src/armv7-a/sctlr.h delete mode 100644 nuttx/arch/arm/src/armv7-a/sctrl.h (limited to 'nuttx/arch/arm/src') diff --git a/nuttx/arch/arm/src/arm/up_copystate.c b/nuttx/arch/arm/src/arm/up_copystate.c index c76ee8e70..fdc7246d9 100644 --- a/nuttx/arch/arm/src/arm/up_copystate.c +++ b/nuttx/arch/arm/src/arm/up_copystate.c @@ -61,7 +61,7 @@ ****************************************************************************/ /**************************************************************************** - * Name: up_undefinedinsn + * Name: up_copystate ****************************************************************************/ /* A little faster than most memcpy's */ diff --git a/nuttx/arch/arm/src/arm/up_prefetchabort.c b/nuttx/arch/arm/src/arm/up_prefetchabort.c index 78ca496ab..c75a92a49 100644 --- a/nuttx/arch/arm/src/arm/up_prefetchabort.c +++ b/nuttx/arch/arm/src/arm/up_prefetchabort.c @@ -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 diff --git a/nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S b/nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S index ba5787cb9..d53129c46 100644 --- a/nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S +++ b/nuttx/arch/arm/src/arm/up_vectoraddrexcptn.S @@ -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 diff --git a/nuttx/arch/arm/src/armv7-a/arm_allocpage.c b/nuttx/arch/arm/src/armv7-a/arm_allocpage.c new file mode 100644 index 000000000..3856dc531 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_allocpage.c @@ -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 + * + * 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 + +#include +#include +#include +#include + +#include + +#ifdef CONFIG_PAGING + +#include + +#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 */ diff --git a/nuttx/arch/arm/src/armv7-a/arm_assert.c b/nuttx/arch/arm/src/armv7-a/arm_assert.c new file mode 100644 index 000000000..a66d33c2e --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_assert.c @@ -0,0 +1,304 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_assert.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include + +#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); +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_blocktask.c b/nuttx/arch/arm/src/armv7-a/arm_blocktask.c new file mode 100644 index 000000000..eac95984b --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_blocktask.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/up_blocktask.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include + +#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); + } + } +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_checkmapping.c b/nuttx/arch/arm/src/armv7-a/arm_checkmapping.c new file mode 100644 index 000000000..50f05cf7e --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_checkmapping.c @@ -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 + * + * 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 + +#include +#include + +#include +#include + +#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 */ diff --git a/nuttx/arch/arm/src/armv7-a/arm_copystate.c b/nuttx/arch/arm/src/armv7-a/arm_copystate.c new file mode 100644 index 000000000..42c46628d --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_copystate.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_copystate.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include + +#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++; + } +} + diff --git a/nuttx/arch/arm/src/armv7-a/arm_dataabort.c b/nuttx/arch/arm/src/armv7-a/arm_dataabort.c new file mode 100644 index 000000000..dc39ac2c3 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_dataabort.c @@ -0,0 +1,201 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_dataabort.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include + +#include "os_internal.h" +#include "up_internal.h" + +#ifdef CONFIG_PAGING +# include +# 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 */ diff --git a/nuttx/arch/arm/src/armv7-a/arm_doirq.c b/nuttx/arch/arm/src/armv7-a/arm_doirq.c new file mode 100644 index 000000000..eec228b91 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_doirq.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_doirq.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#include + +#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); +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_elf.c b/nuttx/arch/arm/src/armv7-a/arm_elf.c new file mode 100644 index 000000000..3a9b86a8a --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_elf.c @@ -0,0 +1,257 @@ +/**************************************************************************** + * arch/arm/src/armv-7a/arm_elf.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include + +#include +#include +#include + +/**************************************************************************** + * 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; +} + diff --git a/nuttx/arch/arm/src/armv7-a/arm_fullcontextrestore.S b/nuttx/arch/arm/src/armv7-a/arm_fullcontextrestore.S new file mode 100644 index 000000000..6b0125612 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_fullcontextrestore.S @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_fullcontextrestore.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#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 diff --git a/nuttx/arch/arm/src/armv7-a/arm_head.S b/nuttx/arch/arm/src/armv7-a/arm_head.S index f0d4b0da1..df6981085 100644 --- a/nuttx/arch/arm/src/armv7-a/arm_head.S +++ b/nuttx/arch/arm/src/armv7-a/arm_head.S @@ -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 */ + + /* Configure the system control register (see sctrl.h) */ + + mrc CP15_SCTLR(r0) /* Get control register */ - /* Clear bits (see arm.h) + /* 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 */ + + mcr CP15_SCTLR(r0) /* Write control reg */ + + /* Read the Main ID register. This will be available in R1 after + * MMU trampoline (not currently used) + */ - mrc p15, 0, r1, c0, c0, 0 /* read id reg */ - mov r1,r1 /* Null-avoiding nop */ - mov r1,r1 /* Null-avoiding nop */ + mrc CP15_MIDR(r1) /* Read main id reg */ + mov r1, r1 /* Null-avoiding nop */ + mov r1, r1 /* Null-avoiding nop */ - /* And "jump" to .Lvstart */ + /* 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: diff --git a/nuttx/arch/arm/src/armv7-a/arm_initialstate.c b/nuttx/arch/arm/src/armv7-a/arm_initialstate.c new file mode 100644 index 000000000..110faf305 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_initialstate.c @@ -0,0 +1,146 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_initialstate.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include + +#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; +} + diff --git a/nuttx/arch/arm/src/armv7-a/arm_pginitialize.c b/nuttx/arch/arm/src/armv7-a/arm_pginitialize.c new file mode 100644 index 000000000..f419a28ba --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_pginitialize.c @@ -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 + * + * 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 + +#include + +#include +#include + +#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 */ diff --git a/nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c b/nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c new file mode 100644 index 000000000..c98bc46ec --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_prefetchabort.c @@ -0,0 +1,154 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_prefetchabort.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include +#ifdef CONFIG_PAGING +# include +#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(); + } +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_releasepending.c b/nuttx/arch/arm/src/armv7-a/arm_releasepending.c new file mode 100644 index 000000000..4dccc7e09 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_releasepending.c @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_releasepending.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#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); + } + } +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_reprioritizertr.c b/nuttx/arch/arm/src/armv7-a/arm_reprioritizertr.c new file mode 100644 index 000000000..2055d395b --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_reprioritizertr.c @@ -0,0 +1,187 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_reprioritizertr.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include +#include +#include + +#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); + } + } + } +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S b/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S new file mode 100644 index 000000000..427a08765 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S @@ -0,0 +1,118 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_saveusercontext.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#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 diff --git a/nuttx/arch/arm/src/armv7-a/arm_schedulesigaction.c b/nuttx/arch/arm/src/armv7-a/arm_schedulesigaction.c new file mode 100644 index 000000000..6516af791 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_schedulesigaction.c @@ -0,0 +1,204 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_schedulesigaction.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include + +#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 */ diff --git a/nuttx/arch/arm/src/armv7-a/arm_sigdeliver.c b/nuttx/arch/arm/src/armv7-a/arm_sigdeliver.c new file mode 100644 index 000000000..d2ad98474 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_sigdeliver.c @@ -0,0 +1,139 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_sigdeliver.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#include +#include +#include + +#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 */ + diff --git a/nuttx/arch/arm/src/armv7-a/arm_syscall.c b/nuttx/arch/arm/src/armv7-a/arm_syscall.c new file mode 100644 index 000000000..c3e6b2174 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_syscall.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_syscall.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#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(); +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_unblocktask.c b/nuttx/arch/arm/src/armv7-a/arm_unblocktask.c new file mode 100644 index 000000000..4906a4a8b --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_unblocktask.c @@ -0,0 +1,154 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_unblocktask.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include +#include + +#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); + } + } +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c b/nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c new file mode 100644 index 000000000..4c63b467f --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_undefinedinsn.c @@ -0,0 +1,81 @@ +/**************************************************************************** + * arch/arm/src/armv7/arm_undefinedinsn.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#include + +#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(); +} diff --git a/nuttx/arch/arm/src/armv7-a/arm_va2pte.c b/nuttx/arch/arm/src/armv7-a/arm_va2pte.c new file mode 100644 index 000000000..1d3aec414 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_va2pte.c @@ -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 + * + * 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 + +#include +#include + +#include +#include + +#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 */ diff --git a/nuttx/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S b/nuttx/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S new file mode 100644 index 000000000..b23f6af1a --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_vectoraddrexcptn.S @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_vectoraddrexceptn.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 +#include +#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 diff --git a/nuttx/arch/arm/src/armv7-a/arm_vectors.S b/nuttx/arch/arm/src/armv7-a/arm_vectors.S index 79597f178..6ba12cd88 100644 --- a/nuttx/arch/arm/src/armv7-a/arm_vectors.S +++ b/nuttx/arch/arm/src/armv7-a/arm_vectors.S @@ -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 diff --git a/nuttx/arch/arm/src/armv7-a/arm_vectortab.S b/nuttx/arch/arm/src/armv7-a/arm_vectortab.S index 80de0f63a..e01ae13b7 100644 --- a/nuttx/arch/arm/src/armv7-a/arm_vectortab.S +++ b/nuttx/arch/arm/src/armv7-a/arm_vectortab.S @@ -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: diff --git a/nuttx/arch/arm/src/armv7-a/arm_vfork.S b/nuttx/arch/arm/src/armv7-a/arm_vfork.S new file mode 100644 index 000000000..d8fa0e14c --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/arm_vfork.S @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/arm/src/armv7-a/arm_vfork.S + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#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 diff --git a/nuttx/arch/arm/src/armv7-a/cp15.h b/nuttx/arch/arm/src/armv7-a/cp15.h index 160bc487b..9c8bf91f1 100644 --- a/nuttx/arch/arm/src/armv7-a/cp15.h +++ b/nuttx/arch/arm/src/armv7-a/cp15.h @@ -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. * diff --git a/nuttx/arch/arm/src/armv7-a/mmu.h b/nuttx/arch/arm/src/armv7-a/mmu.h index 2daab81fc..f02d0ddbd 100644 --- a/nuttx/arch/arm/src/armv7-a/mmu.h +++ b/nuttx/arch/arm/src/armv7-a/mmu.h @@ -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 diff --git a/nuttx/arch/arm/src/armv7-a/sctlr.h b/nuttx/arch/arm/src/armv7-a/sctlr.h new file mode 100644 index 000000000..07959ef45 --- /dev/null +++ b/nuttx/arch/arm/src/armv7-a/sctlr.h @@ -0,0 +1,340 @@ +/************************************************************************************ + * arch/arm/src/armv7-a/sctlr.h + * CP15 System Control Registers + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © 2010 + * ARM. All rights reserved. ARM DDI 0434B (ID101810) + * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © + * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.b (ID072512) + * + * 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_ARMV7_A_SCTLR_H +#define __ARCH_ARM_SRC_ARMV7_A_SCTLR_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Reference: Cortex-A5™ MPCore Paragraph 4.2, "Register summary." */ + +/* Main ID Register (MIDR) */ +/* TODO: To be provided */ + +/* Cache Type Register (CTR) */ +/* TODO: To be provided */ + +/* TCM Type Register + * + * The Cortex-A5 MPCore processor does not implement instruction or data Tightly + * Coupled Memory (TCM), so this register always Reads-As-Zero (RAZ). + * + * TLB Type Register + * + * The Cortex-A5 MPCore processor does not implement instruction or data Tightly + * CoupledMemory (TCM), so this register always Reads-As-Zero (RAZ). + */ + +/* Multiprocessor Affinity Register (MPIDR) */ +/* TODO: To be provided */ + +/* Processor Feature Register 0 (ID_PFR0) */ +/* TODO: To be provided */ + +/* Processor Feature Register 1 (ID_PFR1) */ +/* TODO: To be provided */ + +/* Debug Feature Register 0 (ID_DFR0) */ +/* TODO: To be provided */ + +/* Auxiliary Feature Register 0 (ID_AFR0) */ +/* TODO: To be provided */ + +/* Memory Model Features Register 0 (ID_MMFR0) */ +/* Memory Model Features Register 1 (ID_MMFR1) */ +/* Memory Model Features Register 2 (ID_MMFR2) */ +/* Memory Model Features Register 3 (ID_MMFR3) */ +/* TODO: To be provided */ + +/* Instruction Set Attributes Register 0 (ID_ISAR0) */ +/* Instruction Set Attributes Register 1 (ID_ISAR1) */ +/* Instruction Set Attributes Register 2 (ID_ISAR2) */ +/* Instruction Set Attributes Register 3 (ID_ISAR3) */ +/* Instruction Set Attributes Register 4 (ID_ISAR4) */ +/* Instruction Set Attributes Register 5 (ID_ISAR5) */ +/* Instruction Set Attributes Register 6-7 (ID_ISAR6-7). Reserved. */ +/* TODO: Others to be provided */ + +/* Cache Size Identification Register (CCSIDR) */ +/* TODO: To be provided */ + +/* Cache Level ID Register (CLIDR) */ +/* TODO: To be provided */ + +/* Auxiliary ID Register (AIDR) */ +/* TODO: To be provided */ + +/* Cache Size Selection Register (CSSELR) */ +/* TODO: To be provided */ + +/* System Control Register (SCTLR) + * + * NOTES: + * (1) Always enabled on A5 + * (2) Not available on A5 + */ + +#define SCTLR_M (1 << 0) /* Bit 0: Enables the MMU */ +#define SCTLR_A (1 << 1) /* Bit 1: Enables strict alignment of data */ +#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_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 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 */ +#define SCTLR_TE (1 << 30) /* Bit 30: Thumb exception enable */ + /* Bit 31: Reserved */ + +/* Auxiliary Control Register (ACTLR) */ +/* TODO: To be provided */ + +/* Coprocessor Access Control Register (CPACR) */ +/* TODO: To be provided */ + +/* Secure Configuration Register (SCR) */ +/* TODO: To be provided */ + +/* Secure Debug Enable Register (SDER) */ +/* TODO: To be provided */ + +/* Non-secure Access Control Register (NSACR) */ + + /* Bits 0-9: Reserved */ +#define NSACR_CP10 (1 << 10) /* Bit 10: Permission to access coprocessor 10 */ +#define NSACR_CP11 (1 << 11) /* Bit 11: Permission to access coprocessor 11 */ + /* Bits 12-13: Reserved */ +#define NSACR_NSD32DIS (1 << 14) /* Bit 14: Disable the Non-secure use of VFP D16-D31 */ +#define NSACR_NSASEDIS (1 << 15) /* Bit 15: Disable Non-secure Advanced SIMD Extension */ + /* Bits 16-17: Reserved */ +#define NSACR_NSSMP (1 << 18) /* Bit 18: ACR SMP bit writable */ + /* Bits 19-31: Reserved */ + +/* Virtualization Control Register (VCR) */ +/* TODO: To be provided */ + +/* Translation Table Base Register 0 (TTBR0). See mmu.h */ +/* Translation Table Base Register 1 (TTBR1). See mmu.h */ +/* Translation Table Base Control Register (TTBCR). See mmu.h */ +/* Domain Access Control Register (DACR). See mmu.h */ +/* Data Fault Status Register (DFSR). See mmu.h */ +/* Instruction Fault Status Register (IFSR). See mmu.h */ + +/* Auxiliary Data Fault Status Register (ADFSR). Not used in this implementation. */ + +/* Data Fault Address Register(DFAR) + * + * Holds the MVA of the faulting address when a synchronous fault occurs + * + * Instruction Fault Address Register(IFAR) + * + * Holds the MVA of the faulting address of the instruction that caused a prefetch + * abort. + * + * NOP Register + * + * The use of this register is optional and deprecated. Use the NOP instruction + * instead. + * + * Physical Address Register (PAR) + * + * Holds: + * - the PA after a successful translation + * - the source of the abort for an unsuccessful translation + * + * Instruction Synchronization Barrier + * + * The use of ISB is optional and deprecated. Use the instruction ISB instead. + * + * Data Memory Barrier + * The use of DMB is deprecated and, on Cortex-A5 MPCore, behaves as NOP. Use the + * instruction DMB instead. + */ + +/* Vector Base Address Register (VBAR) */ +/* TODO: To be provided */ + +/* Monitor Vector Base Address Register (MVBAR) */ +/* TODO: To be provided */ + +/* Interrupt Status Register (ISR) */ +/* TODO: To be provided */ + +/* Virtualization Interrupt Register (VIR) */ +/* TODO: To be provided */ + +/* Context ID Register (CONTEXTIDR) */ + +#define CONTEXTIDR_ASID_SHIFT (0) /* Bits 0-7: Address Space Identifier */ +#define CONTEXTIDR_ASID_MASK (0xff << CONTEXTIDR_ASID_SHIFT) +#define CONTEXTIDR_PROCID_SHIFT (8) /* Bits 8-31: Process Identifier */ +#define CONTEXTIDR_PROCID_MASK (0x00ffffff << CONTEXTIDR_PROCID_SHIFT) + +/* Configuration Base Address Register (CBAR) */ +/* TODO: To be provided */ + +/************************************************************************************ + * Assemby Macros + ************************************************************************************/ + +#ifdef __ASSEMBLY__ + +/* Get the device ID */ + + .macro cp15_rdid, id + mrc p15, 0, \id, c0, c0, 0 + .endm + +/* Read/write the system control register (SCTLR) */ + + .macro cp15_rdsctlr, sctlr + mrc p15, 0, \sctlr, c1, c0, 0 + .endm + + .macro cp15_wrsctlr, sctlr + mcr p15, 0, \sctlr, c1, c0, 0 + nop + nop + nop + nop + nop + nop + nop + nop + .endm +#endif /* __ASSEMBLY__ */ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Get the device ID */ + +static inline unsigned int cp15_rdid(void) +{ + unsigned int id; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c0, c0, 0" + : "=r" (id) + : + : "memory" + ); + + return id; +} + +/* Read/write the system control register (SCTLR) */ + +static inline unsigned int cp15_rdsctlr(void) +{ + unsigned int sctlr; + __asm__ __volatile__ + ( + "\tmrc p15, 0, %0, c1, c0, 0" + : "=r" (sctlr) + : + : "memory" + ); + + return sctlr; +} + +static inline void cp15_wrsctlr(unsigned int sctlr) +{ + __asm__ __volatile__ + ( + "\tmcr p15, 0, $0, c1, c0, 0\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + "\tnop\n" + : + : "r" (sctlr) + : "memory" + ); +} + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_ARM_SRC_ARMV7_A_SCTLR_H */ diff --git a/nuttx/arch/arm/src/armv7-a/sctrl.h b/nuttx/arch/arm/src/armv7-a/sctrl.h deleted file mode 100644 index 7ea447b1b..000000000 --- a/nuttx/arch/arm/src/armv7-a/sctrl.h +++ /dev/null @@ -1,340 +0,0 @@ -/************************************************************************************ - * arch/arm/src/armv7-a/sctrl.h - * CP15 System Control Registers - * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * References: - * - * "Cortex-A5™ MPCore, Technical Reference Manual", Revision: r0p1, Copyright © 2010 - * ARM. All rights reserved. ARM DDI 0434B (ID101810) - * "ARM® Architecture Reference Manual, ARMv7-A and ARMv7-R edition", Copyright © - * 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM DDI 0406C.b (ID072512) - * - * 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. - * - ************************************************************************************/ - -#ifndef __ARCH_ARM_SRC_ARMV7_A_CPSR_H -#define __ARCH_ARM_SRC_ARMV7_A_CPSR_H - -/************************************************************************************ - * Included Files - ************************************************************************************/ - -/************************************************************************************ - * Pre-processor Definitions - ************************************************************************************/ -/* Reference: Cortex-A5™ MPCore Paragraph 4.2, "Register summary." */ - -/* Main ID Register (MIDR) */ -/* TODO: To be provided */ - -/* Cache Type Register (CTR) */ -/* TODO: To be provided */ - -/* TCM Type Register - * - * The Cortex-A5 MPCore processor does not implement instruction or data Tightly - * Coupled Memory (TCM), so this register always Reads-As-Zero (RAZ). - * - * TLB Type Register - * - * The Cortex-A5 MPCore processor does not implement instruction or data Tightly - * CoupledMemory (TCM), so this register always Reads-As-Zero (RAZ). - */ - -/* Multiprocessor Affinity Register (MPIDR) */ -/* TODO: To be provided */ - -/* Processor Feature Register 0 (ID_PFR0) */ -/* TODO: To be provided */ - -/* Processor Feature Register 1 (ID_PFR1) */ -/* TODO: To be provided */ - -/* Debug Feature Register 0 (ID_DFR0) */ -/* TODO: To be provided */ - -/* Auxiliary Feature Register 0 (ID_AFR0) */ -/* TODO: To be provided */ - -/* Memory Model Features Register 0 (ID_MMFR0) */ -/* Memory Model Features Register 1 (ID_MMFR1) */ -/* Memory Model Features Register 2 (ID_MMFR2) */ -/* Memory Model Features Register 3 (ID_MMFR3) */ -/* TODO: To be provided */ - -/* Instruction Set Attributes Register 0 (ID_ISAR0) */ -/* Instruction Set Attributes Register 1 (ID_ISAR1) */ -/* Instruction Set Attributes Register 2 (ID_ISAR2) */ -/* Instruction Set Attributes Register 3 (ID_ISAR3) */ -/* Instruction Set Attributes Register 4 (ID_ISAR4) */ -/* Instruction Set Attributes Register 5 (ID_ISAR5) */ -/* Instruction Set Attributes Register 6-7 (ID_ISAR6-7). Reserved. */ -/* TODO: Others to be provided */ - -/* Cache Size Identification Register (CCSIDR) */ -/* TODO: To be provided */ - -/* Cache Level ID Register (CLIDR) */ -/* TODO: To be provided */ - -/* Auxiliary ID Register (AIDR) */ -/* TODO: To be provided */ - -/* Cache Size Selection Register (CSSELR) */ -/* TODO: To be provided */ - -/* System Control Register (SCTLR) - * - * NOTES: - * (1) Always enabled on A5 - * (2) Not available on A5 - */ - -#define SCTLR_M (1 << 0) /* Bit 0: Enables the MMU */ -#define SCTLR_A (1 << 1) /* Bit 1: Enables strict alignment of data */ -#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_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 */ - /* Bits 26-27: Reserved */ -#define SCTLR_TRE (1 << 28) /* Bit 28: TEX remap */ -#define SCTLR_AFE (1 << 29) /* Bit 29: Access Flag Enable bit */ -#define SCTLR_TE (1 << 30) /* Bit 30: Thumb exception enable */ - /* Bit 31: Reserved */ - -/* Auxiliary Control Register (ACTLR) */ -/* TODO: To be provided */ - -/* Coprocessor Access Control Register (CPACR) */ -/* TODO: To be provided */ - -/* Secure Configuration Register (SCR) */ -/* TODO: To be provided */ - -/* Secure Debug Enable Register (SDER) */ -/* TODO: To be provided */ - -/* Non-secure Access Control Register (NSACR) */ - - /* Bits 0-9: Reserved */ -#define NSACR_CP10 (1 << 10) /* Bit 10: Permission to access coprocessor 10 */ -#define NSACR_CP11 (1 << 11) /* Bit 11: Permission to access coprocessor 11 */ - /* Bits 12-13: Reserved */ -#define NSACR_NSD32DIS (1 << 14) /* Bit 14: Disable the Non-secure use of VFP D16-D31 */ -#define NSACR_NSASEDIS (1 << 15) /* Bit 15: Disable Non-secure Advanced SIMD Extension */ - /* Bits 16-17: Reserved */ -#define NSACR_NSSMP (1 << 18) /* Bit 18: ACR SMP bit writable */ - /* Bits 19-31: Reserved */ - -/* Virtualization Control Register (VCR) */ -/* TODO: To be provided */ - -/* Translation Table Base Register 0 (TTBR0). See mmu.h */ -/* Translation Table Base Register 1 (TTBR1). See mmu.h */ -/* Translation Table Base Control Register (TTBCR). See mmu.h */ -/* Domain Access Control Register (DACR). See mmu.h */ -/* Data Fault Status Register (DFSR). See mmu.h */ -/* Instruction Fault Status Register (IFSR). See mmu.h */ - -/* Auxiliary Data Fault Status Register (ADFSR). Not used in this implementation. */ - -/* Data Fault Address Register(DFAR) - * - * Holds the MVA of the faulting address when a synchronous fault occurs - * - * Instruction Fault Address Register(IFAR) - * - * Holds the MVA of the faulting address of the instruction that caused a prefetch - * abort. - * - * NOP Register - * - * The use of this register is optional and deprecated. Use the NOP instruction - * instead. - * - * Physical Address Register (PAR) - * - * Holds: - * - the PA after a successful translation - * - the source of the abort for an unsuccessful translation - * - * Instruction Synchronization Barrier - * - * The use of ISB is optional and deprecated. Use the instruction ISB instead. - * - * Data Memory Barrier - * The use of DMB is deprecated and, on Cortex-A5 MPCore, behaves as NOP. Use the - * instruction DMB instead. - */ - -/* Vector Base Address Register (VBAR) */ -/* TODO: To be provided */ - -/* Monitor Vector Base Address Register (MVBAR) */ -/* TODO: To be provided */ - -/* Interrupt Status Register (ISR) */ -/* TODO: To be provided */ - -/* Virtualization Interrupt Register (VIR) */ -/* TODO: To be provided */ - -/* Context ID Register (CONTEXTIDR) */ - -#define CONTEXTIDR_ASID_SHIFT (0) /* Bits 0-7: Address Space Identifier */ -#define CONTEXTIDR_ASID_MASK (0xff << CONTEXTIDR_ASID_SHIFT) -#define CONTEXTIDR_PROCID_SHIFT (8) /* Bits 8-31: Process Identifier */ -#define CONTEXTIDR_PROCID_MASK (0x00ffffff << CONTEXTIDR_PROCID_SHIFT) - -/* Configuration Base Address Register (CBAR) */ -/* TODO: To be provided */ - -/************************************************************************************ - * Assemby Macros - ************************************************************************************/ - -#ifdef __ASSEMBLY__ - -/* Get the device ID */ - - .macro cp15_rdid, id - mrc p15, 0, \id, c0, c0, 0 - .endm - -/* Read/write the system control register (SCTRL) */ - - .macro cp15_rdsctrl, sctrl - mrc p15, 0, \sctrl, c1, c0, 0 - .endm - - .macro cp15_wrsctrl, sctrl - mcr p15, 0, \sctrl, c1, c0, 0 - nop - nop - nop - nop - nop - nop - nop - nop - .endm -#endif /* __ASSEMBLY__ */ - -/************************************************************************************ - * Inline Functions - ************************************************************************************/ - -#ifndef __ASSEMBLY__ - -/* Get the device ID */ - -static inline unsigned int cp15_rdid(void) -{ - unsigned int id; - __asm__ __volatile__ - ( - "\tmrc p15, 0, %0, c0, c0, 0" - : "=r" (id) - : - : "memory" - ); - - return id; -} - -/* Read/write the system control register (SCTRL) */ - -static inline unsigned int cp15_rdsctrl(void) -{ - unsigned int sctrl; - __asm__ __volatile__ - ( - "\tmrc p15, 0, %0, c1, c0, 0" - : "=r" (sctrl) - : - : "memory" - ); - - return sctrl; -} - -static inline void cp15_wrsctrl(unsigned int sctrl) -{ - __asm__ __volatile__ - ( - "\tmcr p15, 0, $0, c1, c0, 0\n" - "\tnop\n" - "\tnop\n" - "\tnop\n" - "\tnop\n" - "\tnop\n" - "\tnop\n" - "\tnop\n" - "\tnop\n" - : - : "r" (sctrl) - : "memory" - ); -} - -#endif /* __ASSEMBLY__ */ - -/**************************************************************************** - * Public Variables - ****************************************************************************/ - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#ifndef __ASSEMBLY__ -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" { -#else -#define EXTERN extern -#endif - -#undef EXTERN -#ifdef __cplusplus -} -#endif -#endif /* __ASSEMBLY__ */ - -#endif /* __ARCH_ARM_SRC_ARMV7_A_CPSR_H */ -- cgit v1.2.3