From f369f64ed1b29451c82c69c698da60ed8a8eb28f Mon Sep 17 00:00:00 2001 From: Antony Pavlov Date: Wed, 12 Dec 2012 23:24:46 +0400 Subject: MIPS: add pre-bootloader (pbl) image support This patch is based on ARM pbl support and allows creating a pre-bootloader binary for compressed image. For different MIPS SoCs (or even for different boards based on the same SoC) the operations carried on in start-pbl.S can be very different. The additional constraints can be imposed on the size of the boot code or the special magic labels in the beginning of the boot code; In some cases it could be necessary to show CPU is alive as early as possible (transmit a char via UART or blink a LED). So the demands for pbl start operation can be very different. E.g. malta board store boot code at the NOR flash mapped to the MIPS power-on address (0xbfc00000); it is the most simple case: we need just copy pbl image from direct-mapped flash to RAM and jump there. The XBurst-powered boards store boot code in the beginning of a NAND flash or in the beginning of SD/MMC card. In this case we must use simple and short NAND or SD/MMC access routines to copy pbl image to RAM. To meet so different demands a simple technique is selected: * MIPS pbl entry point located in file arch/mips/boot/start-pbl.S. * MIPS pbl code (see start-pbl.S) assumes that every pbl-enabled board has a arch/mips/boards//include/board/board_pbl_start.h header file. This file must contain definition of the board_pbl_start macro. This macro is used as start of pbl image; * the most popular asm routines (stack setup, relocation to link address, NS16550 initialization (WIP) and so on) are containt in the arch/mips/include/asm/pbl_macros.h header file. So board pbl macro can use it if necessary. It is possible to create similar headers with macros for each specific SoC; so even if we have many different boards based on the same SoC the board_pbl_start macro for every board can be short and clear. * after board-specific initialization the stack pointer is initialized and pbl C code is started. Signed-off-by: Antony Pavlov Signed-off-by: Sascha Hauer --- arch/mips/include/asm/pbl_macros.h | 135 +++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 arch/mips/include/asm/pbl_macros.h (limited to 'arch/mips/include') diff --git a/arch/mips/include/asm/pbl_macros.h b/arch/mips/include/asm/pbl_macros.h new file mode 100644 index 0000000000..c32a2296a0 --- /dev/null +++ b/arch/mips/include/asm/pbl_macros.h @@ -0,0 +1,135 @@ +/* + * Startup Code for MIPS CPU + * + * Copyright (C) 2011, 2012 Antony Pavlov + * ADR macro copyrighted (C) 2009 by Shinya Kuribayashi + * + * This file is part of barebox. + * See file CREDITS for list of people who contributed to this project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 __ASM_PBL_MACROS_H +#define __ASM_PBL_MACROS_H + +#include +#include +#include +#include +#include +#include + + /* + * ADR macro instruction (inspired by ARM) + * + * ARM architecture doesn't have PC-relative jump instruction + * like MIPS' B/BAL insns. When ARM makes PC-relative jumps, + * it uses ADR insn. ADR is used to get a destination address + * of 'label' against current PC. With this, ARM can safely + * make PC-relative jumps. + */ + .macro ADR rd label temp + .set push + .set noreorder + move \temp, ra # preserve ra beforehand + bal _pc + nop +_pc: addiu \rd, ra, \label - _pc # label is assumed to be + move ra, \temp # within pc +/- 32KB + .set pop + .endm + +#define LONGSIZE 4 + + .macro copy_to_link_location start_addr + .set push + .set noreorder + + /* copy barebox to link location */ + ADR a0, \start_addr, t1 /* a0 <- pc-relative + position of start_addr */ + + la a1, \start_addr /* a1 <- link (RAM) start_addr address */ + + beq a0, a1, copy_loop_exit + nop + + la t0, \start_addr + la t1, __bss_start + subu t2, t1, t0 /* t2 <- size of pbl */ + addu a2, a0, t2 /* a2 <- source end address */ + +copy_loop: + /* copy from source address [a0] */ + lw t4, LONGSIZE * 0(a0) + lw t5, LONGSIZE * 1(a0) + lw t6, LONGSIZE * 2(a0) + lw t7, LONGSIZE * 3(a0) + /* copy to target address [a1] */ + sw t4, LONGSIZE * 0(a1) + sw t5, LONGSIZE * 1(a1) + sw t6, LONGSIZE * 2(a1) + sw t7, LONGSIZE * 3(a1) + addi a0, LONGSIZE * 4 + subu t3, a0, a2 + blez t3, copy_loop + addi a1, LONGSIZE * 4 + +copy_loop_exit: + + .set pop + .endm + + .macro mips_disable_interrupts + .set push + .set noreorder + mfc0 k0, CP0_STATUS + li k1, ~ST0_IE + and k0, k1 + mtc0 k0, CP0_STATUS + .set pop + .endm + + /* + * Dominic Sweetman, See MIPS Run, Morgan Kaufmann, 2nd edition, 2006 + * + * 11.2.2 Stack Argument Structure in o32 + * ... + * At the point where a function is called, sp must be + * eight-byte-aligned, matching the alignment of the largest + * basic types -- a long long integer or a floating-point double. + * The eight-byte alignment is not required by 32-bit MIPS integer + * hardware, but it's essential for compatibility with CPUs with + * 64-bit registers, and thus part of the rules. Subroutines fit + * in with this by always adjusting the stack pointer by a multiple + * of eight. + * ... + * SGI's n32 and n64 standards call for the stack to be maintained + * with 16-byte alignment. + * + */ + +#if (STACK_BASE + STACK_SIZE) % 16 != 0 +#error stack pointer must be 16-byte-aligned +#endif + + .macro stack_setup + .set push + .set noreorder + + /* set stack pointer; reserve four 32-bit argument slots */ + la sp, STACK_BASE + STACK_SIZE - 16 + + .set pop + .endm + +#endif /* __ASM_PBL_MACROS_H */ -- cgit v1.2.3