[coreboot] New patch to review for coreboot: 3027231 libpayload: Initial ARMv7 port

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Fri Dec 14 22:07:56 CET 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2035

-gerrit

commit 302723138abc6aa3c4ed6d48e7ff7974b70f7522
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Fri Dec 14 13:05:21 2012 -0800

    libpayload: Initial ARMv7 port
    
    This compiles, but it's not tested yet.
    
    Change-Id: I2f73a814649aa36c39af3e77cefd8a968671f5c0
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 payloads/libpayload/Config.in                    |  18 +-
 payloads/libpayload/Makefile                     |  32 ++-
 payloads/libpayload/Makefile.inc                 |   5 +-
 payloads/libpayload/arch/Config.in               |   3 +-
 payloads/libpayload/arch/armv7/Config.in         |  29 +++
 payloads/libpayload/arch/armv7/Makefile.inc      |  35 +++
 payloads/libpayload/arch/armv7/assembler.h       |  60 +++++
 payloads/libpayload/arch/armv7/coreboot.c        | 287 +++++++++++++++++++++++
 payloads/libpayload/arch/armv7/head.S            |  52 ++++
 payloads/libpayload/arch/armv7/main.c            |  70 ++++++
 payloads/libpayload/arch/armv7/memcpy.S          | 243 +++++++++++++++++++
 payloads/libpayload/arch/armv7/memset.S          | 126 ++++++++++
 payloads/libpayload/arch/armv7/sysinfo.c         |  64 +++++
 payloads/libpayload/arch/armv7/timer.c           | 101 ++++++++
 payloads/libpayload/arch/armv7/util.S            |  36 +++
 payloads/libpayload/arch/armv7/virtual.c         |  38 +++
 payloads/libpayload/arch/powerpc/Config.in       |   2 +-
 payloads/libpayload/bin/lpgcc                    |  13 +-
 payloads/libpayload/configs/defconfig            |   3 +-
 payloads/libpayload/include/armv7/arch/io.h      |  42 ++++
 payloads/libpayload/include/armv7/arch/types.h   |  60 +++++
 payloads/libpayload/include/armv7/arch/virtual.h |  41 ++++
 payloads/libpayload/include/cbfs.h               |  12 +
 payloads/libpayload/include/cbfs_core.h          |   3 +
 payloads/libpayload/libc/time.c                  |   2 +-
 payloads/libpayload/util/xcompile/xcompile       | 239 ++++++++++++++-----
 26 files changed, 1535 insertions(+), 81 deletions(-)

diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index bf30a44..a14291d 100644
--- a/payloads/libpayload/Config.in
+++ b/payloads/libpayload/Config.in
@@ -67,16 +67,21 @@ choice
         prompt "Target Architecture"
         default ARCH_X86
 
-config ARCH_X86
-        bool "x86"
+config ARCH_ARMV7
+        bool "ARMv7"
         help
           Support the x86 architecture
 
-config TARGET_POWERPC
+config ARCH_POWERPC
         bool "PowerPC"
         help
 	  Support the PowerPC architecture
 
+config ARCH_X86
+        bool "x86"
+        help
+          Support the x86 architecture
+
 endchoice
 
 config MEMMAP_RAM_ONLY
@@ -198,12 +203,12 @@ config VIDEO_CONSOLE
 
 config VGA_VIDEO_CONSOLE
 	bool "VGA video console driver"
-	depends on VIDEO_CONSOLE
+	depends on ARCH_X86 && VIDEO_CONSOLE
 	default y
 
 config GEODELX_VIDEO_CONSOLE
 	bool "Geode LX video console driver"
-	depends on VIDEO_CONSOLE
+	depends on ARCH_X86 && VIDEO_CONSOLE
 	default n
 
 config COREBOOT_VIDEO_CONSOLE
@@ -234,10 +239,12 @@ menu "Drivers"
 
 config PCI
 	bool "Support for PCI devices"
+	depends on ARCH_X86 # for now
 	default y
 
 config NVRAM
 	bool "Support for reading/writing NVRAM bytes"
+	depends on ARCH_X86 # for now
 	default y
 
 config RTC_PORT_EXTENDED_VIA
@@ -258,6 +265,7 @@ config RTC_PORT_EXTENDED_VIA
 
 config SPEAKER
 	bool "Support for PC speaker"
+	depends on ARCH_X86
 	default y
 
 config STORAGE
diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile
index 667822d..cbfd43a 100644
--- a/payloads/libpayload/Makefile
+++ b/payloads/libpayload/Makefile
@@ -79,7 +79,6 @@ HOSTCC = gcc
 HOSTCXX = g++
 HOSTCFLAGS := -I$(srck) -I$(objk) -g
 HOSTCXXFLAGS := -I$(srck) -I$(objk)
-LIBGCC_FILE_NAME := $(shell test -r `$(CC) -print-libgcc-file-name` && $(CC) -print-libgcc-file-name)
 
 DOXYGEN := doxygen
 DOXYGEN_OUTPUT_DIR := doxygen
@@ -90,6 +89,35 @@ all: real-all
 # Order _does_ matter for pattern rules.
 include util/kconfig/Makefile
 
+include $(HAVE_DOTCONFIG)
+
+ARCHDIR-$(CONFIG_ARCH_ARMV7)   := armv7
+ARCHDIR-$(CONFIG_ARCH_POWERPC) := powerpc
+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_ARMV7)   := armv7
+ARCH-$(CONFIG_ARCH_ARMV7)   := armv7
+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)
+
 # Three cases where we don't need fully populated $(obj) lists:
 # 1. when no .config exists
 # 2. when make config (in any flavour) is run
@@ -110,8 +138,6 @@ real-all: config
 
 else
 
-include $(HAVE_DOTCONFIG)
-
 ifneq ($(INNER_SCANBUILD),y)
 ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
 CC:=clang -m32
