[coreboot] New patch to review for coreboot: 5b1d2d9 Make xcompile support multiple architectures

Ronald G. Minnich (rminnich@gmail.com) gerrit at coreboot.org
Mon Nov 26 23:29:51 CET 2012


Ronald G. Minnich (rminnich at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1914

-gerrit

commit 5b1d2d919ae67d5e618adb3ca6e776c281680477
Author: Ronald G. Minnich <rminnich at gmail.com>
Date:   Mon Nov 26 14:26:36 2012 -0800

    Make xcompile support multiple architectures
    
    With this change the the xcompile script now creates environment variables
    for more than one architecture.
    
    Change-Id: Ic9c080a0297381930060a4daaf22406edaf8c586
    Signed-off-by: David Hendricks <dhendrix at chromium.org>
    Signed-off-by: Hung-Te Lin <hungte at chromium.org>
    Signed-off-by: Stefan Reinauer <stepan at coresystems.de>
    Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>
---
 Makefile                        |  30 ++++-
 Makefile.inc                    |   1 -
 documentation/cbfs.txt          |  24 +++-
 payloads/coreinfo/cbfs_module.c |   3 +-
 src/Kconfig                     |   9 ++
 src/arch/x86/Makefile.inc       |   2 +-
 src/arch/x86/include/stddef.h   |  24 ----
 src/console/Kconfig             |  38 +++++-
 src/console/post.c              |   4 +
 src/cpu/Kconfig                 |  21 ++++
 src/cpu/Makefile.inc            |   1 +
 src/drivers/Kconfig             |   1 +
 src/drivers/Makefile.inc        |   1 +
 src/include/cbfs_core.h         |  21 +++-
 src/lib/gcc.c                   |  11 ++
 src/mainboard/Kconfig           |  16 +++
 util/cbfstool/cbfs-mkstage.c    |   7 ++
 util/cbfstool/cbfs.h            |  14 ++-
 util/cbfstool/cbfstool.c        |  46 +++++--
 util/cbfstool/common.c          | 178 ++++++++++++++++++++++------
 util/cbfstool/common.h          |  16 +++
 util/xcompile/xcompile          | 257 ++++++++++++++++++++++++++++------------
 22 files changed, 554 insertions(+), 171 deletions(-)

diff --git a/Makefile b/Makefile
index b40574b..6c8fb03 100644
--- a/Makefile
+++ b/Makefile
@@ -76,9 +76,8 @@ endif
 
 HOSTCC = gcc
 HOSTCXX = g++
-HOSTCFLAGS := -g
-HOSTCXXFLAGS := -g
-LIBGCC_FILE_NAME := $(shell test -r `$(CC) -print-libgcc-file-name` && $(CC) -print-libgcc-file-name)
+HOSTCFLAGS := -I$(srck) -I$(objk) -g
+HOSTCXXFLAGS := -I$(srck) -I$(objk)
 
 DOXYGEN := doxygen
 DOXYGEN_OUTPUT_DIR := doxygen
@@ -114,6 +113,31 @@ else
 
 include $(HAVE_DOTCONFIG)
 
+ARCHDIR-$(CONFIG_ARCH_ARM)     := armv7
+ARCHDIR-$(CONFIG_ARCH_X86)     := x86
+
+ARCH-y := $(ARCHDIR-y)
+
+# If architecture folder name is different from GCC binutils architecture name,
+# override here.
+ARCH-$(CONFIG_ARCH_ARM)     := littlearm
+ARCH-$(CONFIG_ARCH_X86)     := i386
+
+CC := $(CC_$(ARCH-y))
+AS := $(AS_$(ARCH-y))
+LD := $(LD_$(ARCH-y))
+NM := $(NM_$(ARCH-y))
+OBJCOPY := $(OBJCOPY_$(ARCH-y))
+OBJDUMP := $(OBJDUMP_$(ARCH-y))
+READELF := $(READELF_$(ARCH-y))
+STRIP := $(STRIP_$(ARCH-y))
+AR := $(AR_$(ARCH-y))
+
+CFLAGS += $(CFLAGS_$(ARCH-y))
+
+LIBGCC_FILE_NAME := $(shell test -r `$(CC) -print-libgcc-file-name` && \
+		      $(CC) -print-libgcc-file-name)
+
 ifneq ($(INNER_SCANBUILD),y)
 ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
 CC:=clang -m32 -mno-mmx -mno-sse
diff --git a/Makefile.inc b/Makefile.inc
index 4c0a53f..ff7454e 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -23,7 +23,6 @@ export KERNELVERSION := $(shell if [ -d "$(top)/.git" -a -f "`which git`" ]; the
 
 #######################################################################
 # Basic component discovery
-ARCHDIR-$(CONFIG_ARCH_X86) := x86
 MAINBOARDDIR=$(call strip_quotes,$(CONFIG_MAINBOARD_DIR))
 export MAINBOARDDIR
 
diff --git a/documentation/cbfs.txt b/documentation/cbfs.txt
index 61f9f79..4b266f2 100644
--- a/documentation/cbfs.txt
+++ b/documentation/cbfs.txt
@@ -144,11 +144,15 @@ need to read the pointer and do the appropriate math to locate the header.
 The following is the structure of the master header:
 
 struct cbfs_header {
-	unsigned int magic;
-	unsigned int size;
-	unsigned int align;
-	unsigned int offset;
-};
+        u32 magic;
+        u32 version;
+        u32 romsize;
+        u32 bootblocksize;
+        u32 align;
+        u32 offset;
+        u32 architecture;
+        u32 pad[1];
+} __attribute__((packed));
 
 The meaning of each member is as follows:
 
@@ -156,9 +160,14 @@ The meaning of each member is as follows:
 magic
 number is 0x4F524243, which is 'ORBC' in ASCII.
 
-'size' is the size of the ROM in bytes.  Coreboot will subtract 'size' from
+'version' is a version number for CBFS header. cbfs_header structure may be
+different if version is not matched.
+
+'romsize' is the size of the ROM in bytes.  Coreboot will subtract 'size' from
 0xFFFFFFFF to locate the beginning of the ROM in memory.
 
+'bootblocksize' is the size of bootblock reserved in firmware image.
+
 'align' is the number of bytes that each component is aligned to within the
 ROM.  This is used to make sure that each component is aligned correctly
 with
@@ -169,6 +178,9 @@ component at runtime without disturbing the others.
 the ROM).  This is to allow for arbitrary space to be left at the beginning
 of the ROM for things like embedded controller firmware.
 
