From f772acf8a584067033eff1e231fcd1fb3a00d3d9 Mon Sep 17 00:00:00 2001
From: Wolfgang Denk <wd@denx.de>
Date: Mon, 17 Aug 2009 13:17:29 +0200
Subject: [PATCH] ARM: compiler options cleanup - improve tool chain support

For some time there have been repeated reports about build problems
with some ARM (cross) tool chains.  Especially issues about
(in)compatibility with the tool chain provided runtime support
library libgcc.a caused to add and support a private implementation
of such runtime support code in U-Boot.  A closer look at the code
indicated that some of these issues are actually home-made.  This
patch attempts to clean up some of the most obvious problems and make
building of U-Boot with different tool chains easier:

- Even though all ARM systems basicy used the same compiler options
  to select a specific ABI from the tool chain, the code for this was
  distributed over all cpu/*/config.mk files.  We move this one level
  up into lib_arm/config.mk instead.

- So far, we only checked if "-mapcs-32" was supported by the tool
  chain; if yes, this was used, if not, "-mabi=apcs-gnu" was
  selected, no matter if the tool chain actually understood this
  option.  There was no support for EABI conformant tool chains.
  This patch implements the following logic:

  1) If the tool chain supports
	"-mabi=aapcs-linux -mno-thumb-interwork"
     we use these options (EABI conformant tool chain).
  2) Otherwise, we check first if
	"-mapcs-32"
     is supported, and then check for
	"-mabi=apcs-gnu"
     If one test succeeds, we use the first found option.
  3) In case 2), we also test if "-mno-thumb-interwork", and use
     this if the test succeeds. [For "-mabi=aapcs-linux" we set
     "-mno-thumb-interwork" mandatorily.]

  This way we use a similar logic for the compile options as the
  Linux kernel does.

- Some EABI conformant tool chains cause external references to
  utility functions like raise(); such functions are provided in the
  new file lib_arm/eabi_compat.c

  Note that lib_arm/config.mk gets parsed several times, so we must
  make sure to add eabi_compat.o only once to the linker list.

Signed-off-by: Wolfgang Denk <wd@denx.de>
Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Dirk Behme <dirk.behme@googlemail.com>
Cc: Magnus Lilja <lilja.magnus@gmail.com>
Cc: Tom Rix <Tom.Rix@windriver.com>
Cc: Prafulla Wadaskar <prafulla@marvell.com>
Acked-by: Sergey Kubushyn <ksi@koi8.net>
Tested-by: Magnus Lilja <lilja.magnus@gmail.com>
Tested-by: Andrzej Wolski <awolski@poczta.fm>
Tested-by: Gaye Abdoulaye Walsimou <walsimou@walsimou.com>
Tested-by: Tom Rix <Tom.Rix@windriver.com>
Tested-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
 config.mk                       |  2 +-
 cpu/arm1136/config.mk           |  2 --
 cpu/arm1176/config.mk           |  2 --
 cpu/arm1176/s3c64xx/config.mk   |  1 -
 cpu/arm720t/config.mk           |  2 --
 cpu/arm920t/config.mk           |  2 --
 cpu/arm925t/config.mk           |  2 --
 cpu/arm926ejs/config.mk         |  2 --
 cpu/arm926ejs/davinci/config.mk |  2 --
 cpu/arm946es/config.mk          |  2 --
 cpu/arm_cortexa8/config.mk      |  1 -
 cpu/arm_cortexa8/omap3/board.c  |  7 -------
 cpu/arm_intcm/config.mk         |  2 --
 cpu/ixp/config.mk               |  1 -
 cpu/lh7a40x/config.mk           |  2 --
 cpu/pxa/config.mk               |  2 --
 cpu/s3c44b0/config.mk           |  2 --
 cpu/sa1100/config.mk            |  2 --
 lib_arm/Makefile                | 15 ++++++++++++---
 lib_arm/config.mk               | 28 ++++++++++++++++++++++++++++
 lib_arm/eabi_compat.c           | 18 ++++++++++++++++++
 21 files changed, 59 insertions(+), 40 deletions(-)
 create mode 100644 lib_arm/eabi_compat.c

diff --git a/config.mk b/config.mk
index fd56621fefe..0c6d1d1aa76 100644
--- a/config.mk
+++ b/config.mk
@@ -86,7 +86,7 @@ ifdef	ARCH
 sinclude $(TOPDIR)/lib_$(ARCH)/config.mk	# include architecture dependend rules
 endif
 ifdef	CPU
-sinclude $(TOPDIR)/cpu/$(CPU)/config.mk	# include  CPU	specific rules
+sinclude $(TOPDIR)/cpu/$(CPU)/config.mk		# include  CPU	specific rules
 endif
 ifdef	SOC
 sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk	# include  SoC	specific rules
diff --git a/cpu/arm1136/config.mk b/cpu/arm1136/config.mk
index 295e8a5b87a..61d5a382ed8 100644
--- a/cpu/arm1136/config.mk
+++ b/cpu/arm1136/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk
index d2f057bf74f..a31c7b0f897 100644
--- a/cpu/arm1176/config.mk
+++ b/cpu/arm1176/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5t
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk
index 4f3b66c5d74..a31c7b0f897 100644
--- a/cpu/arm1176/s3c64xx/config.mk
+++ b/cpu/arm1176/s3c64xx/config.mk
@@ -30,5 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5t
 # Supply options according to compiler version
 #
 # =========================================================================
-#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm720t/config.mk b/cpu/arm720t/config.mk
index 3cae1dc8f73..74d52831ede 100644
--- a/cpu/arm720t/config.mk
+++ b/cpu/arm720t/config.mk
@@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm920t/config.mk b/cpu/arm920t/config.mk
index 5d8a10ff628..a43b1567110 100644
--- a/cpu/arm920t/config.mk
+++ b/cpu/arm920t/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm925t/config.mk b/cpu/arm925t/config.mk
index 5d8a10ff628..a43b1567110 100644
--- a/cpu/arm925t/config.mk
+++ b/cpu/arm925t/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm926ejs/config.mk b/cpu/arm926ejs/config.mk
index 885d5c134e9..90eb3c0edec 100644
--- a/cpu/arm926ejs/config.mk
+++ b/cpu/arm926ejs/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5te
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm926ejs/davinci/config.mk b/cpu/arm926ejs/davinci/config.mk
index a57d03aa01d..7757be398ae 100644
--- a/cpu/arm926ejs/davinci/config.mk
+++ b/cpu/arm926ejs/davinci/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5te
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm946es/config.mk b/cpu/arm946es/config.mk
index 9d62ba8e3f4..a81321bd3cc 100644
--- a/cpu/arm946es/config.mk
+++ b/cpu/arm946es/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS +=  -march=armv4
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm_cortexa8/config.mk b/cpu/arm_cortexa8/config.mk
index 3bfe3db20c9..da5ee162c5f 100644
--- a/cpu/arm_cortexa8/config.mk
+++ b/cpu/arm_cortexa8/config.mk
@@ -30,6 +30,5 @@ PLATFORM_CPPFLAGS += -march=armv5
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
 		    $(call cc-option,-malignment-traps,))
diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c
index 233728762f9..b8bd0524af9 100644
--- a/cpu/arm_cortexa8/omap3/board.c
+++ b/cpu/arm_cortexa8/omap3/board.c
@@ -297,13 +297,6 @@ int dram_init(void)
 	return 0;
 }
 
-/******************************************************************************
- * Dummy function to handle errors for EABI incompatibility
- *****************************************************************************/
-void raise(void)
-{
-}
-
 /******************************************************************************
  * Dummy function to handle errors for EABI incompatibility
  *****************************************************************************/