diff --git a/payloads/libpayload/Makefile.inc b/payloads/libpayload/Makefile.inc
index 5ae888b..9419ac8 100644
--- a/payloads/libpayload/Makefile.inc
+++ b/payloads/libpayload/Makefile.inc
@@ -31,8 +31,9 @@
 
 export KERNELVERSION      := 0.2.0
 
-ARCHDIR-$(CONFIG_ARCH_X86)       := x86
-ARCHDIR-$(CONFIG_TARGET_POWERPC) := powerpc
+ARCHDIR-$(CONFIG_ARCH_ARMV7)   := armv7
+ARCHDIR-$(CONFIG_ARCH_X86)     := x86
+ARCHDIR-$(CONFIG_ARCH_POWERPC) := powerpc
 DESTDIR ?= install
 
 real-target: lib
diff --git a/payloads/libpayload/arch/Config.in b/payloads/libpayload/arch/Config.in
index 690b12a..ccd1851 100644
--- a/payloads/libpayload/arch/Config.in
+++ b/payloads/libpayload/arch/Config.in
@@ -20,5 +20,6 @@
 ## MA 02111-1307 USA
 ##
 
-source "arch/x86/Config.in"
+source "arch/armv7/Config.in"
 source "arch/powerpc/Config.in"
+source "arch/x86/Config.in"
diff --git a/payloads/libpayload/arch/armv7/Config.in b/payloads/libpayload/arch/armv7/Config.in
new file mode 100644
index 0000000..efc6761
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/Config.in
@@ -0,0 +1,29 @@
+##
+## Copyright (c) 2012 The Chromium OS Authors.
+##
+## See file CREDITS for list of people who contributed to this
+## project.
+##
+## 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.
+##
+## This program is distributed in the hope that it will be useful,
+## but without any warranty; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+## MA 02111-1307 USA
+##
+
+if ARCH_ARMV7
+
+config ARCH_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select LITTLE_ENDIAN
+
+endif
diff --git a/payloads/libpayload/arch/armv7/Makefile.inc b/payloads/libpayload/arch/armv7/Makefile.inc
new file mode 100644
index 0000000..6d9e6c5
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/Makefile.inc
@@ -0,0 +1,35 @@
+##
+## This file is part of the libpayload project.
+##
+## Copyright (C) 2008 Advanced Micro Devices, Inc.
+##
+## 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 author may not be used to endorse or promote products
+##    derived from this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+##
+
+head.o-y += head.S
+libc-y += main.c sysinfo.c
+libc-y += timer.c coreboot.c util.S
+libc-y += virtual.c
+libc-y += memcpy.S memset.S
+
diff --git a/payloads/libpayload/arch/armv7/assembler.h b/payloads/libpayload/arch/armv7/assembler.h
new file mode 100644
index 0000000..5e4789b
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/assembler.h
@@ -0,0 +1,60 @@
+/*
+ *  arch/arm/include/asm/assembler.h
+ *
+ *  Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  This file contains arm architecture specific defines
+ *  for the different processors.
+ *
+ *  Do not include any C declarations in this file - it is included by
+ *  assembler source.
+ */
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull		lsr
+#define push		lsl
+#define get_byte_0	lsl #0
+#define get_byte_1	lsr #8
+#define get_byte_2	lsr #16
+#define get_byte_3	lsr #24
+#define put_byte_0	lsl #0
+#define put_byte_1	lsl #8
+#define put_byte_2	lsl #16
+#define put_byte_3	lsl #24
+#else
+#define pull		lsl
+#define push		lsr
+#define get_byte_0	lsr #24
+#define get_byte_1	lsr #16
+#define get_byte_2	lsr #8
+#define get_byte_3      lsl #0
+#define put_byte_0	lsl #24
+#define put_byte_1	lsl #16
+#define put_byte_2	lsl #8
+#define put_byte_3      lsl #0
+#endif
+
+/*
+ * Data preload for architectures that support it
+ */
+#if defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
+	defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+	defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || \
+	defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_7A__) || \
+	defined(__ARM_ARCH_7R__)
+#define PLD(code...)	code
+#else
+#define PLD(code...)
+#endif
+
+/*
+ * Cache alligned
+ */
+#define CALGN(code...) code
diff --git a/payloads/libpayload/arch/armv7/coreboot.c b/payloads/libpayload/arch/armv7/coreboot.c
new file mode 100644
index 0000000..01ec53c
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/coreboot.c
@@ -0,0 +1,287 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ */
+
+#include <libpayload-config.h>
+#include <libpayload.h>
+#include <coreboot_tables.h>
+
+/*
+ * Some of this is x86 specific, and the rest of it is generic. Right now,
+ * since we only support x86, we'll avoid trying to make lots of infrastructure
+ * we don't need. If in the future, we want to use coreboot on some other
+ * architecture, then take out the generic parsing code and move it elsewhere.
+ */
+
+/* === Parsing code === */
+/* This is the generic parsing code. */
+
+static void cb_parse_memory(void *ptr, struct sysinfo_t *info)
+{
+	struct cb_memory *mem = ptr;
+	int count = MEM_RANGE_COUNT(mem);
+	int i;
+
+	if (count > SYSINFO_MAX_MEM_RANGES)
+		count = SYSINFO_MAX_MEM_RANGES;
+
+	info->n_memranges = 0;
+
+	for (i = 0; i < count; i++) {
+		struct cb_memory_range *range = MEM_RANGE_PTR(mem, i);
+
+#ifdef CONFIG_MEMMAP_RAM_ONLY
+		if (range->type != CB_MEM_RAM)
+			continue;
+#endif
+
+		info->memrange[info->n_memranges].base =
+		    cb_unpack64(range->start);
+
+		info->memrange[info->n_memranges].size =
+		    cb_unpack64(range->size);
+
+		info->memrange[info->n_memranges].type = range->type;
+
+		info->n_memranges++;
+	}
+}
+
+static void cb_parse_serial(void *ptr, struct sysinfo_t *info)
+{
+	info->serial = ((struct cb_serial *)ptr);
+}
+
+#ifdef CONFIG_CHROMEOS
+static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
+{
+	struct cb_vbnv *vbnv = (struct cb_vbnv *)ptr;
+
+	info->vbnv_start = vbnv->vbnv_start;
+	info->vbnv_size = vbnv->vbnv_size;
+}
+
+static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
+{
+	int i;
+	struct cb_gpios *gpios = (struct cb_gpios *)ptr;
+
+	info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ?
+				(gpios->count) : SYSINFO_MAX_GPIOS;
+
+	for (i = 0; i < info->num_gpios; i++)
+		info->gpios[i] = gpios->gpios[i];
+}
+
+static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info)
+{
+	struct cb_vdat *vdat = (struct cb_vdat *) ptr;
+
+	info->vdat_addr = phys_to_virt(vdat->vdat_addr);
+	info->vdat_size = vdat->vdat_size;
+}
+#endif
+
+static void cb_parse_tstamp(unsigned char *ptr, struct sysinfo_t *info)
+{
+	struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+	info->tstamp_table = phys_to_virt(cbmem->cbmem_tab);
+}
+
+static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info)
+{
+	struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+	info->cbmem_cons = phys_to_virt(cbmem->cbmem_tab);
+}
+
+static void cb_parse_mrc_cache(unsigned char *ptr, struct sysinfo_t *info)
+{
+	struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+	info->mrc_cache = phys_to_virt(cbmem->cbmem_tab);
+}
+
+#ifdef CONFIG_NVRAM
+static void cb_parse_optiontable(void *ptr, struct sysinfo_t *info)
+{
+	info->option_table = ptr;
+}
+
+static void cb_parse_checksum(void *ptr, struct sysinfo_t *info)
+{
+	struct cb_cmos_checksum *cmos_cksum = ptr;
+	info->cmos_range_start = cmos_cksum->range_start;
+	info->cmos_range_end = cmos_cksum->range_end;
+	info->cmos_checksum_location = cmos_cksum->location;
+}
+#endif
+
+#ifdef CONFIG_COREBOOT_VIDEO_CONSOLE
+static void cb_parse_framebuffer(void *ptr, struct sysinfo_t *info)
+{
+	info->framebuffer = ptr;
+}
+#endif
+
+static void cb_parse_string(unsigned char *ptr, char **info)
+{
+	*info = (char *)((struct cb_string *)ptr)->string;
+}
+
+static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
+{
+	struct cb_header *header;
+	unsigned char *ptr = addr;
+	void *forward;
+	int i;
+
+	for (i = 0; i < len; i += 16, ptr += 16) {
+		header = (struct cb_header *)ptr;
+		if (!strncmp((const char *)header->signature, "LBIO", 4))
+			break;
+	}
+
+	/* We walked the entire space and didn't find anything. */
+	if (i >= len)
+		return -1;
+
+	if (!header->table_bytes)
+		return 0;
+
+	/* Make sure the checksums match. */
+	if (ipchksum((u16 *) header, sizeof(*header)) != 0)
+		return -1;
+
+	if (ipchksum((u16 *) (ptr + sizeof(*header)),
+		     header->table_bytes) != header->table_checksum)
+		return -1;
+
+	info->header = header;
+
+	/* Now, walk the tables. */
+	ptr += header->header_bytes;
+
+	for (i = 0; i < header->table_entries; i++) {
+		struct cb_record *rec = (struct cb_record *)ptr;
+
+		/* We only care about a few tags here (maybe more later). */
+		switch (rec->tag) {
+		case CB_TAG_FORWARD:
+			forward = phys_to_virt((void *)(unsigned long)((struct cb_forward *)rec)->forward);
+			return cb_parse_header(forward, len, info);
+			continue;
+		case CB_TAG_MEMORY:
+			cb_parse_memory(ptr, info);
+			break;
+		case CB_TAG_SERIAL:
+			cb_parse_serial(ptr, info);
+			break;
+		case CB_TAG_VERSION:
+			cb_parse_string(ptr, &info->cb_version);
+			break;
+		case CB_TAG_EXTRA_VERSION:
+			cb_parse_string(ptr, &info->extra_version);
+			break;
+		case CB_TAG_BUILD:
+			cb_parse_string(ptr, &info->build);
+			break;
+		case CB_TAG_COMPILE_TIME:
+			cb_parse_string(ptr, &info->compile_time);
+			break;
+		case CB_TAG_COMPILE_BY:
+			cb_parse_string(ptr, &info->compile_by);
+			break;
+		case CB_TAG_COMPILE_HOST:
+			cb_parse_string(ptr, &info->compile_host);
+			break;
+		case CB_TAG_COMPILE_DOMAIN:
+			cb_parse_string(ptr, &info->compile_domain);
+			break;
+		case CB_TAG_COMPILER:
+			cb_parse_string(ptr, &info->compiler);
+			break;
+		case CB_TAG_LINKER:
+			cb_parse_string(ptr, &info->linker);
+			break;
+		case CB_TAG_ASSEMBLER:
+			cb_parse_string(ptr, &info->assembler);
+			break;
+#ifdef CONFIG_NVRAM
+		case CB_TAG_CMOS_OPTION_TABLE:
+			cb_parse_optiontable(ptr, info);
+			break;
+		case CB_TAG_OPTION_CHECKSUM:
+			cb_parse_checksum(ptr, info);
+			break;
+#endif
+#ifdef CONFIG_COREBOOT_VIDEO_CONSOLE
+		// FIXME we should warn on serial if coreboot set up a
+		// framebuffer buf the payload does not know about it.
+		case CB_TAG_FRAMEBUFFER:
+			cb_parse_framebuffer(ptr, info);
+			break;
+#endif
+		case CB_TAG_MAINBOARD:
+			info->mainboard = (struct cb_mainboard *)ptr;
+#ifdef CONFIG_CHROMEOS
+		case CB_TAG_GPIO:
+			cb_parse_gpios(ptr, info);
+			break;
+		case CB_TAG_VDAT:
+			cb_parse_vdat(ptr, info);
+			break;
+		case CB_TAG_VBNV:
+			cb_parse_vbnv(ptr, info);
+			break;
+#endif
+		case CB_TAG_TIMESTAMPS:
+			cb_parse_tstamp(ptr, info);
+			break;
+		case CB_TAG_CBMEM_CONSOLE:
+			cb_parse_cbmem_cons(ptr, info);
+			break;
+		case CB_TAG_MRC_CACHE:
+			cb_parse_mrc_cache(ptr, info);
+			break;
+		}
+
+		ptr += rec->size;
+	}
+
+	return 1;
+}
+
+/* == Architecture specific == */
+/* FIXME put in actual address range */
+
+int get_coreboot_info(struct sysinfo_t *info)
+{
+	int ret = cb_parse_header(phys_to_virt(0x00000000), 0x1000, info);
+
+	return (ret == 1) ? 0 : -1;
+}
diff --git a/payloads/libpayload/arch/armv7/head.S b/payloads/libpayload/arch/armv7/head.S
new file mode 100644
index 0000000..e1b5737
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/head.S
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ */
+
+	.global _entry, _leave
+	.text
+	.align 4
+
+/*
+ * Our entry point
+ */
+_entry:
+
+	/* TODO: disable interrupts */
+	/* TODO: Clear BSS */
+	/* TODO: Setup new stack */
+	/* TODO: Save old stack pointer */
+
+	/* Let's rock. */
+	b start_main
+
+	/* %eax has the return value - pass it on unmolested */
+_leave:
+	/* TODO: restore old stack pointer. */
+
+	/* Return to the original context. */
+	mov pc, lr
diff --git a/payloads/libpayload/arch/armv7/main.c b/payloads/libpayload/arch/armv7/main.c
new file mode 100644
index 0000000..6b54b27
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/main.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ */
+
+#include <libpayload.h>
+
+unsigned int main_argc;    /**< The argc value to pass to main() */
+
+/** The argv value to pass to main() */
+char *main_argv[MAX_ARGC_COUNT];
+
+/**
+ * This is our C entry function - set up the system
+ * and jump into the payload entry point.
+ */
+void start_main(void);
+void start_main(void)
+{
+	extern int main(int argc, char **argv);
+
+	/* Gather system information. */
+	lib_get_sysinfo();
+
+	/* Optionally set up the consoles. */
+#ifndef CONFIG_SKIP_CONSOLE_INIT
+	console_init();
+#endif
+
+	/*
+	 * Any other system init that has to happen before the
+	 * user gets control goes here.
+	 */
+
+	/*
+	 * Go to the entry point.
+	 * In the future we may care about the return value.
+	 */
+
+	(void) main(main_argc, (main_argc != 0) ? main_argv : NULL);
+
+	/*
+	 * Returning here will go to the _leave function to return
+	 * us to the original context.
+	 */
+}
diff --git a/payloads/libpayload/arch/armv7/memcpy.S b/payloads/libpayload/arch/armv7/memcpy.S
new file mode 100644
index 0000000..549320c
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/memcpy.S
@@ -0,0 +1,243 @@
+/*
+ *  linux/arch/arm/lib/memcpy.S
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Sep 28, 2005
+ *  Copyright:	MontaVista Software, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include "assembler.h"
+
+#define W(instr)	instr
+
+#define LDR1W_SHIFT	0
+#define STR1W_SHIFT	0
+
+	.macro ldr1w ptr reg abort
+	W(ldr) \reg, [\ptr], #4
+	.endm
+
+	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+	.endm
+
+	.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+	.endm
+
+	.macro ldr1b ptr reg cond=al abort
+	ldr\cond\()b \reg, [\ptr], #1
+	.endm
+
+	.macro str1w ptr reg abort
+	W(str) \reg, [\ptr], #4
+	.endm
+
+	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+	stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+	.endm
+
+	.macro str1b ptr reg cond=al abort
+	str\cond\()b \reg, [\ptr], #1
+	.endm
+
+	.macro enter reg1 reg2
+	stmdb sp!, {r0, \reg1, \reg2}
+	.endm
+
+	.macro exit reg1 reg2
+	ldmfd sp!, {r0, \reg1, \reg2}
+	.endm
+
+	.text
+
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
+.globl memcpy
+memcpy:
+
+		cmp	r0, r1
+		moveq	pc, lr
+
+		enter	r4, lr
+
+		subs	r2, r2, #4
+		blt	8f
+		ands	ip, r0, #3
+	PLD(	pld	[r1, #0]		)
+		bne	9f
+		ands	ip, r1, #3
+		bne	10f
+
+1:		subs	r2, r2, #(28)
+		stmfd	sp!, {r5 - r8}
+		blt	5f
+
+	CALGN(	ands	ip, r0, #31		)
+	CALGN(	rsb	r3, ip, #32		)
+	CALGN(	sbcnes	r4, r3, r2		)  @ C is always set here
+	CALGN(	bcs	2f			)
+	CALGN(	adr	r4, 6f			)
+	CALGN(	subs	r2, r2, r3		)  @ C gets set
+	CALGN(	add	pc, r4, ip		)
+
+	PLD(	pld	[r1, #0]		)
+2:	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #28]		)
+	PLD(	blt	4f			)
+	PLD(	pld	[r1, #60]		)
+	PLD(	pld	[r1, #92]		)
+
+3:	PLD(	pld	[r1, #124]		)
+4:		ldr8w	r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+		subs	r2, r2, #32
+		str8w	r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+		bge	3b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	4b			)
+
+5:		ands	ip, r2, #28
+		rsb	ip, ip, #32
+#if LDR1W_SHIFT > 0
+		lsl	ip, ip, #LDR1W_SHIFT
+#endif
+		addne	pc, pc, ip		@ C is always clear here
+		b	7f
+6:
+		.rept	(1 << LDR1W_SHIFT)
+		W(nop)
+		.endr
+		ldr1w	r1, r3, abort=20f
+		ldr1w	r1, r4, abort=20f
+		ldr1w	r1, r5, abort=20f
+		ldr1w	r1, r6, abort=20f
+		ldr1w	r1, r7, abort=20f
+		ldr1w	r1, r8, abort=20f
+		ldr1w	r1, lr, abort=20f
+
+#if LDR1W_SHIFT < STR1W_SHIFT
+		lsl	ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+		lsr	ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
+		add	pc, pc, ip
+		nop
+		.rept	(1 << STR1W_SHIFT)
+		W(nop)
+		.endr
+		str1w	r0, r3, abort=20f
+		str1w	r0, r4, abort=20f
+		str1w	r0, r5, abort=20f
+		str1w	r0, r6, abort=20f
+		str1w	r0, r7, abort=20f
+		str1w	r0, r8, abort=20f
+		str1w	r0, lr, abort=20f
+
+	CALGN(	bcs	2b			)
+
+7:		ldmfd	sp!, {r5 - r8}
+
+8:		movs	r2, r2, lsl #31
+		ldr1b	r1, r3, ne, abort=21f
+		ldr1b	r1, r4, cs, abort=21f
+		ldr1b	r1, ip, cs, abort=21f
+		str1b	r0, r3, ne, abort=21f
+		str1b	r0, r4, cs, abort=21f
+		str1b	r0, ip, cs, abort=21f
+
+		exit	r4, pc
+
+9:		rsb	ip, ip, #4
+		cmp	ip, #2
+		ldr1b	r1, r3, gt, abort=21f
+		ldr1b	r1, r4, ge, abort=21f
+		ldr1b	r1, lr, abort=21f
+		str1b	r0, r3, gt, abort=21f
+		str1b	r0, r4, ge, abort=21f
+		subs	r2, r2, ip
+		str1b	r0, lr, abort=21f
+		blt	8b
+		ands	ip, r1, #3
+		beq	1b
+
+10:		bic	r1, r1, #3
+		cmp	ip, #2
+		ldr1w	r1, lr, abort=21f
+		beq	17f
+		bgt	18f
+
+
+		.macro	forward_copy_shift pull push
+
+		subs	r2, r2, #28
+		blt	14f
+
+	CALGN(	ands	ip, r0, #31		)
+	CALGN(	rsb	ip, ip, #32		)
+	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
+	CALGN(	subcc	r2, r2, ip		)
+	CALGN(	bcc	15f			)
+
+11:		stmfd	sp!, {r5 - r9}
+
+	PLD(	pld	[r1, #0]		)
+	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #28]		)
+	PLD(	blt	13f			)
+	PLD(	pld	[r1, #60]		)
+	PLD(	pld	[r1, #92]		)
+
+12:	PLD(	pld	[r1, #124]		)
+13:		ldr4w	r1, r4, r5, r6, r7, abort=19f
+		mov	r3, lr, pull #\pull
+		subs	r2, r2, #32
+		ldr4w	r1, r8, r9, ip, lr, abort=19f
+		orr	r3, r3, r4, push #\push
+		mov	r4, r4, pull #\pull
+		orr	r4, r4, r5, push #\push
+		mov	r5, r5, pull #\pull
+		orr	r5, r5, r6, push #\push
+		mov	r6, r6, pull #\pull
+		orr	r6, r6, r7, push #\push
+		mov	r7, r7, pull #\pull
+		orr	r7, r7, r8, push #\push
+		mov	r8, r8, pull #\pull
+		orr	r8, r8, r9, push #\push
+		mov	r9, r9, pull #\pull
+		orr	r9, r9, ip, push #\push
+		mov	ip, ip, pull #\pull
+		orr	ip, ip, lr, push #\push
+		str8w	r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
+		bge	12b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	13b			)
+
+		ldmfd	sp!, {r5 - r9}
+
+14:		ands	ip, r2, #28
+		beq	16f
+
+15:		mov	r3, lr, pull #\pull
+		ldr1w	r1, lr, abort=21f
+		subs	ip, ip, #4
+		orr	r3, r3, lr, push #\push
+		str1w	r0, r3, abort=21f
+		bgt	15b
+	CALGN(	cmp	r2, #0			)
+	CALGN(	bge	11b			)
+
+16:		sub	r1, r1, #(\push / 8)
+		b	8b
+
+		.endm
+
+
+		forward_copy_shift	pull=8	push=24
+
+17:		forward_copy_shift	pull=16	push=16
+
+18:		forward_copy_shift	pull=24	push=8
diff --git a/payloads/libpayload/arch/armv7/memset.S b/payloads/libpayload/arch/armv7/memset.S
new file mode 100644
index 0000000..4ff4c3c
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/memset.S
@@ -0,0 +1,126 @@
+/*
+ *  linux/arch/arm/lib/memset.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include "assembler.h"
+
+	.text
+	.align	5
+	.word	0
+
+1:	subs	r2, r2, #4		@ 1 do we have enough
+	blt	5f			@ 1 bytes to align with?
+	cmp	r3, #2			@ 1
+	strltb	r1, [r0], #1		@ 1
+	strleb	r1, [r0], #1		@ 1
+	strb	r1, [r0], #1		@ 1
+	add	r2, r2, r3		@ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted.  Try doing the
+ * memset again.
+ */
+
+.globl memset
+memset:
+	ands	r3, r0, #3		@ 1 unaligned?
+	bne	1b			@ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+	orr	r1, r1, r1, lsl #8
+	orr	r1, r1, r1, lsl #16
+	mov	r3, r1
+	cmp	r2, #16
+	blt	4f
+
+#if ! CALGN(1)+0
+
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+	str	lr, [sp, #-4]!
+	mov	ip, r1
+	mov	lr, r1
+
+2:	subs	r2, r2, #64
+	stmgeia	r0!, {r1, r3, ip, lr}	@ 64 bytes at a time.
+	stmgeia	r0!, {r1, r3, ip, lr}
+	stmgeia	r0!, {r1, r3, ip, lr}
+	stmgeia	r0!, {r1, r3, ip, lr}
+	bgt	2b
+	ldmeqfd	sp!, {pc}		@ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+	tst	r2, #32
+	stmneia	r0!, {r1, r3, ip, lr}
+	stmneia	r0!, {r1, r3, ip, lr}
+	tst	r2, #16
+	stmneia	r0!, {r1, r3, ip, lr}
+	ldr	lr, [sp], #4
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+	stmfd	sp!, {r4-r7, lr}
+	mov	r4, r1
+	mov	r5, r1
+	mov	r6, r1
+	mov	r7, r1
+	mov	ip, r1
+	mov	lr, r1
+
+	cmp	r2, #96
+	tstgt	r0, #31
+	ble	3f
+
+	and	ip, r0, #31
+	rsb	ip, ip, #32
+	sub	r2, r2, ip
+	movs	ip, ip, lsl #(32 - 4)
+	stmcsia	r0!, {r4, r5, r6, r7}
+	stmmiia	r0!, {r4, r5}
+	tst	ip, #(1 << 30)
+	mov	ip, r1
+	strne	r1, [r0], #4
+
+3:	subs	r2, r2, #64
+	stmgeia	r0!, {r1, r3-r7, ip, lr}
+	stmgeia	r0!, {r1, r3-r7, ip, lr}
+	bgt	3b
+	ldmeqfd	sp!, {r4-r7, pc}
+
+	tst	r2, #32
+	stmneia	r0!, {r1, r3-r7, ip, lr}
+	tst	r2, #16
+	stmneia	r0!, {r4-r7}
+	ldmfd	sp!, {r4-r7, lr}
+
+#endif
+
+4:	tst	r2, #8
+	stmneia	r0!, {r1, r3}
+	tst	r2, #4
+	strne	r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero.  We
+ * may have an unaligned pointer as well.
+ */
+5:	tst	r2, #2
+	strneb	r1, [r0], #1
+	strneb	r1, [r0], #1
+	tst	r2, #1
+	strneb	r1, [r0], #1
+	mov	pc, lr
diff --git a/payloads/libpayload/arch/armv7/sysinfo.c b/payloads/libpayload/arch/armv7/sysinfo.c
new file mode 100644
index 0000000..5aa5175
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/sysinfo.c
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ */
+
+#include <libpayload-config.h>
+#include <libpayload.h>
+#include <coreboot_tables.h>
+
+/**
+ * This is a global structure that is used through the library - we set it
+ * up initially with some dummy values - hopefully they will be overridden.
+ */
+struct sysinfo_t lib_sysinfo = {
+	.cpu_khz = 200,
+};
+
+int lib_get_sysinfo(void)
+{
+	int ret;
+
+	/* Get the CPU speed (for delays). */
+	lib_sysinfo.cpu_khz = get_cpu_speed();
+
+	/* Get information from the coreboot tables,
+	 * if they exist */
+
+	ret = get_coreboot_info(&lib_sysinfo);
+
+	if (!lib_sysinfo.n_memranges) {
+		/* If we can't get a good memory range, use the default. */
+		lib_sysinfo.n_memranges = 2;
+
+		lib_sysinfo.memrange[0].base = 0;
+		lib_sysinfo.memrange[0].size = 1024 * 1024;
+		lib_sysinfo.memrange[0].type = CB_MEM_RAM;
+	}
+
+	return ret;
+}
diff --git a/payloads/libpayload/arch/armv7/timer.c b/payloads/libpayload/arch/armv7/timer.c
new file mode 100644
index 0000000..24b0a0f
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/timer.c
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ */
+
+/**
+ * @file armv7/timer.c
+ * ARMv7 specific timer routines
+ */
+
+#include <libpayload.h>
+
+/**
+ * @ingroup arch
+ * Global variable containing the speed of the processor in KHz.
+ */
+u32 cpu_khz;
+
+/**
+ * Calculate the speed of the processor for use in delays.
+ *
+ * @return The CPU speed in kHz.
+ */
+unsigned int get_cpu_speed(void)
+{
+	/* FIXME */
+	cpu_khz = 1000000U;
+
+	return cpu_khz;
+}
+
+static inline void _delay(unsigned long long delta)
+{
+	/* FIXME */
+}
+
+/**
+ * Delay for a specified number of nanoseconds.
+ *
+ * @param n Number of nanoseconds to delay for.
+ */
+void ndelay(unsigned int n)
+{
+	_delay((unsigned long long)n * cpu_khz / 1000000);
+}
+
+/**
+ * Delay for a specified number of microseconds.
+ *
+ * @param n Number of microseconds to delay for.
+ */
+void udelay(unsigned int n)
+{
+	_delay((unsigned long long)n * cpu_khz / 1000);
+}
+
+/**
+ * Delay for a specified number of milliseconds.
+ *
+ * @param m Number of milliseconds to delay for.
+ */
+void mdelay(unsigned int m)
+{
+	_delay((unsigned long long)m * cpu_khz);
+}
+
+/**
+ * Delay for a specified number of seconds.
+ *
+ * @param s Number of seconds to delay for.
+ */
+void delay(unsigned int s)
+{
+	int i;
+	for (i=0; i<1000; i++)
+		_delay((unsigned long long)s * cpu_khz);
+}
diff --git a/payloads/libpayload/arch/armv7/util.S b/payloads/libpayload/arch/armv7/util.S
new file mode 100644
index 0000000..4cf61f3
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/util.S
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ */
+
+	.global halt
+	.text
+	.align 4
+
+/* This function puts the system into a halt. */
+halt:
+	b halt
diff --git a/payloads/libpayload/arch/armv7/virtual.c b/payloads/libpayload/arch/armv7/virtual.c
new file mode 100644
index 0000000..59768db
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/virtual.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 coresystems GmbH
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ */
+
+#include <unistd.h>
+
+unsigned long virtual_offset = 0;
+
+
+int getpagesize(void)
+{
+	return 4096;
+}
diff --git a/payloads/libpayload/arch/powerpc/Config.in b/payloads/libpayload/arch/powerpc/Config.in
index 37318f0..487e090 100644
--- a/payloads/libpayload/arch/powerpc/Config.in
+++ b/payloads/libpayload/arch/powerpc/Config.in
@@ -20,7 +20,7 @@
 ## MA 02111-1307 USA
 ##
 
-if TARGET_POWERPC
+if ARCH_POWERPC
 
 config ARCH_SPECIFIC_OPTIONS # dummy
 	def_bool y
diff --git a/payloads/libpayload/bin/lpgcc b/payloads/libpayload/bin/lpgcc
index 6cba45d..52a8e55 100755
--- a/payloads/libpayload/bin/lpgcc
+++ b/payloads/libpayload/bin/lpgcc
@@ -107,16 +107,21 @@ while [ $# -gt 0 ]; do
 	shift
 done
 
-if [ "$CONFIG_ARCH_X86" = "y" ]; then
-  _ARCHINCDIR=$_INCDIR/x86
-  _ARCHLIBDIR=$_LIBDIR/x86
+if [ "$CONFIG_ARCH_ARMV7" = "y" ]; then
+  _ARCHINCDIR=$_INCDIR/armv7
+  _ARCHLIBDIR=$_LIBDIR/armv7
 fi
 
-if [ "$CONFIG_TARGET_POWERPC" = "y" ]; then
+if [ "$CONFIG_ARCH_POWERPC" = "y" ]; then
   _ARCHINCDIR=$_INCDIR/powerpc
   _ARCHLIBDIR=$_LIBDIR/powerpc
 fi
 
+if [ "$CONFIG_ARCH_X86" = "y" ]; then
+  _ARCHINCDIR=$_INCDIR/x86
+  _ARCHLIBDIR=$_LIBDIR/x86
+fi
+
 _CFLAGS="-m32 -nostdinc -nostdlib -I$_INCDIR -I$_ARCHINCDIR -D__LIBPAYLOAD__=1"
 
 # Check for the -fno-stack-protector silliness
diff --git a/payloads/libpayload/configs/defconfig b/payloads/libpayload/configs/defconfig
index 87d9d4b..1dce37a 100644
--- a/payloads/libpayload/configs/defconfig
+++ b/payloads/libpayload/configs/defconfig
@@ -14,8 +14,9 @@
 #
 # Architecture Options
 #
+# CONFIG_ARCH_ARMV7 is not set
+# CONFIG_ARCH_POWERPC is not set
 CONFIG_ARCH_X86=y
-# CONFIG_TARGET_POWERPC is not set
 # CONFIG_MEMMAP_RAM_ONLY is not set
 # CONFIG_MULTIBOOT is not set
 
diff --git a/payloads/libpayload/include/armv7/arch/io.h b/payloads/libpayload/include/armv7/arch/io.h
new file mode 100644
index 0000000..e71e1dd
--- /dev/null
+++ b/payloads/libpayload/include/armv7/arch/io.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008 coresystems GmbH
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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 _ARCH_IO_H
+#define _ARCH_IO_H
+
+#define readb(_a) (*(volatile unsigned char *) (_a))
+#define readw(_a) (*(volatile unsigned short *) (_a))
+#define readl(_a) (*(volatile unsigned long *) (_a))
+
+#define writeb(_v, _a) (*(volatile unsigned char *) (_a) = (_v))
+#define writew(_v, _a) (*(volatile unsigned short *) (_a) = (_v))
+#define writel(_v, _a) (*(volatile unsigned long *) (_a) = (_v))
+
+#endif
diff --git a/payloads/libpayload/include/armv7/arch/types.h b/payloads/libpayload/include/armv7/arch/types.h
new file mode 100644
index 0000000..1bd815b
--- /dev/null
+++ b/payloads/libpayload/include/armv7/arch/types.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe at hermann-uwe.de>
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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 _ARCH_TYPES_H
+#define _ARCH_TYPES_H
+
+typedef unsigned char uint8_t;
+typedef unsigned char u8;
+typedef signed char int8_t;
+typedef signed char s8;
+
+typedef unsigned short uint16_t;
+typedef unsigned short u16;
+typedef signed short int16_t;
+typedef signed short s16;
+
+typedef unsigned int uint32_t;
+typedef unsigned int u32;
+typedef signed int int32_t;
+typedef signed int s32;
+
+typedef unsigned long long uint64_t;
+typedef unsigned long long u64;
+typedef signed long long int64_t;
+typedef signed long long s64;
+
+typedef long time_t;
+typedef long suseconds_t;
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#endif
diff --git a/payloads/libpayload/include/armv7/arch/virtual.h b/payloads/libpayload/include/armv7/arch/virtual.h
new file mode 100644
index 0000000..328c3aa
--- /dev/null
+++ b/payloads/libpayload/include/armv7/arch/virtual.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 coresystems GmbH
+ *
+ * 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 author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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 _ARCH_VIRTUAL_H
+#define _ARCH_VIRTUAL_H
+
+extern unsigned long virtual_offset;
+
+#define virt_to_phys(virt) ((unsigned long) (virt) + virtual_offset)
+#define phys_to_virt(phys) ((void *) ((unsigned long) (phys) - virtual_offset))
+
+#define virt_to_bus(addr) virt_to_phys(addr)
+#define bus_to_virt(addr) phys_to_virt(addr)
+
+#endif
diff --git a/payloads/libpayload/include/cbfs.h b/payloads/libpayload/include/cbfs.h
index 8b8b024..cf0584e 100644
--- a/payloads/libpayload/include/cbfs.h
+++ b/payloads/libpayload/include/cbfs.h
@@ -1,4 +1,16 @@
 #include <arch/types.h>
+
+/* FIXME: workaround for coreboot/libpayload Kconfig differences */
+#ifndef CONFIG_ARCH_ARMV7
+#define CONFIG_ARCH_ARMV7 0
+#endif
+#ifndef CONFIG_ARCH_POWERPC
+#define CONFIG_ARCH_POWERPC 0
+#endif
+#ifndef CONFIG_ARCH_X86
+#define CONFIG_ARCH_X86 0
+#endif
+
 #include "cbfs_core.h"
 void setup_cbfs_from_ram(void* start, uint32_t size);
 void setup_cbfs_from_flash(void);
diff --git a/payloads/libpayload/include/cbfs_core.h b/payloads/libpayload/include/cbfs_core.h
index 32f2670..9a21a78 100644
--- a/payloads/libpayload/include/cbfs_core.h
+++ b/payloads/libpayload/include/cbfs_core.h
@@ -84,6 +84,9 @@
 #define CBFS_HEADER_MAGIC  0x4F524243
 #if CONFIG_ARCH_X86
 #define CBFS_HEADPTR_ADDR 0xFFFFFFFC
+#elif CONFIG_ARCH_ARMV7
+/* FIXME: This could also be 0xFFFF0000 with HIVECS enabled */
+#define CBFS_HEADPTR_ADDR 0x0000000C
 #endif
 #define VERSION1 0x31313131
 #define VERSION2 0x31313132
diff --git a/payloads/libpayload/libc/time.c b/payloads/libpayload/libc/time.c
index 5ff47b3..5358c02 100644
--- a/payloads/libpayload/libc/time.c
+++ b/payloads/libpayload/libc/time.c
@@ -118,7 +118,7 @@ static void gettimeofday_init(void)
 }
 #endif
 #endif
-#ifdef CONFIG_TARGET_POWERPC
+#ifdef CONFIG_ARCH_POWERPC
 static void update_clock(void)
 {
 }
diff --git a/payloads/libpayload/util/xcompile/xcompile b/payloads/libpayload/util/xcompile/xcompile
index 5e9ce83..fdc5213 100644
--- a/payloads/libpayload/util/xcompile/xcompile
+++ b/payloads/libpayload/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,86 +19,198 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 #
 
-testcc()
-{
-	echo "_start(void) {}" > .$$$$.c
-	$1 -nostdlib $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
+}
+
+program_exists() {
+	type "$1" >/dev/null 2>&1
+}
 
-GCCPREFIX=invalid
-TMPFILE=`mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz`
-touch $TMPFILE
+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"
 
-# This should be a loop over all supported architectures
-TARCH=i386
-TWIDTH=32
-for gccprefixes in `pwd`/../../util/crossgcc/xgcc/bin/${TARCH}-elf- ${TARCH}-elf- ""; 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 "
-			LDFLAGS="-b elf32-i386"
-			break
-		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
+
+	return 0
+}
+
+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}-${TBFDARCH} 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 armv7"
+
+# ARM Architecture
+TARCH_armv7="armv7"
+TBFDARCH_armv7="littlearm"
+TCLIST_armv7="armv7a"
+TWIDTH_armv7="32"
+
+# X86 Architecture
+TARCH_x86="i386"
+TBFDARCH_x86="i386"
+TCLIST_x86="i386 x86_64"
+TWIDTH_x86="32"
+XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
+
+# This loops over all supported architectures.
+for architecture in $SUPPORTED_ARCHITECTURE; do
+	GCCPREFIX="invalid"
+	TARCH="$(eval echo \$TARCH_$architecture)"
+	TBFDARCH="$(eval echo \$TBFDARCH_$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-"
+		search="$search $XGCCPATH$toolchain-eabi-"
+		search="$search $toolchain-eabi-"
+	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" "$TBFDARCH" "" && break
+		testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "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
-rm -f $TMPFILE ${TMPFILE}.o
 
-if [ "$GCCPREFIX" = "invalid" ]; then
-	echo '$(error no suitable gcc found)'
-	exit 1
+if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
+	IASL=${XGCCPATH}iasl
+else
+	IASL=iasl
 fi
 
-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 "
-
-if which gcc 2>/dev/null >/dev/null; then
+if program_exists gcc; then
 	HOSTCC=gcc
 else
 	HOSTCC=cc
 fi
 
-cat << EOF
-# elf${TWIDTH}-${TARCH} toolchain
-AS:=${GCCPREFIX}as ${ASFLAGS}
-CC:=${GCCPREFIX}gcc ${CFLAGS}
-CPP:=${GCCPREFIX}cpp
-AR:=${GCCPREFIX}ar
-LD:=${GCCPREFIX}ld ${LDFLAGS}
-STRIP:=${GCCPREFIX}strip
-NM:=${GCCPREFIX}nm
-OBJCOPY:=${GCCPREFIX}objcopy
-OBJDUMP:=${GCCPREFIX}objdump
+cat <<EOF
+IASL:=${IASL}
 
 # native toolchain
 HOSTCC:=${HOSTCC}
 EOF
-



More information about the coreboot mailing list