* 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.
This commit is contained in:
Nick Clifton 2011-07-13 15:06:21 +00:00
parent 1d15e018c7
commit 415e1ecce4
7 changed files with 163 additions and 45 deletions

View File

@ -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> 2011-07-01 Mike Frysinger <vapier@gentoo.org>
* bfin/syscalls.c (_getpid): Call do_syscall with func argument n and * bfin/syscalls.c (_getpid): Call do_syscall with func argument n and

53
libgloss/arm/arm.h Normal file
View File

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

View File

@ -1,4 +1,5 @@
#include "newlib.h" #include "newlib.h"
#include "arm.h"
#include "swi.h" #include "swi.h"
/* ANSI concatenation macros. */ /* ANSI concatenation macros. */
@ -18,8 +19,8 @@
/* .text is used instead of .section .text so it works with arm-aout too. */ /* .text is used instead of .section .text so it works with arm-aout too. */
.text .text
#if defined(__thumb2__)
.syntax unified .syntax unified
#ifdef THUMB_V7_V6M
.thumb .thumb
.macro FUNC_START name .macro FUNC_START name
.global \name .global \name
@ -48,25 +49,57 @@
/* Issue Demon SWI to read stack info */ /* Issue Demon SWI to read stack info */
swi SWI_GetEnv /* Returns command line in r0 */ swi SWI_GetEnv /* Returns command line in r0 */
mov sp,r1 /* and the highest memory address in r1 */ 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 */ /* stack limit is at end of data */
/* and small frames */ /* 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 #else
#ifdef ARM_RDI_MONITOR #ifdef ARM_RDI_MONITOR
/* Issue Angel SWI to read stack info */ /* 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 */ adr r1, .LC0 /* point at ptr to 4 words to receive data */
#if defined(__thumb2__) #ifdef THUMB_V7M_V6M
bkpt AngelSWI bkpt AngelSWI
#elif defined(__thumb2__)
/* We are in thumb mode for startup on armv7 architectures. */
AngelSWIAsm AngelSWI
#else #else
/* We are always in ARM mode for startup */ /* We are always in ARM mode for startup on pre armv7 archs. */
AngelSWIAsm AngelSWI_ARM AngelSWIAsm AngelSWI_ARM
#endif #endif
ldr r0, .LC0 /* point at values read */ ldr r0, .LC0 /* point at values read */
ldr sp, [r0, #8] ldr r1, [r0, #8]
ldr sl, [r0, #12] ldr r2, [r0, #12]
add sl, sl, #256 /* allow slop for stack overflow handling */ /* We skip setting sp/sl if 0 returned from semihosting.
/* and small frames */ - 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 #else
/* Set up the stack pointer to a fixed value */ /* Set up the stack pointer to a fixed value */
/* Changes by toralf: /* Changes by toralf:
@ -85,13 +118,19 @@
#ifdef __thumb2__ #ifdef __thumb2__
it eq it eq
#endif #endif
#ifdef __ARM_ARCH_6M__
bne .LC28
ldr r3, .LC0
.LC28:
#else
ldreq r3, .LC0 ldreq r3, .LC0
#endif
/* Note: This 'mov' is essential when starting in User, and ensures we /* Note: This 'mov' is essential when starting in User, and ensures we
always get *some* sp value for the initial mode, even if 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 have somehow missed it below (in which case it gets the same
value as FIQ - not ideal, but better than nothing.) */ value as FIQ - not ideal, but better than nothing.) */
mov sp, r3 mov sp, r3
#ifdef __thumb2__ #ifdef THUMB_V7_V6M
/* XXX Fill in stack assignments for interrupt modes. */ /* XXX Fill in stack assignments for interrupt modes. */
#else #else
mrs r2, CPSR mrs r2, CPSR
@ -134,20 +173,27 @@
this default 64k is enough for the program being executed. this default 64k is enough for the program being executed.
However, it ensures that this simple crt0 world will not However, it ensures that this simple crt0 world will not
immediately cause an overflow event: */ 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 */ sub sl, r3, #64 << 10 /* Still assumes 256bytes below sl */
#endif #endif
#endif
#endif #endif
/* Zero the memory in the .bss section. */ /* 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 fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */ mov r7, a2 /* Null frame pointer for Thumb */
ldr a1, .LC1 /* First arg: start of memory block */ ldr a1, .LC1 /* First arg: start of memory block */
ldr a3, .LC2 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.... */ /* Enter Thumb mode.... */
add a4, pc, #1 /* Get the address of the Thumb block */ add a4, pc, #1 /* Get the address of the Thumb block */
bx a4 /* Go there and start Thumb decoding */ bx a4 /* Go there and start Thumb decoding */
@ -185,8 +231,8 @@ __change_mode:
#endif #endif
.LC25: .LC25:
mov r0, #0 /* no arguments */ movs r0, #0 /* no arguments */
mov r1, #0 /* no argv either */ movs r1, #0 /* no argv either */
#else #else
/* Need to set up standard file handles */ /* Need to set up standard file handles */
bl FUNCTION (initialise_monitor_handles) bl FUNCTION (initialise_monitor_handles)
@ -195,13 +241,13 @@ __change_mode:
swi SWI_GetEnv /* sets r0 to point to the command line */ swi SWI_GetEnv /* sets r0 to point to the command line */
mov r1, r0 mov r1, r0
#else #else
mov r0, #AngelSWI_Reason_GetCmdLine movs r0, #AngelSWI_Reason_GetCmdLine
adr r1, .LC30 /* Space for command line */ adr r1, .LC30 /* Space for command line */
AngelSWIAsm AngelSWI AngelSWIAsm AngelSWI
ldr r1, .LC30 ldr r1, .LC30
#endif #endif
/* Parse string at r1 */ /* 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. */ /* Push a NULL argument onto the end of the list. */
#ifdef __thumb__ #ifdef __thumb__
push {r0} push {r0}
@ -212,7 +258,7 @@ __change_mode:
/* Skip leading blanks */ /* Skip leading blanks */
#ifdef __thumb__ #ifdef __thumb__
ldrb r3, [r1] ldrb r3, [r1]
add r1, #1 adds r1, #1
#else #else
ldrb r3, [r1], #1 ldrb r3, [r1], #1
#endif #endif
@ -232,8 +278,8 @@ __change_mode:
b .LC22 b .LC22
.LC21: .LC21:
mov r2, #' ' /* terminator type */ movs r2, #' ' /* terminator type */
sub r1, r1, #1 /* adjust back to point at start char */ subs r1, r1, #1 /* adjust back to point at start char */
.LC22: .LC22:
#else #else
cmpne r3, #'\'' cmpne r3, #'\''
@ -248,11 +294,11 @@ __change_mode:
#else #else
stmfd sp!, {r1} stmfd sp!, {r1}
#endif #endif
add r0, r0, #1 adds r0, r0, #1
.LC11: .LC11:
#ifdef __thumb__ #ifdef __thumb__
ldrb r3, [r1] ldrb r3, [r1]
add r1, #1 adds r1, #1
#else #else
ldrb r3, [r1], #1 ldrb r3, [r1], #1
#endif #endif
@ -260,8 +306,8 @@ __change_mode:
beq .LC12 beq .LC12
cmp r2, r3 /* reached terminator? */ cmp r2, r3 /* reached terminator? */
bne .LC11 bne .LC11
mov r2, #0 movs r2, #0
sub r3, r1, #1 subs r3, r1, #1
strb r2, [r3] /* terminate the arg string */ strb r2, [r3] /* terminate the arg string */
b .LC10 b .LC10
@ -270,23 +316,23 @@ __change_mode:
/* We've now got the stacked args in order reverse the */ /* We've now got the stacked args in order reverse the */
#ifdef __thumb__ #ifdef __thumb__
mov r2, r0 mov r2, r0
lsl r2, #2 lsls r2, #2
add r2, sp add r2, sp
mov r3, sp mov r3, sp
.LC15: cmp r2, r3 .LC15: cmp r2, r3
bls .LC14 bls .LC14
sub r2, #4 subs r2, #4
ldr r4, [r2] ldr r4, [r2]
ldr r5, [r3] ldr r5, [r3]
str r5, [r2] str r5, [r2]
str r4, [r3] str r4, [r3]
add r3, #4 adds r3, #4
b .LC15 b .LC15
.LC14: .LC14:
/* Ensure doubleword stack alignment. */ /* Ensure doubleword stack alignment. */
mov r4, sp mov r4, sp
mov r5, #7 movs r5, #7
bic r4, r5 bics r4, r5
mov sp, r4 mov sp, r4
#else #else
add r2, sp, r0, LSL #2 /* End of args */ add r2, sp, r0, LSL #2 /* End of args */
@ -319,7 +365,7 @@ __change_mode:
bl FUNCTION (exit) /* Should not return. */ 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. */ /* Come out of Thumb mode. This code should be redundant. */
mov a4, pc mov a4, pc

View File

@ -8,10 +8,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include "arm.h"
static int _main(int argc, char *argv[]) __attribute__((noreturn)); static int _main(int argc, char *argv[]) __attribute__((noreturn));
#if __thumb__ && !__thumb2__ #if defined(__thumb__) && !defined(THUMB_V7_V6M)
asm("\n" asm("\n"
".code 32\n" ".code 32\n"
".global _start\n" ".global _start\n"

View File

@ -1,3 +1,4 @@
#include "arm.h"
.file "crt0.S" .file "crt0.S"
@ -11,14 +12,14 @@
#endif #endif
.text .text
.syntax unified
/* Setup the assembly entry point. */ /* Setup the assembly entry point. */
#ifdef __thumb2__ #ifdef THUMB_V7_V6M
.macro FUNC_START name .macro FUNC_START name
.global \name .global \name
.thumb_func .thumb_func
\name: \name:
.endm .endm
.syntax unified
.thumb .thumb
#else #else
.macro FUNC_START name .macro FUNC_START name
@ -29,11 +30,15 @@
#endif #endif
FUNC_START SYM_NAME(start) FUNC_START SYM_NAME(start)
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 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. */ /* Enable interrupts for gdb debugging. */
#ifdef __thumb2__ #ifdef THUMB_V7_V6M
cpsie if cpsie if
#else #else
mrs r0, cpsr mrs r0, cpsr
@ -41,10 +46,10 @@
msr cpsr, r0 msr cpsr, r0
#endif #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 a1, .LC1 /* First arg: start of memory block. */
ldr a3, .LC2 ldr a3, .LC2
sub a3, a3, a1 /* Third arg: length of block. */ subs a3, a3, a1 /* Third arg: length of block. */
#ifdef GCRT0 #ifdef GCRT0
/* Zero out the bss without using memset. /* Zero out the bss without using memset.
@ -62,7 +67,8 @@
/* Nothing to left to clear. */ /* Nothing to left to clear. */
#endif #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. */ add a4, pc, #1 /* Get the address of the Thumb block. */
bx a4 /* Go there and start Thumb decoding. */ bx a4 /* Go there and start Thumb decoding. */
@ -76,7 +82,7 @@ __change_mode:
bl SYM_NAME(memset) bl SYM_NAME(memset)
#endif #endif
bl SYM_NAME(__get_memtop) bl SYM_NAME(__get_memtop)
sub r0, r0, #32 subs r0, r0, #32
mov sp, r0 mov sp, r0
#ifdef __USES_INITFINI__ #ifdef __USES_INITFINI__
@ -89,7 +95,7 @@ __change_mode:
bl SYM_NAME (_init) bl SYM_NAME (_init)
#endif #endif
mov a1, #0 movs a1, #0
ldr a2, .LC3 ldr a2, .LC3
mov a3, a2 mov a3, a2
bl SYM_NAME(main) bl SYM_NAME(main)

View File

@ -1,3 +1,5 @@
#include "arm.h"
/* SWI numbers for RDP (Demon) monitor. */ /* SWI numbers for RDP (Demon) monitor. */
#define SWI_WriteC 0x0 #define SWI_WriteC 0x0
#define SWI_Write0 0x2 #define SWI_Write0 0x2
@ -33,8 +35,8 @@
#else #else
#define AngelSWI AngelSWI_ARM #define AngelSWI AngelSWI_ARM
#endif #endif
/* For Thumb-2 code use the BKPT instruction instead of SWI. */ /* For thumb only architectures use the BKPT instruction instead of SWI. */
#ifdef __thumb2__ #ifdef THUMB_V7M_V6M
#define AngelSWIInsn "bkpt" #define AngelSWIInsn "bkpt"
#define AngelSWIAsm bkpt #define AngelSWIAsm bkpt
#else #else

View File

@ -1,5 +1,6 @@
#include "arm.h"
/* Run-time exception support */ /* Run-time exception support */
#if !defined(__thumb2__) #ifndef THUMB_V7_V6M
#include "swi.h" #include "swi.h"
/* .text is used instead of .section .text so it works with arm-aout too. */ /* .text is used instead of .section .text so it works with arm-aout too. */