diff options
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 |