[coreboot-gerrit] New patch to review for coreboot: e1ff2b2 libpayload: Add support for arm64 in libpayload

Marc Jones (marc.jones@se-eng.com) gerrit at coreboot.org
Sun Jan 4 00:29:19 CET 2015


Marc Jones (marc.jones at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8063

-gerrit

commit e1ff2b2303fe858b5c5bf14320be8f8dadcfab30
Author: Furquan Shaikh <furquan at google.com>
Date:   Wed Feb 19 11:35:30 2014 -0800

    libpayload: Add support for arm64 in libpayload
    
    Basic support for arm64 is enabled in libpayload.
    Features added:
    1) mem* operations in assembly.
    2) Basic exception handling and support for testing exceptions.
    3) Caching support.
    
    Tested with arm64-generic board compilation.
    
    BUG=None
    BRANCH=None
    TEST=Compilation successful
    
    Original-Change-Id: I4e86301f9c6383abc078e2b70071fb84bd6e4741
    Original-Signed-off-by: Furquan Shaikh <furquan at google.com>
    Original-Reviewed-on: https://chromium-review.googlesource.com/187067
    Original-Tested-by: Furquan Shaikh <furquan at chromium.org>
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Original-Commit-Queue: Furquan Shaikh <furquan at chromium.org>
    (cherry picked from commit a70d13f3d225535843ab352290eab2e1ec7a9b4b)
    Signed-off-by: Marc Jones <marc.jones at se-eng.com>
    
    Change-Id: Ie3affe6a2bdd4fed3058de739d4c6aa573e5b251
---
 payloads/libpayload/Config.in                      |   5 +
 payloads/libpayload/Makefile                       |   2 +
 payloads/libpayload/Makefile.inc                   |   1 +
 payloads/libpayload/arch/Config.in                 |   1 +
 payloads/libpayload/arch/arm64/Config.in           |  36 +++
 payloads/libpayload/arch/arm64/Makefile.inc        |  43 +++
 payloads/libpayload/arch/arm64/cache.c             | 149 ++++++++++
 payloads/libpayload/arch/arm64/coreboot.c          | 307 +++++++++++++++++++
 payloads/libpayload/arch/arm64/cpu.S               |  98 +++++++
 payloads/libpayload/arch/arm64/dummy_media.c       |  42 +++
 payloads/libpayload/arch/arm64/exception.c         |  96 ++++++
 payloads/libpayload/arch/arm64/exception_asm.S     | 146 ++++++++++
 payloads/libpayload/arch/arm64/head.S              |  66 +++++
 payloads/libpayload/arch/arm64/libpayload.ldscript |  93 ++++++
 payloads/libpayload/arch/arm64/main.c              |  82 ++++++
 payloads/libpayload/arch/arm64/memcpy.S            | 189 ++++++++++++
 payloads/libpayload/arch/arm64/memmove.S           | 324 +++++++++++++++++++++
 payloads/libpayload/arch/arm64/memset.S            | 242 +++++++++++++++
 payloads/libpayload/arch/arm64/sysinfo.c           |  64 ++++
 payloads/libpayload/arch/arm64/timer.c             |  54 ++++
 payloads/libpayload/arch/arm64/util.S              |  35 +++
 payloads/libpayload/arch/arm64/virtual.c           |  38 +++
 payloads/libpayload/bin/lpgcc                      |   7 +-
 payloads/libpayload/configs/config.arm64-generic   |  62 ++++
 payloads/libpayload/configs/defconfig              |   1 +
 payloads/libpayload/configs/defconfig-arm          |   3 +-
 payloads/libpayload/configs/defconfig.orig         |  84 ++++++
 payloads/libpayload/include/arm64/arch/asm.h       |  29 ++
 payloads/libpayload/include/arm64/arch/cache.h     | 259 ++++++++++++++++
 payloads/libpayload/include/arm64/arch/exception.h |  53 ++++
 payloads/libpayload/include/arm64/arch/io.h        |  76 +++++
 payloads/libpayload/include/arm64/arch/types.h     |  60 ++++
 payloads/libpayload/include/arm64/arch/virtual.h   |  41 +++
 payloads/libpayload/include/cbfs_core.h            |   1 +
 payloads/libpayload/util/xcompile/xcompile         |  13 +-
 35 files changed, 2799 insertions(+), 3 deletions(-)

diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index f943cb6..dc18faf 100644
--- a/payloads/libpayload/Config.in
+++ b/payloads/libpayload/Config.in
@@ -77,6 +77,11 @@ config ARCH_X86
         help
           Support the x86 architecture
 
+config ARCH_ARM64
+        bool "ARM64"
+        help
+          Support the ARM64 architecture
+
 endchoice
 
 config MEMMAP_RAM_ONLY
diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile
index 0b2f109..7d8cad7 100644
--- a/payloads/libpayload/Makefile
+++ b/payloads/libpayload/Makefile
@@ -92,6 +92,7 @@ include util/kconfig/Makefile
 include $(HAVE_DOTCONFIG)
 
 ARCHDIR-$(CONFIG_LP_ARCH_ARM)     := arm
+ARCHDIR-$(CONFIG_LP_ARCH_ARM64)   := arm64
 ARCHDIR-$(CONFIG_LP_ARCH_X86)     := x86
 
 ARCH-y := $(ARCHDIR-y)
@@ -99,6 +100,7 @@ ARCH-y := $(ARCHDIR-y)
 # If architecture folder name is different from GCC binutils architecture name,
 # override here.
 ARCH-$(CONFIG_LP_ARCH_ARM)     := arm
+ARCH-$(CONFIG_LP_ARCH_ARM64)   := arm64
 ARCH-$(CONFIG_LP_ARCH_X86)     := i386
 
 CC := $(CC_$(ARCH-y))
diff --git a/payloads/libpayload/Makefile.inc b/payloads/libpayload/Makefile.inc
index dd83f88..16446b5 100644
--- a/payloads/libpayload/Makefile.inc
+++ b/payloads/libpayload/Makefile.inc
@@ -32,6 +32,7 @@
 export KERNELVERSION      := 0.2.0
 
 ARCHDIR-$(CONFIG_LP_ARCH_ARM)     := arm
+ARCHDIR-$(CONFIG_LP_ARCH_ARM64)   := arm64
 ARCHDIR-$(CONFIG_LP_ARCH_X86)     := x86
 DESTDIR ?= install
 
diff --git a/payloads/libpayload/arch/Config.in b/payloads/libpayload/arch/Config.in
index 541f64f..3d3d0b5 100644
--- a/payloads/libpayload/arch/Config.in
+++ b/payloads/libpayload/arch/Config.in
@@ -29,3 +29,4 @@
 
 source "arch/arm/Config.in"
 source "arch/x86/Config.in"