diff --git a/cpu/arm_intcm/config.mk b/cpu/arm_intcm/config.mk
index 9d62ba8e3f4..a81321bd3cc 100644
--- a/cpu/arm_intcm/config.mk
+++ b/cpu/arm_intcm/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS +=  -march=armv4
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/ixp/config.mk b/cpu/ixp/config.mk
index a71a20b822d..2c33b40a2cb 100644
--- a/cpu/ixp/config.mk
+++ b/cpu/ixp/config.mk
@@ -33,5 +33,4 @@ PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100
 # Supply options according to compiler version
 #
 # =========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/lh7a40x/config.mk b/cpu/lh7a40x/config.mk
index c0e7a1d0448..27bc4812606 100644
--- a/cpu/lh7a40x/config.mk
+++ b/cpu/lh7a40x/config.mk
@@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4
 # Supply options according to compiler version
 #
 # ========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/pxa/config.mk b/cpu/pxa/config.mk
index af910e2f670..f360478d0c2 100644
--- a/cpu/pxa/config.mk
+++ b/cpu/pxa/config.mk
@@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv5te -mtune=xscale
 # Supply options according to compiler version
 #
 # ========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/s3c44b0/config.mk b/cpu/s3c44b0/config.mk
index 01e7040d61d..3623f2503e2 100644
--- a/cpu/s3c44b0/config.mk
+++ b/cpu/s3c44b0/config.mk
@@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi -msoft-float
 # Supply options according to compiler version
 #
 # ========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/sa1100/config.mk b/cpu/sa1100/config.mk
