9
0
Fork 0
barebox/arch/mips/include/asm/pbl_macros.h

172 lines
3.9 KiB
C

/*
* Startup Code for MIPS CPU
*
* Copyright (C) 2011, 2012 Antony Pavlov <antonynpavlov@gmail.com>
* ADR macro copyrighted (C) 2009 by Shinya Kuribayashi <skuribay@pobox.com>
*
* 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 <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/asm.h>
#include <asm-generic/memory_layout.h>
#include <generated/compile.h>
#include <generated/utsrelease.h>
.macro pbl_sleep reg count
.set push
.set noreorder
li \reg, \count
254:
bgtz \reg, 254b
addi \reg, -1
.set pop
.endm
.macro pbl_probe_mem ret1 ret2 addr
.set push
.set noreorder
la \ret1, \addr
sw zero, 0(\ret1)
li \ret2, 0x12345678
sw \ret2, 0(\ret1)
lw \ret2, 0(\ret1)
li \ret1, 0x12345678
.set pop
.endm
/*
* 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 255f
nop
255: addiu \rd, ra, \label - 255b # label is assumed to be
move ra, \temp # within pc +/- 32KB
.set pop
.endm
.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
.macro mips_barebox_10h
.set push
.set noreorder
b 1f
nop
.org 0x10
.ascii "barebox " UTS_RELEASE " " UTS_VERSION
.byte 0
.align 4
1:
.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 */