Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8741
-gerrit
commit c36cd4559a2b7341fdb95f283c4f0fea535cfd5f
Author: Ionela Voinescu <ionela.voinescu(a)imgtec.com>
Date: Wed Sep 24 17:05:33 2014 +0100
libpayload: arch/mips: Add basic MIPS architecture support
Add the basic build infrastructure and architectural support
required to build for targets using the MIPS architecture.
This will require the addition of cache maintenance.
BUG=chrome-os-partner:31438
TEST=tested on Pistachio FPGA with Depthcharge as payload;
succesfully executed payload.
BRANCH=none
Change-Id: I75cfd0536860b6d84b53a567940fe6668d9b2cbb
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 758c8cb9a6846e6ca32be409ec5f7a888ac9c888
Original-Signed-off-by: Ionela Voinescu <ionela.voinescu(a)imgtec.com>
Original-Change-Id: I0b9af983bf5032335a519ce2510a0b3aca082edf
Original-Reviewed-on: https://chromium-review.googlesource.com/219740
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
---
payloads/libpayload/Config.in | 12 ++
payloads/libpayload/Makefile | 2 +
payloads/libpayload/Makefile.inc | 1 +
payloads/libpayload/arch/Config.in | 3 +-
payloads/libpayload/arch/mips/Config.in | 29 +++
payloads/libpayload/arch/mips/Makefile.inc | 39 ++++
payloads/libpayload/arch/mips/cache.c | 76 ++++++++
payloads/libpayload/arch/mips/coreboot.c | 55 ++++++
payloads/libpayload/arch/mips/dummy_media.c | 41 +++++
payloads/libpayload/arch/mips/exception.c | 107 +++++++++++
payloads/libpayload/arch/mips/exception_asm.S | 208 ++++++++++++++++++++++
payloads/libpayload/arch/mips/gdb.c | 32 ++++
payloads/libpayload/arch/mips/head.S | 110 ++++++++++++
payloads/libpayload/arch/mips/libpayload.ldscript | 95 ++++++++++
payloads/libpayload/arch/mips/main.c | 62 +++++++
payloads/libpayload/arch/mips/selfboot.c | 36 ++++
payloads/libpayload/arch/mips/string.c | 72 ++++++++
payloads/libpayload/arch/mips/sysinfo.c | 53 ++++++
payloads/libpayload/arch/mips/timer.c | 43 +++++
payloads/libpayload/arch/mips/util.S | 26 +++
payloads/libpayload/arch/mips/virtual.c | 27 +++
payloads/libpayload/bin/lpgcc | 6 +
payloads/libpayload/drivers/Makefile.inc | 2 +
payloads/libpayload/drivers/timer/img_pistachio.c | 36 ++++
payloads/libpayload/include/mips/arch/byteorder.h | 43 +++++
payloads/libpayload/include/mips/arch/cache.h | 98 ++++++++++
payloads/libpayload/include/mips/arch/cpu.h | 85 +++++++++
payloads/libpayload/include/mips/arch/exception.h | 90 ++++++++++
payloads/libpayload/include/mips/arch/io.h | 67 +++++++
payloads/libpayload/include/mips/arch/stdint.h | 95 ++++++++++
payloads/libpayload/include/mips/arch/types.h | 76 ++++++++
payloads/libpayload/include/mips/arch/virtual.h | 31 ++++
payloads/libpayload/include/swab.h | 44 +++++
payloads/libpayload/util/xcompile/xcompile | 28 ++-
34 files changed, 1821 insertions(+), 9 deletions(-)
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index 6c95bfa..7587b6a 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 7d8cad7..1097ce5 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 b97a03e..8bf4ef5 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 3d3d0b5..057fe2b 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 0000000..8c53f73
--- /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 0000000..223b3df
--- /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 0000000..01840fd
--- /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 0000000..fb940c5
--- /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 cb_range *dma = (struct cb_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 0000000..539773d
--- /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 0000000..c910ada
--- /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 0000000..5906d39
--- /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 0000000..cea67ab
--- /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 0000000..f25e77a
--- /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 0000000..a38d3ab
--- /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 0000000..d6f980a
--- /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 0000000..c695831
--- /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 0000000..0f0c7c3
--- /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 0000000..ab1db63
--- /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 0000000..1710a32
--- /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 0000000..09bfddc
--- /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 0000000..9d22649
--- /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 47a34f8..1dbd716 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/drivers/Makefile.inc b/payloads/libpayload/drivers/Makefile.inc
index 0fc2faa..4a569c4 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 0000000..dcfe555
--- /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 0000000..002451a
--- /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 0000000..9485671
--- /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 0000000..952ec7c
--- /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 0000000..9557cb7
--- /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 0000000..d2d9338
--- /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 0000000..c182530
--- /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 0000000..151817e
--- /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 0000000..70aea20
--- /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 0000000..35f5319
--- /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(a)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 how 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 9cc2d69..214e9af 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
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8740
-gerrit
commit 7d782506ae96eab2428a349b31be5e0a92971292
Author: Vadim Bendebury <vbendeb(a)chromium.org>
Date: Thu Nov 27 18:49:33 2014 -0800
libpayload: Do not include gcclib for mips targets
As opposed to other architectures, on MIPS gcc toolchain provided
gcclib is not always adequate, for instance when the library does not
account for the case when data segment is too large to fit into the
64K GOT.
Let's make sure the library is not included when building for MIPS
targets.
BRANCH=none
BUG=chrome-os-partner:31438
TEST=with the rest of patches applied the FPGA board boots all the way
to verifying and loading the kernel from the USB stick.
Change-Id: I710d3c49bdc57877152cf28d5bd8cb4fa4d0b9ad
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: f8d7d84c81af7e3eee1c8f3304c15069e8701cde
Original-Change-Id: I1a26b9e575a20101329359b80dffc236ef7f9e9f
Original-Signed-off-by: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/232231
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
---
payloads/libpayload/bin/lpgcc | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/payloads/libpayload/bin/lpgcc b/payloads/libpayload/bin/lpgcc
index 90a8b99..47a34f8 100755
--- a/payloads/libpayload/bin/lpgcc
+++ b/payloads/libpayload/bin/lpgcc
@@ -164,7 +164,9 @@ if [ $DOLINK -eq 0 ]; then
$DEFAULT_CC $_CFLAGS $CMDLINE
else
- _LIBGCC=`$DEFAULT_CC $_ARCHEXTRA -print-libgcc-file-name`
+ if [ -z "${CONFIG_LP_ARCH_MIPS}" ]; then
+ _LIBGCC=`$DEFAULT_CC $_ARCHEXTRA -print-libgcc-file-name`
+ fi
if [ -f $_ARCHLIBDIR/head.o ]; then
HEAD_O=$_ARCHLIBDIR/head.o
elif [ -f $BASE/../build/head.o ]; then
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8739
-gerrit
commit 6cbd97e4c996a40dee08d1ed7855ad6800e70c8a
Author: Furquan Shaikh <furquan(a)google.com>
Date: Mon Aug 25 15:06:18 2014 -0700
libpayload console: Add check for already existing driver
Add support to check if the driver for console_out or console_in is already
present in the list. If console_init is called twice, then the driver might get
added twice leading to a loop.
BUG=None
BRANCH=None
TEST=With console_init in libpayload and depthcharge both, there are no console
loops seen anymore
Change-Id: I9103230dfe88added28c51bff33ea4fa1ab034c1
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 6931236ba2cfa71849973fe41cc340b7d70656ad
Original-Change-Id: If9a927318b850ec59619d92b1da4dddd0aa09cd1
Original-Signed-off-by: Furquan Shaikh <furquan(a)google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/214072
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
Original-Tested-by: Furquan Shaikh <furquan(a)chromium.org>
Original-Commit-Queue: Furquan Shaikh <furquan(a)chromium.org>
---
payloads/libpayload/libc/console.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/payloads/libpayload/libc/console.c b/payloads/libpayload/libc/console.c
index 827da79..7717daf 100644
--- a/payloads/libpayload/libc/console.c
+++ b/payloads/libpayload/libc/console.c
@@ -35,15 +35,47 @@ struct console_output_driver *console_out;
struct console_input_driver *console_in;
static console_input_type last_getchar_input_type;
+static int output_driver_exists(struct console_output_driver *out)
+{
+ struct console_output_driver *head = console_out;
+
+ while (head) {
+ if (head == out)
+ return 1;
+ head = head->next;
+ }
+
+ return 0;
+}
+
+static int input_driver_exists(struct console_input_driver *in)
+{
+ struct console_input_driver *head = console_in;
+
+ while (head) {
+ if (head == in)
+ return 1;
+ head = head->next;
+ }
+
+ return 0;
+}
+
void console_add_output_driver(struct console_output_driver *out)
{
die_if(!out->putchar && !out->write, "Need at least one output func\n");
+ /* Check if this driver was already added to the console list */
+ if (output_driver_exists(out))
+ return;
out->next = console_out;
console_out = out;
}
void console_add_input_driver(struct console_input_driver *in)
{
+ /* Check if this driver was already added to the console list */
+ if (input_driver_exists(in))
+ return;
in->next = console_in;
console_in = in;
}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8738
-gerrit
commit 5e295fa4484e97984501adc3d75344c1ab3c03a5
Author: Jim Lin <jilin(a)nvidia.com>
Date: Tue Sep 16 16:39:08 2014 +0800
libpayload: EHCI: Make periodic list pointers point to 64-byte aligned
Chapter 3.1 "Periodic Frame List" of EHCI 1.0 specification says
"Frame List Link pointers always reference memory objects that are
32-byte aligned."
jwerner(a)chromium.org suggests setting it to be 64-byte aligned for
consistency with other EHCI queue structures.
BUG=chrome-os-partner:31993
TEST=Tested on nyan platform. Before adding patch, USB keyboard behind
an external hub is not working to switch between "Default Locale" and
"English" (after pressing ESC+REFRESH+POWER on embedded keyboard and
later Left/Right-Arrow key on USB keyboard).
Change-Id: Ie6259f2df20ae2618c2074e831fad087f227091d
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 23fc02e6ba3b17be4eaf18810ec6fc0d9c0e0b9a
Original-Change-Id: If52ddc43ebd5d509c19f104928dced5bd09b1706
Original-Signed-off-by: Jim Lin <jilin(a)nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/218403
Original-Reviewed-by: Tom Warren <twarren(a)nvidia.com>
Original-Reviewed-by: Julius Werner <jwerner(a)chromium.org>
---
payloads/libpayload/drivers/usb/ehci.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/payloads/libpayload/drivers/usb/ehci.c b/payloads/libpayload/drivers/usb/ehci.c
index 1d019b0..c9ababd 100644
--- a/payloads/libpayload/drivers/usb/ehci.c
+++ b/payloads/libpayload/drivers/usb/ehci.c
@@ -634,7 +634,8 @@ static void *ehci_create_intr_queue(
return NULL;
}
- intr_queue_t *const intrq = (intr_queue_t *)malloc(sizeof(intr_queue_t));
+ intr_queue_t *const intrq = (intr_queue_t *)dma_memalign(64,
+ sizeof(intr_queue_t));
/*
* reqcount data chunks
* plus one more spare, which we'll leave out of queue
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8737
-gerrit
commit cf51b27a62205845424bbfb16735879f86fcfb35
Author: Jim Lin <jilin(a)nvidia.com>
Date: Fri Sep 26 19:12:41 2014 +0800
libpayload: EHCI: Support root-hub TT feature
If EHCI controller has TT (Transaction Translator) support in
root-hub, then we need to keep control over this controller when
USB keyboard (low-speed device) is connected to root-hub port.
Need to add "CONFIG_LP_USB_EHCI_HOSTPC_ROOT_HUB_TT=y" to config file
(e.g. payloads/libpayload/configs/config.nyan_big) to support this
feature.
BUG=chrome-os-partner:32355
TEST=Tested on nyan_big platform.
Press ESC+REFRESH+POWER keys on internal keyboard to power up.
Press Left Arrow or Right Arrow on USB keyboard to switch between
"English" and "Default Locale" in coreboot UI. Or unplug and plug
in device and try again.
Root hub <- low-speed USB keyboard
Root hub <- full-speed hub <- low-speed USB keyboard
Root hub <- high-speed hub <- low-speed USB keyboard
Change-Id: Iaa2823f64c8769fc808ee7a316c378f18f004e63
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 4ad57fd673d6dc8814fe99a4ac420566bb17e77b
Original-Change-Id: Id86a289bc587653b85227c1d50f7a4f476f37983
Original-Signed-off-by: Jim Lin <jilin(a)nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/220125
Original-Reviewed-by: Julius Werner <jwerner(a)chromium.org>
---
payloads/libpayload/Config.in | 10 ++++++++++
payloads/libpayload/drivers/usb/ehci.c | 2 +-
payloads/libpayload/drivers/usb/ehci_private.h | 3 +++
payloads/libpayload/drivers/usb/ehci_rh.c | 27 +++++++++++++++++++-------
4 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/payloads/libpayload/Config.in b/payloads/libpayload/Config.in
index 6c95bfa..639ba24 100644
--- a/payloads/libpayload/Config.in
+++ b/payloads/libpayload/Config.in
@@ -476,6 +476,16 @@ config USB_HUB
Select this option if you want to compile in support for USB hubs.
Say Y here unless you know exactly what you are doing.
+config USB_EHCI_HOSTPC_ROOT_HUB_TT
+ bool "Support for USB EHCI ROOT HUB that has TT"
+ depends on USB_EHCI
+ default n
+ help
+ Select this option if USB EHCI root hub supports TT (Transaction
+ Translator).
+ To support this TT feature we read port-speed from non-standard
+ register HOSTPC (offset 84h of Operational Register base).
+
config USB_MSC
bool "Support for USB storage"
depends on USB
diff --git a/payloads/libpayload/drivers/usb/ehci.c b/payloads/libpayload/drivers/usb/ehci.c
index b83712c..1d019b0 100644
--- a/payloads/libpayload/drivers/usb/ehci.c
+++ b/payloads/libpayload/drivers/usb/ehci.c
@@ -202,7 +202,7 @@ static int closest_usb2_hub(const usbdev_t *dev, int *const addr, int *const por
const usbdev_t *usb1dev;
do {
usb1dev = dev;
- if ((dev->hub > 0) && (dev->hub < 128))
+ if ((dev->hub >= 0) && (dev->hub < 128))
dev = dev->controller->devices[dev->hub];
else
dev = NULL;
diff --git a/payloads/libpayload/drivers/usb/ehci_private.h b/payloads/libpayload/drivers/usb/ehci_private.h
index c9fa6e0..8519c0f 100644
--- a/payloads/libpayload/drivers/usb/ehci_private.h
+++ b/payloads/libpayload/drivers/usb/ehci_private.h
@@ -80,6 +80,9 @@ typedef volatile struct {
u8 res1[0x40-0x1c];
u32 configflag;
portsc_t portsc[0];
+ u8 res2[0x40];
+ u32 hostpc;
+ /* hostpc register is used for CONFIG_LP_USB_EHCI_HOSTPC_ROOT_HUB_TT */
} __attribute__ ((packed)) hc_op_t;
typedef volatile struct {
diff --git a/payloads/libpayload/drivers/usb/ehci_rh.c b/payloads/libpayload/drivers/usb/ehci_rh.c
index 6109505..da8d8af 100644
--- a/payloads/libpayload/drivers/usb/ehci_rh.c
+++ b/payloads/libpayload/drivers/usb/ehci_rh.c
@@ -30,6 +30,7 @@
//#define USB_DEBUG
#include <libpayload.h>
+#include <kconfig.h>
#include "ehci.h"
#include "ehci_private.h"
@@ -91,6 +92,8 @@ ehci_rh_hand_over_port (usbdev_t *dev, int port)
static void
ehci_rh_scanport (usbdev_t *dev, int port)
{
+ usb_speed port_speed;
+
if (RH_INST(dev)->devices[port]!=-1) {
usb_debug("Unregister device at port %x\n", port+1);
usb_detach_device(dev->controller, RH_INST(dev)->devices[port]);
@@ -99,7 +102,9 @@ ehci_rh_scanport (usbdev_t *dev, int port)
/* device connected, handle */
if (RH_INST(dev)->ports[port] & P_CURR_CONN_STATUS) {
mdelay(100); // usb20 spec 9.1.2
- if ((RH_INST(dev)->ports[port] & P_LINE_STATUS) == P_LINE_STATUS_LOWSPEED) {
+ if (!IS_ENABLED(CONFIG_LP_USB_EHCI_HOSTPC_ROOT_HUB_TT) &&
+ (RH_INST(dev)->ports[port] & P_LINE_STATUS) ==
+ P_LINE_STATUS_LOWSPEED) {
ehci_rh_hand_over_port(dev, port);
return;
}
@@ -133,8 +138,16 @@ ehci_rh_scanport (usbdev_t *dev, int port)
ehci_rh_hand_over_port(dev, port);
return;
}
- usb_debug("port %x hosts a USB2 device\n", port+1);
- RH_INST(dev)->devices[port] = usb_attach_device(dev->controller, dev->address, port, 2);
+ if (IS_ENABLED(CONFIG_LP_USB_EHCI_HOSTPC_ROOT_HUB_TT)) {
+ port_speed = (usb_speed)
+ ((EHCI_INST(dev->controller)->operation->hostpc
+ >> 25) & 0x03);
+ } else {
+ usb_debug("port %x hosts a USB2 device\n", port+1);
+ port_speed = HIGH_SPEED;
+ }
+ RH_INST(dev)->devices[port] = usb_attach_device(dev->controller
+ , dev->address, port, port_speed);
}
/* RW/C register, so clear it by writing 1 */
RH_INST(dev)->ports[port] |= P_CONN_STATUS_CHANGE;
@@ -186,12 +199,12 @@ ehci_rh_init (usbdev_t *dev)
}
mdelay(20); // ehci spec 2.3.9
+ dev->speed = HIGH_SPEED;
+ dev->address = 0;
+ dev->hub = -1;
+ dev->port = -1;
for (i=0; i < RH_INST(dev)->n_ports; i++) {
RH_INST(dev)->devices[i] = -1;
ehci_rh_scanport(dev, i);
}
-
- dev->address = 0;
- dev->hub = -1;
- dev->port = -1;
}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8736
-gerrit
commit 0ad8a68910c8f3a3b115c9f85fd069695faf6174
Author: Sourabh Banerjee <sbanerje(a)codeaurora.org>
Date: Wed Sep 24 16:14:45 2014 +0530
libpayload: usb: xhci: set ENT flag in last Normal TRB
If a TD is comprised of one or more Normal TRBs and terminated with an
Event Data TRB, then the transition to the Idle state (and associated
Stream state save) could occur after all the data for the TD has been
moved (e.g. after Transfer Event TRBs have been executed), but before the
Event Data TRB is executed. Under these conditions, the execution of the
Event Data TRB is necessary to complete the TD, otherwise it does not
occur until the nexttime the Stream is scheduled. This could lead to the
lock up.
The Evaluate Next TRB(ENT) flag provides a means of forcing the execution
of a terminating Event Data TRB. Setting ENT flag in last Normal TRB makes
the xHC to evaluate the Even Data TRB.
BUG=chrome-os-partner:29375
TEST=Verified kernel boot-up on storm from previously failing USB stick.
USB stick model: Sandisk Ultra USB 3.0 Pen Drive 32 GB
Strontium Jet USB 3.0 Pen Drive(32 GB)
Change-Id: I092e2109c55c2274239c493cb67b47d730304ed2
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 7eefb3b2858c841165ae839d349d2a0be50fbcc8
Original-Change-Id: I4e123577ec5a5996d87d2fc52cb6cf5c571c9fae
Original-Signed-off-by: Sourabh Banerjee <sbanerje(a)codeaurora.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/220123
Original-Reviewed-by: Julius Werner <jwerner(a)chromium.org>
Original-Commit-Queue: Vadim Bendebury <vbendeb(a)chromium.org>
Original-Tested-by: Vadim Bendebury <vbendeb(a)chromium.org>
---
payloads/libpayload/drivers/usb/xhci.c | 8 ++++++++
payloads/libpayload/drivers/usb/xhci_private.h | 3 +++
2 files changed, 11 insertions(+)
diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c
index 33009bc..4eea09e 100644
--- a/payloads/libpayload/drivers/usb/xhci.c
+++ b/payloads/libpayload/drivers/usb/xhci.c
@@ -551,6 +551,14 @@ xhci_enqueue_td(transfer_ring_t *const tr, const int ep, const size_t mps,
} else {
TRB_SET(TT, trb, TRB_NORMAL);
}
+ /*
+ * This is a workaround for Synopsys DWC3. If the ENT flag is
+ * not set for the Normal and Data Stage TRBs. We get Event TRB
+ * with length 0x20d from the controller when We enqueue a TRB
+ * for the IN endpoint with length 0x200.
+ */
+ if (!length)
+ TRB_SET(ENT, trb, 1);
xhci_enqueue_trb(tr);
diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h
index 43800d8..3861858 100644
--- a/payloads/libpayload/drivers/usb/xhci_private.h
+++ b/payloads/libpayload/drivers/usb/xhci_private.h
@@ -93,6 +93,9 @@ enum { TRB_DIR_OUT = 0, TRB_DIR_IN = 1 };
#define TRB_TC_FIELD control /* TC - Toggle Cycle */
#define TRB_TC_START 1
#define TRB_TC_LEN 1
+#define TRB_ENT_FIELD control /* ENT - Evaluate Next TRB */
+#define TRB_ENT_START 1
+#define TRB_ENT_LEN 1
#define TRB_ISP_FIELD control /* ISP - Interrupt-on Short Packet */
#define TRB_ISP_START 2
#define TRB_ISP_LEN 1
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8735
-gerrit
commit e7b585e051ee5f05d0c54c8940475aeb566a367e
Author: Patrick Georgi <pgeorgi(a)chromium.org>
Date: Mon Nov 10 16:50:21 2014 +0100
libpayload/usb: wait a millisecond to work around device bugs
Some USB sticks seem to send a NAK at a place where they mustn't
by spec, leading to a controller side error condition.
To avoid it, wait a millisecond which is enough to get past the
NAK condition. That delay only happens on device discovery so it
won't affect boot time by more than 1ms per device.
BUG=chromium:414959
BRANCH=none
TEST=depthcharge recognizes a Lexar 16GB USB stick after applying
this change.
Change-Id: I0e385702a5259b16fda0a253fc121d8f66e6705c
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 10bbfda8395af009e7f910cc503f50c2ad969ae8
Original-Change-Id: I6dd5ca34e9f3767003ccb0ca9daaf16116f4a2df
Original-Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/228791
Original-Reviewed-by: Julius Werner <jwerner(a)chromium.org>
Original-Reviewed-by: Sheng-liang Song <ssl(a)chromium.org>
---
payloads/libpayload/drivers/usb/usb.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/payloads/libpayload/drivers/usb/usb.c b/payloads/libpayload/drivers/usb/usb.c
index 53006ff..54b113c 100644
--- a/payloads/libpayload/drivers/usb/usb.c
+++ b/payloads/libpayload/drivers/usb/usb.c
@@ -393,6 +393,9 @@ set_address (hci_t *controller, usb_speed speed, int hubport, int hubaddr)
usb_detach_device (controller, dev->address);
return -1;
}
+ /* workaround for some USB devices: wait until they're ready, or
+ * they send a NAK when they're not allowed to do. 1ms is enough */
+ mdelay(1);
dev->configuration = malloc(buf[1]);
if (!dev->configuration) {
usb_debug ("could not allocate %d bytes for DT_CFG\n", buf[1]);
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8734
-gerrit
commit 8d9b6e94f8b0574cb8b5683dbd9986d4c4bf6913
Author: Lee Leahy <leroy.p.leahy(a)intel.com>
Date: Wed Dec 17 13:05:26 2014 -0800
libpayload: PCI bus scan - Eliminate endless loop
Don't attempt to scan the PCI bus if the bridge is disabled. When
the PCI bridge is not setup and enabled, it is possible for the
secondary bus register to contain the value zero (0). In this case
the usb_scan_pci_bus routine gets into an infinite recursive loop
which ends only when the heap or stack is exhausted. This patch
verifies that the PCI bridge is enabled by verifying that it is
enabled for either memory or I/O operations. When enabled, the
secondary bus is scanned.
BRANCH=none
BUG=None
TEST=Build and run on Samus
Change-Id: I6826dc1d73b7c24729de5ac7c4d3534922ca73c5
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 63d04b47934761351b54c847a2692bdef81ce54f
Original-Change-Id: I855240c52fa3eba841e6754816ebbcb824abc4cd
Original-Signed-off-by: Lee Leahy <Leroy.P.Leahy(a)intel.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/236382
Original-Commit-Queue: Leroy P Leahy <leroy.p.leahy(a)intel.com>
Original-Tested-by: Leroy P Leahy <leroy.p.leahy(a)intel.com>
Original-Reviewed-by: Giri P Mudusuru <giri.p.mudusuru(a)intel.com>
Original-Reviewed-by: Duncan Laurie <dlaurie(a)chromium.org>
---
payloads/libpayload/drivers/usb/usbinit.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/payloads/libpayload/drivers/usb/usbinit.c b/payloads/libpayload/drivers/usb/usbinit.c
index 6fb7d4b..4225c3f 100644
--- a/payloads/libpayload/drivers/usb/usbinit.c
+++ b/payloads/libpayload/drivers/usb/usbinit.c
@@ -146,9 +146,13 @@ static void usb_scan_pci_bus(int bus)
header_type = pci_read_config8(pci_device, REG_HEADER_TYPE);
/* If this is a bridge, scan the other side. */
if ((header_type & ~HEADER_TYPE_MULTIFUNCTION) ==
- HEADER_TYPE_BRIDGE)
- usb_scan_pci_bus(pci_read_config8(pci_device,
- REG_SECONDARY_BUS));
+ HEADER_TYPE_BRIDGE) {
+ /* Verify that the bridge is enabled */
+ if ((pci_read_config16(pci_device, REG_COMMAND)
+ & 3) != 0)
+ usb_scan_pci_bus(pci_read_config8(
+ pci_device, REG_SECONDARY_BUS));
+ }
else
usb_controller_initialize(bus, dev, func);
}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8733
-gerrit
commit 2da339fb48fcaea86cc2544818d8426538443ec0
Author: Dan Ehrenberg <dehrenberg(a)chromium.org>
Date: Fri Nov 21 15:50:27 2014 -0800
libpayload: UTF-16LE to ASCII conversion
This patch adds a simple function to convert a string in UTF-16LE
to ASCII.
TEST=Ran against a string found in a GPT with the intended outcome
BRANCH=none
BUG=none
Change-Id: I94ec0a32f5712259d3d0caec2233c992330228e3
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 1104db8328a197c7ccf6959a238277f416a2113a
Original-Signed-off-by: Dan Ehrenberg <dehrenberg(a)chromium.org>
Original-Change-Id: I50ca5bfdfbef9e084321b2beb1b8d4194ca5af9c
Original-Reviewed-on: https://chromium-review.googlesource.com/231456
Original-Reviewed-by: Julius Werner <jwerner(a)chromium.org>
---
payloads/libpayload/include/string.h | 7 +++++++
payloads/libpayload/libc/string.c | 19 +++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/payloads/libpayload/include/string.h b/payloads/libpayload/include/string.h
index 952261f..ca5d513 100644
--- a/payloads/libpayload/include/string.h
+++ b/payloads/libpayload/include/string.h
@@ -69,6 +69,13 @@ char *strerror(int errnum);
/** @} */
/**
+ * @defgroup string Unicode functions
+ * @{
+ */
+char *utf16le_to_ascii(uint16_t *utf16_string, int maxlen);
+/** @} */
+
+/**
* @defgroup string OpenBSD based safe string functions
* @{
*/
diff --git a/payloads/libpayload/libc/string.c b/payloads/libpayload/libc/string.c
index 71dd1a6..549fe0c 100644
--- a/payloads/libpayload/libc/string.c
+++ b/payloads/libpayload/libc/string.c
@@ -653,3 +653,22 @@ char *strerror(int errnum)
snprintf(errstr, sizeof(errstr), "Unknown error %d", errnum);
return errstr;
}
+
+/*
+ * Simple routine to convert UTF-16 to ASCII, giving up with ? if too high.
+ * A single code point may convert to ?? if in not in the BMP.
+ * @param utf16_string A string encoded in UTF-16LE
+ * @param maxlen Maximum possible length of the string in code points
+ * @return Newly allocated ASCII string
+ */
+char *utf16le_to_ascii(uint16_t *utf16_string, int maxlen)
+{
+ char *ascii_string = xmalloc(maxlen + 1); /* +1 for trailing \0 */
+ ascii_string[maxlen] = '\0';
+ int i;
+ for (i = 0; i < maxlen; i++) {
+ uint16_t wchar = utf16_string[i];
+ ascii_string[i] = wchar > 0x7f ? '?' : (char)wchar;
+ }
+ return ascii_string;
+}
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8732
-gerrit
commit fdee0e5718c83a9e2569ecc3bf7cac6130d82a18
Author: Furquan Shaikh <furquan(a)google.com>
Date: Sun Aug 24 23:07:43 2014 -0700
libpayload EHCI: Add memory barrier to EHCI driver
EHCI driver accesses mmio space using regular struct pointers. In order to avoid
any CPU re-ordering, memory barrier is required in async_set_schedule,
especially for arm64. Without the memory barrier, there seems to be re-ordering
taking place which leads to USB errors with some flash drives as well as
transfer errors in netboot.
BUG=chrome-os-partner:31533
BRANCH=None
TEST=With the memory barrier introduced, netboot for ryu completes transfer
without any error and finishes within 6-7 seconds.
Change-Id: Ib6d29dc79fd5722c27284478e8da316929e86bff
Signed-off-by: Patrick Georgi <pgeorgi(a)chromium.org>
Original-Commit-Id: 561bdd746c4d4446ce0a6d21337d354625d85ddc
Original-Change-Id: Ic05d47422312a1cddbebe3180f4f159853604440
Original-Signed-off-by: Furquan Shaikh <furquan(a)google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/213917
Original-Reviewed-by: Aaron Durbin <adurbin(a)chromium.org>
Original-Tested-by: Furquan Shaikh <furquan(a)chromium.org>
Original-Commit-Queue: Furquan Shaikh <furquan(a)chromium.org>
---
payloads/libpayload/drivers/usb/ehci.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/payloads/libpayload/drivers/usb/ehci.c b/payloads/libpayload/drivers/usb/ehci.c
index b83712c..0ca6b09 100644
--- a/payloads/libpayload/drivers/usb/ehci.c
+++ b/payloads/libpayload/drivers/usb/ehci.c
@@ -30,6 +30,7 @@
//#define USB_DEBUG
#include <libpayload.h>
+#include <arch/barrier.h>
#include <arch/cache.h>
#include "ehci.h"
#include "ehci_private.h"
@@ -317,6 +318,14 @@ static int wait_for_tds(qtd_t *head)
static int ehci_set_async_schedule(ehci_t *ehcic, int enable)
{
+
+ /* Memory barrier to ensure that all memory accesses before we set the
+ * async schedule are complete. It was observed especially in the case of
+ * arm64, that netboot and usb stuff resulted in lot of errors possibly
+ * due to CPU reordering. Hence, enforcing strict CPU ordering.
+ */
+ mb();
+
/* Set async schedule status. */
if (enable)
ehcic->operation->usbcmd |= HC_OP_ASYNC_SCHED_EN;