index 9ef4a19d339..553cd0c9cfc 100644
--- a/cpu/sa1100/config.mk
+++ b/cpu/sa1100/config.mk
@@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=strongarm1100
 # Supply options according to compiler version
 #
 # ========================================================================
-PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
-PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
 PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/lib_arm/Makefile b/lib_arm/Makefile
index c37e2e0d8a9..02933485cd1 100644
--- a/lib_arm/Makefile
+++ b/lib_arm/Makefile
@@ -51,12 +51,21 @@ OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
 LGOBJS	:= $(addprefix $(obj),$(GLSOBJS)) \
 	   $(addprefix $(obj),$(GLCOBJS))
 
+# Always build libarm.a
+TARGETS	:= $(LIB)
+
+# Build private libgcc only when asked for
 ifdef USE_PRIVATE_LIBGCC
-all:	$(LIB) $(LIBGCC)
-else
-all:	$(LIB)
+TARGETS	+= $(LIBGCC)
+endif
+
+# For EABI conformant tool chains, provide eabi_compat()
+ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
+TARGETS	+= $(obj)eabi_compat.o
 endif
 
+all:	$(TARGETS)
+
 $(LIB):	$(obj).depend $(OBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 
diff --git a/lib_arm/config.mk b/lib_arm/config.mk
index a13603e4091..705dfc306c4 100644
--- a/lib_arm/config.mk
+++ b/lib_arm/config.mk
@@ -25,4 +25,32 @@ CROSS_COMPILE ?= arm-linux-
 
 PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
 
+# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
+PLATFORM_CPPFLAGS += $(call cc-option,-marm,)
+
+# Try if EABI is supported, else fall back to old API,
+# i. e. for example:
+# - with ELDK 4.2 (EABI supported), use:
+#	-mabi=aapcs-linux -mno-thumb-interwork
+# - with ELDK 4.1 (gcc 4.x, no EABI), use:
+#	-mabi=apcs-gnu -mno-thumb-interwork
+# - with ELDK 3.1 (gcc 3.x), use:
+#	-mapcs-32 -mno-thumb-interwork
+PLATFORM_CPPFLAGS += $(call cc-option,\
+				-mabi=aapcs-linux -mno-thumb-interwork,\
+				$(call cc-option,\
+					-mapcs-32,\
+					$(call cc-option,\
+						-mabi=apcs-gnu,\
+					)\
+				) $(call cc-option,-mno-thumb-interwork,)\
+			)
+
+# For EABI, make sure to provide raise()
+ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
+# This file is parsed several times; make sure to add only once.
+ifeq (,$(findstring lib_arm/eabi_compat.o,$(PLATFORM_LIBS)))
+PLATFORM_LIBS += $(OBJTREE)/lib_arm/eabi_compat.o
+endif
+endif
 LDSCRIPT := $(SRCTREE)/cpu/$(CPU)/u-boot.lds
diff --git a/lib_arm/eabi_compat.c b/lib_arm/eabi_compat.c
new file mode 100644
index 00000000000..86eacf1b0e9
--- /dev/null
+++ b/lib_arm/eabi_compat.c
@@ -0,0 +1,18 @@
+/*
+ * Utility functions needed for (some) EABI conformant tool chains.
+ *
+ * (C) Copyright 2009 Wolfgang Denk <wd@denx.de>
+ *
+ * This program is Free Software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <common.h>
+
+int raise (int signum)
+{
+	printf("raise: Signal # %d caught\n", signum);
+	return 0;
+}
-- 
GitLab