+source "arch/arm64/Config.in"
diff --git a/payloads/libpayload/arch/arm64/Config.in b/payloads/libpayload/arch/arm64/Config.in
new file mode 100644
index 0000000..0f2596c
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/Config.in
@@ -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.
+##
+
+if ARCH_ARM64
+
+config ARCH_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select LITTLE_ENDIAN
+
+endif
diff --git a/payloads/libpayload/arch/arm64/Makefile.inc b/payloads/libpayload/arch/arm64/Makefile.inc
new file mode 100644
index 0000000..682e58b
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/Makefile.inc
@@ -0,0 +1,43 @@
+##
+## 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.
+##
+
+CFLAGS += -march=armv8-a
+arm64_asm_flags =
+
+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 memmove.S
+libc-y += exception_asm.S exception.c
+libc-y += cache.c cpu.S
+
+# Add other classes here when you put assembly files into them!
+ head.o-S-ccopts += $(arm64_asm_flags)
+ libc-S-ccopts += $(arm64_asm_flags)
diff --git a/payloads/libpayload/arch/arm64/cache.c b/payloads/libpayload/arch/arm64/cache.c
new file mode 100644
index 0000000..f6faafa
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/cache.c
@@ -0,0 +1,149 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 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.
+ *
+ * cache.c: Cache maintenance routines for ARM64-A and ARM64-R
+ *
+ * Reference: ARM64 Architecture Reference Manual, ARM64-A and ARM64-R edition
+ */
+
+#include <stdint.h>
+
+#include <arch/cache.h>
+
+void tlb_invalidate_all(void)
+{
+	/* TLBIALL includes dTLB and iTLB on systems that have them. */
+	tlbiall_el3();
+	dsb();
+	isb();
+}
+
+enum dcache_op {
+	OP_DCCSW,
+	OP_DCCISW,
+	OP_DCISW,
+	OP_DCCIVAC,
+	OP_DCCVAC,
+	OP_DCIVAC,
+};
+
+unsigned int dcache_line_bytes(void)
+{
+	uint32_t ccsidr;
+	static unsigned int line_bytes = 0;
+
+	if (line_bytes)
+		return line_bytes;
+
+	ccsidr = read_ccsidr();
+	/* [2:0] - Indicates (Log2(number of words in cache line)) - 2 */
+	line_bytes = 1 << ((ccsidr & 0x7) + 2);	/* words per line */
+	line_bytes *= sizeof(unsigned int);	/* bytes per word */
+
+	return line_bytes;
+}
+
+/*
+ * Do a dcache operation by virtual address. This is useful for
+ * maintaining coherency in drivers which do DMA transfers and only need to
+ * perform cache maintenance on a particular memory range rather than the
+ * entire cache.
+ */
+static void dcache_op_va(void const *addr, size_t len, enum dcache_op op)
+{
+	unsigned long line, linesize;
+
+	linesize = dcache_line_bytes();
+	line = (uintptr_t)addr & ~(linesize - 1);
+
+	dsb();
+	while (line < (uintptr_t)addr + len) {
+		switch(op) {
+		case OP_DCCIVAC:
+			dccivac(line);
+			break;
+		case OP_DCCVAC:
+			dccvac(line);
+			break;
+		case OP_DCIVAC:
+			dcivac(line);
+			break;
+		default:
+			break;
+		}
+		line += linesize;
+	}
+	isb();
+}
+
+void dcache_clean_by_va(void const *addr, size_t len)
+{
+	dcache_op_va(addr, len, OP_DCCVAC);
+}
+
+void dcache_clean_invalidate_by_va(void const *addr, size_t len)
+{
+	dcache_op_va(addr, len, OP_DCCIVAC);
+}
+
+void dcache_invalidate_by_va(void const *addr, size_t len)
+{
+	dcache_op_va(addr, len, OP_DCIVAC);
+}
+
+/*
+ * CAUTION: This implementation assumes that coreboot never uses non-identity
+ * page tables for pages containing executed code. If you ever want to violate
+ * this assumption, have fun figuring out the associated problems on your own.
+ */
+void dcache_mmu_disable(void)
+{
+	uint32_t sctlr;
+
+	dcache_clean_invalidate_all();
+	sctlr = read_sctlr_el3();
+	sctlr &= ~(SCTLR_C | SCTLR_M);
+	write_sctlr_el3(sctlr);
+}
+
+void dcache_mmu_enable(void)
+{
+	uint32_t sctlr;
+
+	sctlr = read_sctlr_el3();
+	sctlr |= SCTLR_C | SCTLR_M;
+	write_sctlr_el3(sctlr);
+}
+
+void cache_sync_instructions(void)
+{
+	dcache_clean_all();	/* includes trailing DSB (in assembly) */
+	iciallu();		/* includes BPIALLU (architecturally) */
+	dsb();
+	isb();
+}
diff --git a/payloads/libpayload/arch/arm64/coreboot.c b/payloads/libpayload/arch/arm64/coreboot.c
new file mode 100644
index 0000000..4630947
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/coreboot.c
@@ -0,0 +1,307 @@
+/*
+ * 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>
+
+/* This pointer gets set in head.S and is passed in from coreboot. */
+void *cb_header_ptr;
+
+/*
+ * 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_LP_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_LP_CHROMEOS
+static void cb_parse_vboot_handoff(unsigned char *ptr, struct sysinfo_t *info)
+{
+	struct cb_range *vbho = (struct cb_range *)ptr;
+
+	info->vboot_handoff = (void *)(uintptr_t)vbho->range_start;
+	info->vboot_handoff_size = vbho->range_size;
+}
+
+static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
+{
+	struct cb_range *vbnv = (struct cb_range *)ptr;
+
+	info->vbnv_start = vbnv->range_start;
+	info->vbnv_size = vbnv->range_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_range *vdat = (struct cb_range *)ptr;
+
+	info->vdat_addr = phys_to_virt(vdat->range_start);
+	info->vdat_size = vdat->range_size;
+}
+#endif
+
+static void cb_parse_dma(unsigned char *ptr)
+{
+	struct cb_range *dma = (struct cb_range *)ptr;
+	init_dma_memory(phys_to_virt(dma->range_start), dma->range_size);
+}
+
+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_LP_NVRAM
+static void cb_parse_optiontable(void *ptr, struct sysinfo_t *info)
+{
+	/* ptr points to a coreboot table entry and is already virtual */
+	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_LP_COREBOOT_VIDEO_CONSOLE
+static void cb_parse_framebuffer(void *ptr, struct sysinfo_t *info)
+{
+	/* ptr points to a coreboot table entry and is already virtual */
+	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, struct sysinfo_t *info)
+{
+	struct cb_header *header = addr;
+	unsigned char *ptr = addr;
+	void *forward;
+	int i;
+
+	/* No signature found. */
+	if (strncmp((const char *)header->signature, "LBIO", 4))
+			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, 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_LP_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_LP_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;
+			break;
+#ifdef CONFIG_LP_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;
+		case CB_TAG_VBOOT_HANDOFF:
+			cb_parse_vboot_handoff(ptr, info);
+			break;
+#endif
+		case CB_TAG_DMA:
+			cb_parse_dma(ptr);
+			break;
+		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(cb_header_ptr, info);
+
+	return (ret == 1) ? 0 : -1;
+}
diff --git a/payloads/libpayload/arch/arm64/cpu.S b/payloads/libpayload/arch/arm64/cpu.S
new file mode 100644
index 0000000..d80f73c
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/cpu.S
@@ -0,0 +1,98 @@
+/*
+ * Optimized assembly for low-level CPU operations on ARM64 processors.
+ *
+ * Copyright (c) 2010 Per Odlund <per.odlund at armagedon.se>
+ * Copyright (c) 2014 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.
+ */
+
+#include <arch/asm.h>
+
+.macro	dcache_apply_all crm
+	dsb	sy
+	mrs	x0, clidr_el1			// read CLIDR
+	and	w3, w0, #0x07000000		// narrow to LoC
+	lsr	w3, w3, #23			// left align LoC (low 4 bits)
+	cbz	w3, 5f //done
+
+	mov	w10, #0				// w10 = 2 * cache level
+	mov	w8, #1				// w8 = constant 0b1
+
+1:	//next_level
+	add	w2, w10, w10, lsr #1		// calculate 3 * cache level
+	lsr	w1, w0, w2			// extract 3-bit cache type for this level
+	and	w1, w1, #0x7			// w1 = cache type
+	cmp	w1, #2				// is it data or i&d?
+	b.lt	4f //skip
+	msr	csselr_el1, x10			// select current cache level
+	isb					// sync change of csselr
+	mrs	x1, ccsidr_el1			// w1 = read ccsidr
+	and	w2, w1, #7			// w2 = log2(linelen_bytes) - 4
+	add	w2, w2, #4			// w2 = log2(linelen_bytes)
+	ubfx	w4, w1, #3, #10			// w4 = associativity - 1 (also
+						// max way number)
+	clz	w5, w4				// w5 = 32 - log2(ways)
+						// (bit position of way in DC)
+	lsl	w9, w4, w5			// w9 = max way number
+						// (aligned for DC)
+	lsl	w16, w8, w5			// w16 = amount to decrement (way
+						// number per iteration)
+2:	//next_way
+	ubfx	w7, w1, #13, #15		// w7 = max set #, right aligned
+	lsl	w7, w7, w2			// w7 = max set #, DC aligned
+	lsl	w17, w8, w2			// w17 = amount to decrement (set
+						// number per iteration)
+
+3:	//next_set
+	orr	w11, w10, w9			// w11 = combine way # & cache #
+	orr	w11, w11, w7			// ... and set #
+	dc	\crm, x11			// clean and/or invalidate line
+	subs	w7, w7, w17			// decrement set number
+	b.ge	3b //next_set
+	subs	x9, x9, x16			// decrement way number
+	b.ge	2b //next_way
+
+4:	//skip
+	add	w10, w10, #2			// increment 2 *cache level
+	cmp	w3, w10				// Went beyond LoC?
+	b.gt	1b //next_level
+
+5:	//done
+	dsb	sy
+	isb
+	ret
+.endm
+
+ENTRY(dcache_invalidate_all)
+	dcache_apply_all crm=isw
+ENDPROC(dcache_invalidate_all)
+
+ENTRY(dcache_clean_all)
+	dcache_apply_all crm=csw
+ENDPROC(dcache_clean_all)
+
+ENTRY(dcache_clean_invalidate_all)
+	dcache_apply_all crm=cisw
+ENDPROC(dcache_clean_invalidate_all)
diff --git a/payloads/libpayload/arch/arm64/dummy_media.c b/payloads/libpayload/arch/arm64/dummy_media.c
new file mode 100644
index 0000000..7926976
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/dummy_media.c
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2013 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.
+ */
+#define LIBPAYLOAD
+
+#include <cbfs.h>
+#include <string.h>
+
+/* The generic cbfs code relies on the libpayload_init_default_cbfs_media
+ * symbol. Therefore, provide an implementation that just throws an error. */
+
+int libpayload_init_default_cbfs_media(struct cbfs_media *media);
+
+int libpayload_init_default_cbfs_media(struct cbfs_media *media)
+{
+	return -1;
+}
diff --git a/payloads/libpayload/arch/arm64/exception.c b/payloads/libpayload/arch/arm64/exception.c
new file mode 100644
index 0000000..988bef9
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/exception.c
@@ -0,0 +1,96 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2014 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.
+ */
+
+#include <exception.h>
+#include <libpayload.h>
+#include <stdint.h>
+
+extern unsigned int test_exc;
+
+struct exception_handler_info
+{
+	const char *name;
+	exception_hook hook;
+};
+
+static struct exception_handler_info exceptions[EXC_COUNT] = {
+	[EXC_INV]  = { "_invalid_exception" },
+	[EXC_SYNC] = { "_sync" },
+	[EXC_IRQ]  = { "_irq" },
+	[EXC_FIQ]  = { "_fiq" },
+	[EXC_SERROR] = {"_serror"}
+};
+
+static void print_regs(struct exception_state *state)
+{
+	int i;
+
+	printf("ELR = 0x%016llx        ",state->elr);
+	printf("ESR = 0x%08llx         ",state->esr);
+	for (i = 0; i < 31; i++) {
+		printf("X%02d = 0x%016llx        ", i, state->regs[i]);
+	}
+}
+
+void exception_dispatch(struct exception_state *state, int idx);
+void exception_dispatch(struct exception_state *state, int idx)
+{
+	if (idx >= EXC_COUNT) {
+		printf("Bad exception index %d.\n", idx);
+	} else {
+		struct exception_handler_info *info = &exceptions[idx];
+		if (info->hook) {
+			info->hook(idx, state);
+			return;
+		}
+
+		if (info->name)
+			printf("exception %s\n", info->name);
+		else
+			printf("exception _not_used.\n");
+	}
+	print_regs(state);
+
+	if (test_exc)
+		test_exc = 0;
+	else
+		halt();
+}
+
+void exception_init(void)
+{
+	extern void* exception_table;
+	set_vbar(exception_table);
+}
+
+void exception_install_hook(int type, exception_hook hook)
+{
+	die_if(type >= EXC_COUNT, "Out of bounds exception index %d.\n", type);
+	exceptions[type].hook = hook;
+}
diff --git a/payloads/libpayload/arch/arm64/exception_asm.S b/payloads/libpayload/arch/arm64/exception_asm.S
new file mode 100644
index 0000000..c68ba5a
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/exception_asm.S
@@ -0,0 +1,146 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2014 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.
+ */
+
+	.text
+
+	/* Macro for exception entry
+	 * Store x30 before any branch
+	 * Branch to exception_prologue to save rest of the registers
+	 * Move exception id into x1
+	 * Branch to exception_handler
+	 */
+.macro eentry id
+	stp     x30, xzr, [sp, #-16]!
+	bl      exception_prologue
+	mov     x1, \id
+	bl      exception_handler
+.endm
+
+	/* Exception table has 16 entries and each of 128 bytes
+	 * Hence, 16 * 128 = 2048. Thus, 11 passed as parameter
+	 * to align
+	 */
+
+	.align  11
+	.global exception_table
+exception_table:
+
+	.align  7
+sync_el0:
+	eentry #0
+
+	.align  7
+irq_el0:
+	eentry #0
+
+	.align  7
+fiq_el0:
+	eentry #0
+
+	.align  7
+serror_el0:
+	eentry #0
+
+	.align  7
+sync_elx:
+	eentry #1
+
+	.align  7
+irq_elx:
+	eentry #2
+
+	.align  7
+fiq_elx:
+	eentry #3
+
+	.align  7
+serror_elx:
+	eentry #4
+
+exception_prologue:
+	/* Save all registers x0-x29 */
+	stp     x28, x29, [sp, #-16]!
+	stp     x26, x27, [sp, #-16]!
+	stp     x24, x25, [sp, #-16]!
+	stp     x22, x23, [sp, #-16]!
+	stp     x20, x21, [sp, #-16]!
+	stp     x18, x19, [sp, #-16]!
+	stp     x16, x17, [sp, #-16]!
+	stp     x14, x15, [sp, #-16]!
+	stp     x12, x13, [sp, #-16]!
+	stp     x10, x11, [sp, #-16]!
+	stp     x8, x9, [sp, #-16]!
+	stp     x6, x7, [sp, #-16]!
+	stp     x4, x5, [sp, #-16]!
+	stp     x2, x3, [sp, #-16]!
+	stp     x0, x1, [sp, #-16]!
+
+	/* Save the exception reason on stack */
+	mrs     x1,  esr_el3
+
+	/* Save the return address on stack */
+	mrs     x0, elr_el3
+	stp     x0, x1, [sp, #-16]!
+
+	ret
+
+exception_handler:
+	/* Save address of saved registers into x0
+	 * This acts as first argument to exception_dispatch
+	 */
+	mov     x0, sp
+	bl      exception_dispatch
+
+	/* Pop return address saved on stack */
+	ldp     x0, x1, [sp], #16
+	/* Pop exception reason saved on stack, followed by regs x0-x30 */
+	ldp     x0, x1, [sp], #16
+	ldp     x2, x3, [sp], #16
+	ldp     x4, x5, [sp], #16
+	ldp     x6, x7, [sp], #16
+	ldp     x8, x9, [sp], #16
+	ldp     x10, x11, [sp], #16
+	ldp     x12, x13, [sp], #16
+	ldp     x14, x15, [sp], #16
+	ldp     x16, x17, [sp], #16
+	ldp     x18, x19, [sp], #16
+	ldp     x20, x21, [sp], #16
+	ldp     x22, x23, [sp], #16
+	ldp     x24, x25, [sp], #16
+	ldp     x26, x27, [sp], #16
+	ldp     x28, x29, [sp], #16
+	ldp     x30, xzr, [sp], #16
+	eret
+
+	.global set_vbar
+set_vbar:
+	/* Initialize the exception table address in vbar for EL3 */
+	/* FIXME: Do we need to initialize for other levels too? EL1/EL2 */
+	msr     vbar_el3, x0
+	ret
diff --git a/payloads/libpayload/arch/arm64/head.S b/payloads/libpayload/arch/arm64/head.S
new file mode 100644
index 0000000..214c5d7
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/head.S
@@ -0,0 +1,66 @@
+/*
+ * 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 <arch/asm.h>
+
+/*
+ * Our entry point
+ */
+ENTRY(_entry)
+
+	/* Save off the location of the coreboot tables */
+	ldr x1, 1f
+	str x0, [x1]
+
+	/* TODO: disable interrupts */
+
+	/* TODO: Clear BSS */
+
+	/* Setup new stack */
+	ldr x1, 2f
+	mov sp, x1
+
+	/* TODO: Save old stack pointer and link register */
+
+	/* Let's rock. */
+	bl start_main
+
+	/* %r0 has the return value - pass it on unmolested */
+
+	/* TODO: restore old stack pointer and link register */
+
+	/* Return to the original context. */
+	ret
+ENDPROC(_entry)
+
+.align 4
+1:
+.quad	cb_header_ptr
+2:
+.quad	_stack
diff --git a/payloads/libpayload/arch/arm64/libpayload.ldscript b/payloads/libpayload/arch/arm64/libpayload.ldscript
new file mode 100644
index 0000000..41a2e89
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/libpayload.ldscript
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2013 Google, Inc.
+ * 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.
+ */
+
+BASE_ADDRESS = 0x80100000;
+
+OUTPUT_FORMAT("elf64-littleaarch64","elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(arm64)
+
+ENTRY(_entry)
+
+HEAP_SIZE = 2*64*1024;
+STACK_SIZE = 16384;
+
+SECTIONS
+{
+	. = BASE_ADDRESS;
+
+	. = ALIGN(16);
+	_start = .;
+
+	.text : {
+		*(.text._entry)
+		*(.text)
+		*(.text.*)
+	}
+
+	.rodata : {
+		*(.rodata)
+		*(.rodata.*)
+	}
+
+	.data : {
+		*(.data)
+		*(.data.*)
+	}
+
+	_edata = .;
+
+	.bss : {
+		*(.sbss)
+		*(.sbss.*)
+		*(.bss)
+		*(.bss.*)
+		*(COMMON)
+
+		/* Stack and heap */
+
+		. = ALIGN(16);
+		_heap = .;
+		. += HEAP_SIZE;
+		. = ALIGN(16);
+		_eheap = .;
+
+		_estack = .;
+		. += STACK_SIZE;
+		. = ALIGN(16);
+		_stack = .;
+	}
+
+	_end = .;
+
+	/DISCARD/ : {
+		*(.comment)
+		*(.note*)
+	}
+}
diff --git a/payloads/libpayload/arch/arm64/main.c b/payloads/libpayload/arch/arm64/main.c
new file mode 100644
index 0000000..ba4fc60
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/main.c
@@ -0,0 +1,82 @@
+/*
+ * 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 <exception.h>
+#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];
+
+unsigned int test_exc;
+
+int test_exception(void);
+int test_exception(void)
+{
+	int a = 1;
+	int b = 0;
+	test_exc = 1;
+	return a/b;
+}
+
+/**
+ * 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);
+
+	printf("hello libpayload world");
+	/* Gather system information. */
+	lib_get_sysinfo();
+
+
+	exception_init();
+
+	test_exception();
+	/*
+	 * 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/arm64/memcpy.S b/payloads/libpayload/arch/arm64/memcpy.S
new file mode 100644
index 0000000..1c8e55d
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/memcpy.S
@@ -0,0 +1,189 @@
+/* Copyright (c) 2012-2013, Linaro Limited
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * 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.
+       * Neither the name of the Linaro nor the
+         names of its contributors may be used to endorse or promote products
+         derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+   HOLDER 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. */
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64
+ * Unaligned accesses
+ *
+ */
+
+#define dstin	x0
+#define src	x1
+#define count	x2
+#define tmp1	x3
+#define tmp1w	w3
+#define tmp2	x4
+#define tmp2w	w4
+#define tmp3	x5
+#define tmp3w	w5
+#define dst	x6
+
+#define A_l	x7
+#define A_h	x8
+#define B_l	x9
+#define B_h	x10
+#define C_l	x11
+#define C_h	x12
+#define D_l	x13
+#define D_h	x14
+
+.macro def_fn f p2align=0
+.text
+.p2align \p2align
+.global \f
+.type \f, %function
+\f:
+.endm
+
+def_fn memcpy p2align=6
+
+	mov	dst, dstin
+	cmp	count, #64
+	b.ge	.Lcpy_not_short
+	cmp	count, #15
+	b.le	.Ltail15tiny
+
+	/* Deal with small copies quickly by dropping straight into the
+	 * exit block.  */
+.Ltail63:
+	/* Copy up to 48 bytes of data.  At this point we only need the
+	 * bottom 6 bits of count to be accurate.  */
+	ands	tmp1, count, #0x30
+	b.eq	.Ltail15
+	add	dst, dst, tmp1
+	add	src, src, tmp1
+	cmp	tmp1w, #0x20
+	b.eq	1f
+	b.lt	2f
+	ldp	A_l, A_h, [src, #-48]
+	stp	A_l, A_h, [dst, #-48]
+1:
+	ldp	A_l, A_h, [src, #-32]
+	stp	A_l, A_h, [dst, #-32]
+2:
+	ldp	A_l, A_h, [src, #-16]
+	stp	A_l, A_h, [dst, #-16]
+
+.Ltail15:
+	ands	count, count, #15
+	beq	1f
+	add	src, src, count
+	ldp	A_l, A_h, [src, #-16]
+	add	dst, dst, count
+	stp	A_l, A_h, [dst, #-16]
+1:
+	ret
+
+.Ltail15tiny:
+	/* Copy up to 15 bytes of data.  Does not assume additional data
+	   being copied.  */
+	tbz	count, #3, 1f
+	ldr	tmp1, [src], #8
+	str	tmp1, [dst], #8
+1:
+	tbz	count, #2, 1f
+	ldr	tmp1w, [src], #4
+	str	tmp1w, [dst], #4
+1:
+	tbz	count, #1, 1f
+	ldrh	tmp1w, [src], #2
+	strh	tmp1w, [dst], #2
+1:
+	tbz	count, #0, 1f
+	ldrb	tmp1w, [src]
+	strb	tmp1w, [dst]
+1:
+	ret
+
+.Lcpy_not_short:
+	/* We don't much care about the alignment of DST, but we want SRC
+	 * to be 128-bit (16 byte) aligned so that we don't cross cache line
+	 * boundaries on both loads and stores.  */
+	neg	tmp2, src
+	ands	tmp2, tmp2, #15		/* Bytes to reach alignment.  */
+	b.eq	2f
+	sub	count, count, tmp2
+	/* Copy more data than needed; it's faster than jumping
+	 * around copying sub-Quadword quantities.  We know that
+	 * it can't overrun.  */
+	ldp	A_l, A_h, [src]
+	add	src, src, tmp2
+	stp	A_l, A_h, [dst]
+	add	dst, dst, tmp2
+	/* There may be less than 63 bytes to go now.  */
+	cmp	count, #63
+	b.le	.Ltail63
+2:
+	subs	count, count, #128
+	b.ge	.Lcpy_body_large
+	/* Less than 128 bytes to copy, so handle 64 here and then jump
+	 * to the tail.  */
+	ldp	A_l, A_h, [src]
+	ldp	B_l, B_h, [src, #16]
+	ldp	C_l, C_h, [src, #32]
+	ldp	D_l, D_h, [src, #48]
+	stp	A_l, A_h, [dst]
+	stp	B_l, B_h, [dst, #16]
+	stp	C_l, C_h, [dst, #32]
+	stp	D_l, D_h, [dst, #48]
+	tst	count, #0x3f
+	add	src, src, #64
+	add	dst, dst, #64
+	b.ne	.Ltail63
+	ret
+
+	/* Critical loop.  Start at a new cache line boundary.  Assuming
+	 * 64 bytes per line this ensures the entire loop is in one line.  */
+	.p2align 6
+.Lcpy_body_large:
+	/* There are at least 128 bytes to copy.  */
+	ldp	A_l, A_h, [src, #0]
+	sub	dst, dst, #16		/* Pre-bias.  */
+	ldp	B_l, B_h, [src, #16]
+	ldp	C_l, C_h, [src, #32]
+	ldp	D_l, D_h, [src, #48]!	/* src += 64 - Pre-bias.  */
+1:
+	stp	A_l, A_h, [dst, #16]
+	ldp	A_l, A_h, [src, #16]
+	stp	B_l, B_h, [dst, #32]
+	ldp	B_l, B_h, [src, #32]
+	stp	C_l, C_h, [dst, #48]
+	ldp	C_l, C_h, [src, #48]
+	stp	D_l, D_h, [dst, #64]!
+	ldp	D_l, D_h, [src, #64]!
+	subs	count, count, #64
+	b.ge	1b
+	stp	A_l, A_h, [dst, #16]
+	stp	B_l, B_h, [dst, #32]
+	stp	C_l, C_h, [dst, #48]
+	stp	D_l, D_h, [dst, #64]
+	add	src, src, #16
+	add	dst, dst, #64 + 16
+	tst	count, #0x3f
+	b.ne	.Ltail63
+	ret
+	.size	memcpy, .-memcpy
diff --git a/payloads/libpayload/arch/arm64/memmove.S b/payloads/libpayload/arch/arm64/memmove.S
new file mode 100644
index 0000000..d79316e
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/memmove.S
@@ -0,0 +1,324 @@
+/* Copyright (c) 2013, Linaro Limited
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * 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.
+       * Neither the name of the Linaro nor the
+         names of its contributors may be used to endorse or promote products
+         derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+   HOLDER 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. */
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64
+ * Unaligned accesses
+ */
+
+.macro def_fn f p2align=0
+.text
+.p2align \p2align
+.global \f
+.type \f, %function
+\f:
+.endm
+
+/* Parameters and result.  */
+#define dstin	x0
+#define src	x1
+#define count	x2
+#define tmp1	x3
+#define tmp1w	w3
+#define tmp2	x4
+#define tmp2w	w4
+#define tmp3	x5
+#define tmp3w	w5
+#define dst	x6
+
+#define A_l	x7
+#define A_h	x8
+#define B_l	x9
+#define B_h	x10
+#define C_l	x11
+#define C_h	x12
+#define D_l	x13
+#define D_h	x14
+
+def_fn memmove, 6
+	cmp	dstin, src
+	b.lo	.Ldownwards
+	add	tmp1, src, count
+	cmp	dstin, tmp1
+	b.hs	memcpy		/* No overlap.  */
+
+	/* Upwards move with potential overlap.
+	 * Need to move from the tail backwards.  SRC and DST point one
+	 * byte beyond the remaining data to move.  */
+	add	dst, dstin, count
+	add	src, src, count
+	cmp	count, #64
+	b.ge	.Lmov_not_short_up
+
+	/* Deal with small moves quickly by dropping straight into the
+	 * exit block.  */
+.Ltail63up:
+	/* Move up to 48 bytes of data.  At this point we only need the
+	 * bottom 6 bits of count to be accurate.  */
+	ands	tmp1, count, #0x30
+	b.eq	.Ltail15up
+	sub	dst, dst, tmp1
+	sub	src, src, tmp1
+	cmp	tmp1w, #0x20
+	b.eq	1f
+	b.lt	2f
+	ldp	A_l, A_h, [src, #32]
+	stp	A_l, A_h, [dst, #32]
+1:
+	ldp	A_l, A_h, [src, #16]
+	stp	A_l, A_h, [dst, #16]
+2:
+	ldp	A_l, A_h, [src]
+	stp	A_l, A_h, [dst]
+.Ltail15up:
+	/* Move up to 15 bytes of data.  Does not assume additional data
+	 * being moved.  */
+	tbz	count, #3, 1f
+	ldr	tmp1, [src, #-8]!
+	str	tmp1, [dst, #-8]!
+1:
+	tbz	count, #2, 1f
+	ldr	tmp1w, [src, #-4]!
+	str	tmp1w, [dst, #-4]!
+1:
+	tbz	count, #1, 1f
+	ldrh	tmp1w, [src, #-2]!
+	strh	tmp1w, [dst, #-2]!
+1:
+	tbz	count, #0, 1f
+	ldrb	tmp1w, [src, #-1]
+	strb	tmp1w, [dst, #-1]
+1:
+	ret
+
+.Lmov_not_short_up:
+	/* We don't much care about the alignment of DST, but we want SRC
+	 * to be 128-bit (16 byte) aligned so that we don't cross cache line
+	 * boundaries on both loads and stores.  */
+	ands	tmp2, src, #15		/* Bytes to reach alignment.  */
+	b.eq	2f
+	sub	count, count, tmp2
+	/* Move enough data to reach alignment; unlike memcpy, we have to
+	 * be aware of the overlap, which means we can't move data twice.  */
+	tbz	tmp2, #3, 1f
+	ldr	tmp1, [src, #-8]!
+	str	tmp1, [dst, #-8]!
+1:
+	tbz	tmp2, #2, 1f
+	ldr	tmp1w, [src, #-4]!
+	str	tmp1w, [dst, #-4]!
+1:
+	tbz	tmp2, #1, 1f
+	ldrh	tmp1w, [src, #-2]!
+	strh	tmp1w, [dst, #-2]!
+1:
+	tbz	tmp2, #0, 1f
+	ldrb	tmp1w, [src, #-1]!
+	strb	tmp1w, [dst, #-1]!
+1:
+
+	/* There may be less than 63 bytes to go now.  */
+	cmp	count, #63
+	b.le	.Ltail63up
+2:
+	subs	count, count, #128
+	b.ge	.Lmov_body_large_up
+	/* Less than 128 bytes to move, so handle 64 here and then jump
+	 * to the tail.  */
+	ldp	A_l, A_h, [src, #-64]!
+	ldp	B_l, B_h, [src, #16]
+	ldp	C_l, C_h, [src, #32]
+	ldp	D_l, D_h, [src, #48]
+	stp	A_l, A_h, [dst, #-64]!
+	stp	B_l, B_h, [dst, #16]
+	stp	C_l, C_h, [dst, #32]
+	stp	D_l, D_h, [dst, #48]
+	tst	count, #0x3f
+	b.ne	.Ltail63up
+	ret
+
+	/* Critical loop.  Start at a new Icache line boundary.  Assuming
+	 * 64 bytes per line this ensures the entire loop is in one line.  */
+	.p2align 6
+.Lmov_body_large_up:
+	/* There are at least 128 bytes to move.  */
+	ldp	A_l, A_h, [src, #-16]
+	ldp	B_l, B_h, [src, #-32]
+	ldp	C_l, C_h, [src, #-48]
+	ldp	D_l, D_h, [src, #-64]!
+1:
+	stp	A_l, A_h, [dst, #-16]
+	ldp	A_l, A_h, [src, #-16]
+	stp	B_l, B_h, [dst, #-32]
+	ldp	B_l, B_h, [src, #-32]
+	stp	C_l, C_h, [dst, #-48]
+	ldp	C_l, C_h, [src, #-48]
+	stp	D_l, D_h, [dst, #-64]!
+	ldp	D_l, D_h, [src, #-64]!
+	subs	count, count, #64
+	b.ge	1b
+	stp	A_l, A_h, [dst, #-16]
+	stp	B_l, B_h, [dst, #-32]
+	stp	C_l, C_h, [dst, #-48]
+	stp	D_l, D_h, [dst, #-64]!
+	tst	count, #0x3f
+	b.ne	.Ltail63up
+	ret
+
+
+.Ldownwards:
+	/* For a downwards move we can safely use memcpy provided that
+	 * DST is more than 16 bytes away from SRC.  */
+	sub	tmp1, src, #16
+	cmp	dstin, tmp1
+	b.ls	memcpy		/* May overlap, but not critically.  */
+
+	mov	dst, dstin	/* Preserve DSTIN for return value.  */
+	cmp	count, #64
+	b.ge	.Lmov_not_short_down
+
+	/* Deal with small moves quickly by dropping straight into the
+	 * exit block.  */
+.Ltail63down:
+	/* Move up to 48 bytes of data.  At this point we only need the
+	 * bottom 6 bits of count to be accurate.  */
+	ands	tmp1, count, #0x30
+	b.eq	.Ltail15down
+	add	dst, dst, tmp1
+	add	src, src, tmp1
+	cmp	tmp1w, #0x20
+	b.eq	1f
+	b.lt	2f
+	ldp	A_l, A_h, [src, #-48]
+	stp	A_l, A_h, [dst, #-48]
+1:
+	ldp	A_l, A_h, [src, #-32]
+	stp	A_l, A_h, [dst, #-32]
+2:
+	ldp	A_l, A_h, [src, #-16]
+	stp	A_l, A_h, [dst, #-16]
+.Ltail15down:
+	/* Move up to 15 bytes of data.  Does not assume additional data
+	   being moved.  */
+	tbz	count, #3, 1f
+	ldr	tmp1, [src], #8
+	str	tmp1, [dst], #8
+1:
+	tbz	count, #2, 1f
+	ldr	tmp1w, [src], #4
+	str	tmp1w, [dst], #4
+1:
+	tbz	count, #1, 1f
+	ldrh	tmp1w, [src], #2
+	strh	tmp1w, [dst], #2
+1:
+	tbz	count, #0, 1f
+	ldrb	tmp1w, [src]
+	strb	tmp1w, [dst]
+1:
+	ret
+
+.Lmov_not_short_down:
+	/* We don't much care about the alignment of DST, but we want SRC
+	 * to be 128-bit (16 byte) aligned so that we don't cross cache line
+	 * boundaries on both loads and stores.  */
+	neg	tmp2, src
+	ands	tmp2, tmp2, #15		/* Bytes to reach alignment.  */
+	b.eq	2f
+	sub	count, count, tmp2
+	/* Move enough data to reach alignment; unlike memcpy, we have to
+	 * be aware of the overlap, which means we can't move data twice.  */
+	tbz	tmp2, #3, 1f
+	ldr	tmp1, [src], #8
+	str	tmp1, [dst], #8
+1:
+	tbz	tmp2, #2, 1f
+	ldr	tmp1w, [src], #4
+	str	tmp1w, [dst], #4
+1:
+	tbz	tmp2, #1, 1f
+	ldrh	tmp1w, [src], #2
+	strh	tmp1w, [dst], #2
+1:
+	tbz	tmp2, #0, 1f
+	ldrb	tmp1w, [src], #1
+	strb	tmp1w, [dst], #1
+1:
+
+	/* There may be less than 63 bytes to go now.  */
+	cmp	count, #63
+	b.le	.Ltail63down
+2:
+	subs	count, count, #128
+	b.ge	.Lmov_body_large_down
+	/* Less than 128 bytes to move, so handle 64 here and then jump
+	 * to the tail.  */
+	ldp	A_l, A_h, [src]
+	ldp	B_l, B_h, [src, #16]
+	ldp	C_l, C_h, [src, #32]
+	ldp	D_l, D_h, [src, #48]
+	stp	A_l, A_h, [dst]
+	stp	B_l, B_h, [dst, #16]
+	stp	C_l, C_h, [dst, #32]
+	stp	D_l, D_h, [dst, #48]
+	tst	count, #0x3f
+	add	src, src, #64
+	add	dst, dst, #64
+	b.ne	.Ltail63down
+	ret
+
+	/* Critical loop.  Start at a new cache line boundary.  Assuming
+	 * 64 bytes per line this ensures the entire loop is in one line.  */
+	.p2align 6
+.Lmov_body_large_down:
+	/* There are at least 128 bytes to move.  */
+	ldp	A_l, A_h, [src, #0]
+	sub	dst, dst, #16		/* Pre-bias.  */
+	ldp	B_l, B_h, [src, #16]
+	ldp	C_l, C_h, [src, #32]
+	ldp	D_l, D_h, [src, #48]!	/* src += 64 - Pre-bias.  */
+1:
+	stp	A_l, A_h, [dst, #16]
+	ldp	A_l, A_h, [src, #16]
+	stp	B_l, B_h, [dst, #32]
+	ldp	B_l, B_h, [src, #32]
+	stp	C_l, C_h, [dst, #48]
+	ldp	C_l, C_h, [src, #48]
+	stp	D_l, D_h, [dst, #64]!
+	ldp	D_l, D_h, [src, #64]!
+	subs	count, count, #64
+	b.ge	1b
+	stp	A_l, A_h, [dst, #16]
+	stp	B_l, B_h, [dst, #32]
+	stp	C_l, C_h, [dst, #48]
+	stp	D_l, D_h, [dst, #64]
+	add	src, src, #16
+	add	dst, dst, #64 + 16
+	tst	count, #0x3f
+	b.ne	.Ltail63down
+	ret
+	.size memmove, . - memmove
diff --git a/payloads/libpayload/arch/arm64/memset.S b/payloads/libpayload/arch/arm64/memset.S
new file mode 100644
index 0000000..ee8f818
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/memset.S
@@ -0,0 +1,242 @@
+/* Copyright (c) 2012-2013, Linaro Limited
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+       * Redistributions of source code must retain the above copyright
+         notice, this list of conditions and the following disclaimer.
+       * 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.
+       * Neither the name of the Linaro nor the
+         names of its contributors may be used to endorse or promote products
+         derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+   HOLDER 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. */
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64
+ * Unaligned accesses
+ *
+ */
+
+/* By default we assume that the DC instruction can be used to zero
+   data blocks more efficiently.  In some circumstances this might be
+   unsafe, for example in an asymmetric multiprocessor environment with
+   different DC clear lengths (neither the upper nor lower lengths are
+   safe to use).  The feature can be disabled by defining DONT_USE_DC.
+
+   If code may be run in a virtualized environment, then define
+   MAYBE_VIRT.  This will cause the code to cache the system register
+   values rather than re-reading them each call.  */
+
+#define dstin		x0
+#define val		w1
+#define count		x2
+#define tmp1		x3
+#define tmp1w		w3
+#define tmp2		x4
+#define tmp2w		w4
+#define zva_len_x	x5
+#define zva_len		w5
+#define zva_bits_x	x6
+
+#define A_l		x7
+#define A_lw		w7
+#define dst		x8
+#define tmp3w		w9
+
+
+.macro def_fn f p2align=0
+.text
+.p2align \p2align
+.global \f
+.type \f, %function
+\f:
+.endm
+
+def_fn memset p2align=6
+
+	mov	dst, dstin		/* Preserve return value.  */
+	ands	A_lw, val, #255
+#ifndef DONT_USE_DC
+	b.eq	.Lzero_mem
+#endif
+	orr	A_lw, A_lw, A_lw, lsl #8
+	orr	A_lw, A_lw, A_lw, lsl #16
+	orr	A_l, A_l, A_l, lsl #32
+.Ltail_maybe_long:
+	cmp	count, #64
+	b.ge	.Lnot_short
+.Ltail_maybe_tiny:
+	cmp	count, #15
+	b.le	.Ltail15tiny
+.Ltail63:
+	ands	tmp1, count, #0x30
+	b.eq	.Ltail15
+	add	dst, dst, tmp1
+	cmp	tmp1w, #0x20
+	b.eq	1f
+	b.lt	2f
+	stp	A_l, A_l, [dst, #-48]
+1:
+	stp	A_l, A_l, [dst, #-32]
+2:
+	stp	A_l, A_l, [dst, #-16]
+
+.Ltail15:
+	and	count, count, #15
+	add	dst, dst, count
+	stp	A_l, A_l, [dst, #-16]	/* Repeat some/all of last store. */
+	ret
+
+.Ltail15tiny:
+	/* Set up to 15 bytes.  Does not assume earlier memory
+	   being set.  */
+	tbz	count, #3, 1f
+	str	A_l, [dst], #8
+1:
+	tbz	count, #2, 1f
+	str	A_lw, [dst], #4
+1:
+	tbz	count, #1, 1f
+	strh	A_lw, [dst], #2
+1:
+	tbz	count, #0, 1f
+	strb	A_lw, [dst]
+1:
+	ret
+
+	/* Critical loop.  Start at a new cache line boundary.  Assuming
+	 * 64 bytes per line, this ensures the entire loop is in one line.  */
+	.p2align 6
+.Lnot_short:
+	neg	tmp2, dst
+	ands	tmp2, tmp2, #15
+	b.eq	2f
+	/* Bring DST to 128-bit (16-byte) alignment.  We know that there's
+	 * more than that to set, so we simply store 16 bytes and advance by
+	 * the amount required to reach alignment.  */
+	sub	count, count, tmp2
+	stp	A_l, A_l, [dst]
+	add	dst, dst, tmp2
+	/* There may be less than 63 bytes to go now.  */
+	cmp	count, #63
+	b.le	.Ltail63
+2:
+	sub	dst, dst, #16		/* Pre-bias.  */
+	sub	count, count, #64
+1:
+	stp	A_l, A_l, [dst, #16]
+	stp	A_l, A_l, [dst, #32]
+	stp	A_l, A_l, [dst, #48]
+	stp	A_l, A_l, [dst, #64]!
+	subs	count, count, #64
+	b.ge	1b
+	tst	count, #0x3f
+	add	dst, dst, #16
+	b.ne	.Ltail63
+	ret
+
+#ifndef DONT_USE_DC
+	/* For zeroing memory, check to see if we can use the ZVA feature to
+	 * zero entire 'cache' lines.  */
+.Lzero_mem:
+	mov	A_l, #0
+	cmp	count, #63
+	b.le	.Ltail_maybe_tiny
+	neg	tmp2, dst
+	ands	tmp2, tmp2, #15
+	b.eq	1f
+	sub	count, count, tmp2
+	stp	A_l, A_l, [dst]
+	add	dst, dst, tmp2
+	cmp	count, #63
+	b.le	.Ltail63
+1:
+	/* For zeroing small amounts of memory, it's not worth setting up
+	 * the line-clear code.  */
+	cmp	count, #128
+	b.lt	.Lnot_short
+#ifdef MAYBE_VIRT
+	/* For efficiency when virtualized, we cache the ZVA capability.  */
+	adrp	tmp2, .Lcache_clear
+	ldr	zva_len, [tmp2, #:lo12:.Lcache_clear]
+	tbnz	zva_len, #31, .Lnot_short
+	cbnz	zva_len, .Lzero_by_line
+	mrs	tmp1, dczid_el0
+	tbz	tmp1, #4, 1f
+	/* ZVA not available.  Remember this for next time.  */
+	mov	zva_len, #~0
+	str	zva_len, [tmp2, #:lo12:.Lcache_clear]
+	b	.Lnot_short
+1:
+	mov	tmp3w, #4
+	and	zva_len, tmp1w, #15	/* Safety: other bits reserved.  */
+	lsl	zva_len, tmp3w, zva_len
+	str	zva_len, [tmp2, #:lo12:.Lcache_clear]
+#else
+	mrs	tmp1, dczid_el0
+	tbnz	tmp1, #4, .Lnot_short
+	mov	tmp3w, #4
+	and	zva_len, tmp1w, #15	/* Safety: other bits reserved.  */
+	lsl	zva_len, tmp3w, zva_len
+#endif
+
+.Lzero_by_line:
+	/* Compute how far we need to go to become suitably aligned.  We're
+	 * already at quad-word alignment.  */
+	cmp	count, zva_len_x
+	b.lt	.Lnot_short		/* Not enough to reach alignment.  */
+	sub	zva_bits_x, zva_len_x, #1
+	neg	tmp2, dst
+	ands	tmp2, tmp2, zva_bits_x
+	b.eq	1f			/* Already aligned.  */
+	/* Not aligned, check that there's enough to copy after alignment.  */
+	sub	tmp1, count, tmp2
+	cmp	tmp1, #64
+	ccmp	tmp1, zva_len_x, #8, ge	/* NZCV=0b1000 */
+	b.lt	.Lnot_short
+	/* We know that there's at least 64 bytes to zero and that it's safe
+	 * to overrun by 64 bytes.  */
+	mov	count, tmp1
+2:
+	stp	A_l, A_l, [dst]
+	stp	A_l, A_l, [dst, #16]
+	stp	A_l, A_l, [dst, #32]
+	subs	tmp2, tmp2, #64
+	stp	A_l, A_l, [dst, #48]
+	add	dst, dst, #64
+	b.ge	2b
+	/* We've overrun a bit, so adjust dst downwards.  */
+	add	dst, dst, tmp2
+1:
+	sub	count, count, zva_len_x
+3:
+	dc	zva, dst
+	add	dst, dst, zva_len_x
+	subs	count, count, zva_len_x
+	b.ge	3b
+	ands	count, count, zva_bits_x
+	b.ne	.Ltail_maybe_long
+	ret
+	.size	memset, .-memset
+#ifdef MAYBE_VIRT
+	.bss
+	.p2align 2
+	.Lcache_clear:
+	.space 4
+#endif
+#endif /* DONT_USE_DC */
+
diff --git a/payloads/libpayload/arch/arm64/sysinfo.c b/payloads/libpayload/arch/arm64/sysinfo.c
new file mode 100644
index 0000000..6d204e2
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/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 = 1;
+
+		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/arm64/timer.c b/payloads/libpayload/arch/arm64/timer.c
new file mode 100644
index 0000000..4587f31
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/timer.c
@@ -0,0 +1,54 @@
+/*
+ * 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 arm64/timer.c
+ * ARM64 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;
+}
diff --git a/payloads/libpayload/arch/arm64/util.S b/payloads/libpayload/arch/arm64/util.S
new file mode 100644
index 0000000..7c14a39
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/util.S
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#include <arch/asm.h>
+
+/* This function puts the system into a halt. */
+ENTRY(halt)
+	b halt
+ENDPROC(halt)
diff --git a/payloads/libpayload/arch/arm64/virtual.c b/payloads/libpayload/arch/arm64/virtual.c
new file mode 100644
index 0000000..59768db
--- /dev/null
+++ b/payloads/libpayload/arch/arm64/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/bin/lpgcc b/payloads/libpayload/bin/lpgcc
index d54669a..90a8b99 100755
--- a/payloads/libpayload/bin/lpgcc
+++ b/payloads/libpayload/bin/lpgcc
@@ -74,7 +74,12 @@ if [ "$CONFIG_LP_ARCH_ARM" = "y" ]; then
   _ARCHEXTRA=""
   _ARCH=arm
 fi
-
+if [ "$CONFIG_LP_ARCH_ARM64" = "y" ]; then
+  _ARCHINCDIR=$_INCDIR/arm64
+  _ARCHLIBDIR=$_LIBDIR/arm64
+  _ARCHEXTRA=""
+  _ARCH=arm64
+fi
 if [ "$CONFIG_LP_ARCH_X86" = "y" ]; then
   _ARCHINCDIR=$_INCDIR/x86
   _ARCHLIBDIR=$_LIBDIR/x86
diff --git a/payloads/libpayload/configs/config.arm64-generic b/payloads/libpayload/configs/config.arm64-generic
new file mode 100644
index 0000000..8ed65f1
--- /dev/null
+++ b/payloads/libpayload/configs/config.arm64-generic
@@ -0,0 +1,62 @@
+#
+# Automatically generated make config: don't edit
+# libpayload version: 0.2.0
+# Wed Dec 31 11:29:14 2014
+#
+
+#
+# Generic Options
+#
+# CONFIG_LP_EXPERIMENTAL is not set
+# CONFIG_LP_OBSOLETE is not set
+# CONFIG_LP_DEVELOPER is not set
+CONFIG_LP_CHROMEOS=y
+
+#
+# Architecture Options
+#
+# CONFIG_LP_ARCH_ARM is not set
+# CONFIG_LP_ARCH_X86 is not set
+CONFIG_LP_ARCH_ARM64=y
+# CONFIG_LP_MEMMAP_RAM_ONLY is not set
+
+#
+# Standard Libraries
+#
+CONFIG_LP_LIBC=y
+# CONFIG_LP_CURSES is not set
+CONFIG_LP_CBFS=y
+CONFIG_LP_LZMA=y
+
+#
+# Console Options
+#
+CONFIG_LP_SKIP_CONSOLE_INIT=y
+CONFIG_LP_CBMEM_CONSOLE=y
+# CONFIG_LP_SERIAL_CONSOLE is not set
+CONFIG_LP_VIDEO_CONSOLE=y
+CONFIG_LP_COREBOOT_VIDEO_CONSOLE=y
+# CONFIG_LP_PC_KEYBOARD is not set
+
+#
+# Drivers
+#
+# CONFIG_LP_RTC_PORT_EXTENDED_VIA is not set
+# CONFIG_LP_STORAGE is not set
+CONFIG_LP_TIMER_NONE=y
+# CONFIG_LP_TIMER_MCT is not set
+# CONFIG_LP_TIMER_TEGRA_1US is not set
+# CONFIG_LP_TIMER_IPQ806X is not set
+CONFIG_LP_USB=y
+# CONFIG_LP_USB_OHCI is not set
+CONFIG_LP_USB_EHCI=y
+CONFIG_LP_USB_XHCI=y
+CONFIG_LP_USB_HID=y
+CONFIG_LP_USB_HUB=y
+CONFIG_LP_USB_MSC=y
+CONFIG_LP_USB_GEN_HUB=y
+# CONFIG_LP_USB_PCI is not set
+# CONFIG_LP_BIG_ENDIAN is not set
+CONFIG_LP_LITTLE_ENDIAN=y
+# CONFIG_LP_IO_ADDRESS_SPACE is not set
+CONFIG_LP_ARCH_SPECIFIC_OPTIONS=y
diff --git a/payloads/libpayload/configs/defconfig b/payloads/libpayload/configs/defconfig
index 208bf38..0a52272 100644
--- a/payloads/libpayload/configs/defconfig
+++ b/payloads/libpayload/configs/defconfig
@@ -16,6 +16,7 @@
 # Architecture Options
 #
 # CONFIG_LP_ARCH_ARM is not set
+# CONFIG_LP_ARCH_ARM64 is not set
 CONFIG_LP_ARCH_X86=y
 # CONFIG_LP_MEMMAP_RAM_ONLY is not set
 # CONFIG_LP_MULTIBOOT is not set
diff --git a/payloads/libpayload/configs/defconfig-arm b/payloads/libpayload/configs/defconfig-arm
index 1d4fcb0..235220c 100644
--- a/payloads/libpayload/configs/defconfig-arm
+++ b/payloads/libpayload/configs/defconfig-arm
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # libpayload version: 0.2.0
-# Wed Dec 31 11:37:12 2014
+# Wed Dec 31 11:39:10 2014
 #
 
 #
@@ -17,6 +17,7 @@
 #
 CONFIG_LP_ARCH_ARM=y
 # CONFIG_LP_ARCH_X86 is not set
+# CONFIG_LP_ARCH_ARM64 is not set
 # CONFIG_LP_MEMMAP_RAM_ONLY is not set
 
 #
diff --git a/payloads/libpayload/configs/defconfig.orig b/payloads/libpayload/configs/defconfig.orig
new file mode 100644
index 0000000..0734e15
--- /dev/null
+++ b/payloads/libpayload/configs/defconfig.orig
@@ -0,0 +1,84 @@
+#
+# Automatically generated make config: don't edit
+# libpayload version: 0.2.0
+# Wed Nov 12 14:25:19 2014
+#
+
+#
+# Generic Options
+#
+# CONFIG_LP_EXPERIMENTAL is not set
+# CONFIG_LP_OBSOLETE is not set
+# CONFIG_LP_DEVELOPER is not set
+# CONFIG_LP_CHROMEOS is not set
+
+#
+# Architecture Options
+#
+# CONFIG_LP_ARCH_ARM is not set
+<<<<<<< HEAD
+=======
+# CONFIG_LP_ARCH_POWERPC is not set
+# CONFIG_LP_ARCH_ARM64 is not set
+>>>>>>> a70d13f... libpayload: Add support for arm64 in libpayload
+CONFIG_LP_ARCH_X86=y
+# CONFIG_LP_MEMMAP_RAM_ONLY is not set
+# CONFIG_LP_MULTIBOOT is not set
+
+#
+# Standard Libraries
+#
+CONFIG_LP_LIBC=y
+CONFIG_LP_CURSES=y
+# CONFIG_LP_TINYCURSES is not set
+CONFIG_LP_PDCURSES=y
+CONFIG_LP_CBFS=y
+CONFIG_LP_LZMA=y
+
+#
+# Console Options
+#
+# CONFIG_LP_SKIP_CONSOLE_INIT is not set
+CONFIG_LP_CBMEM_CONSOLE=y
+CONFIG_LP_SERIAL_CONSOLE=y
+CONFIG_LP_8250_SERIAL_CONSOLE=y
+# CONFIG_LP_S5P_SERIAL_CONSOLE is not set
+# CONFIG_LP_TEGRA_SERIAL_CONSOLE is not set
+CONFIG_LP_SERIAL_IOBASE=0x3f8
+# CONFIG_LP_SERIAL_SET_SPEED is not set
+# CONFIG_LP_SERIAL_ACS_FALLBACK is not set
+CONFIG_LP_VIDEO_CONSOLE=y
+CONFIG_LP_VGA_VIDEO_CONSOLE=y
+# CONFIG_LP_GEODELX_VIDEO_CONSOLE is not set
+CONFIG_LP_COREBOOT_VIDEO_CONSOLE=y
+CONFIG_LP_PC_KEYBOARD=y
+CONFIG_LP_PC_KEYBOARD_LAYOUT_US=y
+# CONFIG_LP_PC_KEYBOARD_LAYOUT_DE is not set
+
+#
+# Drivers
+#
+CONFIG_LP_PCI=y
+CONFIG_LP_NVRAM=y
+# CONFIG_LP_RTC_PORT_EXTENDED_VIA is not set
+CONFIG_LP_SPEAKER=y
+CONFIG_LP_STORAGE=y
+# CONFIG_LP_STORAGE_64BIT_LBA is not set
+CONFIG_LP_STORAGE_ATA=y
+CONFIG_LP_STORAGE_ATAPI=y
+CONFIG_LP_STORAGE_AHCI=y
+CONFIG_LP_STORAGE_AHCI_ONLY_TESTED=y
+CONFIG_LP_USB=y
+CONFIG_LP_USB_UHCI=y
+CONFIG_LP_USB_OHCI=y
+CONFIG_LP_USB_EHCI=y
+CONFIG_LP_USB_XHCI=y
+CONFIG_LP_USB_HID=y
+CONFIG_LP_USB_HUB=y
+CONFIG_LP_USB_MSC=y
+CONFIG_LP_USB_GEN_HUB=y
+CONFIG_LP_USB_PCI=y
+# CONFIG_LP_BIG_ENDIAN is not set
+CONFIG_LP_LITTLE_ENDIAN=y
+CONFIG_LP_IO_ADDRESS_SPACE=y
+CONFIG_LP_ARCH_SPECIFIC_OPTIONS=y
diff --git a/payloads/libpayload/include/arm64/arch/asm.h b/payloads/libpayload/include/arm64/arch/asm.h
new file mode 100644
index 0000000..de44482
--- /dev/null
+++ b/payloads/libpayload/include/arm64/arch/asm.h
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 Google Inc.
+ *
+ */
+
+#ifndef __ARM64_ASM_H
+#define __ARM64_ASM_H
+
+#  define ARM64(x...)	x
+#  define W(instr)	instr
+
+#define ALIGN .align 2
+
+#define ENDPROC(name) \
+	.type name, %function; \
+	END(name)
+
+#define ENTRY(name) \
+	.section .text.name, "ax", %progbits; \
+	.global name; \
+	ALIGN; \
+	name:
+
+#define END(name) \
+	.size name, .-name
+
+#endif	/* __ARM64_ASM_H */
diff --git a/payloads/libpayload/include/arm64/arch/cache.h b/payloads/libpayload/include/arm64/arch/cache.h
new file mode 100644
index 0000000..d1fc1aa
--- /dev/null
+++ b/payloads/libpayload/include/arm64/arch/cache.h
@@ -0,0 +1,259 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2013 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.
+ *
+ * cache.h: Cache maintenance API for ARM64
+ */
+
+#ifndef ARM64_CACHE_H
+#define ARM64_CACHE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* SCTLR bits */
+#define SCTLR_M		(1 << 0)	/* MMU enable			*/
+#define SCTLR_A		(1 << 1)	/* Alignment check enable	*/
+#define SCTLR_C		(1 << 2)	/* Data/unified cache enable	*/
+/* Bits 4:3 are reserved */
+#define SCTLR_CP15BEN	(1 << 5)	/* CP15 barrier enable		*/
+/* Bit 6 is reserved */
+#define SCTLR_B		(1 << 7)	/* Endianness			*/
+/* Bits 9:8 */
+#define SCTLR_SW	(1 << 10)	/* SWP and SWPB enable		*/
+#define SCTLR_Z		(1 << 11)	/* Branch prediction enable	*/
+#define SCTLR_I		(1 << 12)	/* Instruction cache enable	*/
+#define SCTLR_V		(1 << 13)	/* Low/high exception vectors 	*/
+#define SCTLR_RR  	(1 << 14)	/* Round Robin select		*/
+/* Bits 16:15 are reserved */
+#define SCTLR_HA	(1 << 17)	/* Hardware Access flag enable	*/
+/* Bit 18 is reserved */
+/* Bits 20:19 reserved virtualization not supported */
+#define SCTLR_WXN	(1 << 19)	/* Write permission implies XN	*/
+#define SCTLR_UWXN	(1 << 20)	/* Unprivileged write permission
+					   implies PL1 XN		*/
+#define SCTLR_FI	(1 << 21)	/* Fast interrupt config enable	*/
+#define SCTLR_U		(1 << 22)	/* Unaligned access behavior	*/
+#define SCTLR_VE	(1 << 24)	/* Interrupt vectors enable	*/
+#define SCTLR_EE	(1 << 25)	/* Exception endianness		*/
+/* Bit 26 is reserved */
+#define SCTLR_NMFI	(1 << 27)	/* Non-maskable FIQ support	*/
+#define SCTLR_TRE	(1 << 28)	/* TEX remap enable		*/
+#define SCTLR_AFE	(1 << 29)	/* Access flag enable		*/
+#define SCTLR_TE	(1 << 30)	/* Thumb exception enable	*/
+/* Bit 31 is reserved */
+
+/*
+ * Sync primitives
+ */
+
+/* data memory barrier */
+static inline void dmb(void)
+{
+	asm volatile ("dmb sy" : : : "memory");
+}
+
+/* data sync barrier */
+static inline void dsb(void)
+{
+	asm volatile ("dsb sy" : : : "memory");
+}
+
+/* instruction sync barrier */
+static inline void isb(void)
+{
+	asm volatile ("isb" : : : "memory");
+}
+
+/*
+ * Low-level TLB maintenance operations
+ */
+
+/* invalidate entire unified TLB */
+static inline void tlbiall_el3(void)
+{
+	asm volatile ("tlbi alle3" : : : "memory");
+}
+
+/* invalidate unified TLB by VA, all ASID */
+static inline void tlbivaa(unsigned long va)
+{
+	asm volatile ("tlbi vaae1, %0" : : "r" (va) : "memory");
+}
+
+/*
+ * Low-level cache maintenance operations
+ */
+
+/* data cache clean and invalidate by VA to PoC */
+static inline void dccivac(unsigned long va)
+{
+	asm volatile ("dc civac, %0" : : "r" (va) : "memory");
+}
+
+/* data cache invalidate by set/way */
+static inline void dccisw(uint32_t val)
+{
+	asm volatile ("dc cisw, %0" : : "r" (val) : "memory");
+}
+
+/* data cache clean by VA to PoC */
+static inline void dccvac(unsigned long va)
+{
+	asm volatile ("dc cvac, %0" : : "r" (va) : "memory");
+}
+
+/* data cache clean by set/way */
+static inline void dccsw(uint32_t val)
+{
+	asm volatile ("dc csw, %0" : : "r" (val) : "memory");
+}
+
+/* data cache invalidate by VA to PoC */
+static inline void dcivac(unsigned long va)
+{
+	asm volatile ("dc ivac, %0" : : "r" (va) : "memory");
+}
+
+/* data cache invalidate by set/way */
+static inline void dcisw(uint32_t val)
+{
+	asm volatile ("dc isw, %0" : : "r" (val) : "memory");
+}
+
+/* instruction cache invalidate all by PoU */
+static inline void iciallu(void)
+{
+	asm volatile ("ic iallu" : : "r" (0));
+}
+
+/* read cache level ID register (CLIDR) */
+static inline uint32_t read_clidr(void)
+{
+	uint32_t val = 0;
+	asm volatile ("mrs %0, clidr_el1" : "=r" (val));
+	return val;
+}
+
+/* read cache size ID register register (CCSIDR) */
+static inline uint32_t read_ccsidr(void)
+{
+	uint32_t val = 0;
+	asm volatile ("mrs %0, ccsidr_el1" : "=r" (val));
+	return val;
+}
+
+/* read cache size selection register (CSSELR) */
+static inline uint32_t read_csselr(void)
+{
+	uint32_t val = 0;
+	asm volatile ("mrs %0, csselr_el1" : "=r" (val));
+	return val;
+}
+
+/* write to cache size selection register (CSSELR) */
+static inline void write_csselr(uint32_t val)
+{
+	/*
+	 * Bits [3:1] - Cache level + 1 (0b000 = L1, 0b110 = L7, 0b111 is rsvd)
+	 * Bit 0 - 0 = data or unified cache, 1 = instruction cache
+	 */
+	asm volatile ("msr csselr_el1, %0" : : "r" (val));
+	isb();	/* ISB to sync the change to CCSIDR */
+}
+
+/* read system control register (SCTLR) */
+static inline uint32_t read_sctlr_el3(void)
+{
+	uint32_t val;
+	asm volatile ("mrs %0, sctlr_el3" : "=r" (val));
+	return val;
+}
+
+/* write system control register (SCTLR) */
+static inline void write_sctlr_el3(uint32_t val)
+{
+	asm volatile ("msr sctlr_el3, %0" : : "r" (val) : "cc");
+	isb();
+}
+
+/*
+ * Cache maintenance API
+ */
+
+/* dcache clean and invalidate all (on current level given by CCSELR) */
+void dcache_clean_invalidate_all(void);
+
+/* dcache clean by virtual address to PoC */
+void dcache_clean_by_va(void const *addr, size_t len);
+
+/* dcache clean and invalidate by virtual address to PoC */
+void dcache_clean_invalidate_by_va(void const *addr, size_t len);
+
+/* dcache invalidate by virtual address to PoC */
+void dcache_invalidate_by_va(void const *addr, size_t len);
+
+void dcache_clean_all(void);
+
+/* dcache invalidate all (on current level given by CCSELR) */
+void dcache_invalidate_all(void);
+
+/* returns number of bytes per cache line */
+unsigned int dcache_line_bytes(void);
+
+/* dcache and MMU disable */
+void dcache_mmu_disable(void);
+
+/* dcache and MMU enable */
+void dcache_mmu_enable(void);
+
+/* perform all icache/dcache maintenance needed after loading new code */
+void cache_sync_instructions(void);
+
+/* tlb invalidate all */
+void tlb_invalidate_all(void);
+
+/*
+ * Generalized setup/init functions
+ */
+
+/* mmu initialization (set page table address, set permissions, etc) */
+void mmu_init(void);
+
+enum dcache_policy {
+	DCACHE_OFF,
+	DCACHE_WRITEBACK,
+	DCACHE_WRITETHROUGH,
+};
+
+/* disable the mmu for a range. Primarily useful to lock out address 0. */
+void mmu_disable_range(unsigned long start_mb, unsigned long size_mb);
+/* mmu range configuration (set dcache policy) */
+void mmu_config_range(unsigned long start_mb, unsigned long size_mb,
+						enum dcache_policy policy);
+
+#endif /* ARM64_CACHE_H */
diff --git a/payloads/libpayload/include/arm64/arch/exception.h b/payloads/libpayload/include/arm64/arch/exception.h
new file mode 100644
index 0000000..f4a7552
--- /dev/null
+++ b/payloads/libpayload/include/arm64/arch/exception.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright 2014 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.
+ */
+
+#ifndef _ARCH_EXCEPTION_H
+#define _ARCH_EXCEPTION_H
+
+#include <stdint.h>
+
+void set_vbar(void* vbar);
+
+struct exception_state
+{
+	uint64_t elr;
+	uint64_t esr;
+	uint64_t regs[31];
+} __attribute__((packed));
+
+enum {
+	EXC_INV = 0,
+	EXC_SYNC = 1,
+	EXC_IRQ = 2,
+	EXC_FIQ = 3,
+	EXC_SERROR = 4,
+	EXC_COUNT
+};
+
+#endif
diff --git a/payloads/libpayload/include/arm64/arch/io.h b/payloads/libpayload/include/arm64/arch/io.h
new file mode 100644
index 0000000..8948e13
--- /dev/null
+++ b/payloads/libpayload/include/arm64/arch/io.h
@@ -0,0 +1,76 @@
+/*
+ * 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
+
+#include <stdint.h>
+#include <arch/cache.h>
+
+static inline uint8_t readb(volatile void *_a)
+{
+	dmb();
+	return *(volatile uint8_t *)_a;
+}
+
+static inline uint16_t readw(volatile void *_a)
+{
+	dmb();
+	return *(volatile uint16_t *)_a;
+}
+
+static inline uint32_t readl(volatile void *_a)
+{
+	dmb();
+	return *(volatile uint32_t *)_a;
+}
+
+static inline void writeb(uint8_t _v, volatile void *_a)
+{
+	dmb();
+	*(volatile uint8_t *)_a = _v;
+	dmb();
+}
+
+static inline void writew(uint16_t _v, volatile void *_a)
+{
+	dmb();
+	*(volatile uint16_t *)_a = _v;
+	dmb();
+}
+
+static inline void writel(uint32_t _v, volatile void *_a)
+{
+	dmb();
+	*(volatile uint32_t *)_a = _v;
+	dmb();
+}
+
+#endif
diff --git a/payloads/libpayload/include/arm64/arch/types.h b/payloads/libpayload/include/arm64/arch/types.h
new file mode 100644
index 0000000..1bd815b
--- /dev/null
+++ b/payloads/libpayload/include/arm64/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/arm64/arch/virtual.h b/payloads/libpayload/include/arm64/arch/virtual.h
new file mode 100644
index 0000000..328c3aa
--- /dev/null
+++ b/payloads/libpayload/include/arm64/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_core.h b/payloads/libpayload/include/cbfs_core.h
index 6edad0e..42f2dc8 100644
--- a/payloads/libpayload/include/cbfs_core.h
+++ b/payloads/libpayload/include/cbfs_core.h
@@ -107,6 +107,7 @@ struct cbfs_header {
 #define CBFS_ARCHITECTURE_UNKNOWN  0xFFFFFFFF
 #define CBFS_ARCHITECTURE_X86      0x00000001
 #define CBFS_ARCHITECTURE_ARM      0x00000010
+#define CBFS_ARCHITECTURE_ARM64    0x00000011
 
 /** This is a component header - every entry in the CBFS
     will have this header.
diff --git a/payloads/libpayload/util/xcompile/xcompile b/payloads/libpayload/util/xcompile/xcompile
index 03d6f1f..9cc2d69 100644
--- a/payloads/libpayload/util/xcompile/xcompile
+++ b/payloads/libpayload/util/xcompile/xcompile
@@ -111,6 +111,11 @@ detect_special_flags() {
 			#	CFLAGS="$CFLAGS -mcpu=cortex-a9"
 			;;
 	esac
+
+	case "$architecture" in
+		arm64-generic )
+			;;
+	esac
 }
 
 report_arch_toolchain() {
@@ -135,7 +140,7 @@ touch "$TMPFILE"
 trap clean_up EXIT
 
 # Architecture definition
-SUPPORTED_ARCHITECTURE="x86 arm"
+SUPPORTED_ARCHITECTURE="x86 arm arm64"
 
 # ARM Architecture
 TARCH_arm="arm"
@@ -143,6 +148,12 @@ TBFDARCH_arm="littlearm"
 TCLIST_arm="armv7a armv7-a"
 TWIDTH_arm="32"
 
+# ARM64 Architecture
+TARCH_arm64="arm64"
+TBFDARCH_arm64="littleaarch64"
+TCLIST_arm64="aarch64"
+TWIDTH_arm64="64"
+
 # X86 Architecture
 TARCH_x86="i386"
 TBFDARCH_x86="i386"



More information about the coreboot-gerrit mailing list