aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/arch/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload/arch/armv7')
-rw-r--r--payloads/libpayload/arch/armv7/Config.in29
-rw-r--r--payloads/libpayload/arch/armv7/Makefile.inc35
-rw-r--r--payloads/libpayload/arch/armv7/assembler.h60
-rw-r--r--payloads/libpayload/arch/armv7/coreboot.c287
-rw-r--r--payloads/libpayload/arch/armv7/head.S52
-rw-r--r--payloads/libpayload/arch/armv7/main.c70
-rw-r--r--payloads/libpayload/arch/armv7/memcpy.S243
-rw-r--r--payloads/libpayload/arch/armv7/memset.S126
-rw-r--r--payloads/libpayload/arch/armv7/sysinfo.c64
-rw-r--r--payloads/libpayload/arch/armv7/timer.c101
-rw-r--r--payloads/libpayload/arch/armv7/util.S36
-rw-r--r--payloads/libpayload/arch/armv7/virtual.c38
12 files changed, 1141 insertions, 0 deletions
diff --git a/payloads/libpayload/arch/armv7/Config.in b/payloads/libpayload/arch/armv7/Config.in
new file mode 100644
index 0000000000..efc67612dc
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/Config.in
@@ -0,0 +1,29 @@
+##
+## Copyright (c) 2012 The Chromium OS Authors.
+##
+## See file CREDITS for list of people who contributed to this
+## project.
+##
+## This program is free software; you can redistribute it and/or
+## modify it under the terms of the GNU General Public License as
+## published by the Free Software Foundation; either version 2 of
+## the License, or (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but without any warranty; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+## MA 02111-1307 USA
+##
+
+if ARCH_ARMV7
+
+config ARCH_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select LITTLE_ENDIAN
+
+endif
diff --git a/payloads/libpayload/arch/armv7/Makefile.inc b/payloads/libpayload/arch/armv7/Makefile.inc
new file mode 100644
index 0000000000..6d9e6c5c55
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/Makefile.inc
@@ -0,0 +1,35 @@
+##
+## This file is part of the libpayload project.
+##
+## Copyright (C) 2008 Advanced Micro Devices, Inc.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+## 3. The name of the author may not be used to endorse or promote products
+## derived from this software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+##
+
+head.o-y += head.S
+libc-y += main.c sysinfo.c
+libc-y += timer.c coreboot.c util.S
+libc-y += virtual.c
+libc-y += memcpy.S memset.S
+
diff --git a/payloads/libpayload/arch/armv7/assembler.h b/payloads/libpayload/arch/armv7/assembler.h
new file mode 100644
index 0000000000..5e4789b145
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/assembler.h
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/include/asm/assembler.h
+ *
+ * Copyright (C) 1996-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains arm architecture specific defines
+ * for the different processors.
+ *
+ * Do not include any C declarations in this file - it is included by
+ * assembler source.
+ */
+
+/*
+ * Endian independent macros for shifting bytes within registers.
+ */
+#ifndef __ARMEB__
+#define pull lsr
+#define push lsl
+#define get_byte_0 lsl #0
+#define get_byte_1 lsr #8
+#define get_byte_2 lsr #16
+#define get_byte_3 lsr #24
+#define put_byte_0 lsl #0
+#define put_byte_1 lsl #8
+#define put_byte_2 lsl #16
+#define put_byte_3 lsl #24
+#else
+#define pull lsl
+#define push lsr
+#define get_byte_0 lsr #24
+#define get_byte_1 lsr #16
+#define get_byte_2 lsr #8
+#define get_byte_3 lsl #0
+#define put_byte_0 lsl #24
+#define put_byte_1 lsl #16
+#define put_byte_2 lsl #8
+#define put_byte_3 lsl #0
+#endif
+
+/*
+ * Data preload for architectures that support it
+ */
+#if defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
+ defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+ defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || \
+ defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_7A__) || \
+ defined(__ARM_ARCH_7R__)
+#define PLD(code...) code
+#else
+#define PLD(code...)
+#endif
+
+/*
+ * Cache alligned
+ */
+#define CALGN(code...) code
diff --git a/payloads/libpayload/arch/armv7/coreboot.c b/payloads/libpayload/arch/armv7/coreboot.c
new file mode 100644
index 0000000000..01ec53cb01
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/coreboot.c
@@ -0,0 +1,287 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload-config.h>
+#include <libpayload.h>
+#include <coreboot_tables.h>
+
+/*
+ * Some of this is x86 specific, and the rest of it is generic. Right now,
+ * since we only support x86, we'll avoid trying to make lots of infrastructure
+ * we don't need. If in the future, we want to use coreboot on some other
+ * architecture, then take out the generic parsing code and move it elsewhere.
+ */
+
+/* === Parsing code === */
+/* This is the generic parsing code. */
+
+static void cb_parse_memory(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_memory *mem = ptr;
+ int count = MEM_RANGE_COUNT(mem);
+ int i;
+
+ if (count > SYSINFO_MAX_MEM_RANGES)
+ count = SYSINFO_MAX_MEM_RANGES;
+
+ info->n_memranges = 0;
+
+ for (i = 0; i < count; i++) {
+ struct cb_memory_range *range = MEM_RANGE_PTR(mem, i);
+
+#ifdef CONFIG_MEMMAP_RAM_ONLY
+ if (range->type != CB_MEM_RAM)
+ continue;
+#endif
+
+ info->memrange[info->n_memranges].base =
+ cb_unpack64(range->start);
+
+ info->memrange[info->n_memranges].size =
+ cb_unpack64(range->size);
+
+ info->memrange[info->n_memranges].type = range->type;
+
+ info->n_memranges++;
+ }
+}
+
+static void cb_parse_serial(void *ptr, struct sysinfo_t *info)
+{
+ info->serial = ((struct cb_serial *)ptr);
+}
+
+#ifdef CONFIG_CHROMEOS
+static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_vbnv *vbnv = (struct cb_vbnv *)ptr;
+
+ info->vbnv_start = vbnv->vbnv_start;
+ info->vbnv_size = vbnv->vbnv_size;
+}
+
+static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info)
+{
+ int i;
+ struct cb_gpios *gpios = (struct cb_gpios *)ptr;
+
+ info->num_gpios = (gpios->count < SYSINFO_MAX_GPIOS) ?
+ (gpios->count) : SYSINFO_MAX_GPIOS;
+
+ for (i = 0; i < info->num_gpios; i++)
+ info->gpios[i] = gpios->gpios[i];
+}
+
+static void cb_parse_vdat(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_vdat *vdat = (struct cb_vdat *) ptr;
+
+ info->vdat_addr = phys_to_virt(vdat->vdat_addr);
+ info->vdat_size = vdat->vdat_size;
+}
+#endif
+
+static void cb_parse_tstamp(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+ info->tstamp_table = phys_to_virt(cbmem->cbmem_tab);
+}
+
+static void cb_parse_cbmem_cons(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+ info->cbmem_cons = phys_to_virt(cbmem->cbmem_tab);
+}
+
+static void cb_parse_mrc_cache(unsigned char *ptr, struct sysinfo_t *info)
+{
+ struct cb_cbmem_tab *const cbmem = (struct cb_cbmem_tab *)ptr;
+ info->mrc_cache = phys_to_virt(cbmem->cbmem_tab);
+}
+
+#ifdef CONFIG_NVRAM
+static void cb_parse_optiontable(void *ptr, struct sysinfo_t *info)
+{
+ info->option_table = ptr;
+}
+
+static void cb_parse_checksum(void *ptr, struct sysinfo_t *info)
+{
+ struct cb_cmos_checksum *cmos_cksum = ptr;
+ info->cmos_range_start = cmos_cksum->range_start;
+ info->cmos_range_end = cmos_cksum->range_end;
+ info->cmos_checksum_location = cmos_cksum->location;
+}
+#endif
+
+#ifdef CONFIG_COREBOOT_VIDEO_CONSOLE
+static void cb_parse_framebuffer(void *ptr, struct sysinfo_t *info)
+{
+ info->framebuffer = ptr;
+}
+#endif
+
+static void cb_parse_string(unsigned char *ptr, char **info)
+{
+ *info = (char *)((struct cb_string *)ptr)->string;
+}
+
+static int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
+{
+ struct cb_header *header;
+ unsigned char *ptr = addr;
+ void *forward;
+ int i;
+
+ for (i = 0; i < len; i += 16, ptr += 16) {
+ header = (struct cb_header *)ptr;
+ if (!strncmp((const char *)header->signature, "LBIO", 4))
+ break;
+ }
+
+ /* We walked the entire space and didn't find anything. */
+ if (i >= len)
+ return -1;
+
+ if (!header->table_bytes)
+ return 0;
+
+ /* Make sure the checksums match. */
+ if (ipchksum((u16 *) header, sizeof(*header)) != 0)
+ return -1;
+
+ if (ipchksum((u16 *) (ptr + sizeof(*header)),
+ header->table_bytes) != header->table_checksum)
+ return -1;
+
+ info->header = header;
+
+ /* Now, walk the tables. */
+ ptr += header->header_bytes;
+
+ for (i = 0; i < header->table_entries; i++) {
+ struct cb_record *rec = (struct cb_record *)ptr;
+
+ /* We only care about a few tags here (maybe more later). */
+ switch (rec->tag) {
+ case CB_TAG_FORWARD:
+ forward = phys_to_virt((void *)(unsigned long)((struct cb_forward *)rec)->forward);
+ return cb_parse_header(forward, len, info);
+ continue;
+ case CB_TAG_MEMORY:
+ cb_parse_memory(ptr, info);
+ break;
+ case CB_TAG_SERIAL:
+ cb_parse_serial(ptr, info);
+ break;
+ case CB_TAG_VERSION:
+ cb_parse_string(ptr, &info->cb_version);
+ break;
+ case CB_TAG_EXTRA_VERSION:
+ cb_parse_string(ptr, &info->extra_version);
+ break;
+ case CB_TAG_BUILD:
+ cb_parse_string(ptr, &info->build);
+ break;
+ case CB_TAG_COMPILE_TIME:
+ cb_parse_string(ptr, &info->compile_time);
+ break;
+ case CB_TAG_COMPILE_BY:
+ cb_parse_string(ptr, &info->compile_by);
+ break;
+ case CB_TAG_COMPILE_HOST:
+ cb_parse_string(ptr, &info->compile_host);
+ break;
+ case CB_TAG_COMPILE_DOMAIN:
+ cb_parse_string(ptr, &info->compile_domain);
+ break;
+ case CB_TAG_COMPILER:
+ cb_parse_string(ptr, &info->compiler);
+ break;
+ case CB_TAG_LINKER:
+ cb_parse_string(ptr, &info->linker);
+ break;
+ case CB_TAG_ASSEMBLER:
+ cb_parse_string(ptr, &info->assembler);
+ break;
+#ifdef CONFIG_NVRAM
+ case CB_TAG_CMOS_OPTION_TABLE:
+ cb_parse_optiontable(ptr, info);
+ break;
+ case CB_TAG_OPTION_CHECKSUM:
+ cb_parse_checksum(ptr, info);
+ break;
+#endif
+#ifdef CONFIG_COREBOOT_VIDEO_CONSOLE
+ // FIXME we should warn on serial if coreboot set up a
+ // framebuffer buf the payload does not know about it.
+ case CB_TAG_FRAMEBUFFER:
+ cb_parse_framebuffer(ptr, info);
+ break;
+#endif
+ case CB_TAG_MAINBOARD:
+ info->mainboard = (struct cb_mainboard *)ptr;
+#ifdef CONFIG_CHROMEOS
+ case CB_TAG_GPIO:
+ cb_parse_gpios(ptr, info);
+ break;
+ case CB_TAG_VDAT:
+ cb_parse_vdat(ptr, info);
+ break;
+ case CB_TAG_VBNV:
+ cb_parse_vbnv(ptr, info);
+ break;
+#endif
+ case CB_TAG_TIMESTAMPS:
+ cb_parse_tstamp(ptr, info);
+ break;
+ case CB_TAG_CBMEM_CONSOLE:
+ cb_parse_cbmem_cons(ptr, info);
+ break;
+ case CB_TAG_MRC_CACHE:
+ cb_parse_mrc_cache(ptr, info);
+ break;
+ }
+
+ ptr += rec->size;
+ }
+
+ return 1;
+}
+
+/* == Architecture specific == */
+/* FIXME put in actual address range */
+
+int get_coreboot_info(struct sysinfo_t *info)
+{
+ int ret = cb_parse_header(phys_to_virt(0x00000000), 0x1000, info);
+
+ return (ret == 1) ? 0 : -1;
+}
diff --git a/payloads/libpayload/arch/armv7/head.S b/payloads/libpayload/arch/armv7/head.S
new file mode 100644
index 0000000000..e1b5737ead
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/head.S
@@ -0,0 +1,52 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ .global _entry, _leave
+ .text
+ .align 4
+
+/*
+ * Our entry point
+ */
+_entry:
+
+ /* TODO: disable interrupts */
+ /* TODO: Clear BSS */
+ /* TODO: Setup new stack */
+ /* TODO: Save old stack pointer */
+
+ /* Let's rock. */
+ b start_main
+
+ /* %eax has the return value - pass it on unmolested */
+_leave:
+ /* TODO: restore old stack pointer. */
+
+ /* Return to the original context. */
+ mov pc, lr
diff --git a/payloads/libpayload/arch/armv7/main.c b/payloads/libpayload/arch/armv7/main.c
new file mode 100644
index 0000000000..6b54b27fc6
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/main.c
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload.h>
+
+unsigned int main_argc; /**< The argc value to pass to main() */
+
+/** The argv value to pass to main() */
+char *main_argv[MAX_ARGC_COUNT];
+
+/**
+ * This is our C entry function - set up the system
+ * and jump into the payload entry point.
+ */
+void start_main(void);
+void start_main(void)
+{
+ extern int main(int argc, char **argv);
+
+ /* Gather system information. */
+ lib_get_sysinfo();
+
+ /* Optionally set up the consoles. */
+#ifndef CONFIG_SKIP_CONSOLE_INIT
+ console_init();
+#endif
+
+ /*
+ * Any other system init that has to happen before the
+ * user gets control goes here.
+ */
+
+ /*
+ * Go to the entry point.
+ * In the future we may care about the return value.
+ */
+
+ (void) main(main_argc, (main_argc != 0) ? main_argv : NULL);
+
+ /*
+ * Returning here will go to the _leave function to return
+ * us to the original context.
+ */
+}
diff --git a/payloads/libpayload/arch/armv7/memcpy.S b/payloads/libpayload/arch/armv7/memcpy.S
new file mode 100644
index 0000000000..549320c8d1
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/memcpy.S
@@ -0,0 +1,243 @@
+/*
+ * linux/arch/arm/lib/memcpy.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "assembler.h"
+
+#define W(instr) instr
+
+#define LDR1W_SHIFT 0
+#define STR1W_SHIFT 0
+
+ .macro ldr1w ptr reg abort
+ W(ldr) \reg, [\ptr], #4
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+ ldr\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro str1w ptr reg abort
+ W(str) \reg, [\ptr], #4
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+ str\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro enter reg1 reg2
+ stmdb sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
+.globl memcpy
+memcpy:
+
+ cmp r0, r1
+ moveq pc, lr
+
+ enter r4, lr
+
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #0] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb r3, ip, #32 )
+ CALGN( sbcnes r4, r3, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, r3 ) @ C gets set
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #0] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 4f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+3: PLD( pld [r1, #124] )
+4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ subs r2, r2, #32
+ str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ bge 3b
+ PLD( cmn r2, #96 )
+ PLD( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+#if LDR1W_SHIFT > 0
+ lsl ip, ip, #LDR1W_SHIFT
+#endif
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6:
+ .rept (1 << LDR1W_SHIFT)
+ W(nop)
+ .endr
+ ldr1w r1, r3, abort=20f
+ ldr1w r1, r4, abort=20f
+ ldr1w r1, r5, abort=20f
+ ldr1w r1, r6, abort=20f
+ ldr1w r1, r7, abort=20f
+ ldr1w r1, r8, abort=20f
+ ldr1w r1, lr, abort=20f
+
+#if LDR1W_SHIFT < STR1W_SHIFT
+ lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+ lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
+ add pc, pc, ip
+ nop
+ .rept (1 << STR1W_SHIFT)
+ W(nop)
+ .endr
+ str1w r0, r3, abort=20f
+ str1w r0, r4, abort=20f
+ str1w r0, r5, abort=20f
+ str1w r0, r6, abort=20f
+ str1w r0, r7, abort=20f
+ str1w r0, r8, abort=20f
+ str1w r0, lr, abort=20f
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldr1b r1, r3, ne, abort=21f
+ ldr1b r1, r4, cs, abort=21f
+ ldr1b r1, ip, cs, abort=21f
+ str1b r0, r3, ne, abort=21f
+ str1b r0, r4, cs, abort=21f
+ str1b r0, ip, cs, abort=21f
+
+ exit r4, pc
+
+9: rsb ip, ip, #4
+ cmp ip, #2
+ ldr1b r1, r3, gt, abort=21f
+ ldr1b r1, r4, ge, abort=21f
+ ldr1b r1, lr, abort=21f
+ str1b r0, r3, gt, abort=21f
+ str1b r0, r4, ge, abort=21f
+ subs r2, r2, ip
+ str1b r0, lr, abort=21f
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr1w r1, lr, abort=21f
+ beq 17f
+ bgt 18f
+
+
+ .macro forward_copy_shift pull push
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb ip, ip, #32 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #0] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 13f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+12: PLD( pld [r1, #124] )
+13: ldr4w r1, r4, r5, r6, r7, abort=19f
+ mov r3, lr, pull #\pull
+ subs r2, r2, #32
+ ldr4w r1, r8, r9, ip, lr, abort=19f
+ orr r3, r3, r4, push #\push
+ mov r4, r4, pull #\pull
+ orr r4, r4, r5, push #\push
+ mov r5, r5, pull #\pull
+ orr r5, r5, r6, push #\push
+ mov r6, r6, pull #\pull
+ orr r6, r6, r7, push #\push
+ mov r7, r7, pull #\pull
+ orr r7, r7, r8, push #\push
+ mov r8, r8, pull #\pull
+ orr r8, r8, r9, push #\push
+ mov r9, r9, pull #\pull
+ orr r9, r9, ip, push #\push
+ mov ip, ip, pull #\pull
+ orr ip, ip, lr, push #\push
+ str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov r3, lr, pull #\pull
+ ldr1w r1, lr, abort=21f
+ subs ip, ip, #4
+ orr r3, r3, lr, push #\push
+ str1w r0, r3, abort=21f
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: sub r1, r1, #(\push / 8)
+ b 8b
+
+ .endm
+
+
+ forward_copy_shift pull=8 push=24
+
+17: forward_copy_shift pull=16 push=16
+
+18: forward_copy_shift pull=24 push=8
diff --git a/payloads/libpayload/arch/armv7/memset.S b/payloads/libpayload/arch/armv7/memset.S
new file mode 100644
index 0000000000..4ff4c3ce93
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/memset.S
@@ -0,0 +1,126 @@
+/*
+ * linux/arch/arm/lib/memset.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ASM optimised string functions
+ */
+#include "assembler.h"
+
+ .text
+ .align 5
+ .word 0
+
+1: subs r2, r2, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [r0], #1 @ 1
+ strleb r1, [r0], #1 @ 1
+ strb r1, [r0], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memset again.
+ */
+
+.globl memset
+memset:
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+ orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ mov r3, r1
+ cmp r2, #16
+ blt 4f
+
+#if ! CALGN(1)+0
+
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]!
+ mov ip, r1
+ mov lr, r1
+
+2: subs r2, r2, #64
+ stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ bgt 2b
+ ldmeqfd sp!, {pc} @ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+ stmneia r0!, {r1, r3, ip, lr}
+ stmneia r0!, {r1, r3, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r1, r3, ip, lr}
+ ldr lr, [sp], #4
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+ stmfd sp!, {r4-r7, lr}
+ mov r4, r1
+ mov r5, r1
+ mov r6, r1
+ mov r7, r1
+ mov ip, r1
+ mov lr, r1
+
+ cmp r2, #96
+ tstgt r0, #31
+ ble 3f
+
+ and ip, r0, #31
+ rsb ip, ip, #32
+ sub r2, r2, ip
+ movs ip, ip, lsl #(32 - 4)
+ stmcsia r0!, {r4, r5, r6, r7}
+ stmmiia r0!, {r4, r5}
+ tst ip, #(1 << 30)
+ mov ip, r1
+ strne r1, [r0], #4
+
+3: subs r2, r2, #64
+ stmgeia r0!, {r1, r3-r7, ip, lr}
+ stmgeia r0!, {r1, r3-r7, ip, lr}
+ bgt 3b
+ ldmeqfd sp!, {r4-r7, pc}
+
+ tst r2, #32
+ stmneia r0!, {r1, r3-r7, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r4-r7}
+ ldmfd sp!, {r4-r7, lr}
+
+#endif
+
+4: tst r2, #8
+ stmneia r0!, {r1, r3}
+ tst r2, #4
+ strne r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r2, #2
+ strneb r1, [r0], #1
+ strneb r1, [r0], #1
+ tst r2, #1
+ strneb r1, [r0], #1
+ mov pc, lr
diff --git a/payloads/libpayload/arch/armv7/sysinfo.c b/payloads/libpayload/arch/armv7/sysinfo.c
new file mode 100644
index 0000000000..5aa517594c
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/sysinfo.c
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <libpayload-config.h>
+#include <libpayload.h>
+#include <coreboot_tables.h>
+
+/**
+ * This is a global structure that is used through the library - we set it
+ * up initially with some dummy values - hopefully they will be overridden.
+ */
+struct sysinfo_t lib_sysinfo = {
+ .cpu_khz = 200,
+};
+
+int lib_get_sysinfo(void)
+{
+ int ret;
+
+ /* Get the CPU speed (for delays). */
+ lib_sysinfo.cpu_khz = get_cpu_speed();
+
+ /* Get information from the coreboot tables,
+ * if they exist */
+
+ ret = get_coreboot_info(&lib_sysinfo);
+
+ if (!lib_sysinfo.n_memranges) {
+ /* If we can't get a good memory range, use the default. */
+ lib_sysinfo.n_memranges = 2;
+
+ lib_sysinfo.memrange[0].base = 0;
+ lib_sysinfo.memrange[0].size = 1024 * 1024;
+ lib_sysinfo.memrange[0].type = CB_MEM_RAM;
+ }
+
+ return ret;
+}
diff --git a/payloads/libpayload/arch/armv7/timer.c b/payloads/libpayload/arch/armv7/timer.c
new file mode 100644
index 0000000000..24b0a0fa34
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/timer.c
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/**
+ * @file armv7/timer.c
+ * ARMv7 specific timer routines
+ */
+
+#include <libpayload.h>
+
+/**
+ * @ingroup arch
+ * Global variable containing the speed of the processor in KHz.
+ */
+u32 cpu_khz;
+
+/**
+ * Calculate the speed of the processor for use in delays.
+ *
+ * @return The CPU speed in kHz.
+ */
+unsigned int get_cpu_speed(void)
+{
+ /* FIXME */
+ cpu_khz = 1000000U;
+
+ return cpu_khz;
+}
+
+static inline void _delay(unsigned long long delta)
+{
+ /* FIXME */
+}
+
+/**
+ * Delay for a specified number of nanoseconds.
+ *
+ * @param n Number of nanoseconds to delay for.
+ */
+void ndelay(unsigned int n)
+{
+ _delay((unsigned long long)n * cpu_khz / 1000000);
+}
+
+/**
+ * Delay for a specified number of microseconds.
+ *
+ * @param n Number of microseconds to delay for.
+ */
+void udelay(unsigned int n)
+{
+ _delay((unsigned long long)n * cpu_khz / 1000);
+}
+
+/**
+ * Delay for a specified number of milliseconds.
+ *
+ * @param m Number of milliseconds to delay for.
+ */
+void mdelay(unsigned int m)
+{
+ _delay((unsigned long long)m * cpu_khz);
+}
+
+/**
+ * Delay for a specified number of seconds.
+ *
+ * @param s Number of seconds to delay for.
+ */
+void delay(unsigned int s)
+{
+ int i;
+ for (i=0; i<1000; i++)
+ _delay((unsigned long long)s * cpu_khz);
+}
diff --git a/payloads/libpayload/arch/armv7/util.S b/payloads/libpayload/arch/armv7/util.S
new file mode 100644
index 0000000000..4cf61f3084
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/util.S
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+ .global halt
+ .text
+ .align 4
+
+/* This function puts the system into a halt. */
+halt:
+ b halt
diff --git a/payloads/libpayload/arch/armv7/virtual.c b/payloads/libpayload/arch/armv7/virtual.c
new file mode 100644
index 0000000000..59768dbd66
--- /dev/null
+++ b/payloads/libpayload/arch/armv7/virtual.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2008 coresystems GmbH
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <unistd.h>
+
+unsigned long virtual_offset = 0;
+
+
+int getpagesize(void)
+{
+ return 4096;
+}