diff options
-rw-r--r-- | libgloss/ChangeLog | 9 | ||||
-rw-r--r-- | libgloss/arm/arm.h | 53 | ||||
-rw-r--r-- | libgloss/arm/crt0.S | 110 | ||||
-rw-r--r-- | libgloss/arm/linux-crt0.c | 3 | ||||
-rw-r--r-- | libgloss/arm/redboot-crt0.S | 24 | ||||
-rw-r--r-- | libgloss/arm/swi.h | 6 | ||||
-rw-r--r-- | libgloss/arm/trap.S | 3 |
7 files changed, 163 insertions, 45 deletions
diff --git a/libgloss/ChangeLog b/libgloss/ChangeLog index f37af8b..e433ec5 100644 --- a/libgloss/ChangeLog +++ b/libgloss/ChangeLog @@ -1,3 +1,12 @@ +2011-07-13 Bin Cheng <bin.cheng@arm.com> + + * arm/crt0.S: Support armv6-m processors in libgloss. + * arm/swi.h: Likewise. + * arm/trap.S: Likewise. + * arm/redboot-crt0.S: Likewise. + * arm/linux-crt0.c: Likewise. + * arm/arm.h: New. + 2011-07-01 Mike Frysinger <vapier@gentoo.org> * bfin/syscalls.c (_getpid): Call do_syscall with func argument n and diff --git a/libgloss/arm/arm.h b/libgloss/arm/arm.h new file mode 100644 index 0000000..e8c9d25 --- /dev/null +++ b/libgloss/arm/arm.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 ARM Ltd + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LIBGLOSS_ARM_H +#define _LIBGLOSS_ARM_H + +/* __thumb2__ stands for thumb on armva7(A/R/M/EM) architectures, + __ARM_ARCH_6M__ stands for armv6-M(thumb only) architecture, + __ARM_ARCH_7M__ stands for armv7-M(thumb only) architecture. + __ARM_ARCH_7EM__ stands for armv7e-M(thumb only) architecture. + There are some macro combinations used many times in libgloss/arm, + like (__thumb2__ || (__thumb__ && __ARM_ARCH_6M__)), so factor + it out and use THUMB_V7_V6M instead, which stands for thumb on + v6-m/v7 arch as the combination does. */ +#if defined(__thumb2__) || (defined(__thumb__) && defined(__ARM_ARCH_6M__)) +# define THUMB_V7_V6M +#endif + +/* The (__ARM_ARCH_7EM__ || __ARM_ARCH_7M__ || __ARM_ARCH_6M__) combination + stands for cortex-M profile architectures, which don't support ARM state. + Factor it out and use THUMB_V7M_V6M instead. */ +#if defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) \ + || defined(__ARM_ARCH_6M__) +# define THUMB_V7M_V6M +#endif + +#endif /* _LIBGLOSS_ARM_H */ diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index ea5163a..c98cd2c 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -1,4 +1,5 @@ #include "newlib.h" +#include "arm.h" #include "swi.h" /* ANSI concatenation macros. */ @@ -18,8 +19,8 @@ /* .text is used instead of .section .text so it works with arm-aout too. */ .text -#if defined(__thumb2__) .syntax unified +#ifdef THUMB_V7_V6M .thumb .macro FUNC_START name .global \name @@ -48,25 +49,57 @@ /* Issue Demon SWI to read stack info */ swi SWI_GetEnv /* Returns command line in r0 */ mov sp,r1 /* and the highest memory address in r1 */ - ldr sl, .LC2 /* stack limit is at end of data */ - add sl, sl, #256 /* allow slop for stack overflow handling */ - /* and small frames */ + + /* stack limit is at end of data */ + /* allow slop for stack overflow handling and small frames */ +#ifdef __ARM_ARCH_6M__ + ldr r0, .LC2 + adds r0, #128 + adds r0, #128 + mov sl, r0 +#else + ldr sl, .LC2 + add sl, sl, #256 +#endif #else #ifdef ARM_RDI_MONITOR /* Issue Angel SWI to read stack info */ - mov r0, #AngelSWI_Reason_HeapInfo + movs r0, #AngelSWI_Reason_HeapInfo adr r1, .LC0 /* point at ptr to 4 words to receive data */ -#if defined(__thumb2__) +#ifdef THUMB_V7M_V6M bkpt AngelSWI +#elif defined(__thumb2__) + /* We are in thumb mode for startup on armv7 architectures. */ + AngelSWIAsm AngelSWI #else - /* We are always in ARM mode for startup */ + /* We are always in ARM mode for startup on pre armv7 archs. */ AngelSWIAsm AngelSWI_ARM #endif ldr r0, .LC0 /* point at values read */ - ldr sp, [r0, #8] - ldr sl, [r0, #12] - add sl, sl, #256 /* allow slop for stack overflow handling */ - /* and small frames */ + ldr r1, [r0, #8] + ldr r2, [r0, #12] + /* We skip setting sp/sl if 0 returned from semihosting. + - According to semihosting docs, if 0 returned from semihosting, + the system was unable to calculate the real value, so it's ok + to skip setting sp/sl to 0 here. + - Considering M-profile processors, We might want to initialize + sp by the first entry of vector table and return 0 to SYS_HEAPINFO + semihosting call, which will be skipped here. */ + cmp r1, #0 + beq .LC26 + mov sp, r1 +.LC26: + cmp r2, #0 + beq .LC27 + /* allow slop for stack overflow handling and small frames */ +#ifdef __ARM_ARCH_6M__ + adds r2, #128 + adds r2, #128 + mov sl, r2 +#else + add sl, r2, #256 +#endif +.LC27: #else /* Set up the stack pointer to a fixed value */ /* Changes by toralf: @@ -85,13 +118,19 @@ #ifdef __thumb2__ it eq #endif +#ifdef __ARM_ARCH_6M__ + bne .LC28 + ldr r3, .LC0 +.LC28: +#else ldreq r3, .LC0 +#endif /* Note: This 'mov' is essential when starting in User, and ensures we always get *some* sp value for the initial mode, even if we have somehow missed it below (in which case it gets the same value as FIQ - not ideal, but better than nothing.) */ mov sp, r3 -#ifdef __thumb2__ +#ifdef THUMB_V7_V6M /* XXX Fill in stack assignments for interrupt modes. */ #else mrs r2, CPSR @@ -134,20 +173,27 @@ this default 64k is enough for the program being executed. However, it ensures that this simple crt0 world will not immediately cause an overflow event: */ +#ifdef __ARM_ARCH_6M__ + movs r2, #64 + lsls r2, r2, #10 + subs r2, r3, r2 + mov sl, r2 +#else sub sl, r3, #64 << 10 /* Still assumes 256bytes below sl */ #endif #endif +#endif /* Zero the memory in the .bss section. */ - mov a2, #0 /* Second arg: fill value */ + movs a2, #0 /* Second arg: fill value */ mov fp, a2 /* Null frame pointer */ mov r7, a2 /* Null frame pointer for Thumb */ ldr a1, .LC1 /* First arg: start of memory block */ ldr a3, .LC2 - sub a3, a3, a1 /* Third arg: length of block */ + subs a3, a3, a1 /* Third arg: length of block */ -#if defined(__thumb__) && !defined(__thumb2__) +#if defined(__thumb__) && !defined(THUMB_V7_V6M) /* Enter Thumb mode.... */ add a4, pc, #1 /* Get the address of the Thumb block */ bx a4 /* Go there and start Thumb decoding */ @@ -185,8 +231,8 @@ __change_mode: #endif .LC25: - mov r0, #0 /* no arguments */ - mov r1, #0 /* no argv either */ + movs r0, #0 /* no arguments */ + movs r1, #0 /* no argv either */ #else /* Need to set up standard file handles */ bl FUNCTION (initialise_monitor_handles) @@ -195,13 +241,13 @@ __change_mode: swi SWI_GetEnv /* sets r0 to point to the command line */ mov r1, r0 #else - mov r0, #AngelSWI_Reason_GetCmdLine + movs r0, #AngelSWI_Reason_GetCmdLine adr r1, .LC30 /* Space for command line */ AngelSWIAsm AngelSWI ldr r1, .LC30 #endif /* Parse string at r1 */ - mov r0, #0 /* count of arguments so far */ + movs r0, #0 /* count of arguments so far */ /* Push a NULL argument onto the end of the list. */ #ifdef __thumb__ push {r0} @@ -212,7 +258,7 @@ __change_mode: /* Skip leading blanks */ #ifdef __thumb__ ldrb r3, [r1] - add r1, #1 + adds r1, #1 #else ldrb r3, [r1], #1 #endif @@ -232,8 +278,8 @@ __change_mode: b .LC22 .LC21: - mov r2, #' ' /* terminator type */ - sub r1, r1, #1 /* adjust back to point at start char */ + movs r2, #' ' /* terminator type */ + subs r1, r1, #1 /* adjust back to point at start char */ .LC22: #else cmpne r3, #'\'' @@ -248,11 +294,11 @@ __change_mode: #else stmfd sp!, {r1} #endif - add r0, r0, #1 + adds r0, r0, #1 .LC11: #ifdef __thumb__ ldrb r3, [r1] - add r1, #1 + adds r1, #1 #else ldrb r3, [r1], #1 #endif @@ -260,8 +306,8 @@ __change_mode: beq .LC12 cmp r2, r3 /* reached terminator? */ bne .LC11 - mov r2, #0 - sub r3, r1, #1 + movs r2, #0 + subs r3, r1, #1 strb r2, [r3] /* terminate the arg string */ b .LC10 @@ -270,23 +316,23 @@ __change_mode: /* We've now got the stacked args in order reverse the */ #ifdef __thumb__ mov r2, r0 - lsl r2, #2 + lsls r2, #2 add r2, sp mov r3, sp .LC15: cmp r2, r3 bls .LC14 - sub r2, #4 + subs r2, #4 ldr r4, [r2] ldr r5, [r3] str r5, [r2] str r4, [r3] - add r3, #4 + adds r3, #4 b .LC15 .LC14: /* Ensure doubleword stack alignment. */ mov r4, sp - mov r5, #7 - bic r4, r5 + movs r5, #7 + bics r4, r5 mov sp, r4 #else add r2, sp, r0, LSL #2 /* End of args */ @@ -319,7 +365,7 @@ __change_mode: bl FUNCTION (exit) /* Should not return. */ -#if defined(__thumb__) && !defined(__thumb2__) +#if defined(__thumb__) && !defined(THUMB_V7_V6M) /* Come out of Thumb mode. This code should be redundant. */ mov a4, pc diff --git a/libgloss/arm/linux-crt0.c b/libgloss/arm/linux-crt0.c index 1fe2499..2c1dd4a 100644 --- a/libgloss/arm/linux-crt0.c +++ b/libgloss/arm/linux-crt0.c @@ -8,10 +8,11 @@ #include <stdlib.h> #include <unistd.h> +#include "arm.h" static int _main(int argc, char *argv[]) __attribute__((noreturn)); -#if __thumb__ && !__thumb2__ +#if defined(__thumb__) && !defined(THUMB_V7_V6M) asm("\n" ".code 32\n" ".global _start\n" diff --git a/libgloss/arm/redboot-crt0.S b/libgloss/arm/redboot-crt0.S index 2499ac0..dcd042c 100644 --- a/libgloss/arm/redboot-crt0.S +++ b/libgloss/arm/redboot-crt0.S @@ -1,3 +1,4 @@ +#include "arm.h" .file "crt0.S" @@ -11,14 +12,14 @@ #endif .text + .syntax unified /* Setup the assembly entry point. */ -#ifdef __thumb2__ +#ifdef THUMB_V7_V6M .macro FUNC_START name .global \name .thumb_func \name: .endm - .syntax unified .thumb #else .macro FUNC_START name @@ -29,11 +30,15 @@ #endif FUNC_START SYM_NAME(start) FUNC_START SYM_NAME(_start) + /* Unnecessary to set fp for v6-m/v7-m, which don't support + ARM state. */ +#ifndef THUMB_V7M_V6M mov fp, #0 /* Null frame pointer. */ - mov r7, #0 /* Null frame pointer for Thumb. */ +#endif + movs r7, #0 /* Null frame pointer for Thumb. */ /* Enable interrupts for gdb debugging. */ -#ifdef __thumb2__ +#ifdef THUMB_V7_V6M cpsie if #else mrs r0, cpsr @@ -41,10 +46,10 @@ msr cpsr, r0 #endif - mov a2, #0 /* Second arg: fill value. */ + movs a2, #0 /* Second arg: fill value. */ ldr a1, .LC1 /* First arg: start of memory block. */ ldr a3, .LC2 - sub a3, a3, a1 /* Third arg: length of block. */ + subs a3, a3, a1 /* Third arg: length of block. */ #ifdef GCRT0 /* Zero out the bss without using memset. @@ -62,7 +67,8 @@ /* Nothing to left to clear. */ #endif -#if defined(__thumb__) && !defined(__thumb2__) /* Enter Thumb mode. */ +#if defined(__thumb__) && !defined(THUMB_V7_V6M) + /* Enter Thumb mode. */ add a4, pc, #1 /* Get the address of the Thumb block. */ bx a4 /* Go there and start Thumb decoding. */ @@ -76,7 +82,7 @@ __change_mode: bl SYM_NAME(memset) #endif bl SYM_NAME(__get_memtop) - sub r0, r0, #32 + subs r0, r0, #32 mov sp, r0 #ifdef __USES_INITFINI__ @@ -89,7 +95,7 @@ __change_mode: bl SYM_NAME (_init) #endif - mov a1, #0 + movs a1, #0 ldr a2, .LC3 mov a3, a2 bl SYM_NAME(main) diff --git a/libgloss/arm/swi.h b/libgloss/arm/swi.h index 7638dbe..0f93134 100644 --- a/libgloss/arm/swi.h +++ b/libgloss/arm/swi.h @@ -1,3 +1,5 @@ +#include "arm.h" + /* SWI numbers for RDP (Demon) monitor. */ #define SWI_WriteC 0x0 #define SWI_Write0 0x2 @@ -33,8 +35,8 @@ #else #define AngelSWI AngelSWI_ARM #endif -/* For Thumb-2 code use the BKPT instruction instead of SWI. */ -#ifdef __thumb2__ +/* For thumb only architectures use the BKPT instruction instead of SWI. */ +#ifdef THUMB_V7M_V6M #define AngelSWIInsn "bkpt" #define AngelSWIAsm bkpt #else diff --git a/libgloss/arm/trap.S b/libgloss/arm/trap.S index 21b6937..9eb3906 100644 --- a/libgloss/arm/trap.S +++ b/libgloss/arm/trap.S @@ -1,5 +1,6 @@ +#include "arm.h" /* Run-time exception support */ -#if !defined(__thumb2__) +#ifndef THUMB_V7_V6M #include "swi.h" /* .text is used instead of .section .text so it works with arm-aout too. */ |