uboot/arch/microblaze/cpu/start.S
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007 Michal Simek
   3 * (C) Copyright 2004 Atmark Techno, Inc.
   4 *
   5 * Michal  SIMEK <monstr@monstr.eu>
   6 * Yasushi SHOJI <yashi@atmark-techno.com>
   7 *
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27#include <asm-offsets.h>
  28#include <config.h>
  29
  30        .text
  31        .global _start
  32_start:
  33        /*
  34         * reserve registers:
  35         * r10: Stores little/big endian offset for vectors
  36         * r2: Stores imm opcode
  37         * r3: Stores brai opcode
  38         */
  39
  40        mts     rmsr, r0        /* disable cache */
  41        addi    r1, r0, CONFIG_SYS_INIT_SP_OFFSET
  42        addi    r1, r1, -4      /* Decrement SP to top of memory */
  43
  44        /* Find-out if u-boot is running on BIG/LITTLE endian platform
  45         * There are some steps which is necessary to keep in mind:
  46         * 1. Setup offset value to r6
  47         * 2. Store word offset value to address 0x0
  48         * 3. Load just byte from address 0x0
  49         * 4a) LITTLE endian - r10 contains 0x2 because it is the smallest
  50         *     value that's why is on address 0x0
  51         * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3
  52         */
  53        addik   r6, r0, 0x2 /* BIG/LITTLE endian offset */
  54        lwi     r7, r0, 0x28
  55        swi     r6, r0, 0x28 /* used first unused MB vector */
  56        lbui    r10, r0, 0x28 /* used first unused MB vector */
  57        swi     r7, r0, 0x28
  58
  59        /* add opcode instruction for 32bit jump - 2 instruction imm & brai */
  60        addi    r2, r0, 0xb0000000      /* hex b000 opcode imm */
  61        addi    r3, r0, 0xb8080000      /* hew b808 opcode brai */
  62
  63#ifdef CONFIG_SYS_RESET_ADDRESS
  64        /* reset address */
  65        swi     r2, r0, 0x0     /* reset address - imm opcode */
  66        swi     r3, r0, 0x4     /* reset address - brai opcode */
  67
  68        addik   r6, r0, CONFIG_SYS_RESET_ADDRESS
  69        sw      r6, r1, r0
  70        lhu     r7, r1, r10
  71        rsubi   r8, r10, 0x2
  72        sh      r7, r0, r8
  73        rsubi   r8, r10, 0x6
  74        sh      r6, r0, r8
  75#endif
  76
  77#ifdef CONFIG_SYS_USR_EXCEP
  78        /* user_vector_exception */
  79        swi     r2, r0, 0x8     /* user vector exception - imm opcode */
  80        swi     r3, r0, 0xC     /* user vector exception - brai opcode */
  81
  82        addik   r6, r0, _exception_handler
  83        sw      r6, r1, r0
  84        /*
  85         * BIG ENDIAN memory map for user exception
  86         * 0x8: 0xB000XXXX
  87         * 0xC: 0xB808XXXX
  88         *
  89         * then it is necessary to count address for storing the most significant
  90         * 16bits from _exception_handler address and copy it to
  91         * 0xa address. Big endian use offset in r10=0 that's why is it just
  92         * 0xa address. The same is done for the least significant 16 bits
  93         * for 0xe address.
  94         *
  95         * LITTLE ENDIAN memory map for user exception
  96         * 0x8: 0xXXXX00B0
  97         * 0xC: 0xXXXX08B8
  98         *
  99         * Offset is for little endian setup to 0x2. rsubi instruction decrease
 100         * address value to ensure that points to proper place which is
 101         * 0x8 for the most significant 16 bits and
 102         * 0xC for the least significant 16 bits
 103         */
 104        lhu     r7, r1, r10
 105        rsubi   r8, r10, 0xa
 106        sh      r7, r0, r8
 107        rsubi   r8, r10, 0xe
 108        sh      r6, r0, r8
 109#endif
 110
 111#ifdef CONFIG_SYS_INTC_0
 112        /* interrupt_handler */
 113        swi     r2, r0, 0x10    /* interrupt - imm opcode */
 114        swi     r3, r0, 0x14    /* interrupt - brai opcode */
 115
 116        addik   r6, r0, _interrupt_handler
 117        sw      r6, r1, r0
 118        lhu     r7, r1, r10
 119        rsubi   r8, r10, 0x12
 120        sh      r7, r0, r8
 121        rsubi   r8, r10, 0x16
 122        sh      r6, r0, r8
 123#endif
 124
 125        /* hardware exception */
 126        swi     r2, r0, 0x20    /* hardware exception - imm opcode */
 127        swi     r3, r0, 0x24    /* hardware exception - brai opcode */
 128
 129        addik   r6, r0, _hw_exception_handler
 130        sw      r6, r1, r0
 131        lhu     r7, r1, r10
 132        rsubi   r8, r10, 0x22
 133        sh      r7, r0, r8
 134        rsubi   r8, r10, 0x26
 135        sh      r6, r0, r8
 136
 137        /* enable instruction and data cache */
 138        mfs     r12, rmsr
 139        ori     r12, r12, 0xa0
 140        mts     rmsr, r12
 141
 142clear_bss:
 143        /* clear BSS segments */
 144        addi    r5, r0, __bss_start
 145        addi    r4, r0, __bss_end
 146        cmp     r6, r5, r4
 147        beqi    r6, 3f
 1482:
 149        swi     r0, r5, 0 /* write zero to loc */
 150        addi    r5, r5, 4 /* increment to next loc */
 151        cmp     r6, r5, r4 /* check if we have reach the end */
 152        bnei    r6, 2b
 1533:      /* jumping to board_init */
 154        brai    board_init
 1551:      bri     1b
 156
 157/*
 158 * Read 16bit little endian
 159 */
 160        .text
 161        .global in16
 162        .ent    in16
 163        .align  2
 164in16:   lhu     r3, r0, r5
 165        bslli   r4, r3, 8
 166        bsrli   r3, r3, 8
 167        andi    r4, r4, 0xffff
 168        or      r3, r3, r4
 169        rtsd    r15, 8
 170        sext16  r3, r3
 171        .end    in16
 172
 173/*
 174 * Write 16bit little endian
 175 * first parameter(r5) - address, second(r6) - short value
 176 */
 177        .text
 178        .global out16
 179        .ent    out16
 180        .align  2
 181out16:  bslli   r3, r6, 8
 182        bsrli   r6, r6, 8
 183        andi    r3, r3, 0xffff
 184        or      r3, r3, r6
 185        sh      r3, r0, r5
 186        rtsd    r15, 8
 187        or      r0, r0, r0
 188        .end    out16
 189