+'architecture' describes which architecture (x86, arm, ...) this CBFS is created
+for.
+
 = Bootblock =
 The bootblock is a mandatory component in the ROM.  It is located in the
 last
diff --git a/payloads/coreinfo/cbfs_module.c b/payloads/coreinfo/cbfs_module.c
index ceb0e3c..0635747 100644
--- a/payloads/coreinfo/cbfs_module.c
+++ b/payloads/coreinfo/cbfs_module.c
@@ -41,7 +41,8 @@ struct cbheader {
 	u32 bootblocksize;
 	u32 align;
 	u32 offset;
-	u32 pad[2];
+	u32 architecture;
+	u32 pad[1];
 } __attribute__ ((packed));
 
 struct cbfile {
diff --git a/src/Kconfig b/src/Kconfig
index fadcbc4..a8ae1e9 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -63,6 +63,7 @@ config COMPILER_GCC
 
 config COMPILER_LLVM_CLANG
 	bool "LLVM/clang"
+	depends on ARCH_X86
 	help
 	  Use LLVM/clang to build coreboot.
 
@@ -204,10 +205,18 @@ config ARCH_X86
 	bool
 	default n
 
+config ARCH_ARM
+	bool
+	default n
+
 if ARCH_X86
 source src/arch/x86/Kconfig
 endif
 
+if ARCH_ARM
+source src/arch/armv7/Kconfig
+endif
+
 menu "Chipset"
 
 comment "CPU"
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 44787a3..2ea1205 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -65,7 +65,7 @@ prebuild-files = \
 prebuilt-files = $(foreach file,$(cbfs-files), $(call extract_nth,1,$(file)))
 
 $(obj)/coreboot.pre1: $(objcbfs)/bootblock.bin $$(prebuilt-files) $(CBFSTOOL)
-	$(CBFSTOOL) $@.tmp create -s $(CONFIG_COREBOOT_ROMSIZE_KB)K \
+	$(CBFSTOOL) $@.tmp create -m x86 -s $(CONFIG_COREBOOT_ROMSIZE_KB)K \
 		-B $(objcbfs)/bootblock.bin -a 64 \
 		-o $$(( $(CONFIG_ROM_SIZE) - $(CONFIG_CBFS_SIZE) ))
 	$(prebuild-files) true
diff --git a/src/arch/x86/include/stddef.h b/src/arch/x86/include/stddef.h
deleted file mode 100644
index fc89de5..0000000
--- a/src/arch/x86/include/stddef.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef I386_STDDEF_H
-#define I386_STDDEF_H
-
-typedef long ptrdiff_t;
-#ifndef __SIZE_TYPE__
-#define __SIZE_TYPE__ unsigned long
-#endif
-typedef __SIZE_TYPE__ size_t;
-typedef long ssize_t;
-
-typedef int wchar_t;
-typedef unsigned int wint_t;
-
-#define NULL ((void *)0)
-
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-
-#ifdef __PRE_RAM__
-#define ROMSTAGE_CONST const
-#else
-#define ROMSTAGE_CONST
-#endif
-
-#endif /* I386_STDDEF_H */
diff --git a/src/console/Kconfig b/src/console/Kconfig
index c1c2012..3f5b6ed 100644
--- a/src/console/Kconfig
+++ b/src/console/Kconfig
@@ -1,18 +1,33 @@
 menu "Console"
-# TODO: Rename to SERIAL_CONSOLE once Kconfig transition is complete.
-config CONSOLE_SERIAL8250
+config SERIAL_CONSOLE
 	bool "Serial port console output"
+	default y
+	help
+	  Send coreboot debug output to a serial port
+
+config CONSOLE_SERIAL8250
+	bool "Serial port console output (I/O mapped, 8250-compatible)"
+	depends on SERIAL_CONSOLE
 	depends on HAVE_UART_IO_MAPPED
 	default y
 	help
 	  Send coreboot debug output to an I/O mapped serial port console.
 
 config CONSOLE_SERIAL8250MEM
-	bool "Serial port console output (memory mapped)"
+	bool "Serial port console output (memory mapped, 8250-compatible)"
+	depends on SERIAL_CONSOLE
 	depends on HAVE_UART_MEMORY_MAPPED
 	help
 	  Send coreboot debug output to a memory mapped serial port console.
 
+config CONSOLE_SERIAL_NONSTANDARD_MEM
+	bool "Serial port console output (memory-mapped, device-specific)"
+	depends on SERIAL_CONSOLE
+	depends on HAVE_UART_MEMORY_MAPPED
+	help
+	  Send coreboot debug output to a memory mapped serial port console
+	  on a device-specific UART.
+
 choice
 	prompt "Serial port"
 	default CONSOLE_SERIAL_COM1
@@ -50,7 +65,7 @@ config TTYS0_BASE
 choice
 	prompt "Baud rate"
 	default CONSOLE_SERIAL_115200
-	depends on CONSOLE_SERIAL8250 || CONSOLE_SERIAL8250MEM
+	depends on SERIAL_CONSOLE
 
 config CONSOLE_SERIAL_115200
 	bool "115200"
@@ -75,6 +90,7 @@ config CONSOLE_SERIAL_9600
 
 endchoice
 
+#FIXME(dhendrix): Change name to SERIAL_BAUD?
 config TTYS0_BAUD
 	int
 	default 115200 if CONSOLE_SERIAL_115200
@@ -360,9 +376,21 @@ config NO_POST
 	bool "Don't show any POST codes"
 	default n
 
-config POST_PORT
+config IO_POST
+	bool "Send POST codes to an IO port"
+	default y
+	help
+	  If enabled, POST codes will be written to an IO port.
+
+config IO_POST_PORT
+	depends on IO_POST
 	hex
 	default 0x80
+	help
+	  POST codes on x86 are historically written to the LPC bus on port
+	  0x80. However, it may be desireable to change the port number
+	  depending on the presence of coprocessors/microcontrollers or if the
+	  platform does not support IO in the conventional x86 manner.
 
 config CONSOLE_POST
 	bool "Show POST codes on the debug console"
diff --git a/src/console/post.c b/src/console/post.c
index a565c6b..ac9fbd3 100644
--- a/src/console/post.c
+++ b/src/console/post.c
@@ -21,7 +21,9 @@
 
 #include <arch/io.h>
 #include <console/console.h>
+#if CONFIG_IO_POST
 #include <pc80/mc146818rtc.h>
+#endif
 #include <elog.h>
 
 /* Write POST information */
@@ -100,7 +102,9 @@ void post_code(uint8_t value)
 #if CONFIG_CMOS_POST
 	cmos_post_code(value);
 #endif
+#if CONFIG_IO_POST
 	outb(value, CONFIG_POST_PORT);
 #endif
+#endif
 	mainboard_post(value);
 }
