mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 17:33:08 +08:00
arch/arm: Fix the style issue in assemble files
remove the unused header file and mimic the difference between sub arch Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* arch/arm/src/arm/arm_fullcontextrestore.S
|
||||
*
|
||||
* Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved.
|
||||
@@ -31,59 +31,60 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include "arm_internal.h"
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Types
|
||||
**************************************************************************/
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Function Prototypes
|
||||
**************************************************************************/
|
||||
.file "arm_fullcontextrestore.S"
|
||||
|
||||
/**************************************************************************
|
||||
* Public Data
|
||||
**************************************************************************/
|
||||
/****************************************************************************
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Data
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Functions
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: arm_fullcontextrestore
|
||||
**************************************************************************/
|
||||
*
|
||||
* Description:
|
||||
* Restore the current thread context. Full prototype is:
|
||||
*
|
||||
* void arm_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_fullcontextrestore
|
||||
.type arm_fullcontextrestore, function
|
||||
arm_fullcontextrestore:
|
||||
|
||||
/* On entry, a1 (r0) holds address of the register save area */
|
||||
/* On entry, a1 (r0) holds address of the register save area. All other
|
||||
* registers are available for use.
|
||||
*/
|
||||
|
||||
/* 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 */
|
||||
/* Create a stack frame to hold the some registers */
|
||||
|
||||
sub sp, sp, #(3*4) /* Frame for three registers */
|
||||
ldr r1, [r0, #(4*REG_R0)] /* Fetch the stored r0 value */
|
||||
@@ -104,8 +105,10 @@ arm_fullcontextrestore:
|
||||
msr cpsr, r1 /* Set the CPSR */
|
||||
|
||||
/* Now recover r0 and r1. Then return to the address at the stop of
|
||||
* the stack, destroying the stack frame
|
||||
* the stack, destroying the stack frame
|
||||
*/
|
||||
|
||||
ldmia sp!, {r0-r1, r15}
|
||||
.size arm_fullcontextrestore, . - arm_fullcontextrestore
|
||||
|
||||
.size arm_fullcontextrestore, .-arm_fullcontextrestore
|
||||
.end
|
||||
|
||||
+76
-60
@@ -42,18 +42,21 @@
|
||||
#include "arm.h"
|
||||
#include "chip.h"
|
||||
#include "arm_internal.h"
|
||||
#include "arm_arch.h"
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
# include <nuttx/page.h>
|
||||
# include "pg_macros.h"
|
||||
#endif
|
||||
|
||||
/**********************************************************************************
|
||||
* Configuration
|
||||
**********************************************************************************/
|
||||
.file "arm_head.S"
|
||||
|
||||
#undef ALIGNMENT_TRAP
|
||||
/****************************************************************************
|
||||
* Configuration
|
||||
****************************************************************************/
|
||||
|
||||
/* Hard-coded options */
|
||||
|
||||
#undef CPU_ALIGNMENT_TRAP
|
||||
#undef CPU_DCACHE_WRITETHROUGH
|
||||
#undef CPU_CACHE_ROUND_ROBIN
|
||||
#undef CPU_DCACHE_DISABLE
|
||||
@@ -64,13 +67,13 @@
|
||||
* 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case
|
||||
* the boot logic must:
|
||||
*
|
||||
* - Configure SDRAM,
|
||||
* - Configure SDRAM (if present),
|
||||
* - Initialize the .data section in RAM, and
|
||||
* - Clear .bss section
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BOOT_RUNFROMFLASH
|
||||
# error "Configuration not implemented"
|
||||
# error "configuration not implemented"
|
||||
# define CONFIG_SDRAM 1
|
||||
|
||||
/* Check for the identity mapping: For this configuration, this would be
|
||||
@@ -114,11 +117,11 @@
|
||||
# define CONFIG_IDENTITY_TEXTMAP 1
|
||||
# endif
|
||||
|
||||
/* 3. There is bootloader that copies us to DRAM (but probably not to the beginning)
|
||||
/* 3. There is bootloader that copies us to SDRAM (but probably not to the beginning)
|
||||
* (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). In this case SDRAM
|
||||
* was initialized by the boot loader, and this boot logic must:
|
||||
*
|
||||
* - Clear .bss section
|
||||
* - Clear .bss section (data should be fully initialized)
|
||||
*/
|
||||
|
||||
#else
|
||||
@@ -222,12 +225,15 @@
|
||||
* Name: __start
|
||||
****************************************************************************/
|
||||
|
||||
/* We assume the bootloader has already initialized most of the h/w for us
|
||||
* and that only leaves us having to do some os specific things below.
|
||||
/* We assume the bootloader has already initialized most of the h/w for
|
||||
* us and that only leaves us having to do some os specific things
|
||||
* below.
|
||||
*/
|
||||
|
||||
.text
|
||||
.global __start
|
||||
.type __start, #function
|
||||
|
||||
__start:
|
||||
/* Make sure that we are in SVC mode with all IRQs disabled */
|
||||
|
||||
@@ -255,17 +261,17 @@ __start:
|
||||
bne .Lpgtableclear
|
||||
|
||||
/* Create identity mapping for first MB of the .text section to support
|
||||
* this startup logic executing out of the physical address space. This
|
||||
* this start-up logic executing out of the physical address space. This
|
||||
* identity mapping will be removed by .Lvstart (see below). Of course,
|
||||
* we would only do this if the physical-virtual mapping is not already
|
||||
* the identity mapping.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_IDENTITY_TEXTMAP
|
||||
mksection r0, r4 /* r0=phys. base section */
|
||||
mksection r0, r4 /* r0=phys. base section */
|
||||
ldr r1, .LCmmuflags /* FLGS=MMU_MEMFLAGS */
|
||||
add r3, r1, r0 /* r3=flags + base */
|
||||
str r3, [r4, r0, lsr #18] /* identity mapping */
|
||||
add r3, r1, r0 /* r3=flags + base */
|
||||
str r3, [r4, r0, lsr #18] /* identity mapping */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PAGING
|
||||
@@ -284,35 +290,35 @@ __start:
|
||||
*/
|
||||
|
||||
adr r0, .Ltxtspan
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
|
||||
/* Then populate the L2 table for the locked text region only. */
|
||||
|
||||
adr r0, .Ltxtmap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
|
||||
/* Make sure that the page table is itself mapped and and read/write-able.
|
||||
* First, populate the L1 table:
|
||||
*/
|
||||
|
||||
adr r0, .Lptabspan
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
|
||||
/* Then populate the L2 table. */
|
||||
|
||||
adr r0, .Lptabmap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
|
||||
#else /* CONFIG_PAGING */
|
||||
|
||||
#ifdef CONFIG_IDENTITY_TEXTMAP
|
||||
mksection r0, r4 /* r0=phys. base section */
|
||||
mksection r0, r4 /* r0=phys. base section */
|
||||
ldr r1, .LCmmuflags /* FLGS=MMU_MEMFLAGS */
|
||||
add r3, r1, r0 /* r3=flags + base */
|
||||
add r3, r1, r0 /* r3=flags + base */
|
||||
#endif
|
||||
|
||||
/* Create a virtual single section mapping for the first MB of the .text
|
||||
@@ -325,8 +331,8 @@ __start:
|
||||
*/
|
||||
|
||||
ldr r2, .LCvpgtable /* r2=virt. page table */
|
||||
mksection r0, r2 /* r0=virt. base section */
|
||||
str r3, [r4, r0, lsr #18] /* identity mapping */
|
||||
mksection r0, r2 /* r0=virt. base section */
|
||||
str r3, [r4, r0, lsr #18] /* identity mapping */
|
||||
|
||||
/* NOTE: No .data/.bss access should be attempted. This temporary mapping
|
||||
* can only be assumed to cover the initial .text region.
|
||||
@@ -343,12 +349,12 @@ __start:
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7 /* Invalidate I,D caches */
|
||||
mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */
|
||||
mcr p15, 0, r0, c7, c10, 4 /* Drain write buffer */
|
||||
mcr p15, 0, r0, c8, c7 /* Invalidate I,D TLBs */
|
||||
mcr p15, 0, r4, c2, c0 /* Load page table pointer */
|
||||
|
||||
#ifdef CPU_DCACHE_WRITETHROUGH
|
||||
mov r0, #4 /* Disable write-back on caches explicitly */
|
||||
mov r0, #4 /* Disable write-back on caches explicitly */
|
||||
mcr p15, 7, r0, c15, c0, 0
|
||||
#endif
|
||||
|
||||
@@ -358,7 +364,7 @@ __start:
|
||||
|
||||
ldr lr, .LCvstart /* Abs. virtual address */
|
||||
|
||||
mov r0, #0x1f /* Domains 0, 1 = client */
|
||||
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 */
|
||||
|
||||
@@ -417,20 +423,20 @@ __start:
|
||||
#endif
|
||||
/* CR_A - Alignment abort enable */
|
||||
|
||||
#ifdef ALIGNMENT_TRAP
|
||||
#ifdef CPU_ALIGNMENT_TRAP
|
||||
orr r0, r0, #(CR_A)
|
||||
#endif
|
||||
mcr p15, 0, r0, c1, c0, 0 /* write control reg */
|
||||
mcr p15, 0, r0, c1, c0, 0 /* write control reg */
|
||||
|
||||
/* Get TMP=2 Processor ID register */
|
||||
|
||||
mrc p15, 0, r1, c0, c0, 0 /* read id reg */
|
||||
mov r1,r1 /* Null-avoiding nop */
|
||||
mov r1,r1 /* Null-avoiding nop */
|
||||
mrc p15, 0, r1, c0, c0, 0 /* read id reg */
|
||||
mov r1,r1 /* Null-avoiding nop */
|
||||
mov r1,r1 /* Null-avoiding nop */
|
||||
|
||||
/* And "jump" to .Lvstart */
|
||||
|
||||
mov pc, lr
|
||||
mov pc, lr
|
||||
|
||||
/****************************************************************************
|
||||
* PC_Relative Data
|
||||
@@ -499,6 +505,7 @@ __start:
|
||||
.align 5
|
||||
.local .Lvstart
|
||||
.type .Lvstart, %function
|
||||
|
||||
.Lvstart:
|
||||
|
||||
/* Remove the temporary mapping (if one was made). The following assumes
|
||||
@@ -510,23 +517,23 @@ __start:
|
||||
#ifndef CONFIG_IDENTITY_TEXTMAP
|
||||
ldr r4, .LCvpgtable /* r4=virtual page table */
|
||||
ldr r1, .LCppgtable /* r1=phys. page table */
|
||||
mksection r3, r1 /* r2=phys. base addr */
|
||||
mov r0, #0 /* flags + base = 0 */
|
||||
str r0, [r4, r3, lsr #18] /* Undo identity mapping */
|
||||
mksection r3, r1 /* r2=phys. base addr */
|
||||
mov r0, #0 /* flags + base = 0 */
|
||||
str r0, [r4, r3, lsr #18] /* Undo identity mapping */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PAGING)
|
||||
/* Populate the L1 table for the data region */
|
||||
|
||||
adr r0, .Ldataspan
|
||||
ldmia r0, {r0, r1, r2, r3, r4}
|
||||
pg_l1span r0, r1, r2, r3, r4, r5
|
||||
ldmia r0, {r0, r1, r2, r3, r4}
|
||||
pg_l1span r0, r1, r2, r3, r4, r5
|
||||
|
||||
/* Populate the L2 table for the data region */
|
||||
|
||||
adr r0, .Ldatamap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r4
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r4
|
||||
|
||||
#elif defined(CONFIG_BOOT_RUNFROMFLASH)
|
||||
# error "Logic not implemented"
|
||||
@@ -548,7 +555,7 @@ __start:
|
||||
*/
|
||||
|
||||
ldr r1, .LCmmuflags /* FLGS=MMU_MEMFLAGS */
|
||||
add r3, r3, r1 /* r3=flags + base */
|
||||
add r3, r3, r1 /* r3=flags + base */
|
||||
|
||||
add r0, r4, #(NUTTX_START_VADDR & 0xfff00000) >> 18
|
||||
str r3, [r0], #4
|
||||
@@ -557,7 +564,7 @@ __start:
|
||||
* memory region.
|
||||
*/
|
||||
|
||||
.rept RX_NSECTIONS-1
|
||||
.rept RX_NSECTIONS-1
|
||||
add r3, r3, #SECTION_SIZE
|
||||
str r3, [r0], #4
|
||||
.endr
|
||||
@@ -577,15 +584,15 @@ __start:
|
||||
/* Zero BSS and set up the stack pointer */
|
||||
|
||||
adr r0, .Linitparms
|
||||
ldmia r0, {r0, r1, sp}
|
||||
ldmia r0, {r0, r1, sp}
|
||||
|
||||
/* Clear the frame pointer and .bss */
|
||||
|
||||
mov fp, #0
|
||||
|
||||
.Lbssinit:
|
||||
cmp r0, r1 /* Clear up to _bss_end_ */
|
||||
strcc fp, [r0],#4
|
||||
cmp r0, r1 /* Clear up to _bss_end_ */
|
||||
strcc fp, [r0],#4
|
||||
bcc .Lbssinit
|
||||
|
||||
/* If the .data section is in a separate, uninitialized address space,
|
||||
@@ -599,10 +606,10 @@ __start:
|
||||
|
||||
#if defined(CONFIG_BOOT_RUNFROMFLASH) || defined(CONFIG_PAGING)
|
||||
adr r3, .Ldatainit
|
||||
ldmia r3, {r0, r1, r2}
|
||||
ldmia r3, {r0, r1, r2}
|
||||
|
||||
1: ldmia r0!, {r3 - r10}
|
||||
stmia r1!, {r3 - r10}
|
||||
1: ldmia r0!, {r3 - r10}
|
||||
stmia r1!, {r3 - r10}
|
||||
cmp r1, r2
|
||||
blt 1b
|
||||
#endif
|
||||
@@ -617,13 +624,13 @@ __start:
|
||||
*/
|
||||
|
||||
adr r3, .Lstkinit
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
|
||||
2: /* Top of the loop */
|
||||
2: /* Top of the loop */
|
||||
sub r1, r1, #1 /* R1 = Number of words remaining */
|
||||
cmp r1, #0 /* Check (nwords == 0) */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 2b /* Bottom of the loop */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 2b /* Bottom of the loop */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -632,12 +639,17 @@ __start:
|
||||
mov lr, #0 /* LR = return address (none) */
|
||||
b nx_start /* Branch to nx_start */
|
||||
|
||||
/***************************************************************************
|
||||
* Text-section constants
|
||||
***************************************************************************/
|
||||
|
||||
/* Text-section constants:
|
||||
*
|
||||
* _sbss is the start of the BSS region (see ld.script)
|
||||
* _ebss is the end of the BSS region (see ld.script)
|
||||
* _sbss is the start of the BSS region (see linker script)
|
||||
* _ebss is the end of the BSS region (see linker script)
|
||||
*
|
||||
* The idle task stack starts at the end of BSS and is of size
|
||||
* Typical Configuration:
|
||||
* The idle task stack usually starts at the end of BSS and is of size
|
||||
* CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the
|
||||
* end of memory. See g_idle_topstack below.
|
||||
*/
|
||||
@@ -688,10 +700,12 @@ __start:
|
||||
#endif
|
||||
.size .Lvstart, .-.Lvstart
|
||||
|
||||
/* Data section variables */
|
||||
/***************************************************************************
|
||||
* Data section variables
|
||||
***************************************************************************/
|
||||
|
||||
/* This global variable is unsigned long g_idle_topstack and is
|
||||
* exported from here only because of its coupling to .Linitparms
|
||||
* exported from here only because of its coupling to .Lstackpointer
|
||||
* above.
|
||||
*/
|
||||
|
||||
@@ -699,7 +713,9 @@ __start:
|
||||
.align 4
|
||||
.globl g_idle_topstack
|
||||
.type g_idle_topstack, object
|
||||
|
||||
g_idle_topstack:
|
||||
|
||||
.long _ebss+CONFIG_IDLETHREAD_STACKSIZE
|
||||
.size g_idle_topstack, .-g_idle_topstack
|
||||
.end
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
|
||||
#include "arm.h"
|
||||
#include "arm_internal.h"
|
||||
#include "arm_arch.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Macros
|
||||
@@ -51,8 +50,8 @@
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
.macro showprogress, code
|
||||
mov r0, #\code
|
||||
bl arm_lowputc
|
||||
mov r0, #\code
|
||||
bl arm_lowputc
|
||||
.endm
|
||||
#else
|
||||
.macro showprogress, code
|
||||
@@ -68,7 +67,7 @@
|
||||
* below.
|
||||
*/
|
||||
.text
|
||||
.global __start
|
||||
.global __start
|
||||
.type __start, #function
|
||||
__start:
|
||||
|
||||
@@ -77,31 +76,31 @@ __start:
|
||||
mov r0, #(SVC_MODE | PSR_I_BIT | PSR_F_BIT )
|
||||
msr cpsr, r0
|
||||
|
||||
showprogress 'A'
|
||||
showprogress 'A'
|
||||
|
||||
/* Setup system stack (and get the BSS range) */
|
||||
|
||||
adr r0, .Lbssinit
|
||||
ldmia r0, {r4, r5, sp}
|
||||
ldmia r0, {r4, r5, sp}
|
||||
|
||||
/* Clear system BSS section */
|
||||
|
||||
mov r0, #0
|
||||
1: cmp r4, r5
|
||||
strcc r0, [r4], #4
|
||||
strcc r0, [r4], #4
|
||||
bcc 1b
|
||||
|
||||
showprogress 'B'
|
||||
showprogress 'B'
|
||||
|
||||
/* Copy system .data sections to new home in RAM. */
|
||||
|
||||
#ifdef CONFIG_BOOT_RUNFROMFLASH
|
||||
|
||||
adr r3, .Ldatainit
|
||||
ldmia r3, {r0, r1, r2}
|
||||
ldmia r3, {r0, r1, r2}
|
||||
|
||||
1: ldmia r0!, {r3 - r10}
|
||||
stmia r1!, {r3 - r10}
|
||||
1: ldmia r0!, {r3 - r10}
|
||||
stmia r1!, {r3 - r10}
|
||||
cmp r1, r2
|
||||
blt 1b
|
||||
|
||||
@@ -134,13 +133,13 @@ __start:
|
||||
*/
|
||||
|
||||
adr r3, .Lstkinit
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
|
||||
2: /* Top of the loop */
|
||||
2: /* Top of the loop */
|
||||
sub r1, r1, #1 /* R1 = Number of words remaining */
|
||||
cmp r1, #0 /* Check (nwords == 0) */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 2b /* Bottom of the loop */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 2b /* Bottom of the loop */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* arch/arm/src/arm/arm_saveusercontext.S
|
||||
*
|
||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
||||
@@ -31,64 +31,60 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include "arm_internal.h"
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Types
|
||||
**************************************************************************/
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Function Prototypes
|
||||
**************************************************************************/
|
||||
.file "arm_saveusercontext.S"
|
||||
|
||||
/**************************************************************************
|
||||
* Public Data
|
||||
**************************************************************************/
|
||||
/****************************************************************************
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Data
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Functions
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
**************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: arm_saveusercontext
|
||||
**************************************************************************/
|
||||
*
|
||||
* Description:
|
||||
* Save the current thread context. Full prototype is:
|
||||
*
|
||||
* int arm_saveusercontext(uint32_t *saveregs);
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: Normal return
|
||||
* 1: Context switch return
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
.globl arm_saveusercontext
|
||||
.type arm_saveusercontext, function
|
||||
arm_saveusercontext:
|
||||
/* On entry, a1 (r0) holds address of struct xcptcontext.
|
||||
* Offset to the user region.
|
||||
|
||||
/* On entry, a1 (r0) holds address of struct xcptcontext */
|
||||
|
||||
/* 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 through the normal C calling conventions and the values of
|
||||
* these registers cannot be assumed at the point of setjmp return.
|
||||
*/
|
||||
|
||||
/* 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 through the
|
||||
* normal C calling conventions and the values of these
|
||||
* registers cannot be assumed at the point of setjmp
|
||||
* return.
|
||||
*/
|
||||
|
||||
mov ip, #1
|
||||
mov ip, #1
|
||||
str ip, [r0, #(4*REG_R0)]
|
||||
|
||||
/* Save the volatile registers (plus r12 which really
|
||||
@@ -100,19 +96,20 @@ arm_saveusercontext:
|
||||
|
||||
/* Save the current cpsr */
|
||||
|
||||
mrs r2, cpsr /* R3 = CPSR value */
|
||||
mrs r2, cpsr /* R2 = 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.
|
||||
/* Save the return address as the PC so that we return to the exit from
|
||||
* this function.
|
||||
*/
|
||||
|
||||
add r1, r0, #(4*REG_PC)
|
||||
add r1, r0, #(4*REG_PC)
|
||||
str lr, [r1]
|
||||
|
||||
/* Return 0 */
|
||||
|
||||
mov r0, #0 /* Return value == 0 */
|
||||
mov pc, lr /* Return */
|
||||
.size arm_saveusercontext, . - arm_saveusercontext
|
||||
.size arm_saveusercontext, .-arm_saveusercontext
|
||||
.end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/src/arm/up_vectoraddrexceptn.S
|
||||
/****************************************************************************
|
||||
* arch/arm/src/arm/arm_vectoraddrexceptn.S
|
||||
*
|
||||
* Copyright (C) 2008-2010 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@@ -31,53 +31,56 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include "arm_arch.h"
|
||||
|
||||
/************************************************************************************
|
||||
.file "arm_vectoraddrexcptn.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
.globl arm_vectoraddrexcption
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Macros
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/************************************************************************************
|
||||
* Name: up_vectoraddrexcption
|
||||
/****************************************************************************
|
||||
* Name: arm_vectoraddrexcption
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen. This exception handler is in a separate file from other
|
||||
* vector handlers because some processors (e.g., lpc2148) do not support the
|
||||
* the Address Exception vector.
|
||||
* Shouldn't happen. This exception handler is in a separate file from
|
||||
* other vector handlers because some processors do not support the
|
||||
* Address Exception vector.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_vectoraddrexcptn
|
||||
.type arm_vectoraddrexcptn, %function
|
||||
arm_vectoraddrexcptn:
|
||||
b arm_vectoraddrexcptn
|
||||
b arm_vectoraddrexcptn
|
||||
.size arm_vectoraddrexcptn, . - arm_vectoraddrexcptn
|
||||
.end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* arch/arm/src/arm/arm_vectors.S
|
||||
*
|
||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
||||
@@ -31,73 +31,76 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "arm_arch.h"
|
||||
|
||||
/************************************************************************************
|
||||
.file "arm_vectors.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
.data
|
||||
g_irqtmp:
|
||||
.word 0 /* Saved lr */
|
||||
.word 0 /* Saved spsr */
|
||||
|
||||
g_undeftmp:
|
||||
.word 0 /* Saved lr */
|
||||
.word 0 /* Saved spsr */
|
||||
|
||||
g_aborttmp:
|
||||
.word 0 /* Saved lr */
|
||||
.word 0 /* Saved spsr */
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Assembly Macros
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: arm_vectorirq
|
||||
*
|
||||
* Description:
|
||||
* Interrupt exception. Entered in IRQ mode with spsr = SVC CPSR, lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_decodeirq
|
||||
.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.
|
||||
/* 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 */
|
||||
|
||||
@@ -120,7 +123,7 @@ arm_vectorirq:
|
||||
/* 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 */
|
||||
ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
@@ -147,23 +150,27 @@ arm_vectorirq:
|
||||
|
||||
.Lirqtmp:
|
||||
.word g_irqtmp
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.Lirqstackbase:
|
||||
.word g_intstackbase
|
||||
#endif
|
||||
|
||||
.size arm_vectorirq, . - arm_vectorirq
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Function: arm_vectorswi
|
||||
*
|
||||
* Description:
|
||||
* SWI interrupt. We enter the SWI in SVC mode.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_syscall
|
||||
.globl arm_vectorswi
|
||||
.type arm_vectorswi, %function
|
||||
|
||||
arm_vectorswi:
|
||||
|
||||
/* Create a context structure. First set aside a stack frame
|
||||
@@ -201,7 +208,7 @@ arm_vectorswi:
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: arm_vectordata
|
||||
*
|
||||
* Description:
|
||||
@@ -210,10 +217,12 @@ arm_vectorswi:
|
||||
* current processor state and gives control to data abort handler. This function
|
||||
* is entered in ABORT mode with spsr = SVC CPSR, lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_dataabort
|
||||
.globl arm_vectordata
|
||||
.type arm_vectordata, %function
|
||||
|
||||
arm_vectordata:
|
||||
/* On entry we are free to use the ABORT mode registers
|
||||
* r13 and r14
|
||||
@@ -246,7 +255,7 @@ arm_vectordata:
|
||||
/* 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 */
|
||||
ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
@@ -275,7 +284,7 @@ arm_vectordata:
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: arm_vectorprefetch
|
||||
*
|
||||
* Description:
|
||||
@@ -284,10 +293,12 @@ arm_vectordata:
|
||||
* handler saves the current processor state and gives control to prefetch abort
|
||||
* handler. This function is entered in ABT mode with spsr = SVC CPSR, lr = SVC PC.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_prefetchabort
|
||||
.globl arm_vectorprefetch
|
||||
.type arm_vectorprefetch, %function
|
||||
|
||||
arm_vectorprefetch:
|
||||
/* On entry we are free to use the ABORT mode registers
|
||||
* r13 and r14
|
||||
@@ -320,7 +331,7 @@ arm_vectorprefetch:
|
||||
/* 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 */
|
||||
ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
@@ -345,17 +356,19 @@ arm_vectorprefetch:
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: arm_vectorundefinsn
|
||||
*
|
||||
* Description:
|
||||
* Undefined instruction entry exception. Entered in UND mode, spsr = SVC CPSR,
|
||||
* lr = SVC PC
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_undefinedinsn
|
||||
.globl arm_vectorundefinsn
|
||||
.type arm_vectorundefinsn, %function
|
||||
|
||||
arm_vectorundefinsn:
|
||||
/* On entry we are free to use the UND mode registers
|
||||
* r13 and r14
|
||||
@@ -387,7 +400,7 @@ arm_vectorundefinsn:
|
||||
/* 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 */
|
||||
ldmia r0, {r3, r4} /* Recover r3=lr_IRQ, r4=spsr_IRQ */
|
||||
|
||||
add r0, sp, #(4*REG_SP) /* Offset to pc, cpsr storage */
|
||||
stmia r0, {r1-r4}
|
||||
@@ -412,31 +425,34 @@ arm_vectorundefinsn:
|
||||
|
||||
.align 5
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: arm_vectorfiq
|
||||
*
|
||||
* Description:
|
||||
* Shouldn't happen
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_vectorfiq
|
||||
.type arm_vectorfiq, %function
|
||||
|
||||
arm_vectorfiq:
|
||||
subs pc, lr, #4
|
||||
.size arm_vectorfiq, . - arm_vectorfiq
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: g_intstackalloc/g_intstackbase
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.balign 4
|
||||
|
||||
.globl g_intstackalloc
|
||||
.type g_intstackalloc, object
|
||||
.globl g_intstackbase
|
||||
.type g_intstackbase, object
|
||||
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
g_intstackbase:
|
||||
|
||||
@@ -39,14 +39,19 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
.file "arm_vectortab.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl _vector_start
|
||||
.globl _vector_end
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Macros
|
||||
****************************************************************************/
|
||||
@@ -68,11 +73,11 @@ _vector_start:
|
||||
ldr pc, .Lswihandler /* 0x08: Software interrupt */
|
||||
ldr pc, .Lprefetchaborthandler /* 0x0c: Prefetch abort */
|
||||
ldr pc, .Ldataaborthandler /* 0x10: Data abort */
|
||||
ldr pc, .Laddrexcptnhandler /* 0x14: Address exception */
|
||||
ldr pc, .Laddrexcptnhandler /* 0x14: Address exception (reserved) */
|
||||
ldr pc, .Lirqhandler /* 0x18: IRQ */
|
||||
ldr pc, .Lfiqhandler /* 0x1c: FIQ */
|
||||
|
||||
.globl __start
|
||||
.globl __start
|
||||
.globl arm_vectorundefinsn
|
||||
.globl arm_vectorswi
|
||||
.globl arm_vectorprefetch
|
||||
@@ -82,7 +87,7 @@ _vector_start:
|
||||
.globl arm_vectorfiq
|
||||
|
||||
.Lresethandler:
|
||||
.long __start
|
||||
.long __start
|
||||
.Lundefinedhandler:
|
||||
.long arm_vectorundefinsn
|
||||
.Lswihandler:
|
||||
@@ -100,4 +105,5 @@ _vector_start:
|
||||
|
||||
.globl _vector_end
|
||||
_vector_end:
|
||||
.size _vector_start, . - _vector_start
|
||||
.end
|
||||
|
||||
+27
-26
@@ -1,4 +1,4 @@
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* arch/arm/src/arm/vfork.S
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
@@ -31,49 +31,50 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "arm_vfork.h"
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
.file "vfork.S"
|
||||
.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.
|
||||
* 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:
|
||||
* 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 nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
|
||||
* consists of:
|
||||
* 3) nxtask_setup_vfork() 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
|
||||
@@ -90,19 +91,19 @@
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* 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.
|
||||
* 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 */
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
|
||||
|
||||
/* CPU registers */
|
||||
|
||||
@@ -46,8 +46,6 @@
|
||||
#include <arch/irq.h>
|
||||
#include "exc_return.h"
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
@@ -95,7 +93,7 @@ exception_common:
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
mov r0, r14 /* Copy high register to low register */
|
||||
lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
|
||||
bmi 1f /* Test bit 31 */
|
||||
bmi 1f /* Test bit 31 */
|
||||
mrs r1, msp /* R1=The main stack pointer */
|
||||
b 2f
|
||||
|
||||
@@ -115,13 +113,13 @@ exception_common:
|
||||
2:
|
||||
/* Save SP, PRIMASK, and R4-R7 in the context array */
|
||||
|
||||
sub r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */
|
||||
mov r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */
|
||||
sub r1, #SW_XCPT_SIZE /* R1=Beginning of context array on the stack */
|
||||
mov r2, #XCPTCONTEXT_SIZE /* R2=Size of the context array */
|
||||
add r2, r1 /* R2=MSP/PSP before the interrupt was taken */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
mrs r3, primask /* R3=Current PRIMASK setting */
|
||||
mov r0, r1 /* Copy the context array pointer */
|
||||
stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */
|
||||
stmia r0!, {r2-r7} /* Save the SP, PRIMASK, and R4-R7 in the context array */
|
||||
|
||||
/* Save R8-R11 and the EXEC_RETURN value in the context array */
|
||||
|
||||
@@ -131,9 +129,9 @@ exception_common:
|
||||
mov r5, r11
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
mov r6, r14
|
||||
stmia r0!, {r2-r6} /* Save the high registers r8-r11 and r14 */
|
||||
stmia r0!, {r2-r6} /* Save the high registers r8-r11 and r14 */
|
||||
#else
|
||||
stmia r0!, {r2-r5} /* Save the high registers r8-r11 */
|
||||
stmia r0!, {r2-r5} /* Save the high registers r8-r11 */
|
||||
#endif
|
||||
|
||||
/* Get the exception number in R0=IRQ, R1=register save area on stack */
|
||||
@@ -152,9 +150,9 @@ exception_common:
|
||||
*/
|
||||
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
ldr r7, =g_intstackbase /* R7=Base of the interrupt stack */
|
||||
ldr r7, =g_intstackbase /* R7=Base of the interrupt stack */
|
||||
mov sp, r7 /* Set the new stack point */
|
||||
push {r1} /* Save the MSP on the interrupt stack */
|
||||
push {r1} /* Save the MSP on the interrupt stack */
|
||||
bl arm_doirq /* R0=IRQ, R1=register save area on stack */
|
||||
pop {r1} /* Recover R1=main stack pointer */
|
||||
#else
|
||||
@@ -163,13 +161,13 @@ exception_common:
|
||||
mrs r1, msp /* Recover R1=main stack pointer */
|
||||
#endif
|
||||
|
||||
/* On return from arm_doirq, r0 will hold a pointer to register context
|
||||
/* On return from arm_doirq, R0 will hold a pointer to register context
|
||||
* array to use for the interrupt return. If that return value is the same
|
||||
* as current stack pointer, then things are relatively easy.
|
||||
*/
|
||||
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 3f /* Branch if no context switch */
|
||||
beq 3f /* Branch if no context switch */
|
||||
|
||||
/* We are returning with a pending context switch. This case is different
|
||||
* because in this case, the register save structure does not lie on the
|
||||
@@ -180,13 +178,13 @@ exception_common:
|
||||
/* Copy the hardware-saved context to the new stack */
|
||||
|
||||
mov r2, #SW_XCPT_SIZE /* R2=Size of software-saved portion of the context array */
|
||||
add r1, r0, r2 /* R1=Address of HW save area in reg array */
|
||||
ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */
|
||||
add r1, r0, r2 /* R1=Address of HW save area in reg array */
|
||||
ldr r2, [r0, #(4*REG_SP)] /* R2=Value of SP before the interrupt */
|
||||
sub r2, #HW_XCPT_SIZE /* R2=Address of HW save area on the return stack */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
ldmia r1!, {r4-r7} /* Fetch four registers from the HW save area */
|
||||
stmia r2!, {r4-r7} /* Copy four registers to the return stack */
|
||||
|
||||
/* Restore the register contents */
|
||||
|
||||
@@ -199,17 +197,17 @@ exception_common:
|
||||
|
||||
/* Recover R8-R11 and EXEC_RETURN (5 registers) */
|
||||
|
||||
mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */
|
||||
mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */
|
||||
add r0, r1, r2 /* R0=Address of R8 storage */
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
ldmia r0!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/
|
||||
ldmia r0!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/
|
||||
mov r8, r2 /* Move to position in high registers */
|
||||
mov r9, r3
|
||||
mov r10, r4
|
||||
mov r11, r5
|
||||
mov r14, r6 /* EXEC_RETURN */
|
||||
#else
|
||||
ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/
|
||||
ldmia r0!, {r2-r5} /* Recover R8-R11 and R14 (5 registers)*/
|
||||
mov r8, r2 /* Move to position in high registers */
|
||||
mov r9, r3
|
||||
mov r10, r4
|
||||
@@ -220,8 +218,8 @@ exception_common:
|
||||
* the stack pointer as it was on entry to the exception handler.
|
||||
*/
|
||||
|
||||
ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */
|
||||
mov r1, #HW_XCPT_SIZE /* R1=Size of hardware-saved portion of the context array */
|
||||
ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */
|
||||
mov r1, #HW_XCPT_SIZE /* R1=Size of hardware-saved portion of the context array */
|
||||
sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */
|
||||
|
||||
/* Restore the stack pointer. The EXC_RETURN value tells us whether the
|
||||
@@ -231,7 +229,7 @@ exception_common:
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
mov r0, r14 /* Copy high register to low register */
|
||||
lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */
|
||||
bmi 5f /* Test bit 31 */
|
||||
bmi 5f /* Test bit 31 */
|
||||
msr msp, r1 /* R1=The main stack pointer */
|
||||
b 6f
|
||||
|
||||
@@ -241,7 +239,7 @@ exception_common:
|
||||
6:
|
||||
#else
|
||||
msr msp, r1 /* R1=The main stack pointer */
|
||||
ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */
|
||||
ldr r0, =EXC_RETURN_PRIVTHR /* R0=EXC_RETURN to privileged mode */
|
||||
mov r14, r0 /* R14=EXC_RETURN to privileged mode */
|
||||
#endif
|
||||
|
||||
@@ -254,7 +252,7 @@ exception_common:
|
||||
* return to thread mode, and (2) select the correct stack.
|
||||
*/
|
||||
|
||||
bx r14 /* And return */
|
||||
bx r14 /* And return */
|
||||
|
||||
.size exception_common, .-exception_common
|
||||
|
||||
@@ -269,7 +267,7 @@ exception_common:
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
.bss
|
||||
.global g_intstackalloc
|
||||
.global g_intstackbase
|
||||
.global g_intstackbase
|
||||
.balign 4
|
||||
g_intstackalloc:
|
||||
.skip (CONFIG_ARCH_INTERRUPTSTACK & ~3)
|
||||
|
||||
@@ -84,12 +84,12 @@ arm_fullcontextrestore:
|
||||
|
||||
/* Perform the System call with R0=1 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_restore_context /* R0: restore context */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* This call should not return */
|
||||
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
.size arm_fullcontextrestore, .-arm_fullcontextrestore
|
||||
.end
|
||||
|
||||
@@ -71,20 +71,20 @@ arm_saveusercontext:
|
||||
|
||||
/* Perform the System call with R0=0 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_save_context /* R0: save context (also return value) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* There are two return conditions. On the first return, R0 (the
|
||||
* return value will be zero. On the second return we need to
|
||||
* force R0 to be 1.
|
||||
*/
|
||||
|
||||
mov r3, #(4*REG_R0) /* R3=Offset to R0 storage */
|
||||
add r2, r1, r3 /* R2=Address of R0 storage */
|
||||
mov r3, #1 /* R3=Return value of one */
|
||||
str r3, [r2, #0] /* Save return value */
|
||||
bx lr /* "normal" return with r0=0 or
|
||||
* context switch with r0=1 */
|
||||
mov r3, #(4*REG_R0) /* R3=Offset to R0 storage */
|
||||
add r2, r1, r3 /* R2=Address of R0 storage */
|
||||
mov r3, #1 /* R3=Return value of one */
|
||||
str r3, [r2, #0] /* Save return value */
|
||||
bx lr /* "normal" return with r0=0 or
|
||||
* context switch with r0=1 */
|
||||
.size arm_saveusercontext, .-arm_saveusercontext
|
||||
.end
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
.cpu cortex-m0
|
||||
.file "arm_signal_handler.S"
|
||||
.file "arm_signal_handler.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
@@ -65,6 +65,10 @@
|
||||
* This function is the user-space, signal handler trampoline function. It
|
||||
* is called from up_signal_dispatch() in user-mode.
|
||||
*
|
||||
* R0-R3, R11 - volatile registers need not be preserved.
|
||||
* R4-R10 - static registers must be preserved
|
||||
* R12-R14 - LR and SP must be preserved
|
||||
*
|
||||
* Input Parameters:
|
||||
* R0 = sighand
|
||||
* The address user-space signal handling function
|
||||
@@ -87,7 +91,7 @@ up_signal_handler:
|
||||
|
||||
/* Save some register */
|
||||
|
||||
push {r4, r5 /* Save R4 and R5 on the stack */
|
||||
push {r4, r5} /* Save R4 and R5 on the stack */
|
||||
mov r5, lr /* Save LR in R5 */
|
||||
|
||||
/* Call the signal handler */
|
||||
@@ -96,7 +100,7 @@ up_signal_handler:
|
||||
mov r0, r1 /* R0=signo */
|
||||
mov r1, r2 /* R1=info */
|
||||
mov r2, r3 /* R2=ucontext */
|
||||
blx r4 /* Call the signal handler */
|
||||
blx r4 /* Call the signal handler */
|
||||
|
||||
/* Restore the registers */
|
||||
|
||||
|
||||
@@ -72,10 +72,10 @@ arm_switchcontext:
|
||||
|
||||
mov r2, r1 /* R2: restoreregs */
|
||||
mov r1, r0 /* R1: saveregs */
|
||||
mov r0, #SYS_switch_context /* R0: context switch */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
mov r0, #SYS_switch_context /* R0: context switch */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* We will get here only after the rerturn from the context switch */
|
||||
/* We will get here only after the rerturn from the context switch */
|
||||
|
||||
bx lr
|
||||
.size arm_switchcontext, .-arm_switchcontext
|
||||
|
||||
@@ -61,20 +61,21 @@
|
||||
* 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.
|
||||
* 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:
|
||||
* 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 nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
|
||||
* consists of:
|
||||
* 3) nxtask_setup_vfork() 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
|
||||
@@ -91,10 +92,10 @@
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@@ -106,21 +107,21 @@
|
||||
vfork:
|
||||
/* Create a stack frame */
|
||||
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
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 */
|
||||
|
||||
mov r1, sp
|
||||
stmia r1!, {r4-r7} /* Save r4-r7 in the structure */
|
||||
mov r4, r8 /* Copy high registers to low registers */
|
||||
stmia r1!, {r4-r7} /* Save r4-r7 in the structure */
|
||||
mov r4, r8 /* Copy high registers to low registers */
|
||||
mov r5, r9
|
||||
mov r6, r10
|
||||
mov r7, fp
|
||||
stmia r1!, {r4-r7} /* Save r8-r10 and fp in the structure */
|
||||
mov r5, lr /* Copy lr to a low register */
|
||||
stmia r1!, {r0,r5} /* Save sp and lr in the structure */
|
||||
stmia r1!, {r4-r7} /* Save r8-r10 and fp in the structure */
|
||||
mov r5, lr /* Copy lr to a low register */
|
||||
stmia r1!, {r0,r5} /* Save sp and lr in the structure */
|
||||
|
||||
/* Then, call up_vfork(), passing it a pointer to the stack structure */
|
||||
|
||||
@@ -130,7 +131,7 @@ vfork:
|
||||
/* Recover r4-r7 that were destroyed before up_vfork was called */
|
||||
|
||||
mov r1, sp
|
||||
ldmia r1!, {r4-r7}
|
||||
ldmia r1!, {r4-r7}
|
||||
|
||||
/* Release the stack data and return the value returned by up_vfork */
|
||||
|
||||
|
||||
@@ -24,14 +24,11 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "cp15.h"
|
||||
#include "sctlr.h"
|
||||
#include "mmu.h"
|
||||
#include "smp.h"
|
||||
|
||||
#include "chip.h"
|
||||
#include "arm_internal.h"
|
||||
|
||||
@@ -350,7 +347,7 @@ __cpu3_start:
|
||||
/* Then write the configured control register */
|
||||
|
||||
mcr CP15_SCTLR(r0) /* Write control reg */
|
||||
.rept 12 /* Cortex A8 wants lots of NOPs here */
|
||||
.rept 12 /* Cortex A8 wants lots of NOPs here */
|
||||
nop
|
||||
.endr
|
||||
|
||||
@@ -408,11 +405,11 @@ __cpu3_start:
|
||||
mov r0, sp /* R0 = end of IDLE stack */
|
||||
ldmia r3, {r1, r2} /* R1 = Size of stack; R2 = coloration */
|
||||
|
||||
1: /* Top of the loop */
|
||||
1: /* Top of the loop */
|
||||
sub r1, r1, #1 /* R1 = Number of words remaining */
|
||||
cmp r1, #0 /* Check (nwords == 0) */
|
||||
str r2, [r0, #-4]! /* Save stack color word, increment stack address */
|
||||
bne 1b /* Bottom of the loop */
|
||||
str r2, [r0, #-4]! /* Save stack color word, increment stack address */
|
||||
bne 1b /* Bottom of the loop */
|
||||
#endif
|
||||
|
||||
/* Branch to continue C level CPU initialization */
|
||||
@@ -420,7 +417,7 @@ __cpu3_start:
|
||||
mov fp, #0 /* Clear framepointer */
|
||||
mov lr, #0 /* LR = return address (none) */
|
||||
mov r0, r5 /* Input parameter = CPU index */
|
||||
b arm_cpu_boot /* Branch to C level CPU initialization */
|
||||
b arm_cpu_boot /* Branch to C level CPU initialization */
|
||||
.size .Lcpu_vstart, .-.Lcpu_vstart
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
.file "arm_fetchadd.S"
|
||||
.file "arm_fetchadd.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -55,15 +55,15 @@
|
||||
up_fetchadd32:
|
||||
|
||||
1:
|
||||
ldrex r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrex r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r2 will be 1 is strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd32, . - up_fetchadd32
|
||||
|
||||
/****************************************************************************
|
||||
@@ -89,15 +89,15 @@ up_fetchadd32:
|
||||
up_fetchsub32:
|
||||
|
||||
1:
|
||||
ldrex r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrex r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r2 will be 1 is strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub32, . - up_fetchsub32
|
||||
|
||||
/****************************************************************************
|
||||
@@ -123,15 +123,15 @@ up_fetchsub32:
|
||||
up_fetchadd16:
|
||||
|
||||
1:
|
||||
ldrexh r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrexh r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r2 will be 1 is strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd16, . - up_fetchadd16
|
||||
|
||||
/****************************************************************************
|
||||
@@ -157,17 +157,17 @@ up_fetchadd16:
|
||||
up_fetchsub16:
|
||||
|
||||
1:
|
||||
ldrexh r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrexh r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
/* Attempt to save the decremented value */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r2 will be 1 is strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub16, . - up_fetchsub16
|
||||
|
||||
/****************************************************************************
|
||||
@@ -193,15 +193,15 @@ up_fetchsub16:
|
||||
up_fetchadd8:
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrexb r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r2 will be 1 is strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd8, . - up_fetchadd8
|
||||
|
||||
/****************************************************************************
|
||||
@@ -227,14 +227,14 @@ up_fetchadd8:
|
||||
up_fetchsub8:
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrexb r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r2 will be 1 is strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub8, . - up_fetchsub8
|
||||
.end
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
.file "arm_fpuconfig.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@@ -38,6 +37,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_fpuconfig
|
||||
.file "arm_fpuconfig.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Macros
|
||||
@@ -54,7 +54,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_fpuconfig
|
||||
* Name: arm_fpuconfig
|
||||
*
|
||||
* Description:
|
||||
* Configure the FPU. Enables access to CP10 and CP11
|
||||
@@ -77,9 +77,9 @@ arm_fpuconfig:
|
||||
|
||||
/* Set FPEXC.EN (B30) */
|
||||
|
||||
fmrx r0, fpexc
|
||||
fmrx r0, fpexc
|
||||
orr r0, r0, #0x40000000
|
||||
fmxr fpexc, r0
|
||||
fmxr fpexc, r0
|
||||
bx lr
|
||||
.size arm_fpuconfig, . - arm_fpuconfig
|
||||
#endif
|
||||
|
||||
@@ -23,18 +23,24 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include "arm_internal.h"
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "svcall.h"
|
||||
#include "arm.h"
|
||||
|
||||
.file "arm_fullcontextrestore.S"
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_fullcontextrestore
|
||||
.file "arm_fullcontextrestore.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -44,9 +50,9 @@
|
||||
* Name: arm_fullcontextrestore
|
||||
*
|
||||
* Description:
|
||||
* Restore the specified task context. Full prototype is:
|
||||
* Restore the current thread context. Full prototype is:
|
||||
*
|
||||
* void arm_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
|
||||
* void arm_fullcontextrestore(uint32_t *restoreregs) noreturn_function;
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
@@ -55,7 +61,6 @@
|
||||
|
||||
.globl arm_fullcontextrestore
|
||||
.type arm_fullcontextrestore, function
|
||||
|
||||
arm_fullcontextrestore:
|
||||
|
||||
/* On entry, a1 (r0) holds address of the register save area. All other
|
||||
@@ -74,14 +79,14 @@ arm_fullcontextrestore:
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vldmia r1!, {s0-s31} /* Restore the full FP context */
|
||||
vldmia r1!, {s0-s31} /* Restore the full FP context */
|
||||
|
||||
/* Load the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
ldr r2, [r1], #4 /* Fetch the floating point control and status register */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
@@ -93,13 +98,13 @@ arm_fullcontextrestore:
|
||||
|
||||
/* Perform the System call with R0=SYS_context_restore, R1=restoreregs */
|
||||
|
||||
mov r1, r0 /* R1: restoreregs */
|
||||
mov r1, r0 /* R1: restoreregs */
|
||||
mov r0, #SYS_context_restore /* R0: SYS_context_restore syscall */
|
||||
svc #0x900001 /* Perform the system call */
|
||||
svc #0x900001 /* Perform the system call */
|
||||
|
||||
/* This call should not return */
|
||||
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
|
||||
#else
|
||||
/* For a flat build, we can do all of this here... Just think of this as
|
||||
@@ -109,22 +114,22 @@ arm_fullcontextrestore:
|
||||
/* Recover all registers except for r0, r1, r2, R15, and CPSR */
|
||||
|
||||
add r1, r0, #(4*REG_R3) /* Offset to REG_R3 storage */
|
||||
ldmia r1, {r3-r14} /* Recover registers */
|
||||
ldmia r1, {r3-r14} /* Recover registers */
|
||||
|
||||
ldr r2, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
|
||||
ldr r2, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */
|
||||
|
||||
/* Create a stack frame to hold the some registers */
|
||||
|
||||
sub sp, sp, #(4*4) /* Frame for four 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 */
|
||||
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_R2)] /* Fetch the stored r2 value */
|
||||
ldr r1, [r0, #(4*REG_R2)] /* Fetch the stored r2 value */
|
||||
str r1, [sp, #8] /* Save it in the stack */
|
||||
ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */
|
||||
ldr r1, [r0, #(4*REG_PC)] /* Fetch the stored pc value */
|
||||
tst r2, #PSR_T_BIT
|
||||
orrne r1, r1, #1
|
||||
orrne r1, r1, #1
|
||||
str r1, [sp, #12] /* Save it at the bottom of the frame */
|
||||
|
||||
/* Now we can restore the CPSR. We wait until we are completely
|
||||
@@ -134,12 +139,12 @@ arm_fullcontextrestore:
|
||||
* disabled.
|
||||
*/
|
||||
|
||||
msr cpsr, r2 /* Set the CPSR */
|
||||
msr cpsr, r2 /* Set the CPSR */
|
||||
|
||||
/* Now recover r0 r1 r2 and R15 */
|
||||
|
||||
pop {r0-r2, pc}
|
||||
|
||||
#endif
|
||||
|
||||
.size arm_fullcontextrestore, . - arm_fullcontextrestore
|
||||
.size arm_fullcontextrestore, .-arm_fullcontextrestore
|
||||
.end
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "cp15.h"
|
||||
#include "sctlr.h"
|
||||
@@ -54,7 +52,7 @@
|
||||
* 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case
|
||||
* the boot logic must:
|
||||
*
|
||||
* - Configure SDRAM,
|
||||
* - Configure SDRAM (if present),
|
||||
* - Initialize the .data section in RAM, and
|
||||
* - Clear .bss section
|
||||
*/
|
||||
@@ -73,13 +71,13 @@
|
||||
# define CONFIG_IDENTITY_TEXTMAP 1
|
||||
# endif
|
||||
|
||||
/* 2. We boot in FLASH but copy ourselves to DRAM from better performance.
|
||||
/* 2. We boot in FLASH but copy ourselves to SDRAM from better performance.
|
||||
* (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case
|
||||
* the boot logic must:
|
||||
*
|
||||
* - Configure SDRAM,
|
||||
* - Configure SDRAM (if present),
|
||||
* - Copy ourself to DRAM (after mapping it), and
|
||||
* - Clear .bss section
|
||||
* - Clear .bss section (data should be fully initialized)
|
||||
*
|
||||
* In this case, we assume that the logic within this file executes from FLASH.
|
||||
*/
|
||||
@@ -100,11 +98,11 @@
|
||||
# define CONFIG_IDENTITY_TEXTMAP 1
|
||||
# endif
|
||||
|
||||
/* 3. There is bootloader that copies us to DRAM (but probably not to the beginning)
|
||||
/* 3. There is bootloader that copies us to SDRAM (but probably not to the beginning)
|
||||
* (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). In this case SDRAM
|
||||
* was initialized by the boot loader, and this boot logic must:
|
||||
*
|
||||
* - Clear .bss section
|
||||
* - Clear .bss section (data should be fully initialized)
|
||||
*/
|
||||
|
||||
#else
|
||||
@@ -128,12 +126,6 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* RX_NSECTIONS determines the number of 1Mb sections to map for the
|
||||
* Read/eXecute address region. This is based on NUTTX_TEXT_SIZE.
|
||||
*/
|
||||
|
||||
#define WR_NSECTIONS ((NUTTX_RAM_SIZE+0x000fffff) >> 20)
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Macros
|
||||
****************************************************************************/
|
||||
@@ -170,6 +162,11 @@
|
||||
* Name: __start
|
||||
****************************************************************************/
|
||||
|
||||
/* We assume the bootloader has already initialized most of the h/w for
|
||||
* us and that only leaves us having to do some os specific things
|
||||
* below.
|
||||
*/
|
||||
|
||||
.text
|
||||
.global __start
|
||||
.type __start, #function
|
||||
@@ -219,12 +216,12 @@ __start:
|
||||
*/
|
||||
|
||||
adr r0, .LCptinfo /* Address of page table description */
|
||||
ldmia r0, {r1, r2, r3} /* Load the page table description */
|
||||
ldmia r0, {r1, r2, r3} /* Load the page table description */
|
||||
|
||||
/* A single page is sufficient to map the page table */
|
||||
|
||||
orr r0, r1, r3 /* OR MMU flags into physical address */
|
||||
str r0, [r5, r2, lsr #18] /* Map using the virtual address as an index */
|
||||
orr r0, r1, r3 /* OR MMU flags into physical address */
|
||||
str r0, [r5, r2, lsr #18] /* Map using the virtual address as an index */
|
||||
#endif
|
||||
|
||||
/* Load information needed to map the .text region. After the ldmia, we
|
||||
@@ -238,7 +235,7 @@ __start:
|
||||
*/
|
||||
|
||||
adr r0, .LCtextinfo /* Address of text info */
|
||||
ldmia r0, {r1, r2, r3, r4} /* Load the text description */
|
||||
ldmia r0, {r1, r2, r3, r4} /* Load the text description */
|
||||
|
||||
#ifndef CONFIG_IDENTITY_TEXTMAP
|
||||
/* Create identity mapping for first MB of the .text section to support
|
||||
@@ -248,8 +245,8 @@ __start:
|
||||
* the identity mapping.
|
||||
*/
|
||||
|
||||
orr r0, r1, r3 /* OR MMU flags into physical address */
|
||||
str r0, [r5, r1, lsr #18] /* Identity mapping */
|
||||
orr r0, r1, r3 /* OR MMU flags into physical address */
|
||||
str r0, [r5, r1, lsr #18] /* Identity mapping */
|
||||
#endif
|
||||
|
||||
/* Map the entire .text region. We do this before enabling caches so
|
||||
@@ -269,10 +266,10 @@ __start:
|
||||
*/
|
||||
|
||||
.Lpgtextloop:
|
||||
orr r0, r1, r3 /* R0: OR MMU flags into physical address */
|
||||
subs r4, r4, #1 /* R4: Decrement the section count */
|
||||
orr r0, r1, r3 /* R0: OR MMU flags into physical address */
|
||||
subs r4, r4, #1 /* R4: Decrement the section count */
|
||||
str r0, [r2], #4 /* Save page table entry, increment page table address */
|
||||
add r1, r1, #(1024*1024) /* R1: Increment the physical address */
|
||||
add r1, r1, #(1024*1024) /* R1: Increment the physical address */
|
||||
bne .Lpgtextloop /* Loop while R4 is non-zero */
|
||||
|
||||
#if defined(CONFIG_BOOT_RUNFROMFLASH) && !defined(CONFIG_BOOT_SDRAM_DATA)
|
||||
@@ -293,7 +290,7 @@ __start:
|
||||
*/
|
||||
|
||||
adr r0, .LCraminfo /* Address of primary RAM info */
|
||||
ldmia r0, {r1, r2, r3, r4} /* Load the primary RAM description */
|
||||
ldmia r0, {r1, r2, r3, r4} /* Load the primary RAM description */
|
||||
add r2, r5, r2, lsr #18 /* R2=Offset page table address */
|
||||
|
||||
/* Loop until each page table entry has been written for the primary RAM
|
||||
@@ -301,11 +298,11 @@ __start:
|
||||
*/
|
||||
|
||||
.Lpgramloop:
|
||||
orr r0, r1, r3 /* R0: OR MMU flags into physical address */
|
||||
subs r4, r4, #1 /* R4: Decrement the section count */
|
||||
orr r0, r1, r3 /* R0: OR MMU flags into physical address */
|
||||
subs r4, r4, #1 /* R4: Decrement the section count */
|
||||
str r0, [r2], #4 /* Save page table entry, increment page table address */
|
||||
add r1, r1, #(1024*1024) /* R1: Increment the physical address */
|
||||
bne .Lpgramloop /* Loop while R4 is non-zero */
|
||||
add r1, r1, #(1024*1024) /* R1: Increment the physical address */
|
||||
bne .Lpgramloop /* Loop while R4 is non-zero */
|
||||
|
||||
#endif /* CONFIG_BOOT_RUNFROMFLASH && !CONFIG_BOOT_SDRAM_DATA */
|
||||
#endif /* CONFIG_ARCH_ROMPGTABLE */
|
||||
@@ -492,7 +489,7 @@ __start:
|
||||
/* Then write the configured control register */
|
||||
|
||||
mcr CP15_SCTLR(r0) /* Write control reg */
|
||||
.rept 12 /* Cortex A8 wants lots of NOPs here */
|
||||
.rept 12 /* Cortex A8 wants lots of NOPs here */
|
||||
nop
|
||||
.endr
|
||||
|
||||
@@ -508,7 +505,7 @@ __start:
|
||||
|
||||
.type .LCppgtable, %object
|
||||
.LCppgtable:
|
||||
.long PGTABLE_BASE_PADDR /* Physical start of page table */
|
||||
.long PGTABLE_BASE_PADDR /* Physical start of page table */
|
||||
.size .LCppgtable, . -.LCppgtable
|
||||
|
||||
#ifdef ARMV7A_PGTABLE_MAPPING
|
||||
@@ -524,7 +521,7 @@ __start:
|
||||
.LCptinfo:
|
||||
.long (PGTABLE_BASE_PADDR & 0xfff00000) /* Physical base address */
|
||||
.long (PGTABLE_BASE_VADDR & 0xfff00000) /* Virtual base address */
|
||||
.long MMU_MEMFLAGS /* MMU flags for text section in RAM */
|
||||
.long MMU_MEMFLAGS /* MMU flags for text section in RAM */
|
||||
.size .LCptinfo, . -.LCptinfo
|
||||
#endif
|
||||
|
||||
@@ -552,7 +549,7 @@ __start:
|
||||
#else
|
||||
.long MMU_MEMFLAGS /* MMU flags for text section in RAM */
|
||||
#endif
|
||||
.long (NUTTX_TEXT_SIZE >> 20) /* Number of 1MB read-execute sections */
|
||||
.long (NUTTX_TEXT_SIZE >> 20) /* Number of 1MB read-execute sections */
|
||||
.size .LCtextinfo, . -.LCtextinfo
|
||||
|
||||
#ifdef CONFIG_BOOT_RUNFROMFLASH
|
||||
@@ -573,7 +570,7 @@ __start:
|
||||
.long NUTTX_RAM_PADDR /* Physical base address */
|
||||
.long NUTTX_RAM_VADDR /* Virtual base address */
|
||||
.long MMU_MEMFLAGS /* MMU flags for primary RAM section */
|
||||
.long (NUTTX_RAM_SIZE >> 20) /* Number of 1MB read-execute sections */
|
||||
.long (NUTTX_RAM_SIZE >> 20) /* Number of 1MB read-execute sections */
|
||||
.size .LCraminfo, . -.LCraminfo
|
||||
|
||||
#endif /* CONFIG_BOOT_RUNFROMFLASH */
|
||||
@@ -609,14 +606,14 @@ __start:
|
||||
|
||||
ldr r5, .LCvpgtable /* r5=Virtual page table base address */
|
||||
ldr r3, .LCptextbase /* r0=Physical base address of .text section */
|
||||
mov r0, #0 /* flags + base = 0 */
|
||||
str r3, [r5, r3, lsr #18] /* identity mapping */
|
||||
mov r0, #0 /* flags + base = 0 */
|
||||
str r3, [r5, r3, lsr #18] /* identity mapping */
|
||||
#endif /* !CONFIG_ARCH_ROMPGTABLE && !CONFIG_IDENTITY_TEXTMAP */
|
||||
|
||||
/* Set up the stack pointer and clear the frame pointer */
|
||||
|
||||
ldr sp, .Lstackpointer
|
||||
bic sp, sp, #7 /* Get the stack pointer with 8-byte alignment */
|
||||
bic sp, sp, #7 /* Get the stack pointer with 8-byte alignment */
|
||||
mov fp, #0
|
||||
|
||||
#ifndef CONFIG_BOOT_SDRAM_DATA
|
||||
@@ -641,13 +638,13 @@ __start:
|
||||
*/
|
||||
|
||||
adr r3, .Lstkinit
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
|
||||
1: /* Top of the loop */
|
||||
1: /* Top of the loop */
|
||||
sub r1, r1, #1 /* R1 = Number of words remaining */
|
||||
cmp r1, #0 /* Check (nwords == 0) */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 1b /* Bottom of the loop */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 1b /* Bottom of the loop */
|
||||
#endif
|
||||
|
||||
/* Finally branch to the OS entry point */
|
||||
@@ -669,12 +666,12 @@ arm_data_initialize:
|
||||
/* Zero BSS */
|
||||
|
||||
adr r0, .Linitparms
|
||||
ldmia r0, {r0, r1}
|
||||
ldmia r0, {r0, r1}
|
||||
|
||||
mov r2, #0
|
||||
mov r2, #0
|
||||
1:
|
||||
cmp r0, r1 /* Clear up to _bss_end_ */
|
||||
strcc r2, [r0], #4
|
||||
strcc r2, [r0], #4
|
||||
bcc 1b
|
||||
|
||||
#ifdef CONFIG_BOOT_RUNFROMFLASH
|
||||
@@ -688,7 +685,7 @@ arm_data_initialize:
|
||||
*/
|
||||
|
||||
adr r3, .Ldatainit
|
||||
ldmia r3, {r0, r1, r2}
|
||||
ldmia r3, {r0, r1, r2}
|
||||
|
||||
2:
|
||||
ldr r3, [r0], #4
|
||||
@@ -708,9 +705,10 @@ arm_data_initialize:
|
||||
|
||||
/* Text-section constants:
|
||||
*
|
||||
* _sbss is the start of the BSS region (see ld.script)
|
||||
* _ebss is the end of the BSS region (see ld.script)
|
||||
* _sbss is the start of the BSS region (see linker script)
|
||||
* _ebss is the end of the BSS region (see linker script)
|
||||
*
|
||||
* Typical Configuration:
|
||||
* The idle task stack usually starts at the end of BSS and is of size
|
||||
* CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the
|
||||
* end of memory. See g_idle_topstack below.
|
||||
@@ -725,7 +723,7 @@ arm_data_initialize:
|
||||
|
||||
.type .LCvpgtable, %object
|
||||
.LCvpgtable:
|
||||
.long PGTABLE_BASE_VADDR /* Virtual start of page table */
|
||||
.long PGTABLE_BASE_VADDR /* Virtual start of page table */
|
||||
.size .LCvpgtable, . -.LCvpgtable
|
||||
|
||||
#endif /* CONFIG_ARCH_ROMPGTABLE */
|
||||
@@ -759,7 +757,7 @@ arm_data_initialize:
|
||||
.type .Lstkinit, %object
|
||||
.Lstkinit:
|
||||
#ifdef CONFIG_BOOT_SDRAM_DATA
|
||||
.long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */
|
||||
.long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */
|
||||
#elif defined(CONFIG_SMP)
|
||||
.long _enoinit
|
||||
#else
|
||||
@@ -775,7 +773,7 @@ arm_data_initialize:
|
||||
***************************************************************************/
|
||||
|
||||
/* This global variable is unsigned long g_idle_topstack and is
|
||||
* exported from here only because of its coupling to .Linitparms
|
||||
* exported from here only because of its coupling to .Lstackpointer
|
||||
* above.
|
||||
*/
|
||||
|
||||
|
||||
@@ -25,13 +25,10 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/page.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "arm.h"
|
||||
#include "cp15.h"
|
||||
#include "sctlr.h"
|
||||
#include "mmu.h"
|
||||
|
||||
#include "chip.h"
|
||||
#include "arm_internal.h"
|
||||
|
||||
@@ -61,7 +58,7 @@
|
||||
* 1. We execute in place in FLASH (CONFIG_BOOT_RUNFROMFLASH=y). In this case
|
||||
* the boot logic must:
|
||||
*
|
||||
* - Configure SDRAM,
|
||||
* - Configure SDRAM (if present),
|
||||
* - Initialize the .data section in RAM, and
|
||||
* - Clear .bss section
|
||||
*/
|
||||
@@ -80,13 +77,13 @@
|
||||
# define CONFIG_IDENTITY_TEXTMAP 1
|
||||
# endif
|
||||
|
||||
/* 2. We boot in FLASH but copy ourselves to DRAM from better performance.
|
||||
/* 2. We boot in FLASH but copy ourselves to SDRAM from better performance.
|
||||
* (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=y). In this case
|
||||
* the boot logic must:
|
||||
*
|
||||
* - Configure SDRAM,
|
||||
* - Configure SDRAM (if present),
|
||||
* - Copy ourself to DRAM (after mapping it), and
|
||||
* - Clear .bss section
|
||||
* - Clear .bss section (data should be fully initialized)
|
||||
*
|
||||
* In this case, we assume that the logic within this file executes from FLASH.
|
||||
*/
|
||||
@@ -107,11 +104,11 @@
|
||||
# define CONFIG_IDENTITY_TEXTMAP 1
|
||||
# endif
|
||||
|
||||
/* 3. There is bootloader that copies us to DRAM (but probably not to the beginning)
|
||||
/* 3. There is bootloader that copies us to SDRAM (but probably not to the beginning)
|
||||
* (CONFIG_BOOT_RUNFROMFLASH=n && CONFIG_BOOT_COPYTORAM=n). In this case SDRAM
|
||||
* was initialized by the boot loader, and this boot logic must:
|
||||
*
|
||||
* - Clear .bss section
|
||||
* - Clear .bss section (data should be fully initialized)
|
||||
*/
|
||||
|
||||
#else
|
||||
@@ -152,11 +149,10 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* RX_NSECTIONS determines the number of 1Mb sections to map for the
|
||||
* Read/eXecute address region. This is based on NUTTX_TEXT_SIZE.
|
||||
/* WR_NSECTIONS determines the number of 1Mb sections to map for the
|
||||
* Write/Read/eXecute address region. This is based on NUTTX_TEXT_SIZE.
|
||||
*/
|
||||
|
||||
#define RX_NSECTIONS ((NUTTX_TEXT_SIZE+0x000fffff) >> 20)
|
||||
#define WR_NSECTIONS ((NUTTX_RAM_SIZE+0x000fffff) >> 20)
|
||||
|
||||
/****************************************************************************
|
||||
@@ -195,6 +191,11 @@
|
||||
* Name: __start
|
||||
****************************************************************************/
|
||||
|
||||
/* We assume the bootloader has already initialized most of the h/w for
|
||||
* us and that only leaves us having to do some os specific things
|
||||
* below.
|
||||
*/
|
||||
|
||||
.text
|
||||
.global __start
|
||||
.type __start, #function
|
||||
@@ -236,12 +237,12 @@ __start:
|
||||
*/
|
||||
|
||||
adr r0, .LCptinfo /* Address of page table description */
|
||||
ldmia r0, {r1, r2, r3} /* Load the page table description */
|
||||
ldmia r0, {r1, r2, r3} /* Load the page table description */
|
||||
|
||||
/* A single page is sufficient to map the page table */
|
||||
|
||||
orr r0, r1, r3 /* OR MMU flags into physical address */
|
||||
str r0, [r5, r2, lsr #18] /* Map using the virtual address as an index */
|
||||
orr r0, r1, r3 /* OR MMU flags into physical address */
|
||||
str r0, [r5, r2, lsr #18] /* Map using the virtual address as an index */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_IDENTITY_TEXTMAP
|
||||
@@ -254,8 +255,8 @@ __start:
|
||||
|
||||
ldr r0, .LCptextbase /* r0=phys. base address of .text section */
|
||||
ldr r1, .LCtextflags /* R1=.text section MMU flags */
|
||||
orr r3, r1, r0 /* r3=flags + base */
|
||||
str r3, [r4, r0, lsr #18] /* identity mapping */
|
||||
orr r3, r1, r0 /* r3=flags + base */
|
||||
str r3, [r4, r0, lsr #18] /* identity mapping */
|
||||
#endif
|
||||
|
||||
/* Map the read-only .text region in place. This must be done
|
||||
@@ -272,28 +273,28 @@ __start:
|
||||
*/
|
||||
|
||||
adr r0, .Ltxtspan
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
|
||||
/* Then populate the L2 table for the locked text region only. */
|
||||
|
||||
adr r0, .Ltxtmap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
|
||||
/* Make sure that the page table is itself mapped and and read/write-able.
|
||||
* First, populate the L1 table:
|
||||
*/
|
||||
|
||||
adr r0, .Lptabspan
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
ldmia r0, {r0, r1, r2, r3, r5}
|
||||
pg_l1span r0, r1, r2, r3, r5, r6
|
||||
|
||||
/* Then populate the L2 table. */
|
||||
|
||||
adr r0, .Lptabmap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r5
|
||||
|
||||
/* The following logic will set up the ARMv7-A for normal operation.
|
||||
*
|
||||
@@ -423,7 +424,7 @@ __start:
|
||||
|
||||
/* In SMP configurations, the data cache will not be enabled until later
|
||||
* after SMP cache coherency has been setup.
|
||||
*/
|
||||
*/
|
||||
|
||||
#if !defined(CPU_DCACHE_DISABLE) && !defined(CONFIG_SMP)
|
||||
/* Dcache enable
|
||||
@@ -467,7 +468,7 @@ __start:
|
||||
/* Then write the configured control register */
|
||||
|
||||
mcr CP15_SCTLR(r0) /* Write control reg */
|
||||
.rept 12 /* Cortex A8 wants lots of NOPs here */
|
||||
.rept 12 /* Cortex A8 wants lots of NOPs here */
|
||||
nop
|
||||
.endr
|
||||
|
||||
@@ -499,7 +500,7 @@ __start:
|
||||
.LCptinfo:
|
||||
.long (PGTABLE_BASE_PADDR & 0xfff00000) /* Physical base address */
|
||||
.long (PGTABLE_BASE_VADDR & 0xfff00000) /* Virtual base address */
|
||||
.long MMU_MEMFLAGS /* MMU flags for text section in RAM */
|
||||
.long MMU_MEMFLAGS /* MMU flags for text section in RAM */
|
||||
.size .LCptinfo, . -.LCptinfo
|
||||
#endif
|
||||
|
||||
@@ -555,7 +556,7 @@ __start:
|
||||
.Ltxtmap:
|
||||
.long PG_L2_LOCKED_PADDR /* Physical address in the L2 table */
|
||||
.long PG_LOCKED_PBASE /* Physical address of locked base memory */
|
||||
.long CONFIG_PAGING_NLOCKED /* Number of pages in the locked region */
|
||||
.long CONFIG_PAGING_NLOCKED /* Number of pages in the locked region */
|
||||
.long MMU_L2_TEXTFLAGS /* L2 MMU flags to use */
|
||||
.size .Ltxtmap, . -.Ltxtmap
|
||||
|
||||
@@ -564,7 +565,7 @@ __start:
|
||||
.long PG_L1_PGTABLE_PADDR /* Physical address in the L1 table */
|
||||
.long PG_L2_PGTABLE_PBASE /* Physical address of the start of the L2 page table */
|
||||
.long PG_PGTABLE_NPAGES /* Total mapped page table pages */
|
||||
.long PG_L2_PGTABLE_NPAGE1 /* The number of text pages in the first page table */
|
||||
.long PG_L2_PGTABLE_NPAGE1 /* The number of text pages in the first page table */
|
||||
.long MMU_L1_PGTABFLAGS /* L1 MMU flags to use */
|
||||
.size .Lptabspan, . -.Lptabspan
|
||||
|
||||
@@ -599,28 +600,28 @@ __start:
|
||||
|
||||
ldr r4, .LCvpgtable /* r4=virtual page table base address */
|
||||
ldr r3, .LCvtextbase /* r0=virtual base address of .text section */
|
||||
mov r0, #0 /* flags + base = 0 */
|
||||
str r3, [r4, r3, lsr #18] /* identity mapping */
|
||||
mov r0, #0 /* flags + base = 0 */
|
||||
str r3, [r4, r3, lsr #18] /* identity mapping */
|
||||
#endif
|
||||
|
||||
/* Populate the L1 table for the data region */
|
||||
|
||||
adr r0, .Ldataspan
|
||||
ldmia r0, {r0, r1, r2, r3, r4}
|
||||
pg_l1span r0, r1, r2, r3, r4, r5
|
||||
ldmia r0, {r0, r1, r2, r3, r4}
|
||||
pg_l1span r0, r1, r2, r3, r4, r5
|
||||
|
||||
/* Populate the L2 table for the data region */
|
||||
|
||||
adr r0, .Ldatamap
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r4
|
||||
ldmia r0, {r0, r1, r2, r3}
|
||||
pg_l2map r0, r1, r2, r3, r4
|
||||
|
||||
#ifdef CONFIG_BOOT_RUNFROMFLASH
|
||||
/* Get R3 = Value of RAM L1 page table entry */
|
||||
|
||||
ldr r3, .LCprambase /* r3=Aligned NuttX RAM address (physical) */
|
||||
ldr r1, .LCramflags /* R1=.bss/.data section MMU flags */
|
||||
add r3, r3, r1 /* r3=flags + base */
|
||||
add r3, r3, r1 /* r3=flags + base */
|
||||
|
||||
/* Now setup the page tables for our normal mapped RAM region.
|
||||
* We round NUTTX_RAM_VADDR down to the nearest megabyte boundary.
|
||||
@@ -633,7 +634,7 @@ __start:
|
||||
* region.
|
||||
*/
|
||||
|
||||
.rept WR_NSECTIONS-1
|
||||
.rept WR_NSECTIONS-1
|
||||
add r3, r3, #SECTION_SIZE
|
||||
str r3, [r0], #4
|
||||
.endr
|
||||
@@ -648,7 +649,7 @@ __start:
|
||||
/* Set up the stack pointer and clear the frame pointer */
|
||||
|
||||
ldr sp, .Lstackpointer
|
||||
bic sp, sp, #7 /* Get the stack pointer with 8-byte alignment */
|
||||
bic sp, sp, #7 /* Get the stack pointer with 8-byte alignment */
|
||||
mov fp, #0
|
||||
|
||||
#ifndef CONFIG_BOOT_SDRAM_DATA
|
||||
@@ -673,13 +674,13 @@ __start:
|
||||
*/
|
||||
|
||||
adr r3, .Lstkinit
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
ldmia r3, {r0, r1, r2} /* R0 = start of IDLE stack; R1 = Size of tack; R2 = coloration */
|
||||
|
||||
1: /* Top of the loop */
|
||||
1: /* Top of the loop */
|
||||
sub r1, r1, #1 /* R1 = Number of words remaining */
|
||||
cmp r1, #0 /* Check (nwords == 0) */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 1b /* Bottom of the loop */
|
||||
str r2, [r0], #4 /* Save stack color word, increment stack address */
|
||||
bne 1b /* Bottom of the loop */
|
||||
#endif
|
||||
|
||||
/* Finally branch to the OS entry point */
|
||||
@@ -701,12 +702,12 @@ arm_data_initialize:
|
||||
/* Zero BSS */
|
||||
|
||||
adr r0, .Linitparms
|
||||
ldmia r0, {r0, r1}
|
||||
ldmia r0, {r0, r1}
|
||||
|
||||
mov r2, #0
|
||||
mov r2, #0
|
||||
1:
|
||||
cmp r0, r1 /* Clear up to _bss_end_ */
|
||||
strcc r2, [r0],#4
|
||||
strcc r2, [r0], #4
|
||||
bcc 1b
|
||||
|
||||
#ifdef CONFIG_BOOT_RUNFROMFLASH
|
||||
@@ -720,7 +721,7 @@ arm_data_initialize:
|
||||
*/
|
||||
|
||||
adr r3, .Ldatainit
|
||||
ldmia r3, {r0, r1, r2}
|
||||
ldmia r3, {r0, r1, r2}
|
||||
|
||||
2:
|
||||
ldr r3, [r0], #4
|
||||
@@ -740,9 +741,10 @@ arm_data_initialize:
|
||||
|
||||
/* Text-section constants:
|
||||
*
|
||||
* _sbss is the start of the BSS region (see ld.script)
|
||||
* _ebss is the end of the BSS region (see ld.script)
|
||||
* _sbss is the start of the BSS region (see linker script)
|
||||
* _ebss is the end of the BSS region (see linker script)
|
||||
*
|
||||
* Typical Configuration:
|
||||
* The idle task stack usually starts at the end of BSS and is of size
|
||||
* CONFIG_IDLETHREAD_STACKSIZE. The heap continues from there until the
|
||||
* end of memory. See g_idle_topstack below.
|
||||
@@ -794,7 +796,7 @@ arm_data_initialize:
|
||||
.type .Lstkinit, %object
|
||||
.Lstkinit:
|
||||
#ifdef CONFIG_BOOT_SDRAM_DATA
|
||||
.long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */
|
||||
.long IDLE_STACK_VBASE /* Beginning of the IDLE stack, then words of IDLE stack */
|
||||
#else
|
||||
.long _ebss /* Beginning of the IDLE stack, then words of IDLE stack */
|
||||
#endif
|
||||
@@ -808,7 +810,7 @@ arm_data_initialize:
|
||||
***************************************************************************/
|
||||
|
||||
/* This global variable is unsigned long g_idle_topstack and is
|
||||
* exported from here only because of its coupling to .Linitparms
|
||||
* exported from here only because of its coupling to .Lstackpointer
|
||||
* above.
|
||||
*/
|
||||
|
||||
@@ -825,5 +827,5 @@ g_idle_topstack:
|
||||
.long _ebss+CONFIG_IDLETHREAD_STACKSIZE
|
||||
#endif
|
||||
.size g_idle_topstack, .-g_idle_topstack
|
||||
#endif
|
||||
.end
|
||||
#endif
|
||||
|
||||
@@ -28,13 +28,12 @@
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
|
||||
.file "arm_restorefpu.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_restorefpu
|
||||
.globl arm_restorefpu
|
||||
.file "arm_restorefpu.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -73,14 +72,14 @@ arm_restorefpu:
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vldmia r1!, {s0-s31} /* Restore the full FP context */
|
||||
vldmia r1!, {s0-s31} /* Restore the full FP context */
|
||||
|
||||
/* Load the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
ldr r2, [r1], #4 /* Fetch the floating point control and status register */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
bx lr
|
||||
|
||||
.size arm_restorefpu, .-arm_restorefpu
|
||||
|
||||
@@ -76,13 +76,13 @@ arm_savefpu:
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vstmia r1!, {s0-s31} /* Save the full FP context */
|
||||
vstmia r1!, {s0-s31} /* Save the full FP context */
|
||||
|
||||
/* Store the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
vmrs r2, fpscr /* Fetch the FPCSR */
|
||||
vmrs r2, fpscr /* Fetch the FPCSR */
|
||||
str r2, [r1], #4 /* Save the floating point control and status register */
|
||||
bx lr
|
||||
|
||||
|
||||
@@ -22,30 +22,43 @@
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include "arm_internal.h"
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
.file "arm_saveusercontext.S"
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_saveusercontext
|
||||
.file "arm_saveusercontext.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/****************************************************************************
|
||||
* Name: arm_saveusercontext
|
||||
*
|
||||
* Description:
|
||||
* Save the current thread context. Full prototype is:
|
||||
*
|
||||
* int arm_saveusercontext(uint32_t *saveregs);
|
||||
*
|
||||
* Returned Value:
|
||||
* 0: Normal return
|
||||
* 1: Context switch return
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl arm_saveusercontext
|
||||
.type arm_saveusercontext, function
|
||||
|
||||
arm_saveusercontext:
|
||||
|
||||
/* On entry, a1 (r0) holds address of struct xcptcontext */
|
||||
@@ -64,15 +77,17 @@ arm_saveusercontext:
|
||||
*/
|
||||
|
||||
add r1, r0, #(4*REG_R4)
|
||||
stmia r1, {r4-r14}
|
||||
stmia r1, {r4-r14}
|
||||
|
||||
/* Save the current cpsr */
|
||||
|
||||
mrs r2, cpsr /* R3 = CPSR value */
|
||||
mrs r2, cpsr /* R2 = CPSR value */
|
||||
add r1, r0, #(4*REG_CPSR)
|
||||
str r2, [r1]
|
||||
|
||||
/* Save the return address */
|
||||
/* Save the return address as the PC so that we return to the exit from
|
||||
* this function.
|
||||
*/
|
||||
|
||||
ldr r2, =1f
|
||||
add r1, r0, #(4*REG_PC)
|
||||
@@ -86,20 +101,20 @@ arm_saveusercontext:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
|
||||
add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
|
||||
|
||||
/* Store all floating point registers. Registers are stored in numeric order,
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vstmia r1!, {s0-s31} /* Save the full FP context */
|
||||
vstmia r1!, {s0-s31} /* Save the full FP context */
|
||||
|
||||
/* Store the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
vmrs r2, fpscr /* Fetch the FPCSR */
|
||||
str r2, [r1], #4 /* Save the floating point control and status register */
|
||||
vmrs r2, fpscr /* Fetch the FPCSR */
|
||||
str r2, [r1], #4 /* Save the floating point control and status register */
|
||||
#endif
|
||||
|
||||
/* Return 0 now indicating that this return is not a context switch */
|
||||
@@ -114,5 +129,5 @@ arm_saveusercontext:
|
||||
mov r0, #1 /* Return value == 1 */
|
||||
mov pc, lr /* Return */
|
||||
|
||||
.size arm_saveusercontext, . - arm_saveusercontext
|
||||
.size arm_saveusercontext, .-arm_saveusercontext
|
||||
.end
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
* This function must be provided via the architecture-specific logic.
|
||||
*
|
||||
* Input Parameters:
|
||||
* lock - The address of spinlock object (r0).
|
||||
* lock - The address of spinlock object.
|
||||
*
|
||||
* Returned Value:
|
||||
* The spinlock is always locked upon return. The value of previous value
|
||||
@@ -69,8 +69,6 @@
|
||||
* obtain the lock) or SP_UNLOCKED if the spinlock was previously unlocked
|
||||
* (meaning that we successfully obtained the lock)
|
||||
*
|
||||
* Modifies: r1, r2, and lr
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.globl up_testset
|
||||
@@ -83,19 +81,19 @@ up_testset:
|
||||
/* Test if the spinlock is locked or not */
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Test if spinlock is locked or not */
|
||||
ldrexb r2, [r0] /* Test if spinlock is locked or not */
|
||||
cmp r2, r1 /* Already locked? */
|
||||
beq 2f /* If already locked, return SP_LOCKED */
|
||||
beq 2f /* If already locked, return SP_LOCKED */
|
||||
|
||||
/* Not locked ... attempt to lock it */
|
||||
|
||||
strexb r2, r1, [r0] /* Attempt to set the locked state */
|
||||
strexb r2, r1, [r0] /* Attempt to set the locked state */
|
||||
cmp r2, r1 /* r2 will be 1 is strexb failed */
|
||||
beq 1b /* Failed to lock... try again */
|
||||
beq 1b /* Failed to lock... try again */
|
||||
|
||||
/* Lock acquired -- return SP_UNLOCKED */
|
||||
|
||||
dmb /* Required before accessing protected resource */
|
||||
dmb /* Required before accessing protected resource */
|
||||
mov r0, #SP_UNLOCKED
|
||||
bx lr
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include "arm_arch.h"
|
||||
|
||||
.file "arm_vectoraddrexcptn.S"
|
||||
|
||||
@@ -59,8 +58,8 @@
|
||||
*
|
||||
* 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 Address Exception vector.
|
||||
* other vector handlers because some processors do not support the
|
||||
* Address Exception vector.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
+184
-180
File diff suppressed because it is too large
Load Diff
@@ -54,16 +54,16 @@
|
||||
/* These will be relocated to VECTOR_BASE. */
|
||||
|
||||
_vector_start:
|
||||
ldr pc, .Lresethandler /* 0x00: Reset */
|
||||
ldr pc, .Lresethandler /* 0x00: Reset */
|
||||
ldr pc, .Lundefinedhandler /* 0x04: Undefined instruction */
|
||||
ldr pc, .Lsvchandler /* 0x08: Software interrupt */
|
||||
ldr pc, .Lsvchandler /* 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, .Lirqhandler /* 0x18: IRQ */
|
||||
ldr pc, .Lfiqhandler /* 0x1c: FIQ */
|
||||
|
||||
.globl __start
|
||||
.globl __start
|
||||
.globl arm_vectorundefinsn
|
||||
.globl arm_vectorsvc
|
||||
.globl arm_vectorprefetch
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
*
|
||||
* 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
|
||||
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
|
||||
* Copyright (c) 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
|
||||
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
|
||||
* Copyright (c) 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
|
||||
* DDI 0406C.b (ID072512)
|
||||
*
|
||||
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
|
||||
@@ -92,21 +92,21 @@
|
||||
|
||||
cp15_clean_dcache:
|
||||
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
and r3, r3, #0xf
|
||||
mov r2, #4
|
||||
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
|
||||
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r0, r0, r3 /* R0=aligned start address */
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r0, r0, r3 /* R0=aligned start address */
|
||||
|
||||
/* Loop, cleaning each cache line by writing its contents to memory */
|
||||
|
||||
1:
|
||||
mcr CP15_DCCMVAC(r0) /* Clean data cache line to PoC by VA */
|
||||
add r0, r0, r2 /* R12=Next cache line */
|
||||
cmp r0, r1 /* Loop until all cache lines have been cleaned */
|
||||
add r0, r0, r2 /* R12=Next cache line */
|
||||
cmp r0, r1 /* Loop until all cache lines have been cleaned */
|
||||
blo 1b
|
||||
|
||||
dsb
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
*
|
||||
* 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
|
||||
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
|
||||
* Copyright (c) 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
|
||||
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
|
||||
* Copyright (c) 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
|
||||
* DDI 0406C.b (ID072512)
|
||||
*
|
||||
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
|
||||
@@ -93,37 +93,37 @@
|
||||
.type cp15_coherent_dcache, function
|
||||
|
||||
cp15_coherent_dcache:
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
and r3, r3, #0xf
|
||||
mov r2, #4
|
||||
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
|
||||
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r12, r0, r3 /* R12=aligned start address */
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r12, r0, r3 /* R12=aligned start address */
|
||||
|
||||
/* Loop, flushing each D cache line to memory */
|
||||
1:
|
||||
mcr CP15_DCCMVAU(r12) /* Clean data or unified cache line by VA to PoU */
|
||||
add r12, r12, r2 /* R12=Next cache line */
|
||||
cmp r12, r1 /* Loop until all cache lines have been cleaned */
|
||||
cmp r12, r1 /* Loop until all cache lines have been cleaned */
|
||||
blo 1b
|
||||
|
||||
dsb
|
||||
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
and r3, r3, #0xf /* Isolate the IminLine field */
|
||||
mov r2, #4
|
||||
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
|
||||
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r12, r0, r3 /* R12=aligned start address */
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r12, r0, r3 /* R12=aligned start address */
|
||||
|
||||
/* Loop, invalidating each I cache line to memory */
|
||||
1:
|
||||
mcr CP15_ICIMVAU(r12) /* Invalidate instruction cache by VA to PoU */
|
||||
add r12, r12, r2 /* R12=Next cache line */
|
||||
cmp r12, r1 /* Loop until all cache lines have been invalidated */
|
||||
cmp r12, r1 /* Loop until all cache lines have been invalidated */
|
||||
blo 1b
|
||||
|
||||
mov r0, #0
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
*
|
||||
* 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
|
||||
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
|
||||
* Copyright (c) 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
|
||||
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
|
||||
* Copyright (c) 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
|
||||
* DDI 0406C.b (ID072512)
|
||||
*
|
||||
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
|
||||
@@ -93,20 +93,20 @@
|
||||
cp15_flush_dcache:
|
||||
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
and r3, r3, #0xf
|
||||
mov r2, #4
|
||||
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
|
||||
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r0, r0, r3 /* R0=aligned start address */
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
bic r0, r0, r3 /* R0=aligned start address */
|
||||
|
||||
/* Loop, cleaning and invaliding each D cache line in the address range */
|
||||
|
||||
1:
|
||||
mcr CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */
|
||||
add r0, r0, r2 /* R12=Next cache line */
|
||||
cmp r0, r1 /* Loop until all cache lines have been cleaned */
|
||||
add r0, r0, r2 /* R12=Next cache line */
|
||||
cmp r0, r1 /* Loop until all cache lines have been cleaned */
|
||||
blo 1b
|
||||
|
||||
dsb
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
*
|
||||
* 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
|
||||
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
|
||||
* Copyright (c) 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
|
||||
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
|
||||
* Copyright (c) 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
|
||||
* DDI 0406C.b (ID072512)
|
||||
*
|
||||
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
|
||||
@@ -93,27 +93,27 @@
|
||||
|
||||
cp15_invalidate_dcache:
|
||||
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
mrc CP15_CTR(r3) /* Read the Cache Type Register */
|
||||
lsr r3, r3, #16 /* Isolate the DMinLine field */
|
||||
and r3, r3, #0xf
|
||||
mov r2, #4
|
||||
mov r2, r2, lsl r3 /* Get the cache line size in bytes */
|
||||
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
sub r3, r2, #1 /* R3=Cache line size mask */
|
||||
tst r0, r3
|
||||
bic r0, r0, r3 /* R0=aligned start address */
|
||||
bic r0, r0, r3 /* R0=aligned start address */
|
||||
|
||||
mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */
|
||||
mcrne CP15_DCCIMVAC(r0) /* Clean and invalidate data cache line by VA to PoC */
|
||||
|
||||
tst r1, r3
|
||||
bic r1, r1, r3 /* R0=aligned end address */
|
||||
mcrne CP15_DCCIMVAC(r1) /* Clean and invalidate data cache line by VA to PoC */
|
||||
bic r1, r1, r3 /* R0=aligned end address */
|
||||
mcrne CP15_DCCIMVAC(r1) /* Clean and invalidate data cache line by VA to PoC */
|
||||
|
||||
/* Loop, invalidating each D cache line */
|
||||
1:
|
||||
mcr CP15_DCIMVAC(r0) /* Invalidate data cache line by VA to PoC */
|
||||
add r0, r0, r2 /* R12=Next cache line */
|
||||
cmp r0, r1 /* Loop until all cache lines have been invalidate */
|
||||
add r0, r0, r2 /* R12=Next cache line */
|
||||
cmp r0, r1 /* Loop until all cache lines have been invalidate */
|
||||
blo 1b
|
||||
|
||||
dsb
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
*
|
||||
* 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
|
||||
* "Cortex-A5 MPCore, Technical Reference Manual", Revision: r0p1,
|
||||
* Copyright (c) 2010 ARM. All rights reserved. ARM DDI 0434B (ID101810)
|
||||
* "ARM Architecture Reference Manual, ARMv7-A and ARMv7-R edition",
|
||||
* Copyright (c) 1996-1998, 2000, 2004-2012 ARM. All rights reserved. ARM
|
||||
* DDI 0406C.b (ID072512)
|
||||
*
|
||||
* Portions of this file derive from Atmel sample code for the SAMA5D3 Cortex-A5
|
||||
@@ -91,24 +91,24 @@
|
||||
cp15_invalidate_dcache_all:
|
||||
|
||||
mrc CP15_CCSIDR(r0) /* Read the Cache Size Identification Register */
|
||||
ldr r3, =0xffff /* Isolate the NumSets field (bits 13-27) */
|
||||
ldr r3, =0xffff /* Isolate the NumSets field (bits 13-27) */
|
||||
and r0, r3, r0, lsr #13 /* r0=NumSets (number of sets - 1) */
|
||||
|
||||
mov r1, #0 /* r1 = way loop counter */
|
||||
mov r1, #0 /* r1 = way loop counter */
|
||||
way_loop:
|
||||
|
||||
mov r3, #0 /* r3 = set loop counter */
|
||||
mov r3, #0 /* r3 = set loop counter */
|
||||
set_loop:
|
||||
mov r2, r1, lsl #30 /* r2 = way loop counter << 30 */
|
||||
orr r2, r3, lsl #5 /* r2 = set/way cache operation format */
|
||||
mcr CP15_DCISW(r2) /* Data Cache Invalidate by Set/Way */
|
||||
add r3, r3, #1 /* Increment set counter */
|
||||
cmp r0, r3 /* Last set? */
|
||||
bne set_loop /* Keep looping if not */
|
||||
add r3, r3, #1 /* Increment set counter */
|
||||
cmp r0, r3 /* Last set? */
|
||||
bne set_loop /* Keep looping if not */
|
||||
|
||||
add r1, r1, #1 /* Increment the way counter */
|
||||
cmp r1, #4 /* Last way? (four ways assumed) */
|
||||
bne way_loop /* Keep looping if not */
|
||||
add r1, r1, #1 /* Increment the way counter */
|
||||
cmp r1, #4 /* Last way? (four ways assumed) */
|
||||
bne way_loop /* Keep looping if not */
|
||||
|
||||
dsb
|
||||
bx lr
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
|
||||
#include "arm_vfork.h"
|
||||
|
||||
.file "vfork.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@@ -36,6 +34,7 @@
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.file "vfork.S"
|
||||
.globl up_vfork
|
||||
|
||||
/****************************************************************************
|
||||
@@ -89,7 +88,7 @@
|
||||
vfork:
|
||||
/* Create a stack frame */
|
||||
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
|
||||
|
||||
/* CPU registers */
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/armv7-m/gnu/arm_exception.S
|
||||
*
|
||||
* Copyright (C) 2009-2013, 2015-2016, 2018 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009-2013, 2015-2016, 2018 Gregory Nutt.
|
||||
* All rights reserved.
|
||||
* Copyright (C) 2012 Michael Smith. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
@@ -49,10 +50,11 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
/* Configuration ********************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
/* In kernel mode without an interrupt stack, this interrupt handler will set the
|
||||
/* In protected mode without an interrupt stack, this interrupt handler will set the
|
||||
* MSP to the stack pointer of the interrupted thread. If the interrupted thread
|
||||
* was a privileged thread, that will be the MSP otherwise it will be the PSP. If
|
||||
* the PSP is used, then the value of the MSP will be invalid when the interrupt
|
||||
@@ -68,7 +70,7 @@
|
||||
*/
|
||||
|
||||
# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 8
|
||||
# error Interrupt stack must be used with high priority interrupts in kernel mode
|
||||
# error Interrupt stack must be used with high priority interrupts in protected mode
|
||||
# endif
|
||||
|
||||
/* Use the BASEPRI to control interrupts is required if nested, high
|
||||
@@ -135,8 +137,8 @@
|
||||
*/
|
||||
|
||||
.text
|
||||
.type exception_common, function
|
||||
.thumb_func
|
||||
.type exception_common, function
|
||||
exception_common:
|
||||
|
||||
mrs r0, ipsr /* R0=exception number */
|
||||
@@ -145,15 +147,14 @@ exception_common:
|
||||
|
||||
/* The EXC_RETURN value tells us whether the context is on the MSP or PSP */
|
||||
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 1f /* Branch if context already on the MSP */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 1f /* Branch if context already on the MSP */
|
||||
mrs r1, psp /* R1=The process stack pointer (PSP) */
|
||||
mov sp, r1 /* Set the MSP to the PSP */
|
||||
|
||||
mov sp, r1 /* Set the MSP to the PSP */
|
||||
1:
|
||||
mov r2, sp /* R2=Copy of the main/process stack pointer */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
/* (ignoring the xPSR[9] alignment bit) */
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
mrs r3, basepri /* R3=Current BASEPRI setting */
|
||||
#else
|
||||
@@ -173,11 +174,11 @@ exception_common:
|
||||
* where to put the registers.
|
||||
*/
|
||||
|
||||
vstmdb sp!, {s16-s31} /* Save the non-volatile FP context */
|
||||
vstmdb sp!, {s16-s31} /* Save the non-volatile FP context */
|
||||
|
||||
#endif
|
||||
|
||||
stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */
|
||||
stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP/PRIMASK values */
|
||||
|
||||
/* There are two arguments to arm_doirq:
|
||||
*
|
||||
@@ -197,7 +198,7 @@ exception_common:
|
||||
* here prohibits nested interrupts without some additional logic!
|
||||
*/
|
||||
|
||||
setintstack r2, r3 /* SP = IRQ stack top */
|
||||
setintstack r2, r3 /* SP = IRQ stack top */
|
||||
|
||||
#else
|
||||
/* Otherwise, we will re-use the interrupted thread's stack. That may
|
||||
@@ -219,7 +220,7 @@ exception_common:
|
||||
*/
|
||||
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 2f /* Branch if no context switch */
|
||||
beq 2f /* Branch if no context switch */
|
||||
|
||||
/* We are returning with a pending context switch. This case is different
|
||||
* because in this case, the register save structure does not lie on the
|
||||
@@ -236,32 +237,32 @@ exception_common:
|
||||
*/
|
||||
|
||||
add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */
|
||||
ldmia r1!, {r4-r11} /* Fetch eight registers in HW save area */
|
||||
ldmia r1!, {r4-r11} /* Fetch eight registers in HW save area */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
vldmia r1!, {s0-s15} /* Fetch sixteen FP registers in HW save area */
|
||||
ldmia r1, {r2-r3} /* Fetch FPSCR and Reserved in HW save area */
|
||||
vldmia r1!, {s0-s15} /* Fetch sixteen FP registers in HW save area */
|
||||
ldmia r1, {r2-r3} /* Fetch FPSCR and Reserved in HW save area */
|
||||
#endif
|
||||
ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
stmdb r1!, {r2-r3} /* Store FPSCR and Reserved on the return stack */
|
||||
vstmdb r1!, {s0-s15} /* Store sixteen FP registers on the return stack */
|
||||
stmdb r1!, {r2-r3} /* Store FPSCR and Reserved on the return stack */
|
||||
vstmdb r1!, {s0-s15} /* Store sixteen FP registers on the return stack */
|
||||
#endif
|
||||
stmdb r1!, {r4-r11} /* Store eight registers on the return stack */
|
||||
ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
stmdb r1!, {r4-r11} /* Store eight registers on the return stack */
|
||||
ldmia r0!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
vldmia r0, {s16-s31} /* Recover S16-S31 */
|
||||
vldmia r0, {s16-s31} /* Recover S16-S31 */
|
||||
#endif
|
||||
|
||||
b 3f /* Re-join common logic */
|
||||
b 3f /* Re-join common logic */
|
||||
|
||||
2:
|
||||
/* We are returning with no context switch. We simply need to "unwind"
|
||||
* the same stack frame that we created at entry.
|
||||
*/
|
||||
|
||||
ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
vldmia r1!, {s16-s31} /* Recover S16-S31 */
|
||||
vldmia r1!, {s16-s31} /* Recover S16-S31 */
|
||||
#endif
|
||||
|
||||
3:
|
||||
@@ -275,8 +276,8 @@ exception_common:
|
||||
*/
|
||||
|
||||
mrs r2, control /* R2=Contents of the control register */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 4f /* Branch if privileged */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 4f /* Branch if privileged */
|
||||
|
||||
orr r2, r2, #1 /* Unprivileged mode */
|
||||
msr psp, r1 /* R1=The process stack pointer */
|
||||
@@ -287,10 +288,10 @@ exception_common:
|
||||
5:
|
||||
msr control, r2 /* Save the updated control register */
|
||||
#else
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
ite eq /* next two instructions conditional */
|
||||
msreq msp, r1 /* R1=The main stack pointer */
|
||||
msrne psp, r1 /* R1=The process stack pointer */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
ite eq /* Next two instructions conditional */
|
||||
msreq msp, r1 /* R1=The main stack pointer */
|
||||
msrne psp, r1 /* R1=The process stack pointer */
|
||||
#endif
|
||||
|
||||
/* Restore the interrupt state */
|
||||
@@ -305,7 +306,7 @@ exception_common:
|
||||
* return to thread mode, and (2) select the correct stack.
|
||||
*/
|
||||
|
||||
bx r14 /* And return */
|
||||
bx r14 /* And return */
|
||||
|
||||
.size exception_common, .-exception_common
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "arm_fetchadd.S"
|
||||
.file "arm_fetchadd.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -57,15 +57,15 @@
|
||||
up_fetchadd32:
|
||||
|
||||
1:
|
||||
ldrex r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrex r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd32, . - up_fetchadd32
|
||||
|
||||
/****************************************************************************
|
||||
@@ -91,15 +91,15 @@ up_fetchadd32:
|
||||
up_fetchsub32:
|
||||
|
||||
1:
|
||||
ldrex r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrex r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub32, . - up_fetchsub32
|
||||
|
||||
/****************************************************************************
|
||||
@@ -125,15 +125,15 @@ up_fetchsub32:
|
||||
up_fetchadd16:
|
||||
|
||||
1:
|
||||
ldrexh r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrexh r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd16, . - up_fetchadd16
|
||||
|
||||
/****************************************************************************
|
||||
@@ -159,17 +159,17 @@ up_fetchadd16:
|
||||
up_fetchsub16:
|
||||
|
||||
1:
|
||||
ldrexh r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrexh r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
/* Attempt to save the decremented value */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub16, . - up_fetchsub16
|
||||
|
||||
/****************************************************************************
|
||||
@@ -195,15 +195,15 @@ up_fetchsub16:
|
||||
up_fetchadd8:
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrexb r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchadd8, . - up_fetchadd8
|
||||
|
||||
/****************************************************************************
|
||||
@@ -229,14 +229,14 @@ up_fetchadd8:
|
||||
up_fetchsub8:
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrexb r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
bne 1b /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
.size up_fetchsub8, . - up_fetchsub8
|
||||
.end
|
||||
|
||||
@@ -84,73 +84,73 @@ arm_savefpu:
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vstmia r1!, {s0-s31} /* Save the full FP context */
|
||||
vstmia r1!, {s0-s31} /* Save the full FP context */
|
||||
|
||||
/* Store the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
vmrs r2, fpscr /* Fetch the FPCSR */
|
||||
vmrs r2, fpscr /* Fetch the FPCSR */
|
||||
str r2, [r1], #4 /* Save the floating point control and status register */
|
||||
#else
|
||||
/* Store all floating point registers */
|
||||
|
||||
#if 1 /* Use store multiple */
|
||||
fstmias r1!, {s0-s31} /* Save the full FP context */
|
||||
fstmias r1!, {s0-s31} /* Save the full FP context */
|
||||
#else
|
||||
vmov r2, r3, d0 /* r2, r3 = d0 */
|
||||
vmov r2, r3, d0 /* r2, r3 = d0 */
|
||||
str r2, [r1], #4 /* Save S0 and S1 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d1 /* r2, r3 = d1 */
|
||||
vmov r2, r3, d1 /* r2, r3 = d1 */
|
||||
str r2, [r1], #4 /* Save S2 and S3 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d2 /* r2, r3 = d2 */
|
||||
vmov r2, r3, d2 /* r2, r3 = d2 */
|
||||
str r2, [r1], #4 /* Save S4 and S5 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d3 /* r2, r3 = d3 */
|
||||
vmov r2, r3, d3 /* r2, r3 = d3 */
|
||||
str r2, [r1], #4 /* Save S6 and S7 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d4 /* r2, r3 = d4 */
|
||||
vmov r2, r3, d4 /* r2, r3 = d4 */
|
||||
str r2, [r1], #4 /* Save S8 and S9 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d5 /* r2, r3 = d5 */
|
||||
vmov r2, r3, d5 /* r2, r3 = d5 */
|
||||
str r2, [r1], #4 /* Save S10 and S11 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d6 /* r2, r3 = d6 */
|
||||
vmov r2, r3, d6 /* r2, r3 = d6 */
|
||||
str r2, [r1], #4 /* Save S12 and S13 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d7 /* r2, r3 = d7 */
|
||||
vmov r2, r3, d7 /* r2, r3 = d7 */
|
||||
str r2, [r1], #4 /* Save S14 and S15 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d8 /* r2, r3 = d8 */
|
||||
vmov r2, r3, d8 /* r2, r3 = d8 */
|
||||
str r2, [r1], #4 /* Save S16 and S17 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d9 /* r2, r3 = d9 */
|
||||
vmov r2, r3, d9 /* r2, r3 = d9 */
|
||||
str r2, [r1], #4 /* Save S18 and S19 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d10 /* r2, r3 = d10 */
|
||||
vmov r2, r3, d10 /* r2, r3 = d10 */
|
||||
str r2, [r1], #4 /* Save S20 and S21 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d11 /* r2, r3 = d11 */
|
||||
vmov r2, r3, d11 /* r2, r3 = d11 */
|
||||
str r2, [r1], #4 /* Save S22 and S23 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d12 /* r2, r3 = d12 */
|
||||
vmov r2, r3, d12 /* r2, r3 = d12 */
|
||||
str r2, [r1], #4 /* Save S24 and S25 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d13 /* r2, r3 = d13 */
|
||||
vmov r2, r3, d13 /* r2, r3 = d13 */
|
||||
str r2, [r1], #4 /* Save S26 and S27 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d14 /* r2, r3 = d14 */
|
||||
vmov r2, r3, d14 /* r2, r3 = d14 */
|
||||
str r2, [r1], #4 /* Save S28 and S29 values */
|
||||
str r3, [r1], #4
|
||||
vmov r2, r3, d15 /* r2, r3 = d15 */
|
||||
vmov r2, r3, d15 /* r2, r3 = d15 */
|
||||
str r2, [r1], #4 /* Save S30 and S31 values */
|
||||
str r3, [r1], #4
|
||||
#endif
|
||||
|
||||
/* Store the floating point control and status register */
|
||||
|
||||
fmrx r2, fpscr /* Fetch the FPCSR */
|
||||
fmrx r2, fpscr /* Fetch the FPCSR */
|
||||
str r2, [r1], #4 /* Save the floating point control and status register */
|
||||
#endif
|
||||
bx lr
|
||||
@@ -190,70 +190,70 @@ arm_restorefpu:
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
vldmia r1!, {s0-s31} /* Restore the full FP context */
|
||||
vldmia r1!, {s0-s31} /* Restore the full FP context */
|
||||
|
||||
/* Load the floating point control and status register. At the end of the
|
||||
* vstmia, r1 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
ldr r2, [r1], #4 /* Fetch the floating point control and status register */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
#else
|
||||
/* Load all floating point registers Registers are loaded in numeric order,
|
||||
* s0, s1, ... in increasing address order.
|
||||
*/
|
||||
|
||||
#if 1 /* Use load multiple */
|
||||
fldmias r1!, {s0-s31} /* Restore the full FP context */
|
||||
fldmias r1!, {s0-s31} /* Restore the full FP context */
|
||||
#else
|
||||
ldr r2, [r1], #4 /* Fetch S0 and S1 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d0, r2, r3 /* Save as d0 */
|
||||
vmov d0, r2, r3 /* Save as d0 */
|
||||
ldr r2, [r1], #4 /* Fetch S2 and S3 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d1, r2, r3 /* Save as d1 */
|
||||
vmov d1, r2, r3 /* Save as d1 */
|
||||
ldr r2, [r1], #4 /* Fetch S4 and S5 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d2, r2, r3 /* Save as d2 */
|
||||
vmov d2, r2, r3 /* Save as d2 */
|
||||
ldr r2, [r1], #4 /* Fetch S6 and S7 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d3, r2, r3 /* Save as d3 */
|
||||
vmov d3, r2, r3 /* Save as d3 */
|
||||
ldr r2, [r1], #4 /* Fetch S8 and S9 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d4, r2, r3 /* Save as d4 */
|
||||
vmov d4, r2, r3 /* Save as d4 */
|
||||
ldr r2, [r1], #4 /* Fetch S10 and S11 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d5, r2, r3 /* Save as d5 */
|
||||
vmov d5, r2, r3 /* Save as d5 */
|
||||
ldr r2, [r1], #4 /* Fetch S12 and S13 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d6, r2, r3 /* Save as d6 */
|
||||
vmov d6, r2, r3 /* Save as d6 */
|
||||
ldr r2, [r1], #4 /* Fetch S14 and S15 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d7, r2, r3 /* Save as d7 */
|
||||
vmov d7, r2, r3 /* Save as d7 */
|
||||
ldr r2, [r1], #4 /* Fetch S16 and S17 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d8, r2, r3 /* Save as d8 */
|
||||
vmov d8, r2, r3 /* Save as d8 */
|
||||
ldr r2, [r1], #4 /* Fetch S18 and S19 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d9, r2, r3 /* Save as d9 */
|
||||
vmov d9, r2, r3 /* Save as d9 */
|
||||
ldr r2, [r1], #4 /* Fetch S20 and S21 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d10, r2, r3 /* Save as d10 */
|
||||
vmov d10, r2, r3 /* Save as d10 */
|
||||
ldr r2, [r1], #4 /* Fetch S22 and S23 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d11, r2, r3 /* Save as d11 */
|
||||
vmov d11, r2, r3 /* Save as d11 */
|
||||
ldr r2, [r1], #4 /* Fetch S24 and S25 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d12, r2, r3 /* Save as d12 */
|
||||
vmov d12, r2, r3 /* Save as d12 */
|
||||
ldr r2, [r1], #4 /* Fetch S26 and S27 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d13, r2, r3 /* Save as d13 */
|
||||
vmov d13, r2, r3 /* Save as d13 */
|
||||
ldr r2, [r1], #4 /* Fetch S28 and S29 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d14, r2, r3 /* Save as d14 */
|
||||
vmov d14, r2, r3 /* Save as d14 */
|
||||
ldr r2, [r1], #4 /* Fetch S30 and S31 values */
|
||||
ldr r3, [r1], #4
|
||||
vmov d15, r2, r3 /* Save as d15 */
|
||||
vmov d15, r2, r3 /* Save as d15 */
|
||||
#endif
|
||||
|
||||
/* Load the floating point control and status register. r1 points t
|
||||
@@ -261,7 +261,7 @@ arm_restorefpu:
|
||||
*/
|
||||
|
||||
ldr r2, [r1], #4 /* Fetch the floating point control and status register */
|
||||
fmxr fpscr, r2 /* Restore the FPCSR */
|
||||
fmxr fpscr, r2 /* Restore the FPCSR */
|
||||
#endif
|
||||
bx lr
|
||||
|
||||
|
||||
@@ -68,12 +68,12 @@ arm_fullcontextrestore:
|
||||
|
||||
/* Perform the System call with R0=1 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_restore_context /* R0: restore context */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* This call should not return */
|
||||
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
.size arm_fullcontextrestore, .-arm_fullcontextrestore
|
||||
.end
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_HIPRI_INTERRUPT
|
||||
/* In kernel mode without an interrupt stack, this interrupt handler will set the MSP to the
|
||||
/* In protected mode without an interrupt stack, this interrupt handler will set the MSP to the
|
||||
* stack pointer of the interrupted thread. If the interrupted thread was a privileged
|
||||
* thread, that will be the MSP otherwise it will be the PSP. If the PSP is used, then the
|
||||
* value of the MSP will be invalid when the interrupt handler returns because it will be a
|
||||
@@ -51,7 +51,7 @@
|
||||
*/
|
||||
|
||||
# if defined(CONFIG_BUILD_PROTECTED) && CONFIG_ARCH_INTERRUPTSTACK < 8
|
||||
# error Interrupt stack must be used with high priority interrupts in kernel mode
|
||||
# error Interrupt stack must be used with high priority interrupts in protected mode
|
||||
# endif
|
||||
|
||||
/* Use the BASEPRI to control interrupts is required if nested, high
|
||||
@@ -115,13 +115,13 @@
|
||||
*/
|
||||
|
||||
.text
|
||||
.type exception_common, function
|
||||
.type exception_common, function
|
||||
|
||||
exception_common:
|
||||
|
||||
/* Get the IRQ number from the IPSR */
|
||||
|
||||
mrs r0, ipsr /* R0=exception number */
|
||||
mrs r0, ipsr /* R0=exception number */
|
||||
|
||||
/* Complete the context save */
|
||||
|
||||
@@ -131,21 +131,21 @@ exception_common:
|
||||
* EXC_RETURN is 0xfffffffd (unprivileged thread)
|
||||
*/
|
||||
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 1f /* Branch if context already on the MSP */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* Nonzero if context on process stack */
|
||||
beq 1f /* Branch if context already on the MSP */
|
||||
mrs r1, psp /* R1=The process stack pointer (PSP) */
|
||||
mov sp, r1 /* Set the MSP to the PSP */
|
||||
mov sp, r1 /* Set the MSP to the PSP */
|
||||
|
||||
1:
|
||||
#endif
|
||||
|
||||
/* r1 holds the value of the stack pointer AFTER the exception handling logic
|
||||
/* sp holds the value of the stack pointer AFTER the exception handling logic
|
||||
* pushed the various registers onto the stack. Get r2 = the value of the
|
||||
* stack pointer BEFORE the interrupt modified it.
|
||||
*/
|
||||
|
||||
mov r2, sp /* R2=Copy of the main/process stack pointer */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
add r2, #HW_XCPT_SIZE /* R2=MSP/PSP before the interrupt was taken */
|
||||
|
||||
#ifdef CONFIG_ARMV7M_USEBASEPRI
|
||||
mrs r3, basepri /* R3=Current BASEPRI setting */
|
||||
@@ -169,9 +169,9 @@ exception_common:
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
|
||||
stmdb sp!, {r2-r11,r14} /* Save the remaining registers plus the SP value */
|
||||
#else
|
||||
stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */
|
||||
stmdb sp!, {r2-r11} /* Save the remaining registers plus the SP value */
|
||||
#endif
|
||||
|
||||
/* There are two arguments to arm_doirq:
|
||||
@@ -214,7 +214,7 @@ exception_common:
|
||||
*/
|
||||
|
||||
cmp r0, r1 /* Context switch? */
|
||||
beq 2f /* Branch if no context switch */
|
||||
beq 2f /* Branch if no context switch */
|
||||
|
||||
/* We are returning with a pending context switch.
|
||||
*
|
||||
@@ -241,16 +241,16 @@ exception_common:
|
||||
* values to the stack.
|
||||
*/
|
||||
|
||||
add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */
|
||||
ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */
|
||||
ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */
|
||||
stmdb r1!, {r4-r11} /* Store eight registers in HW save area */
|
||||
add r1, r0, #SW_XCPT_SIZE /* R1=Address of HW save area in reg array */
|
||||
ldmia r1, {r4-r11} /* Fetch eight registers in HW save area */
|
||||
ldr r1, [r0, #(4*REG_SP)] /* R1=Value of SP before interrupt */
|
||||
stmdb r1!, {r4-r11} /* Store eight registers in HW save area */
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
ldmia r0, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#else
|
||||
ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */
|
||||
ldmia r0, {r2-r11} /* Recover R4-R11 + 2 temp values */
|
||||
#endif
|
||||
b 3f /* Re-join common logic */
|
||||
b 3f /* Re-join common logic */
|
||||
|
||||
/* We are returning with no context switch. We simply need to "unwind"
|
||||
* the same stack frame that we created
|
||||
@@ -261,9 +261,9 @@ exception_common:
|
||||
|
||||
2:
|
||||
#ifdef CONFIG_BUILD_PROTECTED
|
||||
ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
ldmia r1!, {r2-r11,r14} /* Recover R4-R11, r14 + 2 temp values */
|
||||
#else
|
||||
ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
|
||||
ldmia r1!, {r2-r11} /* Recover R4-R11 + 2 temp values */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
@@ -292,8 +292,8 @@ exception_common:
|
||||
*/
|
||||
|
||||
mrs r2, control /* R2=Contents of the control register */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 4f /* Branch if privileged */
|
||||
tst r14, #EXC_RETURN_PROCESS_STACK /* nonzero if context on process stack */
|
||||
beq 4f /* Branch if privileged */
|
||||
|
||||
orr r2, r2, #1 /* Unprivileged mode */
|
||||
msr psp, r1 /* R1=The process stack pointer */
|
||||
@@ -310,7 +310,7 @@ exception_common:
|
||||
* actually occurs with interrupts still disabled).
|
||||
*/
|
||||
|
||||
ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */
|
||||
ldr r14, =EXC_RETURN_PRIVTHR /* Load the special value */
|
||||
#endif
|
||||
|
||||
/* Restore the interrupt state */
|
||||
|
||||
@@ -70,9 +70,9 @@ arm_saveusercontext:
|
||||
|
||||
/* Perform the System call with R0=0 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_save_context /* R0: save context (also return value) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* There are two return conditions. On the first return, R0 (the
|
||||
* return value will be zero. On the second return we need to
|
||||
@@ -82,7 +82,7 @@ arm_saveusercontext:
|
||||
add r2, r1, #(4*REG_R0)
|
||||
mov r3, #1
|
||||
str r3, [r2, #0]
|
||||
bx lr /* "normal" return with r0=0 or
|
||||
* context switch with r0=1 */
|
||||
bx lr /* "normal" return with r0=0 or
|
||||
* context switch with r0=1 */
|
||||
.size arm_saveusercontext, .-arm_saveusercontext
|
||||
.end
|
||||
|
||||
@@ -33,11 +33,6 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* When this file is assembled, it will require the following GCC options:
|
||||
*
|
||||
* -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -meabi=5 -mthumb
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
@@ -52,12 +47,12 @@
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
.globl setjmp
|
||||
.globl longjmp
|
||||
.globl setjmp
|
||||
.globl longjmp
|
||||
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "setjmp.S"
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "setjmp.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
@@ -84,33 +79,33 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.thumb_func
|
||||
.type setjmp, function
|
||||
.thumb_func
|
||||
.type setjmp, function
|
||||
setjmp:
|
||||
|
||||
/* Store callee-saved Core registers */
|
||||
/* Store callee-saved Core registers */
|
||||
|
||||
mov ip, sp /* move sp to ip so we can save it */
|
||||
stmia r0!, {r4-r11, ip, lr}
|
||||
mov ip, sp /* Move sp to ip so we can save it */
|
||||
stmia r0!, {r4-r11, ip, lr}
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
vstmia r0!, {s16-s31} /* Save the callee-saved FP registers */
|
||||
vstmia r0!, {s16-s31} /* Save the callee-saved FP registers */
|
||||
|
||||
/* Store the floating point control and status register. At the end of the
|
||||
* vstmia, r0 will point to the FPCSR storage location.
|
||||
*/
|
||||
/* Store the floating point control and status register. At the end of the
|
||||
* vstmia, r0 will point to the FPCSR storage location.
|
||||
*/
|
||||
|
||||
vmrs r1, fpscr /* Fetch the FPCSR */
|
||||
str r1, [r0], #4 /* Save the floating point control and status register */
|
||||
// DSA: don't need to inc r0
|
||||
vmrs r1, fpscr /* Fetch the FPCSR */
|
||||
str r1, [r0], #4 /* Save the floating point control and status register */
|
||||
/* DSA: don't need to inc r0 */
|
||||
#endif /* CONFIG_ARCH_FPU */
|
||||
|
||||
/* we're done, we're out of here */
|
||||
/* we're done, we're out of here */
|
||||
|
||||
mov r0, #0
|
||||
bx lr
|
||||
mov r0, #0
|
||||
bx lr
|
||||
|
||||
.size setjmp, .-setjmp
|
||||
.size setjmp, .-setjmp
|
||||
|
||||
/****************************************************************************
|
||||
* Name: longjmp
|
||||
@@ -134,29 +129,29 @@ setjmp:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.thumb_func
|
||||
.type longjmp, function
|
||||
.thumb_func
|
||||
.type longjmp, function
|
||||
longjmp:
|
||||
|
||||
/* Load callee-saved Core registers */
|
||||
/* Load callee-saved Core registers */
|
||||
|
||||
ldmia r0!, {r4-r11, ip, lr}
|
||||
mov sp, ip /* restore sp */
|
||||
ldmia r0!, {r4-r11, ip, lr}
|
||||
mov sp, ip /* Restore sp */
|
||||
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Load callee-saved floating point registers. */
|
||||
/* Load callee-saved floating point registers. */
|
||||
|
||||
vldmia r0!, {s16-s31} /* Restore FP context */
|
||||
vldmia r0!, {s16-s31} /* Restore FP context */
|
||||
|
||||
/* Load the floating point control and status register. */
|
||||
/* Load the floating point control and status register. */
|
||||
|
||||
ldr r2, [r0], #4 /* Fetch the floating point control and status register */
|
||||
/* DSA: don't need to inc r0 */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
ldr r2, [r0], #4 /* Fetch the floating point control and status register */
|
||||
/* DSA: don't need to inc r0 */
|
||||
vmsr fpscr, r2 /* Restore the FPCSR */
|
||||
#endif /* CONFIG_ARCH_FPU */
|
||||
|
||||
mov r0, r1 /* return val */
|
||||
bx lr
|
||||
mov r0, r1 /* return val */
|
||||
bx lr
|
||||
|
||||
.size longjmp, .-longjmp
|
||||
.end
|
||||
.size longjmp, .-longjmp
|
||||
.end
|
||||
|
||||
@@ -76,7 +76,7 @@ up_signal_handler:
|
||||
|
||||
/* Save some register */
|
||||
|
||||
push {lr} /* Save LR on the stack */
|
||||
push {lr} /* Save LR on the stack */
|
||||
|
||||
/* Call the signal handler */
|
||||
|
||||
@@ -84,7 +84,7 @@ up_signal_handler:
|
||||
mov r0, r1 /* R0=signo */
|
||||
mov r1, r2 /* R1=info */
|
||||
mov r2, r3 /* R2=ucontext */
|
||||
blx ip /* Call the signal handler */
|
||||
blx ip /* Call the signal handler */
|
||||
|
||||
/* Restore the registers */
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ arm_switchcontext:
|
||||
|
||||
mov r2, r1 /* R2: restoreregs */
|
||||
mov r1, r0 /* R1: saveregs */
|
||||
mov r0, #SYS_switch_context /* R0: context switch */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
mov r0, #SYS_switch_context /* R0: context switch */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* We will get here only after the rerturn from the context switch */
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/spinlock.h>
|
||||
|
||||
.syntax unified
|
||||
.syntax unified
|
||||
.thumb
|
||||
.file "arm_testset.S"
|
||||
|
||||
@@ -83,19 +83,19 @@ up_testset:
|
||||
/* Test if the spinlock is locked or not */
|
||||
|
||||
1:
|
||||
ldrexb r2, [r0] /* Test if spinlock is locked or not */
|
||||
ldrexb r2, [r0] /* Test if spinlock is locked or not */
|
||||
cmp r2, r1 /* Already locked? */
|
||||
beq 2f /* If already locked, return SP_LOCKED */
|
||||
beq 2f /* If already locked, return SP_LOCKED */
|
||||
|
||||
/* Not locked ... attempt to lock it */
|
||||
|
||||
strexb r2, r1, [r0] /* Attempt to set the locked state */
|
||||
strexb r2, r1, [r0] /* Attempt to set the locked state */
|
||||
cmp r2, r1 /* r2 will be 1 is strexb failed */
|
||||
beq 1b /* Failed to lock... try again */
|
||||
beq 1b /* Failed to lock... try again */
|
||||
|
||||
/* Lock acquired -- return SP_UNLOCKED */
|
||||
|
||||
dmb /* Required before accessing protected resource */
|
||||
dmb /* Required before accessing protected resource */
|
||||
mov r0, #SP_UNLOCKED
|
||||
bx lr
|
||||
|
||||
|
||||
@@ -47,20 +47,21 @@
|
||||
* 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.
|
||||
* 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:
|
||||
* 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 nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
|
||||
* consists of:
|
||||
* 3) nxtask_setup_vfork() 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
|
||||
@@ -77,10 +78,10 @@
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@@ -90,7 +91,7 @@
|
||||
vfork:
|
||||
/* Create a stack frame */
|
||||
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
|
||||
|
||||
/* CPU registers */
|
||||
|
||||
@@ -63,15 +63,15 @@
|
||||
|
||||
up_fetchadd32:
|
||||
|
||||
ldrex r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrex r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne up_fetchadd32 /* Failed to lock... try again */
|
||||
bne up_fetchadd32 /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchsub32
|
||||
@@ -92,15 +92,15 @@ up_fetchadd32:
|
||||
|
||||
up_fetchsub32:
|
||||
|
||||
ldrex r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrex r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
strex r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strex failed */
|
||||
bne up_fetchsub32 /* Failed to lock... try again */
|
||||
bne up_fetchsub32 /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchadd16
|
||||
@@ -121,15 +121,15 @@ up_fetchsub32:
|
||||
|
||||
up_fetchadd16:
|
||||
|
||||
ldrexh r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrexh r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne up_fetchadd16 /* Failed to lock... try again */
|
||||
bne up_fetchadd16 /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchsub16
|
||||
@@ -150,17 +150,17 @@ up_fetchadd16:
|
||||
|
||||
up_fetchsub16:
|
||||
|
||||
ldrexh r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrexh r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
/* Attempt to save the decremented value */
|
||||
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
strexh r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexh failed */
|
||||
bne up_fetchsub16 /* Failed to lock... try again */
|
||||
bne up_fetchsub16 /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchadd8
|
||||
@@ -181,15 +181,15 @@ up_fetchsub16:
|
||||
|
||||
up_fetchadd8:
|
||||
|
||||
ldrexb r2, [r0] /* Fetch the value to be incremented */
|
||||
ldrexb r2, [r0] /* Fetch the value to be incremented */
|
||||
add r2, r2, r1 /* Add the addend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne up_fetchadd8 /* Failed to lock... try again */
|
||||
bne up_fetchadd8 /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the incremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fetchsub8
|
||||
@@ -210,14 +210,14 @@ up_fetchadd8:
|
||||
|
||||
up_fetchsub8:
|
||||
|
||||
ldrexb r2, [r0] /* Fetch the value to be decremented */
|
||||
ldrexb r2, [r0] /* Fetch the value to be decremented */
|
||||
sub r2, r2, r1 /* Subtract the subtrahend */
|
||||
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
strexb r3, r2, [r0] /* Attempt to save the result */
|
||||
teq r3, #0 /* r3 will be 1 if strexb failed */
|
||||
bne up_fetchsub8 /* Failed to lock... try again */
|
||||
bne up_fetchsub8 /* Failed to lock... try again */
|
||||
|
||||
mov r0, r2 /* Return the decremented value */
|
||||
bx lr /* Successful! */
|
||||
bx lr /* Successful! */
|
||||
|
||||
END
|
||||
|
||||
@@ -68,12 +68,12 @@ arm_fullcontextrestore:
|
||||
|
||||
/* Perform the System call with R0=1 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_restore_context /* R0: restore context */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* This call should not return */
|
||||
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
bx lr /* Unnecessary ... will not return */
|
||||
|
||||
END
|
||||
|
||||
@@ -69,9 +69,9 @@ arm_saveusercontext:
|
||||
|
||||
/* Perform the System call with R0=0 and R1=regs */
|
||||
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r1, r0 /* R1: regs */
|
||||
mov r0, #SYS_save_context /* R0: save context (also return value) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* There are two return conditions. On the first return, R0 (the
|
||||
* return value will be zero. On the second return we need to
|
||||
@@ -81,6 +81,6 @@ arm_saveusercontext:
|
||||
add r2, r1, #(4*REG_R0)
|
||||
mov r3, #1
|
||||
str r3, [r2, #0]
|
||||
bx lr /* "normal" return with r0=0 or
|
||||
* context switch with r0=1 */
|
||||
bx lr /* "normal" return with r0=0 or
|
||||
* context switch with r0=1 */
|
||||
END
|
||||
|
||||
@@ -71,8 +71,8 @@ arm_switchcontext:
|
||||
|
||||
mov r2, r1 /* R2: restoreregs */
|
||||
mov r1, r0 /* R1: saveregs */
|
||||
mov r0, #SYS_switch_context /* R0: context switch */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
mov r0, #SYS_switch_context /* R0: context switch */
|
||||
svc 0 /* Force synchronous SVCall (or Hard Fault) */
|
||||
|
||||
/* We will get here only after the rerturn from the context switch */
|
||||
|
||||
|
||||
@@ -28,12 +28,24 @@
|
||||
MODULE up_testset
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
PUBLIC up_testset
|
||||
|
||||
/****************************************************************************
|
||||
* Assembly Macros
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -67,19 +79,19 @@ up_testset:
|
||||
/* Test if the spinlock is locked or not */
|
||||
|
||||
L1:
|
||||
ldrexb r2, [r0] /* Test if spinlock is locked or not */
|
||||
ldrexb r2, [r0] /* Test if spinlock is locked or not */
|
||||
cmp r2, r1 /* Already locked? */
|
||||
beq L2 /* If already locked, return SP_LOCKED */
|
||||
beq L2 /* If already locked, return SP_LOCKED */
|
||||
|
||||
/* Not locked ... attempt to lock it */
|
||||
|
||||
strexb r2, r1, [r0] /* Attempt to set the locked state */
|
||||
strexb r2, r1, [r0] /* Attempt to set the locked state */
|
||||
cmp r2, r1 /* r2 will be 1 is strexb failed */
|
||||
beq 1b /* Failed to lock... try again */
|
||||
beq L1 /* Failed to lock... try again */
|
||||
|
||||
/* Lock acquired -- return SP_UNLOCKED */
|
||||
|
||||
dmb /* Required before accessing protected resource */
|
||||
dmb /* Required before accessing protected resource */
|
||||
mov r0, #SP_UNLOCKED
|
||||
bx lr
|
||||
|
||||
|
||||
@@ -48,20 +48,21 @@
|
||||
* 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.
|
||||
* 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:
|
||||
* 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 nxtask_setup_vfork().
|
||||
* 3) nxtask_setup_vfork() allocates and configures the child task's TCB. This
|
||||
* consists of:
|
||||
* 3) nxtask_setup_vfork() 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
|
||||
@@ -78,10 +79,10 @@
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@@ -90,7 +91,7 @@
|
||||
vfork:
|
||||
/* Create a stack frame */
|
||||
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
mov r0, sp /* Save the value of the stack on entry */
|
||||
sub sp, sp, #VFORK_SIZEOF /* Allocate the structure on the stack */
|
||||
|
||||
/* CPU registers */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user