summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Reinauer <reinauer@chromium.org>2012-12-14 13:05:21 -0800
committerRonald G. Minnich <rminnich@gmail.com>2012-12-14 22:29:48 +0100
commit8af0d03fd49f9c88db98ef7b3c2d95bf1cd0f319 (patch)
treee33aae504fe01548bfc51a96c8350c3d05d0e6ed
parentf6935a006a6ffe57413877093035cdc1a020e7bd (diff)
libpayload: Initial ARMv7 port
This compiles, but it's not tested yet. Change-Id: I2f73a814649aa36c39af3e77cefd8a968671f5c0 Signed-off-by: Stefan Reinauer <reinauer@google.com> Reviewed-on: http://review.coreboot.org/2035 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
-rw-r--r--payloads/libpayload/Config.in18
-rw-r--r--payloads/libpayload/Makefile32
-rw-r--r--payloads/libpayload/Makefile.inc5
-rw-r--r--payloads/libpayload/arch/Config.in3
-rw-r--r--payloads/libpayload/arch/armv7/Config.in29
-rw-r--r--payloads/libpayload/arch/armv7/Makefile.inc35
-rw-r--r--payloads/libpayload/arch/armv7/assembler.h60
-rw-r--r--payloads/libpayload/arch/armv7/coreboot.c287
-rw-r--r--payloads/libpayload/arch/armv7/head.S52
-rw-r--r--payloads/libpayload/arch/armv7/main.c70
-rw-r--r--payloads/libpayload/arch/armv7/memcpy.S243
-rw-r--r--payloads/libpayload/arch/armv7/memset.S126
-rw-r--r--payloads/libpayload/arch/armv7/sysinfo.c64
-rw-r--r--payloads/libpayload/arch/armv7/timer.c101
-rw-r--r--payloads/libpayload/arch/armv7/util.S36
-rw-r--r--payloads/libpayload/arch/armv7/virtual.c38
-rw-r--r--payloads/libpayload/arch/powerpc/Config.in2
-rwxr-xr-xpayloads/libpayload/bin/lpgcc13
-rw-r--r--payloads/libpayload/configs/defconfig3
-rw-r--r--payloads/libpayload/include/armv7/arch/io.h42
-rw-r--r--payloads/libpayload/include/armv7/arch/types.h60
-rw-r--r--payloads/libpayload/include/armv7/arch/virtual.h41
-rw-r--r--payloads/libpayload/include/cbfs.h12
-rw-r--r--payloads/libpayload/include/cbfs_core.h3
-rw-r--r--payloads/libpayload/libc/time.c2
-rw-r--r--payloads/libpayload/util/xcompile/xcompile239
26 files changed, 1535 insertions, 81 deletions
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index bf30a44360..a14291d50d 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 667822d179..cbfd43a64c 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 5ae888bc41..9419ac8cb4 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 690b12adf5..ccd1851d59 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 0000000000..efc67612dc
--- /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 0000000000..6d9e6c5c55
--- /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 0000000000..5e4789b145
--- /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 0000000000..01ec53cb01
--- /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 0000000000..e1b5737ead
--- /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 0000000000..6b54b27fc6
--- /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 0000000000..549320c8d1
--- /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 0000000000..4ff4c3ce93
--- /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 0000000000..5aa517594c
--- /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 0000000000..24b0a0fa34
--- /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 0000000000..4cf61f3084
--- /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 0000000000..59768dbd66
--- /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 37318f0da3..487e0907ef 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 6cba45d025..52a8e554c0 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 87d9d4b67c..1dce37a924 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 0000000000..e71e1dd7c8
--- /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 0000000000..1bd815bb44
--- /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@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 0000000000..328c3aa34e
--- /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 8b8b0243ef..cf0584ec73 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 32f2670b5b..9a21a7885e 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 5ff47b3868..5358c0247a 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 5e9ce83f98..fdc521338d 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
-