diff --git a/src/cpu/Kconfig b/src/cpu/Kconfig
index 1ed721f..1f0adf8 100644
--- a/src/cpu/Kconfig
+++ b/src/cpu/Kconfig
@@ -1,3 +1,24 @@
+if ARCH_ARM
+
+source src/cpu/samsung/Kconfig
+
+# TODO(dhendrix): not sure if these can be used on exynos5...
+#config CACHE_AS_RAM
+#	bool
+#	default !ROMCC
+#
+#config DCACHE_RAM_BASE
+#	hex
+#
+#config DCACHE_RAM_SIZE
+#	hex
+#
+#config DCACHE_RAM_GLOBAL_VAR_SIZE
+#	hex
+#	default 0x0
+
+endif	# ARCH_ARM
+
 if ARCH_X86
 
 source src/cpu/amd/Kconfig
diff --git a/src/cpu/Makefile.inc b/src/cpu/Makefile.inc
index 938a8df..93b16ae 100644
--- a/src/cpu/Makefile.inc
+++ b/src/cpu/Makefile.inc
@@ -3,6 +3,7 @@
 ################################################################################
 subdirs-y += amd
 subdirs-y += intel
+subdirs-y += samsung
 subdirs-y += via
 
 ################################################################################
diff --git a/src/drivers/Kconfig b/src/drivers/Kconfig
index b6eec3d..1ff42e3 100644
--- a/src/drivers/Kconfig
+++ b/src/drivers/Kconfig
@@ -31,3 +31,4 @@ source src/drivers/realtek/Kconfig
 source src/drivers/sil/Kconfig
 source src/drivers/spi/Kconfig
 source src/drivers/trident/Kconfig
+source src/drivers/maxim/Kconfig
diff --git a/src/drivers/Makefile.inc b/src/drivers/Makefile.inc
index a02b705..65800f0 100644
--- a/src/drivers/Makefile.inc
+++ b/src/drivers/Makefile.inc
@@ -30,4 +30,5 @@ subdirs-y += ics
 subdirs-y += spi
 subdirs-y += ipmi
 subdirs-y += elog
+subdirs-y += maxim
 subdirs-$(CONFIG_ARCH_X86) += pc80
diff --git a/src/include/cbfs_core.h b/src/include/cbfs_core.h
index 43e6b9b..6fb4e04 100644
--- a/src/include/cbfs_core.h
+++ b/src/include/cbfs_core.h
@@ -78,13 +78,19 @@
 
 /** this is the master cbfs header - it need to be
     located somewhere in the bootblock.  Where it
-    actually lives is up to coreboot. A pointer to
-    this header will live at 0xFFFFFFFc, so we can
-    easily find it. */
+    actually lives is up to coreboot. On x86, a
+    pointer to this header will live at 0xFFFFFFFc,
+    so we can easily find it. */
 
 #define CBFS_HEADER_MAGIC  0x4F524243
+#if CONFIG_ARCH_X86
 #define CBFS_HEADPTR_ADDR 0xFFFFFFFc
+#elif CONFIG_ARCH_ARM
+#define CBFS_HEADPTR_ADDR 0x0000000c
+#endif
 #define VERSION1 0x31313131
