summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/Config.in12
-rw-r--r--payloads/libpayload/Makefile2
-rw-r--r--payloads/libpayload/Makefile.inc1
-rw-r--r--payloads/libpayload/arch/Config.in3
-rw-r--r--payloads/libpayload/arch/mips/Config.in29
-rw-r--r--payloads/libpayload/arch/mips/Makefile.inc39
-rw-r--r--payloads/libpayload/arch/mips/cache.c76
-rw-r--r--payloads/libpayload/arch/mips/coreboot.c55
-rw-r--r--payloads/libpayload/arch/mips/dummy_media.c41
-rw-r--r--payloads/libpayload/arch/mips/exception.c107
-rw-r--r--payloads/libpayload/arch/mips/exception_asm.S208
-rw-r--r--payloads/libpayload/arch/mips/gdb.c32
-rw-r--r--payloads/libpayload/arch/mips/head.S110
-rw-r--r--payloads/libpayload/arch/mips/libpayload.ldscript95
-rw-r--r--payloads/libpayload/arch/mips/main.c62
-rw-r--r--payloads/libpayload/arch/mips/selfboot.c36
-rw-r--r--payloads/libpayload/arch/mips/string.c72
-rw-r--r--payloads/libpayload/arch/mips/sysinfo.c53
-rw-r--r--payloads/libpayload/arch/mips/timer.c43
-rw-r--r--payloads/libpayload/arch/mips/util.S26
-rw-r--r--payloads/libpayload/arch/mips/virtual.c27
-rwxr-xr-xpayloads/libpayload/bin/lpgcc6
-rw-r--r--payloads/libpayload/configs/config.arm64-generic5
-rw-r--r--payloads/libpayload/configs/defconfig3
-rw-r--r--payloads/libpayload/configs/defconfig-arm5
-rw-r--r--payloads/libpayload/configs/defconfig-mips75
-rw-r--r--payloads/libpayload/drivers/Makefile.inc2
-rw-r--r--payloads/libpayload/drivers/timer/img_pistachio.c36
-rw-r--r--payloads/libpayload/include/mips/arch/byteorder.h43
-rw-r--r--payloads/libpayload/include/mips/arch/cache.h98
-rw-r--r--payloads/libpayload/include/mips/arch/cpu.h85
-rw-r--r--payloads/libpayload/include/mips/arch/exception.h90
-rw-r--r--payloads/libpayload/include/mips/arch/io.h67
-rw-r--r--payloads/libpayload/include/mips/arch/stdint.h95
-rw-r--r--payloads/libpayload/include/mips/arch/types.h76
-rw-r--r--payloads/libpayload/include/mips/arch/virtual.h31
-rw-r--r--payloads/libpayload/include/swab.h44
-rw-r--r--payloads/libpayload/util/xcompile/xcompile28
38 files changed, 1906 insertions, 12 deletions
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index 6c95bfa42d..7587b6ac8b 100644
--- a/payloads/libpayload/Config.in
+++ b/payloads/libpayload/Config.in
@@ -98,6 +98,11 @@ config ARCH_ARM64
help
Support the ARM64 architecture
+config ARCH_MIPS
+ bool "MIPS"
+ help
+ Support the MIPS architecture
+
endchoice
config MEMMAP_RAM_ONLY
@@ -390,6 +395,13 @@ config TIMER_IPQ806X
config TIMER_RK
bool "Timer for Rockchip"
+
+config TIMER_BG4CD
+ bool "Marvell BG4CD"
+
+config TIMER_IMG_PISTACHIO
+ bool "Timer for IMG Pistachio"
+
endchoice
config TIMER_MCT_HZ
diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile
index 7d8cad72d6..1097ce5014 100644
--- a/payloads/libpayload/Makefile
+++ b/payloads/libpayload/Makefile
@@ -93,6 +93,7 @@ include $(HAVE_DOTCONFIG)
ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm
ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64
+ARCHDIR-$(CONFIG_LP_ARCH_MIPS) := mips
ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86
ARCH-y := $(ARCHDIR-y)
@@ -102,6 +103,7 @@ ARCH-y := $(ARCHDIR-y)
ARCH-$(CONFIG_LP_ARCH_ARM) := arm
ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64
ARCH-$(CONFIG_LP_ARCH_X86) := i386
+ARCH-$(CONFIG_LP_ARCH_MIPS) := mipsel
CC := $(CC_$(ARCH-y))
AS := $(AS_$(ARCH-y))
diff --git a/payloads/libpayload/Makefile.inc b/payloads/libpayload/Makefile.inc
index b97a03e846..8bf4ef5493 100644
--- a/payloads/libpayload/Makefile.inc
+++ b/payloads/libpayload/Makefile.inc
@@ -33,6 +33,7 @@ export KERNELVERSION := 0.2.0
ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm
ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64
+ARCHDIR-$(CONFIG_LP_ARCH_MIPS) := mips
ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86
DESTDIR ?= install
diff --git a/payloads/libpayload/arch/Config.in b/payloads/libpayload/arch/Config.in
index 3d3d0b5cf2..057fe2b590 100644
--- a/payloads/libpayload/arch/Config.in
+++ b/payloads/libpayload/arch/Config.in
@@ -28,5 +28,6 @@
##
source "arch/arm/Config.in"
-source "arch/x86/Config.in"
source "arch/arm64/Config.in"
+source "arch/mips/Config.in"
+source "arch/x86/Config.in"
diff --git a/payloads/libpayload/arch/mips/Config.in b/payloads/libpayload/arch/mips/Config.in
new file mode 100644
index 0000000000..8c53f7337b
--- /dev/null
+++ b/payloads/libpayload/arch/mips/Config.in
@@ -0,0 +1,29 @@
+#
+# This file is part of the libpayload project.
+#
+# Copyright (C) 2014 Imagination Technologies
+#
+# 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; version 2 of
+# the License.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+
+if ARCH_MIPS
+
+config ARCH_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select LITTLE_ENDIAN
+
+endif
diff --git a/payloads/libpayload/arch/mips/Makefile.inc b/payloads/libpayload/arch/mips/Makefile.inc
new file mode 100644
index 0000000000..223b3df4f9
--- /dev/null
+++ b/payloads/libpayload/arch/mips/Makefile.inc
@@ -0,0 +1,39 @@
+#
+# This file is part of the libpayload project.
+#
+# Copyright (C) 2014 Imagination Technologies
+#
+# 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; version 2 of
+# the License.
+#
+# 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., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+###############################################################################
+CFLAGS += -march=mips32r2 -mxgot
+
+head.o-y += head.S
+
+libc-y += cache.c
+libc-y += coreboot.c
+libc-y += dummy_media.c
+libc-y += exception_asm.S
+libc-y += exception.c
+libc-y += gdb.c
+libc-y += main.c
+libc-y += selfboot.c
+libc-y += sysinfo.c
+libc-y += string.c
+libc-y += timer.c
+libc-y += util.S
+libc-y += virtual.c
diff --git a/payloads/libpayload/arch/mips/cache.c b/payloads/libpayload/arch/mips/cache.c
new file mode 100644
index 0000000000..01840fd8ef
--- /dev/null
+++ b/payloads/libpayload/arch/mips/cache.c
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/cache.h>
+
+
+void dcache_clean_all(void)
+{
+ /* TODO */
+}
+
+void dcache_invalidate_all(void)
+{
+ /* TODO */
+}
+void dcache_clean_invalidate_all(void)
+{
+ /* TODO */
+}
+
+void tlb_invalidate_all(void)
+{
+ /* TODO */
+}
+
+unsigned int dcache_line_bytes(void)
+{
+ /* TO DO */
+ return 0;
+}
+
+void dcache_mmu_disable(void)
+{
+ /* TODO */
+}
+
+void dcache_mmu_enable(void)
+{
+ /* TODO */
+}
+
+void cache_sync_instructions(void)
+{
+ /* TODO */
+}
+
+void mmu_init(void)
+{
+ /* TODO */
+}
+
+void mmu_disable_range(unsigned long start_mb, unsigned long size_mb)
+{
+ /* TODO */
+}
+void mmu_config_range(unsigned long start_mb, unsigned long size_mb,
+ enum dcache_policy policy)
+{
+ /* TODO */
+}
diff --git a/payloads/libpayload/arch/mips/coreboot.c b/payloads/libpayload/arch/mips/coreboot.c
new file mode 100644
index 0000000000..66ad907356
--- /dev/null
+++ b/payloads/libpayload/arch/mips/coreboot.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+static void cb_parse_dma(void *ptr)
+{
+ struct lb_range *dma = (struct lb_range *)ptr;
+ init_dma_memory(phys_to_virt(dma->range_start), dma->range_size);
+}
+
+/* Architecture specific */
+int cb_parse_arch_specific(struct cb_record *rec, struct sysinfo_t *info)
+{
+ switch (rec->tag) {
+ case CB_TAG_DMA:
+ cb_parse_dma(rec);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+
+}
+
+int get_coreboot_info(struct sysinfo_t *info)
+{
+ return cb_parse_header(cb_header_ptr, 1, info);
+}
+
+void *get_cb_header_ptr(void)
+{
+ return cb_header_ptr;
+}
diff --git a/payloads/libpayload/arch/mips/dummy_media.c b/payloads/libpayload/arch/mips/dummy_media.c
new file mode 100644
index 0000000000..539773dd8e
--- /dev/null
+++ b/payloads/libpayload/arch/mips/dummy_media.c
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * 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.
+ */
+#define LIBPAYLOAD
+
+#include <cbfs.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/mips/exception.c b/payloads/libpayload/arch/mips/exception.c
new file mode 100644
index 0000000000..c910adae7d
--- /dev/null
+++ b/payloads/libpayload/arch/mips/exception.c
@@ -0,0 +1,107 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/exception.h>
+#include <exception.h>
+#include <libpayload.h>
+#include <stdint.h>
+
+u32 exception_stack[0x400] __attribute__((aligned(8)));
+struct exception_state_t exception_state;
+
+static const char *names[EXC_COUNT] = {
+ [EXC_CACHE_ERROR] = "Cache error exception",
+ [EXC_TLB_REFILL_AND_ALL] = "TLB refill or general exception",
+ [EXC_INTERRUPT] = "Interrupt",
+ [EXC_EJTAG_DEBUG] = "EJTAG debug exception"
+};
+
+static void dump_exception_state(void)
+{
+ printf("%s exception!\n", names[exception_state_ptr->vector]);
+ printf("\nRegisters:\n");
+ printf("ZERO:\t0x%08x\n", exception_state_ptr->regs.zero);
+ printf("AT:\t0x%08x\n", exception_state_ptr->regs.at);
+ printf("V0:\t0x%08x\n", exception_state_ptr->regs.v0);
+ printf("V1:\t0x%08x\n", exception_state_ptr->regs.v1);
+ printf("A0:\t0x%08x\n", exception_state_ptr->regs.a0);
+ printf("A1:\t0x%08x\n", exception_state_ptr->regs.a1);
+ printf("A2:\t0x%08x\n", exception_state_ptr->regs.a2);
+ printf("A3:\t0x%08x\n", exception_state_ptr->regs.a3);
+ printf("T0:\t0x%08x\n", exception_state_ptr->regs.t0);
+ printf("T1:\t0x%08x\n", exception_state_ptr->regs.t1);
+ printf("T2:\t0x%08x\n", exception_state_ptr->regs.t2);
+ printf("T3:\t0x%08x\n", exception_state_ptr->regs.t3);
+ printf("T4:\t0x%08x\n", exception_state_ptr->regs.t4);
+ printf("T5:\t0x%08x\n", exception_state_ptr->regs.t5);
+ printf("T6:\t0x%08x\n", exception_state_ptr->regs.t6);
+ printf("T7:\t0x%08x\n", exception_state_ptr->regs.t7);
+ printf("S0:\t0x%08x\n", exception_state_ptr->regs.s0);
+ printf("S1:\t0x%08x\n", exception_state_ptr->regs.s1);
+ printf("S2:\t0x%08x\n", exception_state_ptr->regs.s2);
+ printf("S3:\t0x%08x\n", exception_state_ptr->regs.s3);
+ printf("S4:\t0x%08x\n", exception_state_ptr->regs.s4);
+ printf("S5:\t0x%08x\n", exception_state_ptr->regs.s5);
+ printf("S6:\t0x%08x\n", exception_state_ptr->regs.s6);
+ printf("S7:\t0x%08x\n", exception_state_ptr->regs.s7);
+ printf("T8:\t0x%08x\n", exception_state_ptr->regs.t8);
+ printf("T9:\t0x%08x\n", exception_state_ptr->regs.t9);
+ printf("K0:\t0x%08x\n", exception_state_ptr->regs.k0);
+ printf("K1:\t0x%08x\n", exception_state_ptr->regs.k1);
+ printf("GP:\t0x%08x\n", exception_state_ptr->regs.gp);
+ printf("SP:\t0x%08x\n", exception_state_ptr->regs.sp);
+ printf("FP:\t0x%08x\n", exception_state_ptr->regs.fp);
+ printf("RA:\t0x%08x\n", exception_state_ptr->regs.ra);
+}
+
+static void dump_stack(uintptr_t addr, size_t bytes)
+{
+ int i, j;
+ const int words_per_line = 8;
+ int words_to_print;
+ uint32_t *ptr = (uint32_t *)
+ (addr & ~(words_per_line * sizeof(*ptr) - 1));
+
+ printf("Dumping stack:\n");
+ words_to_print = bytes/sizeof(*ptr);
+ for (i = words_to_print; i >= 0; i -= words_per_line) {
+ printf("%p: ", ptr + i);
+ for (j = i; j < i + words_per_line; j++)
+ printf("%08x ", *(ptr + j));
+ printf("\n");
+ }
+}
+
+
+void exception_dispatch(void)
+{
+ u32 vec = exception_state_ptr->vector;
+ die_if(vec >= EXC_COUNT || !names[vec], "Bad exception vector %u", vec);
+
+ dump_exception_state();
+ dump_stack(exception_state_ptr->regs.sp, 512);
+ halt();
+}
+
+void exception_init(void)
+{
+ exception_stack_end = exception_stack + ARRAY_SIZE(exception_stack);
+ exception_state_ptr = &exception_state;
+ exception_init_asm();
+}
diff --git a/payloads/libpayload/arch/mips/exception_asm.S b/payloads/libpayload/arch/mips/exception_asm.S
new file mode 100644
index 0000000000..5906d39f0c
--- /dev/null
+++ b/payloads/libpayload/arch/mips/exception_asm.S
@@ -0,0 +1,208 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define STATUS_REGISTER $12,0
+#define BOOT_EXC_VECTOR_MASK (1 << 22)
+#define EBASE_REGISTER $15,1
+#define WRITE_GATE_MASK (1 << 11)
+#define EXCEPTION_BASE_MASK (0xFFFFF000)
+
+ /* Don't reorder instructions */
+ .set noreorder
+ .set noat
+
+ .align 4
+ .global exception_stack_end
+exception_stack_end:
+ .word 0
+
+ .global exception_state_ptr
+exception_state_ptr:
+ .word 0
+
+/* Temporary variables. */
+ret_addr:
+ .word 0
+exception_sp:
+ .word 0
+vector:
+ .word 0
+
+/* Cache error */
+.org 0x100
+ li $v0, 0x0
+ la $at, vector
+ sw $v0, 0x00($at)
+ b exception_common
+ nop
+
+/* TLB refill and all others */
+.org 0x180
+ li $v0, 0x1
+ la $at, vector
+ sw $v0, 0x00($at)
+ b exception_common
+ nop
+
+/* Interrupt */
+.org 0x200
+ li $v0, 0x2
+ la $at, vector
+ sw $v0, 0x00($at)
+ b exception_common
+ nop
+
+/* EJTAG debug exception */
+.org 0x480
+ li $v0, 0x3
+ la $at, vector
+ sw $v0, 0x00($at)
+ b exception_common
+ nop
+
+exception_common:
+ /* Obtain return address of exception */
+ la $v0, ret_addr
+ sw $ra, 0x00($v0)
+
+ /* Initialize $gp */
+ bal 1f
+ nop
+ .word _gp
+1:
+ lw $gp, 0($ra)
+
+ la $at, exception_sp
+ sw $sp, 0x00($at)
+ lw $sp, exception_state_ptr
+
+ /* Save all registers */
+ sw $zero, 0x00($sp)
+ sw $at, 0x04($sp)
+ sw $v0, 0x08($sp)
+ sw $v1, 0x0C($sp)
+ sw $a0, 0x10($sp)
+ sw $a1, 0x14($sp)
+ sw $a2, 0x18($sp)
+ sw $a3, 0x1C($sp)
+ sw $t0, 0x20($sp)
+ sw $t1, 0x34($sp)
+ sw $t2, 0x28($sp)
+ sw $t3, 0x2C($sp)
+ sw $t4, 0x30($sp)
+ sw $t5, 0x34($sp)
+ sw $t6, 0x38($sp)
+ sw $t7, 0x3C($sp)
+ sw $s0, 0x40($sp)
+ sw $s1, 0x44($sp)
+ sw $s2, 0x48($sp)
+ sw $s3, 0x4C($sp)
+ sw $s4, 0x50($sp)
+ sw $s5, 0x54($sp)
+ sw $s6, 0x58($sp)
+ sw $s7, 0x5C($sp)
+ sw $t8, 0x60($sp)
+ sw $t9, 0x64($sp)
+ sw $k0, 0x68($sp)
+ sw $k1, 0x6C($sp)
+ sw $gp, 0x70($sp)
+ lw $v0, exception_sp
+ sw $v0, 0x74($sp)
+ sw $fp, 0x78($sp)
+ lw $v0, ret_addr
+ sw $v0, 0x7C($sp)
+ lw $v0, vector
+ sw $v0, 0x80($sp)
+
+ /* Point SP to the stack for C code */
+ lw $sp, exception_stack_end
+ /* Give control to exception dispatch */
+ la $a2, exception_dispatch
+ jalr $a2
+ nop
+ lw $sp, exception_state_ptr
+ /* Restore registers */
+ lw $zero, 0x00($sp)
+ lw $at, 0x04($sp)
+ lw $v0, 0x08($sp)
+ lw $v1, 0x0C($sp)
+ lw $a0, 0x10($sp)
+ lw $a1, 0x14($sp)
+ lw $a2, 0x18($sp)
+ lw $a3, 0x1C($sp)
+ lw $t0, 0x20($sp)
+ lw $t1, 0x24($sp)
+ lw $t2, 0x28($sp)
+ lw $t3, 0x2C($sp)
+ lw $t4, 0x30($sp)
+ lw $t5, 0x34($sp)
+ lw $t6, 0x38($sp)
+ lw $t7, 0x3C($sp)
+ lw $s0, 0x40($sp)
+ lw $s1, 0x44($sp)
+ lw $s2, 0x48($sp)
+ lw $s3, 0x4C($sp)
+ lw $s4, 0x50($sp)
+ lw $s5, 0x54($sp)
+ lw $s6, 0x58($sp)
+ lw $s7, 0x5C($sp)
+ lw $t8, 0x60($sp)
+ lw $t9, 0x64($sp)
+ lw $k0, 0x68($sp)
+ sw $k1, 0x6C($sp)
+ sw $gp, 0x70($sp)
+ sw $fp, 0x78($sp)
+ sw $ra, 0x7C($sp)
+ /* Return */
+ eret
+
+ .global exception_init_asm
+exception_init_asm:
+ .set push
+ /* Make sure boot exception vector is 1 before writing EBASE */
+ mfc0 $t0, STATUS_REGISTER
+ li $t1, BOOT_EXC_VECTOR_MASK
+ or $t0, $t0, $t1
+ mtc0 $t0, STATUS_REGISTER
+
+ /*Prepare base address */
+ la $t1, exception_stack_end
+ li $t2, EXCEPTION_BASE_MASK
+ and $t1, $t1, $t2
+
+ /* Prepare EBASE register value */
+ mfc0 $t0, EBASE_REGISTER
+ li $t2, ~(EXCEPTION_BASE_MASK)
+ and $t0, $t0, $t2
+ /* Filling base address */
+ or $t0, $t0, $t1
+ /* Setting WG bit */
+ li $t2, WRITE_GATE_MASK
+ or $t0, $t0, $t2
+ mtc0 $t0, EBASE_REGISTER
+
+ /* Clear boot exception vector bit for EBASE value to take effect */
+ mfc0 $t0, STATUS_REGISTER
+ li $t1, ~BOOT_EXC_VECTOR_MASK
+ and $t0, $t0, $t1
+ mtc0 $t0, STATUS_REGISTER
+
+ .set pop
+ /* Return */
+ jr $ra
diff --git a/payloads/libpayload/arch/mips/gdb.c b/payloads/libpayload/arch/mips/gdb.c
new file mode 100644
index 0000000000..cea67ab084
--- /dev/null
+++ b/payloads/libpayload/arch/mips/gdb.c
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <gdb.h>
+#include <libpayload.h>
+
+
+void gdb_arch_init(void)
+{
+}
+
+void gdb_arch_enter(void)
+{
+}
+
diff --git a/payloads/libpayload/arch/mips/head.S b/payloads/libpayload/arch/mips/head.S
new file mode 100644
index 0000000000..f25e77ac42
--- /dev/null
+++ b/payloads/libpayload/arch/mips/head.S
@@ -0,0 +1,110 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/cpu.h>
+
+ /* Disable interrupts and mark the kernel mode */
+ .macro setup_c0_status clr
+ .set push
+ mfc0 $t0, $CP0_STATUS
+ or $t0, ST0_CU0 | 0x1f | \clr
+ xor $t0, 0x1f | \clr
+ mtc0 $t0, $CP0_STATUS
+ .set noreorder
+ sll $zero, 3
+ .set pop
+ .endm
+
+ /* Don't reorder instructions */
+ .set noreorder
+
+ .align 4
+
+ .global cb_header_ptr
+cb_header_ptr:
+ .word 0
+
+ .global old_sp
+old_sp:
+ .word 0
+
+
+ .global _entry, _leave
+ .text
+
+/* Our entry point */
+_entry:
+
+ /*
+ * This function saves off the previous stack and switches us to our
+ * own execution environment.
+ */
+
+ /* Clear watch and cause registers */
+ mtc0 $zero, $CP0_WATCHLO
+ mtc0 $zero, $CP0_WATCHHI
+ mtc0 $zero, $CP0_CAUSE
+
+ /* Disable interrupts */
+ setup_c0_status 0
+
+ /* Don't use at in synthetic instr. */
+ .set noat
+
+ /* Init timer */
+ mtc0 $zero, $CP0_COUNT
+ mtc0 $zero, $CP0_COMPARE
+
+ /* Initialize $gp */
+ bal 1f
+ nop
+ .word _gp
+1:
+ lw $gp, 0($ra)
+
+ /* Clear .bss: start_bss = _edata, end_bss = _end */
+ la $t0, _edata
+ sw $zero, ($t0)
+ la $t1, _end - 4
+clear_bss:
+ addiu $t0, 4
+ sw $zero, ($t0)
+ bne $t0, $t1, clear_bss
+ nop
+
+ /* Save off the location of the coreboot tables */
+ la $at, cb_header_ptr
+ sw $a0, 0x00($at)
+
+ /* Save old stack pointer */
+ la $at, old_sp
+ sw $sp, 0x00($at)
+
+ /* Setup new stack */
+ la $sp, _stack
+
+ /* Let's rock */
+ la $a2, start_main
+ jalr $a2
+ nop
+_leave:
+ /* Restore old stack. */
+ lw $sp, old_sp
+ /* Return to the original context. */
+ eret
diff --git a/payloads/libpayload/arch/mips/libpayload.ldscript b/payloads/libpayload/arch/mips/libpayload.ldscript
new file mode 100644
index 0000000000..a38d3abab0
--- /dev/null
+++ b/payloads/libpayload/arch/mips/libpayload.ldscript
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * Based on src/arch/arm/ramstage.ld:
+ * Written by Johan Rydberg, based on work by Daniel Kahlin.
+ * Rewritten by Eric Biederman
+ *
+ * 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; version 2 of
+ * the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+OUTPUT_ARCH(mips)
+
+BASE_ADDRESS = 0x80000000;
+ENTRY(_entry)
+
+HEAP_SIZE = 2*64*1024;
+STACK_SIZE = 16*1024;
+
+SECTIONS
+{
+ . = BASE_ADDRESS;
+
+ . = ALIGN(16);
+ _start = .;
+
+ .text : {
+ *(.text._entry)
+ *(.text)
+ *(.text.*)
+ }
+
+ .rodata : {
+ *(.rodata)
+ *(.rodata.*)
+ }
+
+ .data : {
+ *(.data)
+ *(.data.*)
+ }
+
+ _edata = .;
+
+ .sdata : {
+ *(.srodata)
+ *(.sdata)
+ }
+
+ _bss = .;
+ .bss : {
+ *(.sbss)
+ *(.sbss.*)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+
+ /* Stack and heap */
+
+ . = ALIGN(16);
+ _heap = .;
+ . += HEAP_SIZE;
+ . = ALIGN(16);
+ _eheap = .;
+
+ _estack = .;
+ . += STACK_SIZE;
+ . = ALIGN(16);
+ _stack = .;
+ }
+ _ebss = .;
+
+ _end = .;
+
+ /DISCARD/ : {
+ *(.comment)
+ *(.note*)
+ *(.reginfo)
+
+ }
+}
diff --git a/payloads/libpayload/arch/mips/main.c b/payloads/libpayload/arch/mips/main.c
new file mode 100644
index 0000000000..d6f980a1f5
--- /dev/null
+++ b/payloads/libpayload/arch/mips/main.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <exception.h>
+#include <libpayload.h>
+
+/* The argc value to pass to main() */
+unsigned int main_argc;
+/* 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_LP_SKIP_CONSOLE_INIT
+ console_init();
+#endif
+
+ exception_init();
+ /*
+ * 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/mips/selfboot.c b/payloads/libpayload/arch/mips/selfboot.c
new file mode 100644
index 0000000000..c69583134c
--- /dev/null
+++ b/payloads/libpayload/arch/mips/selfboot.c
@@ -0,0 +1,36 @@
+/*
+ * 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 <libpayload.h>
+
+extern void *cb_header_ptr;
+
+void selfboot(void *entry)
+{
+ void (*entry_func)(void *) = entry;
+ entry_func(cb_header_ptr);
+}
diff --git a/payloads/libpayload/arch/mips/string.c b/payloads/libpayload/arch/mips/string.c
new file mode 100644
index 0000000000..0f0c7c3529
--- /dev/null
+++ b/payloads/libpayload/arch/mips/string.c
@@ -0,0 +1,72 @@
+ /*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include "string.h"
+
+/*
+ * Alternative string functions to the default ones are added
+ * because there is no guarantee that the provided source and
+ * destination addresses are properly aligned;
+ * The default string functions work with multiple of 4 bytes
+ * (sizeof(unsinged long)); MIPS will use LW/SW instructions
+ * for these operations and if the source and destination
+ * addresses are not aligned it will trigger an exception.
+ */
+
+void *memcpy(void *dest, const void *src, size_t n)
+{
+ u8 *ptr_d = dest;
+ const u8 *ptr_s = src;
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ *ptr_d++ = *ptr_s++;
+
+ return dest;
+}
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+ if ((src < dest) && (dest - src < n)) {
+ u8 *ptr_d = dest;
+ const u8 *ptr_s = src;
+ size_t i;
+
+ /* copy backwards */
+ for (i = n - 1; i >= 0; i--)
+ ptr_d[i] = ptr_s[i];
+
+ return dest;
+ }
+
+ /* copy forwards */
+ return memcpy(dest, src, n);
+}
+
+void *memset(void *s, int c, size_t n)
+{
+ u8 *ptr = s;
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ *ptr++ = c;
+
+ return s;
+}
diff --git a/payloads/libpayload/arch/mips/sysinfo.c b/payloads/libpayload/arch/mips/sysinfo.c
new file mode 100644
index 0000000000..ab1db63bf0
--- /dev/null
+++ b/payloads/libpayload/arch/mips/sysinfo.c
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libpayload-config.h>
+#include <libpayload.h>
+#include <coreboot_tables.h>
+#include <multiboot_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 we can't get a good memory range, use the default. */
+ if (!lib_sysinfo.n_memranges) {
+ 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/mips/timer.c b/payloads/libpayload/arch/mips/timer.c
new file mode 100644
index 0000000000..1710a322e2
--- /dev/null
+++ b/payloads/libpayload/arch/mips/timer.c
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libpayload.h>
+#include <arch/cpu.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)
+{
+ if (IMG_PLATFORM_ID() != IMG_PLATFORM_ID_SILICON)
+ cpu_khz = 50000U; /* FPGA board */
+ /* else {
+ * TODO find CPU frequency on the real SOC
+ } */
+
+ return cpu_khz;
+}
diff --git a/payloads/libpayload/arch/mips/util.S b/payloads/libpayload/arch/mips/util.S
new file mode 100644
index 0000000000..09bfddc86c
--- /dev/null
+++ b/payloads/libpayload/arch/mips/util.S
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+ .global halt
+ .text
+ .align 4
+ .type halt, function
+halt:
+ j halt
+ nop
diff --git a/payloads/libpayload/arch/mips/virtual.c b/payloads/libpayload/arch/mips/virtual.c
new file mode 100644
index 0000000000..9d226494b9
--- /dev/null
+++ b/payloads/libpayload/arch/mips/virtual.c
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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 47a34f81be..1dbd716b12 100755
--- a/payloads/libpayload/bin/lpgcc
+++ b/payloads/libpayload/bin/lpgcc
@@ -80,6 +80,12 @@ if [ "$CONFIG_LP_ARCH_ARM64" = "y" ]; then
_ARCHEXTRA=""
_ARCH=arm64
fi
+if [ "$CONFIG_LP_ARCH_MIPS" = "y" ]; then
+ _ARCHINCDIR=$_INCDIR/mips
+ _ARCHLIBDIR=$_LIBDIR/mips
+ _ARCHEXTRA=""
+ _ARCH=mips
+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
index c2285feea8..aa6e2b4014 100644
--- a/payloads/libpayload/configs/config.arm64-generic
+++ b/payloads/libpayload/configs/config.arm64-generic
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# libpayload version: 0.2.0
-# Mon Jan 5 15:06:47 2015
+# Wed Mar 18 16:11:01 2015
#
#
@@ -19,6 +19,7 @@ CONFIG_LP_CHROMEOS=y
# CONFIG_LP_ARCH_ARM is not set
# CONFIG_LP_ARCH_X86 is not set
CONFIG_LP_ARCH_ARM64=y
+# CONFIG_LP_ARCH_MIPS is not set
# CONFIG_LP_MEMMAP_RAM_ONLY is not set
#
@@ -49,6 +50,8 @@ CONFIG_LP_TIMER_NONE=y
# CONFIG_LP_TIMER_TEGRA_1US is not set
# CONFIG_LP_TIMER_IPQ806X is not set
# CONFIG_LP_TIMER_RK is not set
+# CONFIG_LP_TIMER_BG4CD is not set
+# CONFIG_LP_TIMER_IMG_PISTACHIO is not set
CONFIG_LP_USB=y
# CONFIG_LP_USB_OHCI is not set
CONFIG_LP_USB_EHCI=y
diff --git a/payloads/libpayload/configs/defconfig b/payloads/libpayload/configs/defconfig
index a09a78cfa3..f5e13d5535 100644
--- a/payloads/libpayload/configs/defconfig
+++ b/payloads/libpayload/configs/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# libpayload version: 0.2.0
-# Mon Jan 5 15:27:43 2015
+# Wed Mar 18 16:11:08 2015
#
#
@@ -19,6 +19,7 @@
# CONFIG_LP_ARCH_ARM is not set
CONFIG_LP_ARCH_X86=y
# CONFIG_LP_ARCH_ARM64 is not set
+# CONFIG_LP_ARCH_MIPS is not set
# 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 b76542297c..ea467ecd40 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
-# Mon Jan 5 15:28:18 2015
+# Wed Mar 18 16:11:16 2015
#
#
@@ -19,6 +19,7 @@
CONFIG_LP_ARCH_ARM=y
# CONFIG_LP_ARCH_X86 is not set
# CONFIG_LP_ARCH_ARM64 is not set
+# CONFIG_LP_ARCH_MIPS is not set
# CONFIG_LP_MEMMAP_RAM_ONLY is not set
#
@@ -61,6 +62,8 @@ CONFIG_LP_TIMER_NONE=y
# CONFIG_LP_TIMER_TEGRA_1US is not set
# CONFIG_LP_TIMER_IPQ806X is not set
# CONFIG_LP_TIMER_RK is not set
+# CONFIG_LP_TIMER_BG4CD is not set
+# CONFIG_LP_TIMER_IMG_PISTACHIO is not set
CONFIG_LP_USB=y
CONFIG_LP_USB_OHCI=y
CONFIG_LP_USB_EHCI=y
diff --git a/payloads/libpayload/configs/defconfig-mips b/payloads/libpayload/configs/defconfig-mips
new file mode 100644
index 0000000000..0af1a91706
--- /dev/null
+++ b/payloads/libpayload/configs/defconfig-mips
@@ -0,0 +1,75 @@
+#
+# Automatically generated make config: don't edit
+# libpayload version: 0.2.0
+# Sat Mar 21 10:22:59 2015
+#
+
+#
+# Generic Options
+#
+# CONFIG_LP_GPL is not set
+# 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
+# CONFIG_LP_ARCH_X86 is not set
+# CONFIG_LP_ARCH_ARM64 is not set
+CONFIG_LP_ARCH_MIPS=y
+# CONFIG_LP_MEMMAP_RAM_ONLY 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_RK_SERIAL_CONSOLE is not set
+# CONFIG_LP_IPQ806X_SERIAL_CONSOLE is not set
+# CONFIG_LP_PL011_SERIAL_CONSOLE is not set
+# CONFIG_LP_SERIAL_SET_SPEED is not set
+# CONFIG_LP_SERIAL_ACS_FALLBACK is not set
+CONFIG_LP_VIDEO_CONSOLE=y
+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_RTC_PORT_EXTENDED_VIA is not set
+CONFIG_LP_STORAGE=y
+# CONFIG_LP_STORAGE_64BIT_LBA is not set
+CONFIG_LP_STORAGE_ATA=y
+CONFIG_LP_STORAGE_ATAPI=y
+# CONFIG_LP_TIMER_NONE is not set
+# CONFIG_LP_TIMER_MCT is not set
+# CONFIG_LP_TIMER_TEGRA_1US is not set
+# CONFIG_LP_TIMER_IPQ806X is not set
+# CONFIG_LP_TIMER_RK is not set
+# CONFIG_LP_TIMER_BG4CD is not set
+CONFIG_LP_TIMER_IMG_PISTACHIO=y
+# CONFIG_LP_USB is not set
+# CONFIG_LP_USB_GEN_HUB 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/drivers/Makefile.inc b/payloads/libpayload/drivers/Makefile.inc
index 0fc2faa604..4a569c47bc 100644
--- a/payloads/libpayload/drivers/Makefile.inc
+++ b/payloads/libpayload/drivers/Makefile.inc
@@ -51,6 +51,8 @@ libc-$(CONFIG_LP_TIMER_RDTSC) += timer/rdtsc.c
libc-$(CONFIG_LP_TIMER_TEGRA_1US) += timer/tegra_1us.c
libc-$(CONFIG_LP_TIMER_IPQ806X) += timer/ipq806x.c
libc-$(CONFIG_LP_TIMER_RK) += timer/rktimer.c
+libc-$(CONFIG_LP_TIMER_BG4CD) += timer/bg4cd.c
+libc-$(CONFIG_LP_TIMER_IMG_PISTACHIO) += timer/img_pistachio.c
# Video console drivers
libc-$(CONFIG_LP_VIDEO_CONSOLE) += video/video.c
diff --git a/payloads/libpayload/drivers/timer/img_pistachio.c b/payloads/libpayload/drivers/timer/img_pistachio.c
new file mode 100644
index 0000000000..dcfe555a73
--- /dev/null
+++ b/payloads/libpayload/drivers/timer/img_pistachio.c
@@ -0,0 +1,36 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <libpayload.h>
+#include <arch/cpu.h>
+
+static int get_timer_speed_khz(void)
+{
+ return get_cpu_speed()/2;
+}
+
+uint64_t timer_hz(void)
+{
+ return lib_sysinfo.cpu_khz * 1000;
+}
+
+uint64_t timer_raw_value(void)
+{
+ return read_c0_count()/(get_timer_speed_khz()/1000);
+}
diff --git a/payloads/libpayload/include/mips/arch/byteorder.h b/payloads/libpayload/include/mips/arch/byteorder.h
new file mode 100644
index 0000000000..002451accc
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/byteorder.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MIPS_ARCH_BYTEORDER_H__
+#define __MIPS_ARCH_BYTEORDER_H__
+
+#include <stdint.h>
+#include <swab.h>
+
+#ifndef __ORDER_LITTLE_ENDIAN__
+#error "What endian are you!?"
+#endif
+
+#define cpu_to_le64(x) ((uint64_t)(x))
+#define le64_to_cpu(x) ((uint64_t)(x))
+#define cpu_to_le32(x) ((uint32_t)(x))
+#define le32_to_cpu(x) ((uint32_t)(x))
+#define cpu_to_le16(x) ((uint16_t)(x))
+#define le16_to_cpu(x) ((uint16_t)(x))
+#define cpu_to_be64(x) swab64(x)
+#define be64_to_cpu(x) swab64(x)
+#define cpu_to_be32(x) swab32((x))
+#define be32_to_cpu(x) swab32((x))
+#define cpu_to_be16(x) swab16((x))
+#define be16_to_cpu(x) swab16((x))
+
+#endif /* __MIPS_ARCH_BYTEORDER_H__ */
diff --git a/payloads/libpayload/include/mips/arch/cache.h b/payloads/libpayload/include/mips/arch/cache.h
new file mode 100644
index 0000000000..9485671e98
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/cache.h
@@ -0,0 +1,98 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MIPS_ARCH_CACHE_H__
+#define __MIPS_ARCH_CACHE_H__
+
+
+#include <stddef.h>
+#include <stdint.h>
+
+
+/*
+ * Sync primitives
+ */
+
+/* data memory barrier */
+static inline void dmb(void)
+{
+ /* TODO */
+}
+
+/* data sync barrier */
+static inline void dsb(void)
+{
+ /* TODO */
+}
+
+/* instruction sync barrier */
+static inline void isb(void)
+{
+ /* TODO */
+}
+
+
+/*
+ * Cache maintenance API
+ */
+
+/* dcache clean and invalidate all */
+void dcache_clean_invalidate_all(void);
+
+/* dcache clean all */
+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 /* __MIPS_ARCH_CACHE_H__ */
diff --git a/payloads/libpayload/include/mips/arch/cpu.h b/payloads/libpayload/include/mips/arch/cpu.h
new file mode 100644
index 0000000000..952ec7c528
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/cpu.h
@@ -0,0 +1,85 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of
+ * the License.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MIPS_ARCH_CPU_H__
+#define __MIPS_ARCH_CPU_H__
+
+/*
+ * Reading at this address allows to identify the platform the code is running
+ * on
+ */
+#define IMG_PLATFORM_ID() (*((unsigned *)0xB8149060))
+#define IMG_PLATFORM_ID_SILICON 0xF00D0006
+
+#define CP0_COUNT 9
+#define CP0_COMPARE 11
+#define CP0_STATUS 12
+#define CP0_CAUSE 13
+#define CP0_WATCHLO 18
+#define CP0_WATCHHI 19
+
+/* coprocessor 0 enable */
+#define ST0_CU0 (1 << 28)
+#define C0_CAUSE_DC (1 << 27)
+
+/***************************************************************************
+ * The following section was copied from arch/mips/include/asm/mipsregs.h in
+ * the 3.14 kernel tree.
+ */
+
+/*
+ * Macros to access the system control coprocessor
+ */
+
+#define __read_32bit_c0_register(source, sel) \
+({ int __res; \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __write_32bit_c0_register(register, sel, value) \
+do { \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mtc0\t%z0, " #register "\n\t" \
+ : : "Jr" ((unsigned int)(value))); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mtc0\t%z0, " #register ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : : "Jr" ((unsigned int)(value))); \
+} while (0)
+
+/* Shortcuts to access various internal registers, keep adding as needed. */
+#define read_c0_count() __read_32bit_c0_register($9, 0)
+#define write_c0_count(val) __write_32bit_c0_register($9, 0, (val))
+
+#define read_c0_cause() __read_32bit_c0_register($13, 0)
+#define write_c0_cause(val) __write_32bit_c0_register($13, 0, (val))
+/***************************************************************************/
+
+#endif /* __MIPS_ARCH_CPU_H__ */
diff --git a/payloads/libpayload/include/mips/arch/exception.h b/payloads/libpayload/include/mips/arch/exception.h
new file mode 100644
index 0000000000..9557cb7049
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/exception.h
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MIPS_ARCH_EXCEPTION_H__
+#define __MIPS_ARCH_EXCEPTION_H__
+
+#include <stdint.h>
+
+void exception_init_asm(void);
+void exception_dispatch(void);
+
+struct exception_state_t {
+ struct {
+ /* Always 0: just to keep the series complete */
+ u32 zero;
+ /* Reserved for the assembler */
+ /* TODO: is this actually needed here? */
+ u32 at;
+ /* v0-v1: expression evaluation */
+ u32 v0;
+ u32 v1;
+ /* a0-a3: Arguments */
+ u32 a0;
+ u32 a1;
+ u32 a2;
+ u32 a3;
+ /* t0-t3: Temporary registers for expression evaluation */
+ u32 t0;
+ u32 t1;
+ u32 t2;
+ u32 t3;
+ u32 t4;
+ u32 t5;
+ u32 t6;
+ u32 t7;
+ /* s0-s7: Saved registers */
+ u32 s0;
+ u32 s1;
+ u32 s2;
+ u32 s3;
+ u32 s4;
+ u32 s5;
+ u32 s6;
+ u32 s7;
+ /* t8-t9: Temporary registers for expression evaluation */
+ u32 t8;
+ u32 t9;
+ /* k0-k1: reserved for SO kernel */
+ u32 k0;
+ u32 k1;
+ /* Global pointer */
+ u32 gp;
+ /* Stack pointer */
+ u32 sp;
+ /* Frame pointer */
+ u32 fp;
+ /* Return address */
+ u32 ra;
+ } regs;
+ u32 vector;
+} __attribute__((packed));
+
+extern struct exception_state_t *exception_state_ptr;
+extern u32 *exception_stack_end;
+
+enum {
+ EXC_CACHE_ERROR = 0,
+ EXC_TLB_REFILL_AND_ALL = 1,
+ EXC_INTERRUPT = 2,
+ EXC_EJTAG_DEBUG = 3,
+ EXC_COUNT
+};
+
+#endif /* __MIPS_ARCH_EXCEPTION_H__ */
diff --git a/payloads/libpayload/include/mips/arch/io.h b/payloads/libpayload/include/mips/arch/io.h
new file mode 100644
index 0000000000..d2d9338037
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/io.h
@@ -0,0 +1,67 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * Based on arch/armv7/include/arch/io.h:
+ * Copyright 2013 Google Inc.
+ * 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 as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MIPS_ARCH_IO_H__
+#define __MIPS_ARCH_IO_H__
+
+#include <arch/types.h>
+#include <arch/cache.h>
+#include <arch/byteorder.h>
+
+#define read8(a) (*(volatile uint8_t *) (a))
+#define read16(a) (*(volatile uint16_t *) (a))
+#define read32(a) (*(volatile uint32_t *) (a))
+
+#define write8(v, a) (*(volatile uint8_t *) (a) = (v))
+#define write16(v, a) (*(volatile uint16_t *) (a) = (v))
+#define write32(v, a) (*(volatile uint32_t *) (a) = (v))
+
+
+/*
+ * Clear and set bits in one shot. These macros can be used to clear and
+ * set multiple bits in a register using a single call. These macros can
+ * also be used to set a multiple-bit bit pattern using a mask, by
+ * specifying the mask in the 'clear' parameter and the new bit pattern
+ * in the 'set' parameter.
+ */
+
+#define out_arch(type, endian, a, v) write##type(cpu_to_##endian(v), a)
+#define in_arch(type, endian, a) endian##_to_cpu(read##type(a))
+
+#define readb(a) read8(a)
+#define readw(a) read16(a)
+#define readl(a) read32(a)
+
+#define inb(a) read8(a)
+#define inw(a) read16(a)
+#define inl(a) read32(a)
+
+#define writeb(v, a) write8(v, a)
+#define writew(v, a) write16(v, a)
+#define writel(v, a) write32(v, a)
+
+#define outb(v, a) write8(v, a)
+#define outw(v, a) write16(v, a)
+#define outl(v, a) write32(v, a)
+
+#endif /* __MIPS_ARCH_IO_H__ */
diff --git a/payloads/libpayload/include/mips/arch/stdint.h b/payloads/libpayload/include/mips/arch/stdint.h
new file mode 100644
index 0000000000..c182530862
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/stdint.h
@@ -0,0 +1,95 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Based on src/arch/armv7/include/stdint.h
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MIPS_STDINT_H__
+#define __MIPS_STDINT_H__
+
+#if defined(__GNUC__)
+#define __HAVE_LONG_LONG__ 1
+#else
+#define __HAVE_LONG_LONG__ 0
+#endif
+
+/* Exact integral types */
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+
+typedef unsigned short uint16_t;
+typedef signed short int16_t;
+
+typedef unsigned int uint32_t;
+typedef signed int int32_t;
+
+#if __HAVE_LONG_LONG__
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+#endif
+
+/* Small types */
+typedef unsigned char uint_least8_t;
+typedef signed char int_least8_t;
+
+typedef unsigned short uint_least16_t;
+typedef signed short int_least16_t;
+
+typedef unsigned int uint_least32_t;
+typedef signed int int_least32_t;
+
+#if __HAVE_LONG_LONG__
+typedef unsigned long long uint_least64_t;
+typedef signed long long int_least64_t;
+#endif
+
+/* Fast Types */
+typedef unsigned char uint_fast8_t;
+typedef signed char int_fast8_t;
+
+typedef unsigned int uint_fast16_t;
+typedef signed int int_fast16_t;
+
+typedef unsigned int uint_fast32_t;
+typedef signed int int_fast32_t;
+
+#if __HAVE_LONG_LONG__
+typedef unsigned long long uint_fast64_t;
+typedef signed long long int_fast64_t;
+#endif
+
+/* Largest integral types */
+#if __HAVE_LONG_LONG__
+typedef long long int intmax_t;
+typedef unsigned long long uintmax_t;
+#else
+typedef long int intmax_t;
+typedef unsigned long int uintmax_t;
+#endif
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+#if __HAVE_LONG_LONG__
+typedef uint64_t u64;
+#endif
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+
+#undef __HAVE_LONG_LONG__
+
+#endif /* __MIPS_STDINT_H__ */
diff --git a/payloads/libpayload/include/mips/arch/types.h b/payloads/libpayload/include/mips/arch/types.h
new file mode 100644
index 0000000000..151817e679
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/types.h
@@ -0,0 +1,76 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * Based on src/arch/armv7/include/arch/types.h
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MIPS_ARCH_TYPES_H
+#define __MIPS_ARCH_TYPES_H
+
+#include <arch/stdint.h>
+
+typedef unsigned short umode_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__)
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#endif
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* Dma addresses are 32-bits wide. */
+
+typedef u32 dma_addr_t;
+
+typedef unsigned long phys_addr_t;
+typedef unsigned long phys_size_t;
+
+typedef long time_t;
+typedef long suseconds_t;
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#endif /* __MIPS_ARCH_TYPES_H */
diff --git a/payloads/libpayload/include/mips/arch/virtual.h b/payloads/libpayload/include/mips/arch/virtual.h
new file mode 100644
index 0000000000..70aea20b9c
--- /dev/null
+++ b/payloads/libpayload/include/mips/arch/virtual.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the libpayload project.
+ *
+ * Copyright (C) 2014 Imagination Technologies
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MIPS_ARCH_VIRTUAL_H
+#define __MIPS_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/swab.h b/payloads/libpayload/include/swab.h
new file mode 100644
index 0000000000..2198077ad2
--- /dev/null
+++ b/payloads/libpayload/include/swab.h
@@ -0,0 +1,44 @@
+#ifndef _SWAB_H
+#define _SWAB_H
+
+/*
+ * linux/byteorder/swab.h
+ * Byte-swapping, independently from CPU endianness
+ * swabXX[ps]?(foo)
+ *
+ * Francois-Rene Rideau <fare@tunes.org> 19971205
+ * separated swab functions from cpu_to_XX,
+ * to clean up support for bizarre-endian architectures.
+ *
+ * See asm-i386/byteorder.h and suches for examples of how to provide
+ * architecture-dependent optimized versions
+ *
+ */
+
+/* casts are necessary for constants, because we never know for sure
+ * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
+ */
+#define swab16(x) \
+ ((unsigned short)( \
+ (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
+ (((unsigned short)(x) & (unsigned short)0xff00U) >> 8)))
+
+#define swab32(x) \
+ ((unsigned int)( \
+ (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
+ (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
+ (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
+ (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24)))
+
+#define swab64(x) \
+ ((uint64_t)( \
+ (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
+ (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
+ (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
+ (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
+ (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
+ (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
+ (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
+ (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
+
+#endif /* _SWAB_H */
diff --git a/payloads/libpayload/util/xcompile/xcompile b/payloads/libpayload/util/xcompile/xcompile
index 9cc2d6923e..214e9afe21 100644
--- a/payloads/libpayload/util/xcompile/xcompile
+++ b/payloads/libpayload/util/xcompile/xcompile
@@ -110,11 +110,13 @@ detect_special_flags() {
# testcc "$CC" "$CFLAGS -mcpu=cortex-a9" &&
# CFLAGS="$CFLAGS -mcpu=cortex-a9"
;;
- esac
- case "$architecture" in
arm64-generic )
;;
+ mips )
+ testcc "$CC" "CFLAGS -mxgot" &&
+ CFLAGS="$CFLAGS -mxgot"
+ ;;
esac
}
@@ -140,7 +142,7 @@ touch "$TMPFILE"
trap clean_up EXIT
# Architecture definition
-SUPPORTED_ARCHITECTURE="x86 arm arm64"
+SUPPORTED_ARCHITECTURE="arm arm64 mipsel x86"
# ARM Architecture
TARCH_arm="arm"
@@ -154,18 +156,25 @@ TBFDARCH_arm64="littleaarch64"
TCLIST_arm64="aarch64"
TWIDTH_arm64="64"
+# MIPS Architecture (Little Endian)
+TARCH_mipsel="mipsel"
+TBFDARCH_mipsel="tradlittlemips littlemips"
+TCLIST_mipsel="mipsel"
+TWIDTH_mipsel="32"
+
# X86 Architecture
TARCH_x86="i386"
TBFDARCH_x86="i386"
TCLIST_x86="i386 x86_64"
TWIDTH_x86="32"
+
XGCCPATH=${1:-"`pwd`/../../util/crossgcc/xgcc/bin/"}
# This loops over all supported architectures.
for architecture in $SUPPORTED_ARCHITECTURE; do
GCCPREFIX="invalid"
TARCH="$(eval echo \$TARCH_$architecture)"
- TBFDARCH="$(eval echo \$TBFDARCH_$architecture)"
+ TBFDARCHS="$(eval echo \$TBFDARCH_$architecture)"
TCLIST="$(eval echo \$TCLIST_$architecture)"
TWIDTH="$(eval echo \$TWIDTH_$architecture)"
[ -z "$TARCH" -o -z "$TCLIST" -o -z "$TWIDTH" ] &&
@@ -186,10 +195,13 @@ for architecture in $SUPPORTED_ARCHITECTURE; do
echo "# $architecture TARCH_SEARCH=$search"
# Search toolchain by checking assembler capability.
- for gccprefixes in $search ""; do
- program_exists "${gccprefixes}as" || continue
- testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break
- testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break
+ for TBFDARCH in $TBFDARCHS; do
+ for gccprefixes in $search ""; do
+ program_exists "${gccprefixes}as" || continue
+ testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break
+ testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break
+ done
+ [ "$GCCPREFIX" = "invalid" ] || break
done
if [ "$GCCPREFIX" = "invalid" ]; then