diff options
Diffstat (limited to 'payloads/libpayload/arch')
-rw-r--r-- | payloads/libpayload/arch/Config.in | 3 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/Config.in | 29 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/Makefile.inc | 39 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/cache.c | 76 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/coreboot.c | 55 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/dummy_media.c | 41 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/exception.c | 107 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/exception_asm.S | 208 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/gdb.c | 32 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/head.S | 110 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/libpayload.ldscript | 95 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/main.c | 62 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/selfboot.c | 36 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/string.c | 72 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/sysinfo.c | 53 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/timer.c | 43 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/util.S | 26 | ||||
-rw-r--r-- | payloads/libpayload/arch/mips/virtual.c | 27 |
18 files changed, 1113 insertions, 1 deletions
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; +}; |