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 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11#include <asm-offsets.h> 12#include <config.h> 13 14 .text 15 .global _start 16_start: 17 /* 18 * reserve registers: 19 * r10: Stores little/big endian offset for vectors 20 * r2: Stores imm opcode 21 * r3: Stores brai opcode 22 */ 23 24 mts rmsr, r0 /* disable cache */ 25 addi r1, r0, CONFIG_SYS_INIT_SP_OFFSET 26 addi r1, r1, -4 /* Decrement SP to top of memory */ 27 28 /* Find-out if u-boot is running on BIG/LITTLE endian platform 29 * There are some steps which is necessary to keep in mind: 30 * 1. Setup offset value to r6 31 * 2. Store word offset value to address 0x0 32 * 3. Load just byte from address 0x0 33 * 4a) LITTLE endian - r10 contains 0x2 because it is the smallest 34 * value that's why is on address 0x0 35 * 4b) BIG endian - r10 contains 0x0 because 0x2 offset is on addr 0x3 36 */ 37 addik r6, r0, 0x2 /* BIG/LITTLE endian offset */ 38 lwi r7, r0, 0x28 39 swi r6, r0, 0x28 /* used first unused MB vector */ 40 lbui r10, r0, 0x28 /* used first unused MB vector */ 41 swi r7, r0, 0x28 42 43 /* add opcode instruction for 32bit jump - 2 instruction imm & brai */ 44 addi r2, r0, 0xb0000000 /* hex b000 opcode imm */ 45 addi r3, r0, 0xb8080000 /* hew b808 opcode brai */ 46 47#ifdef CONFIG_SYS_RESET_ADDRESS 48 /* reset address */ 49 swi r2, r0, 0x0 /* reset address - imm opcode */ 50 swi r3, r0, 0x4 /* reset address - brai opcode */ 51 52 addik r6, r0, CONFIG_SYS_RESET_ADDRESS 53 sw r6, r1, r0 54 lhu r7, r1, r10 55 rsubi r8, r10, 0x2 56 sh r7, r0, r8 57 rsubi r8, r10, 0x6 58 sh r6, r0, r8 59#endif 60 61#ifdef CONFIG_SYS_USR_EXCEP 62 /* user_vector_exception */ 63 swi r2, r0, 0x8 /* user vector exception - imm opcode */ 64 swi r3, r0, 0xC /* user vector exception - brai opcode */ 65 66 addik r6, r0, _exception_handler 67 sw r6, r1, r0 68 /* 69 * BIG ENDIAN memory map for user exception 70 * 0x8: 0xB000XXXX 71 * 0xC: 0xB808XXXX 72 * 73 * then it is necessary to count address for storing the most significant 74 * 16bits from _exception_handler address and copy it to 75 * 0xa address. Big endian use offset in r10=0 that's why is it just 76 * 0xa address. The same is done for the least significant 16 bits 77 * for 0xe address. 78 * 79 * LITTLE ENDIAN memory map for user exception 80 * 0x8: 0xXXXX00B0 81 * 0xC: 0xXXXX08B8 82 * 83 * Offset is for little endian setup to 0x2. rsubi instruction decrease 84 * address value to ensure that points to proper place which is 85 * 0x8 for the most significant 16 bits and 86 * 0xC for the least significant 16 bits 87 */ 88 lhu r7, r1, r10 89 rsubi r8, r10, 0xa 90 sh r7, r0, r8 91 rsubi r8, r10, 0xe 92 sh r6, r0, r8 93#endif 94 95 /* interrupt_handler */ 96 swi r2, r0, 0x10 /* interrupt - imm opcode */ 97 swi r3, r0, 0x14 /* interrupt - brai opcode */ 98 99 addik r6, r0, _interrupt_handler 100 sw r6, r1, r0 101 lhu r7, r1, r10 102 rsubi r8, r10, 0x12 103 sh r7, r0, r8 104 rsubi r8, r10, 0x16 105 sh r6, r0, r8 106 107 /* hardware exception */ 108 swi r2, r0, 0x20 /* hardware exception - imm opcode */ 109 swi r3, r0, 0x24 /* hardware exception - brai opcode */ 110 111 addik r6, r0, _hw_exception_handler 112 sw r6, r1, r0 113 lhu r7, r1, r10 114 rsubi r8, r10, 0x22 115 sh r7, r0, r8 116 rsubi r8, r10, 0x26 117 sh r6, r0, r8 118 119 /* Flush cache before enable cache */ 120 addik r5, r0, 0 121 addik r6, r0, XILINX_DCACHE_BYTE_SIZE 122flush: bralid r15, flush_cache 123 nop 124 125 /* enable instruction and data cache */ 126 mfs r12, rmsr 127 ori r12, r12, 0xa0 128 mts rmsr, r12 129 130clear_bss: 131 /* clear BSS segments */ 132 addi r5, r0, __bss_start 133 addi r4, r0, __bss_end 134 cmp r6, r5, r4 135 beqi r6, 3f 1362: 137 swi r0, r5, 0 /* write zero to loc */ 138 addi r5, r5, 4 /* increment to next loc */ 139 cmp r6, r5, r4 /* check if we have reach the end */ 140 bnei r6, 2b 1413: /* jumping to board_init */ 142 brai board_init_f 1431: bri 1b 144 145/* 146 * Read 16bit little endian 147 */ 148 .text 149 .global in16 150 .ent in16 151 .align 2 152in16: lhu r3, r0, r5 153 bslli r4, r3, 8 154 bsrli r3, r3, 8 155 andi r4, r4, 0xffff 156 or r3, r3, r4 157 rtsd r15, 8 158 sext16 r3, r3 159 .end in16 160 161/* 162 * Write 16bit little endian 163 * first parameter(r5) - address, second(r6) - short value 164 */ 165 .text 166 .global out16 167 .ent out16 168 .align 2 169out16: bslli r3, r6, 8 170 bsrli r6, r6, 8 171 andi r3, r3, 0xffff 172 or r3, r3, r6 173 sh r3, r0, r5 174 rtsd r15, 8 175 or r0, r0, r0 176 .end out16 177