+#define VERSION2 0x31313132
+#define VERSION  VERSION2
 
 struct cbfs_header {
 	uint32_t magic;
@@ -93,9 +99,15 @@ struct cbfs_header {
 	uint32_t bootblocksize;
 	uint32_t align;
 	uint32_t offset;
-	uint32_t pad[2];
+	uint32_t architecture;
+	uint32_t pad[1];
 } __attribute__((packed));
 
+// "Legacy" refers to cbfs headers before architecture is defined (i.e., X86).
+#define CBFS_ARCHITECTURE_LEGACY   0xFFFFFFFF
+#define CBFS_ARCHITECTURE_ARM      0x10
+#define CBFS_ARCHITECTURE_X86      0x20
+
 /** This is a component header - every entry in the CBFS
     will have this header.
 
@@ -180,4 +192,3 @@ void *cbfs_find_file(const char *name, int type);
 int cbfs_decompress(int algo, void *src, void *dst, int len);
 struct cbfs_header *get_cbfs_header(void);
 #endif
-
diff --git a/src/lib/gcc.c b/src/lib/gcc.c
index 9b6ef03..e2e5bad 100644
--- a/src/lib/gcc.c
+++ b/src/lib/gcc.c
@@ -22,10 +22,21 @@
  * compiler call specifies. Therefore we need a wrapper around those
  * functions. See gcc bug PR41055 for more information.
  */
+
+#if CONFIG_ARCH_X86
 #define WRAP_LIBGCC_CALL(type, name) \
 	type __real_##name(type a, type b) __attribute__((regparm(0))); \
 	type __wrap_##name(type a, type b); \
 	type __wrap_##name(type a, type b) { return __real_##name(a, b); }
+#elif CONFIG_ARCH_ARM
+#define WRAP_LIBGCC_CALL(type, name) \
+	type __real_##name(type a, type b); \
+	type __wrap_##name(type a, type b); \
+	type __wrap_##name(type a, type b) { return __real_##name(a, b); }
+#else
+#error Architecture unsupported.
+#endif
+
 
 WRAP_LIBGCC_CALL(long long, __divdi3)
 WRAP_LIBGCC_CALL(unsigned long long, __udivdi3)
diff --git a/src/mainboard/Kconfig b/src/mainboard/Kconfig
index da76327..734aaf2 100644
--- a/src/mainboard/Kconfig
+++ b/src/mainboard/Kconfig
@@ -58,6 +58,8 @@ config VENDOR_GETAC
 	bool "Getac"
 config VENDOR_GIGABYTE
 	bool "GIGABYTE"
+config VENDOR_GOOGLE
+	bool "Google"
 config VENDOR_HP
 	bool "HP"
 config VENDOR_IBASE
@@ -158,6 +160,7 @@ source "src/mainboard/ecs/Kconfig"
 source "src/mainboard/emulation/Kconfig"
 source "src/mainboard/getac/Kconfig"
 source "src/mainboard/gigabyte/Kconfig"
+source "src/mainboard/google/Kconfig"
 source "src/mainboard/hp/Kconfig"
 source "src/mainboard/ibase/Kconfig"
 source "src/mainboard/ibm/Kconfig"
@@ -304,6 +307,19 @@ config ROM_SIZE
 	default 0x800000 if COREBOOT_ROMSIZE_KB_8192
 	default 0x1000000 if COREBOOT_ROMSIZE_KB_16384
 
+# FIXME: does this need to be here or in sandybridge/ ?
+#config CBFS_SIZE
+#	hex
+#	default ROM_SIZE
+
+config CACHE_ROM_SIZE
+	hex
+	default ROM_SIZE
+
+config CACHE_ROM_SIZE
+	hex
+	default CBFS_SIZE
+
 config ENABLE_POWER_BUTTON
 	bool "Enable the power button" if POWER_BUTTON_IS_OPTIONAL
 	default y if POWER_BUTTON_DEFAULT_ENABLE
diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c
index 55c81c6..17ad0da 100644
--- a/util/cbfstool/cbfs-mkstage.c
+++ b/util/cbfstool/cbfs-mkstage.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2008 Jordan Crouse <jordan at cosmicpenguin.net>
  *               2009 coresystems GmbH
  *                 written by Patrick Georgi <patrick.georgi at coresystems.de>
+ *               2012 Google Inc
  *
  * 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
@@ -71,6 +72,12 @@ int parse_elf_to_stage(unsigned char *input, unsigned char **output,
 		return -1;
 	}
 
+	if (!((ehdr->e_machine == EM_ARM) && (arch == ARCH_ARMV7)) &&
+	    !((ehdr->e_machine == EM_386) && (arch == ARCH_X86))) {
+		fprintf(stderr, "E:  The incoming file has the wrong architecture\n");
+		return -1;
+	}
+
 	if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {
 		elf_bigendian = 1;
 	}
diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h
index f161ed4..f539a9b 100644
--- a/util/cbfstool/cbfs.h
+++ b/util/cbfstool/cbfs.h
@@ -21,6 +21,12 @@
 
 #include <stdint.h>
 
+#define CBFS_HEADER_MAGIC  0x4F524243
+#define CBFS_HEADPTR_ADDR_X86 0xFFFFFFFC
+#define VERSION1 0x31313131
+#define VERSION2 0x31313132
+#define VERSION  VERSION2
+
 struct cbfs_header {
 	uint32_t magic;
 	uint32_t version;
@@ -28,9 +34,15 @@ struct cbfs_header {
 	uint32_t bootblocksize;
 	uint32_t align;
 	uint32_t offset;
-	uint32_t pad[2];
+	uint32_t architecture;
+	uint32_t pad[1];
 } __attribute__ ((packed));
 
+// "Legacy" refers to cbfs headers before architecture is defined (i.e., X86).
+#define CBFS_ARCHITECTURE_LEGACY   0xFFFFFFFF
+#define CBFS_ARCHITECTURE_ARM      0x10
+#define CBFS_ARCHITECTURE_X86      0x20
+
 struct cbfs_file {
 	uint8_t magic[8];
 	uint32_t len;
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c
index 66db379..4fcb7be 100644
--- a/util/cbfstool/cbfstool.c
+++ b/util/cbfstool/cbfstool.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2009 coresystems GmbH
  *                 written by Patrick Georgi <patrick.georgi at coresystems.de>
+ * Copyright (C) 2012 Google Inc
  *
  * 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
@@ -177,6 +178,11 @@ static int cbfs_add_stage(void)
 		return 1;
 	}
 
+	if (arch == ARCH_UNKNOWN) {
+		fprintf(stderr, "E: You need to specify -m/--machine arch\n");
+		return 1;
+	}
+
 	rom = loadrom(cbfs_name);
 	if (rom == NULL) {
 		fprintf(stderr, "E: Could not load ROM image '%s'.\n",
@@ -372,6 +378,11 @@ static int cbfs_create(void)
 		return 1;
 	}
 
+	if (arch == ARCH_UNKNOWN) {
+		fprintf(stderr, "E: You need to specify -m/--machine arch\n");
+		return 1;
+	}
+
 	return create_cbfs_image(cbfs_name, rom_size, rom_bootblock,
 						rom_alignment, rom_offset);
 }
@@ -390,6 +401,11 @@ static int cbfs_locate(void)
 		return 1;
 	}
 
+	if (arch == ARCH_UNKNOWN) {
+		fprintf(stderr, "E: You need to specify -m/--machine arch\n");
+		return 1;
+	}
+
 	filesize = getfilesize(rom_filename);
 
 	location = cbfs_find_location(cbfs_name, filesize,
@@ -447,11 +463,11 @@ static int cbfs_extract(void)
 static const struct command commands[] = {
 	{"add", "f:n:t:b:h?", cbfs_add},
 	{"add-payload", "f:n:t:c:b:h?", cbfs_add_payload},
-	{"add-stage", "f:n:t:c:b:h?", cbfs_add_stage},
+	{"add-stage", "f:n:t:c:b:m:h?", cbfs_add_stage},
 	{"add-flat-binary", "f:n:l:e:c:b:h?", cbfs_add_flat_binary},
 	{"remove", "n:h?", cbfs_remove},
-	{"create", "s:B:a:o:h?", cbfs_create},
-	{"locate", "f:n:a:h?", cbfs_locate},
+	{"create", "s:B:a:o:m:h?", cbfs_create},
+	{"locate", "f:n:a:m:h?", cbfs_locate},
 	{"print", "h?", cbfs_print},
 	{"extract", "n:f:h?", cbfs_extract},
 };
@@ -468,6 +484,7 @@ static struct option long_options[] = {
 	{"alignment",    required_argument, 0, 'a' },
 	{"offset",       required_argument, 0, 'o' },
 	{"file",         required_argument, 0, 'f' },
+	{"arch",         required_argument, 0, 'm' },
 	{"verbose",      no_argument,       0, 'v' },
 	{"help",         no_argument,       0, 'h' },
 	{NULL,           0,                 0,  0  }
@@ -481,26 +498,28 @@ static void usage(char *name)
 	     " %s FILE COMMAND [PARAMETERS]...\n\n" "OPTIONs:\n"
 	     "  -h		Display this help message\n\n"
 	     "COMMANDs:\n"
-	     " add -f FILE -n NAME -t TYPE [-b base-address]             "
+	     " add -f FILE -n NAME -t TYPE [-b base-address]               "
 			"Add a component\n"
-	     " add-payload -f FILE -n NAME [-c compression] [-b base]    "
+	     " add-payload -f FILE -n NAME [-c compression] [-b base]      "
 			"Add a payload to the ROM\n"
-	     " add-stage -f FILE -n NAME [-c compression] [-b base]      "
+	     " add-stage -f FILE -n NAME [-c compression] [-b base] -m ARCH"
 			"Add a stage to the ROM\n"
 	     " add-flat-binary -f FILE -n NAME -l load-address \\\n"
-	     "        -e entry-point [-c compression] [-b base]          "
+	     "        -e entry-point [-c compression] [-b base]            "
 			"Add a 32bit flat mode binary\n"
-	     " remove -n NAME                                            "
+	     " remove -n NAME                                              "
 			"Remove a component\n"
-	     " create -s size -B bootblock [-a align] [-o offset]        "
+	     " create -s size -B bootblock -m ARCH [-a align] [-o offset]  "
 			"Create a ROM file\n"
-	     " locate -f FILE -n NAME -a align                           "
+	     " locate -f FILE -n NAME -a align -m ARCH                     "
 			"Find a place for a file of that size\n"
-	     " print                                                     "
+	     " print                                                       "
 			"Show the contents of the ROM\n"
-	     " extract -n NAME -f FILE                                   "
+	     " extract -n NAME -f FILE                                     "
 			"Extracts a raw payload from ROM\n"
 	     "\n"
+	     "ARCHes:\n"
+	     "  armv7, x86\n"
 	     "TYPEs:\n", name, name
 	    );
 	print_supported_filetypes();
@@ -610,6 +629,9 @@ int main(int argc, char **argv)
 			case 'v':
 				verbose++;
 				break;
+			case 'm':
+				arch = string_to_arch(optarg);
+				break;
 			case 'h':
 			case '?':
 				usage(argv[0]);
diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c
index 6c67c39..4a6256e 100644
--- a/util/cbfstool/common.c
+++ b/util/cbfstool/common.c
@@ -73,19 +73,74 @@ static struct cbfs_header *master_header;
 static uint32_t phys_start, phys_end, align;
 uint32_t romsize;
 void *offset;
+arch_t arch = ARCH_UNKNOWN;
 
 void recalculate_rom_geometry(void *romarea)
 {
-	offset = romarea + romsize - 0x100000000ULL;
-	master_header = (struct cbfs_header *)
-	    phys_to_virt(*((uint32_t *) phys_to_virt(0xfffffffc)));
-	phys_start = (0 - romsize + ntohl(master_header->offset)) & 0xffffffff;
-	phys_end =
-	    (0 - ntohl(master_header->bootblocksize) -
-	     sizeof(struct cbfs_header)) & 0xffffffff;
+	switch (arch) {
+	case ARCH_ARMV7:
+		offset = romarea;
+		master_header = (struct cbfs_header *)(romarea + 0x20);
+		phys_start = (0 + ntohl(master_header->offset)) & 0xffffffff;
+		phys_end = romsize & 0xffffffff;
+		break;
+
+	case ARCH_X86:
+		offset = romarea + romsize - 0x100000000ULL;
+		master_header = (struct cbfs_header *)
+		    phys_to_virt(*((uint32_t *) phys_to_virt(0xfffffffc)));
+		phys_start = (0 - romsize + ntohl(master_header->offset)) &
+				0xffffffff;
+		phys_end = (0 - ntohl(master_header->bootblocksize) -
+		     sizeof(struct cbfs_header)) & 0xffffffff;
+		break;
+	default:
+		printf("Unknown architecture\n");
+		exit(1);
+	}
+
 	align = ntohl(master_header->align);
 }
 
+struct arch_name arch_names[] = {
+	{ ARCH_ARMV7, "armv7" },
+	{ ARCH_X86, "i386" },
+	{ ARCH_X86, "x86" },
+	{ ARCH_X86, "x86_64" },
+	{ ARCH_UNKNOWN, "unknown" }
+};
+
+arch_t string_to_arch(const char *arch_string)
+{
+	int i;
+	arch_t ret = ARCH_UNKNOWN;
+
+	for (i = 0; i < ARRAY_SIZE(arch_names); i++) {
+		if (!strcasecmp(arch_string, arch_names[i].name)) {
+			ret = arch_names[i].arch;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+const char *arch_to_string(arch_t a)
+{
+	int i;
+	const char *ret = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(arch_names); i++) {
+		if (a == arch_names[i].arch) {
+			ret = arch_names[i].name;
+			break;
+		}
+	}
+
+	return ret;
+
+}
+
 void *loadrom(const char *filename)
 {
 	void *romarea = loadfile(filename, &romsize, 0, SEEK_SET);
@@ -188,9 +243,10 @@ uint64_t intfiletype(const char *name)
 void print_cbfs_directory(const char *filename)
 {
 	printf
-	    ("%s: %d kB, bootblocksize %d, romsize %d, offset 0x%x\nAlignment: %d bytes\n\n",
+	    ("%s: %d kB, bootblocksize %d, romsize %d, offset 0x%x\n"
+	     "Alignment: %d bytes, architecture: %s\n\n",
 	     basename((char *)filename), romsize / 1024, ntohl(master_header->bootblocksize),
-	     romsize, ntohl(master_header->offset), align);
+	     romsize, ntohl(master_header->offset), align, arch_to_string(arch));
 	printf("%-30s %-10s %-12s Size\n", "Name", "Offset", "Type");
 	uint32_t current = phys_start;
 	while (current < phys_end) {
@@ -206,8 +262,8 @@ void print_cbfs_directory(const char *filename)
 			fname = "(empty)";
 
 		printf("%-30s 0x%-8x %-12s %d\n", fname,
-		       current - phys_start, strfiletype(ntohl(thisfile->type)),
-		       length);
+		       current - phys_start + ntohl(master_header->offset),
+		       strfiletype(ntohl(thisfile->type)), length);
 		current =
 		    ALIGN(current + ntohl(thisfile->len) +
 			  ntohl(thisfile->offset), align);
@@ -451,7 +507,7 @@ void *create_cbfs_file(const char *filename, void *data, uint32_t * datasize,
 }
 
 int create_cbfs_image(const char *romfile, uint32_t _romsize,
-		      const char *bootblock, uint32_t align, uint32_t offs)
+		const char *bootblock, uint32_t align, uint32_t offs)
 {
 	uint32_t bootblocksize = 0;
 	struct cbfs_header *master_header;
@@ -466,9 +522,6 @@ int create_cbfs_image(const char *romfile, uint32_t _romsize,
 	}
 	memset(romarea, 0xff, romsize);
 
-	// Set up physical/virtual mapping
-	offset = romarea + romsize - 0x100000000ULL;
-
 	if (align == 0)
 		align = 64;
 
@@ -481,24 +534,83 @@ int create_cbfs_image(const char *romfile, uint32_t _romsize,
 		return 1;
 	}
 
-	master_header =
-	    (struct cbfs_header *)(romarea + romsize - bootblocksize -
-				   sizeof(struct cbfs_header));
-	master_header->magic = ntohl(0x4f524243);
-	master_header->version = ntohl(0x31313131);
-	master_header->romsize = htonl(romsize);
-	master_header->bootblocksize = htonl(bootblocksize);
-	master_header->align = htonl(align);
-	master_header->offset = htonl(offs);
-	((uint32_t *) phys_to_virt(0xfffffffc))[0] =
-	    virt_to_phys(master_header);
-
-	recalculate_rom_geometry(romarea);
-
-	cbfs_create_empty_file((0 - romsize + offs) & 0xffffffff,
-				   romsize - offs - bootblocksize -
-				   sizeof(struct cbfs_header) -
-				   sizeof(struct cbfs_file) - 16);
+	// TODO(hungte) Replace magic numbers by named constants.
+	switch (arch) {
+	case ARCH_ARMV7:
+		/* Set up physical/virtual mapping */
+		offset = romarea;
+
+		// should be aligned to align but then we need to dynamically
+		// create the jump to the bootblock
+		loadfile(bootblock, &bootblocksize, romarea + 0x20 +
+			 sizeof(struct cbfs_header), SEEK_SET);
+		master_header = (struct cbfs_header *)(romarea + 0x20);
+		uint32_t *arm_vec = (uint32_t *)romarea;
+		/*
+		 * Encoding for this branch instruction is:
+		 * 31:28 - condition (0xe for always/unconditional)
+		 * 27:24 - 0xa
+		 * 23: 0 - sign-extended offset (in multiples of 4)
+		 *
+		 * When executing the branch, the PC will read as the address
+		 * of current instruction + 8.
+		 */
+		arm_vec[0] = htonl(0x0e0000ea);  // branch to . + 64 bytes
+
+		master_header->magic = ntohl(CBFS_HEADER_MAGIC);
+		master_header->version = ntohl(VERSION);
+		master_header->romsize = htonl(romsize);
+		master_header->bootblocksize = htonl(bootblocksize);
+		master_header->align = htonl(align);
+		master_header->offset = htonl(
+				ALIGN((0x40 + bootblocksize), align));
+		master_header->architecture = CBFS_ARCHITECTURE_ARM;
+
+		((uint32_t *) phys_to_virt(0x4))[0] =
+				virt_to_phys(master_header);
+
+		recalculate_rom_geometry(romarea);
+
+		cbfs_create_empty_file(
+				ALIGN((0x40 + bootblocksize), align),
+				romsize - ALIGN((bootblocksize + 0x40), align)
+				//- sizeof(struct cbfs_header)
+				- sizeof(struct cbfs_file) );
+		break;
+
+	case ARCH_X86:
+		// Set up physical/virtual mapping
+		offset = romarea + romsize - 0x100000000ULL;
+
+		loadfile(bootblock, &bootblocksize, romarea + romsize,
+			 SEEK_END);
+		master_header = (struct cbfs_header *)(romarea + romsize -
+				  bootblocksize - sizeof(struct cbfs_header));
+
+		master_header->magic = ntohl(CBFS_HEADER_MAGIC);
+		master_header->version = ntohl(VERSION1);
+		master_header->romsize = htonl(romsize);
+		master_header->bootblocksize = htonl(bootblocksize);
+		master_header->align = htonl(align);
+		master_header->offset = htonl(offs);
+		master_header->architecture = CBFS_ARCHITECTURE_X86;
+
+		((uint32_t *) phys_to_virt(CBFS_HEADPTR_ADDR_X86))[0] =
+		    virt_to_phys(master_header);
+
+		recalculate_rom_geometry(romarea);
+
+		cbfs_create_empty_file((0 - romsize + offs) & 0xffffffff,
+				       romsize - offs - bootblocksize -
+				       sizeof(struct cbfs_header) -
+				       sizeof(struct cbfs_file) - 16);
+		break;
+
+	case ARCH_UNKNOWN:
+		// Should not happen.
+		printf("You found a bug in cbfstool.\n");
+		exit(1);
+	}
 
 	writerom(romfile, romarea, romsize);
 	free(romarea);
diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h
index 4fcc1ee..9d168ab 100644
--- a/util/cbfstool/common.h
+++ b/util/cbfstool/common.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 coresystems GmbH
  *                 written by Patrick Georgi <patrick.georgi at coresystems.de>
+ * Copyright (C) 2012 Google Inc
  *
  * 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
@@ -30,6 +31,21 @@ extern void *offset;
 extern uint32_t romsize;
 extern int host_bigendian;
 
+typedef enum {
+	ARCH_UNKNOWN,
+	ARCH_ARMV7,
+	ARCH_X86,
+} arch_t;
+extern arch_t arch;
+
+struct arch_name {
+	arch_t arch;
+	const char *name;
+};
+extern struct arch_name arch_names[];
+const char *arch_to_string(arch_t a);
+arch_t string_to_arch(const char *arch_string);
+
 static inline void *phys_to_virt(uint32_t addr)
 {
 	return offset + addr;
diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile
index 3930460..084587e 100644
--- a/util/xcompile/xcompile
+++ b/util/xcompile/xcompile
@@ -3,6 +3,7 @@
 # This file is part of the coreboot project.
 #
 # Copyright (C) 2007-2010 coresystems GmbH
+# Copyright (C) 2012 Google Inc
 #
 # 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
@@ -18,104 +19,202 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 #
 
-testcc()
-{
-	echo "_start(void) {}" > .$$$$.c
-	$1 -nostdlib -Werror $2 .$$$$.c -o .$$$$.tmp 2>/dev/null >/dev/null
-	ret=$?
-	rm -f .$$$$.c .$$$$.tmp
-	return $ret
+TMPFILE=""
+
+die() {
+	echo "ERROR: $*" >&2
+	exit 1
 }
 
-for make in make gmake gnumake; do
-	if [ "`$make --version 2>/dev/null | grep -c GNU`" -gt 0 ]; then
-		MAKE=$make
-		break
+clean_up() {
+	if [ -n "$TMPFILE" ]; then
+		rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o"
 	fi
-done
+}
 
-GCCPREFIX=invalid
-XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
-echo '# XGCCPATH='${XGCCPATH}
-TMPFILE=`mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz`
-touch $TMPFILE
-
-# This loops over all supported architectures in TARCH
-TARCH=('i386' 'x86_64')
-TWIDTH=32
-for search_for in "${TARCH[@]}"; do
-	TARCH_SEARCH=("${TARCH_SEARCH[@]}" ${XGCCPATH}${search_for}-elf- ${search_for}-elf-)
-done
-echo '# TARCH_SEARCH='${TARCH_SEARCH[@]}
+program_exists() {
+	type "$1" >/dev/null 2>&1
+}
 
-for gccprefixes in "${TARCH_SEARCH[@]}" ""; do
-	if ! which ${gccprefixes}as 2>/dev/null >/dev/null; then
-		continue
-	fi
-	rm -f ${TMPFILE}.o
-	if ${gccprefixes}as -o ${TMPFILE}.o ${TMPFILE}; then
-		TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
-		if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
-			GCCPREFIX=$gccprefixes
-			ASFLAGS=
-			CFLAGS=
-			LDFLAGS=
-			break
-		fi
-	fi
-	if ${gccprefixes}as --32 -o ${TMPFILE}.o ${TMPFILE}; then
-		TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
-		if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
-			GCCPREFIX=$gccprefixes
-			ASFLAGS=--32
-			CFLAGS="-m32 -Wl,-b,elf32-i386 -Wl,-melf_i386 "
-			LDFLAGS="-b elf32-i386 -melf_i386"
-			break
+find_gnu_make() {
+	for make in make gmake gnumake; do
+		if [ "$($make --version 2>/dev/null | grep -c GNU)" -gt 0 ]
+		then
+			echo "$make"
+			return
 		fi
+	done
+}
+
+testcc() {
+	local tmp_c="$TMPFILE.c"
+	local tmp_o="$TMPFILE.o"
+	rm -f "$tmp_c" "$tmp_o"
+	echo "_start(void) {}" >"$tmp_c"
+	"$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
+}
+
+testas() {
+	local gccprefixes="$1"
+	local twidth="$2"
+	local arch="$3"
+	local use_dash_twidth="$4"
+	local obj_file="$TMPFILE.o"
+	local full_arch="elf$twidth-$arch"
+
+	rm -f "$obj_file"
+	[ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth"
+	${gccprefixes}as $use_dash_twidth -o "$obj_file" $TMPFILE 2>/dev/null ||
+		return 1
+
+	# Check output content type.
+	local obj_type="$(${gccprefixes}objdump -p $obj_file)"
+	local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')"
+	[ "$obj_arch" = "$full_arch" ] || return 1
+
+	# Architecture matched.
+	GCCPREFIX="$gccprefixes"
+
+	if [ -z "$use_dash_twidth" ]; then
+		ASFLAGS=""
+		CFLAGS=""
+		LDFLAGS=""
+	else
+		ASFLAGS="--$twidth"
+		CFLAGS="-m$twidth"
+		LDFLAGS="-b $full_arch"
+
 	fi
-done
-rm -f $TMPFILE ${TMPFILE}.o
 
-if [ "$GCCPREFIX" = "invalid" ]; then
-	echo '$(error no suitable gcc found)'
-	exit 1
-fi
+	# Special parameters only available in dash_twidth mode.
+	[ -n "$use_dash_twidth" ] && case "$full_arch" in
+		"elf32-i386" )
+			LDFLAGS="$LDFLAGS -melf_i386"
+			CFLAGS="$CFLAGS -Wl,-b,elf32-i386 -Wl,-melf_i386"
+			;;
+	esac
 
-CC="${GCCPREFIX}gcc"
-testcc "$CC" "$CFLAGS-Wa,--divide " && CFLAGS="$CFLAGS-Wa,--divide "
-testcc "$CC" "$CFLAGS-fno-stack-protector " && CFLAGS="$CFLAGS-fno-stack-protector "
-testcc "$CC" "$CFLAGS-Wl,--build-id=none " && CFLAGS="$CFLAGS-Wl,--build-id=none "
-# GCC 4.6 is much more picky about unused variables. Turn off it's warnings for
-# now:
-testcc "$CC" "$CFLAGS-Wno-unused-but-set-variable " && \
-	       CFLAGS="$CFLAGS-Wno-unused-but-set-variable "
+	return 0
+}
 
-if which gcc 2>/dev/null >/dev/null; then
-	HOSTCC=gcc
-else
-	HOSTCC=cc
-fi
+detect_special_flags() {
+	local architecture="$1"
+	# GCC 4.6 is much more picky about unused variables.
+	# Turn off it's warnings for now:
+	testcc "$CC"   "$CFLAGS -Wno-unused-but-set-variable " &&
+		CFLAGS="$CFLAGS -Wno-unused-but-set-variable "
+
+	# Use bfd linker instead of gold if available:
+	testcc "$CC"   "$CFLAGS -fuse-ld=bfd" &&
+		CFLAGS="$CFLAGS -fuse-ld=bfd" && LINKER_SUFFIX='.bfd'
+
+	testcc "$CC"   "$CFLAGS -Wa,--divide" &&
+		CFLAGS="$CFLAGS -Wa,--divide"
+	testcc "$CC"   "$CFLAGS -fno-stack-protector"&&
+		CFLAGS="$CFLAGS -fno-stack-protector"
+	testcc "$CC"   "$CFLAGS -Wl,--build-id=none" &&
+		CFLAGS="$CFLAGS -Wl,--build-id=none"
+
+	case "$architecture" in
+		arm )
+			# testcc "$CC" "$CFLAGS -mcpu=cortex-a9" &&
+			#	CFLAGS="$CFLAGS -mcpu=cortex-a9"
+			testcc "$CC" "\
+$CFLAGS -ffixed-r8 -msoft-float -marm -mabi=aapcs-linux \
+-mno-thumb-interwork -march=armv7 -mno-thumb-interwork" && CFLAGS="\
+$CFLAGS -ffixed-r8 -msoft-float -marm -mabi=aapcs-linux \
+-mno-thumb-interwork -march=armv7 -mno-thumb-interwork"
+			;;
+	esac
+}
+
+report_arch_toolchain() {
+	cat <<EOF
+# elf${TWIDTH}-${TARCH} toolchain (${GCCPREFIX}gcc)
+CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS}
+AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
+LD_${TARCH}:=${GCCPREFIX}ld ${LDFLAGS}
+NM_${TARCH}:=${GCCPREFIX}nm
+OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy
+OBJDUMP_${TARCH}:=${GCCPREFIX}objdump
+READELF_${TARCH}:=${GCCPREFIX}readelf
+STRIP_${TARCH}:=${GCCPREFIX}strip
+AR_${TARCH}:=${GCCPREFIX}ar
+
+EOF
+}
+
+# Create temporary file(s).
+TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)"
+touch "$TMPFILE"
+trap clean_up EXIT
+
+# Architecture definition
+SUPPORTED_ARCHITECTURE="x86 arm"
+
+# ARM Architecture
+TARCH_arm="littlearm"
+TCLIST_arm="littlearm"
+TWIDTH_arm="32"
+
+# X86 Architecture
+TARCH_x86="i386"
+TCLIST_x86="i386 x86_64"
+TWIDTH_x86="32"
 
-if [ "`${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI`" -gt 0 ]; then
+# This loops over all supported architectures.
+for architecture in $SUPPORTED_ARCHITECTURE; do
+	GCCPREFIX="invalid"
+	TARCH="$(eval echo \$TARCH_$architecture)"
+	TCLIST="$(eval echo \$TCLIST_$architecture)"
+	TWIDTH="$(eval echo \$TWIDTH_$architecture)"
+	[ -z "$TARCH" -o -z "$TCLIST" -o -z "$TWIDTH" ] &&
+		die "Missing architecture definition for $architecture."
+
+	# To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as
+	# environment variable.
+	# Ex: CROSS_COMPILE_arm="armv7a-cros-linux-gnueabi-"
+	#     CROSS_COMPILE_x86="i686-pc-linux-gnu-"
+	search="$(eval echo \$CROSS_COMPILE_$architecture 2>/dev/null)"
+	search="$search $CROSS_COMPILE"
+	for toolchain in $TCLIST; do
+		search="$search $XGCCPATH$toolchain-elf-"
+		search="$search $toolchain-elf-"
+	done
+	echo "# $architecture TARCH_SEARCH=$search"
+
+	# Search toolchain by checking assembler capability.
+	for gccprefixes in $search ""; do
+		program_exists "${gccprefixes}as" || continue
+		testas "$gccprefixes" "$TWIDTH" "$TARCH" "" && break
+		testas "$gccprefixes" "$TWIDTH" "$TARCH" "TRUE" && break
+	done
+
+	if [ "$GCCPREFIX" = "invalid" ]; then
+		echo "Warning: no suitable GCC for $architecture." >&2
+		continue
+	fi
+	CC="${GCCPREFIX}"gcc
+
+	detect_special_flags "$architecture"
+	report_arch_toolchain
+done
+
+if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
 	IASL=${XGCCPATH}iasl
 else
 	IASL=iasl
 fi
 
-cat << EOF
-# elf${TWIDTH}-${TARCH} toolchain
-AS:=${GCCPREFIX}as ${ASFLAGS}
-CC:=${GCCPREFIX}gcc ${CFLAGS}
-AR:=${GCCPREFIX}ar
-LD:=${GCCPREFIX}ld ${LDFLAGS}
-STRIP:=${GCCPREFIX}strip
-NM:=${GCCPREFIX}nm
-OBJCOPY:=${GCCPREFIX}objcopy
-OBJDUMP:=${GCCPREFIX}objdump
+if program_exists gcc; then
+	HOSTCC=gcc
+else
+	HOSTCC=cc
+fi
 
+cat <<EOF
 IASL:=${IASL}
 
 # native toolchain
 HOSTCC:=${HOSTCC}
 EOF
-




More information about the coreboot mailing list