Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | /* * Copyright (C) 2005-2008 Atmel Corporation * * 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 as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * 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., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <config.h> #include <asm/ptrace.h> #include <asm/sysreg.h> #define SYSREG_MMUCR_I_OFFSET 2 #define SYSREG_MMUCR_S_OFFSET 4 #define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0)) #define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE) \ | SYSREG_BIT(FE) | SYSREG_BIT(RE) \ | SYSREG_BIT(IBE) | SYSREG_BIT(IEE)) /* * To save some space, we use the same entry point for * exceptions and reset. This avoids lots of alignment padding * since the reset vector is always suitably aligned. */ .section .exception.text, "ax", @progbits .global _start .global _evba .type _start, @function .type _evba, @function _start: .size _start, 0 _evba: .org 0x00 rjmp unknown_exception /* Unrecoverable exception */ .org 0x04 rjmp unknown_exception /* TLB multiple hit */ .org 0x08 rjmp unknown_exception /* Bus error data fetch */ .org 0x0c rjmp unknown_exception /* Bus error instruction fetch */ .org 0x10 rjmp unknown_exception /* NMI */ .org 0x14 rjmp unknown_exception /* Instruction address */ .org 0x18 rjmp unknown_exception /* ITLB protection */ .org 0x1c rjmp unknown_exception /* Breakpoint */ .org 0x20 rjmp unknown_exception /* Illegal opcode */ .org 0x24 rjmp unknown_exception /* Unimplemented instruction */ .org 0x28 rjmp unknown_exception /* Privilege violation */ .org 0x2c rjmp unknown_exception /* Floating-point */ .org 0x30 rjmp unknown_exception /* Coprocessor absent */ .org 0x34 rjmp unknown_exception /* Data Address (read) */ .org 0x38 rjmp unknown_exception /* Data Address (write) */ .org 0x3c rjmp unknown_exception /* DTLB Protection (read) */ .org 0x40 rjmp unknown_exception /* DTLB Protection (write) */ .org 0x44 rjmp unknown_exception /* DTLB Modified */ .org 0x50 rjmp unknown_exception /* ITLB Miss */ .org 0x60 rjmp unknown_exception /* DTLB Miss (read) */ .org 0x70 rjmp unknown_exception /* DTLB Miss (write) */ .size _evba, . - _evba .align 2 .type unknown_exception, @function unknown_exception: /* Figure out whether we're handling an exception (Exception * mode) or just booting (Supervisor mode). */ csrfcz SYSREG_M1_OFFSET brcc at32ap_cpu_bootstrap /* This is an exception. Complain. */ pushm r0-r12 sub r8, sp, REG_R12 - REG_R0 - 4 mov r9, lr mfsr r10, SYSREG_RAR_EX mfsr r11, SYSREG_RSR_EX pushm r8-r11 mfsr r12, SYSREG_ECR mov r11, sp rcall do_unknown_exception 1: rjmp 1b /* The COUNT/COMPARE timer interrupt handler */ .global timer_interrupt_handler .type timer_interrupt_handler,@function .align 2 timer_interrupt_handler: /* * Increment timer_overflow and re-write COMPARE with 0xffffffff. * * We're running at interrupt level 3, so we don't need to save * r8-r12 or lr to the stack. */ lda.w r8, timer_overflow ld.w r9, r8[0] mov r10, -1 mtsr SYSREG_COMPARE, r10 sub r9, -1 st.w r8[0], r9 rete /* * CPU bootstrap after reset is handled here. SoC code may * override this in case they need to initialize oscillators, * etc. */ .section .text.at32ap_cpu_bootstrap, "ax", @progbits .global at32ap_cpu_bootstrap .weak at32ap_cpu_bootstrap .type at32ap_cpu_bootstrap, @function .align 2 at32ap_cpu_bootstrap: /* Reset the Status Register */ mov r0, lo(SR_INIT) orh r0, hi(SR_INIT) mtsr SYSREG_SR, r0 /* Reset CPUCR and invalidate the BTB */ mov r2, CPUCR_INIT mtsr SYSREG_CPUCR, r2 /* Flush the caches */ mov r1, 0 cache r1[4], 8 cache r1[0], 0 sync 0 /* Reset the MMU to default settings */ mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I) mtsr SYSREG_MMUCR, r0 /* Internal RAM should not need any initialization. We might have to initialize external RAM here if the part doesn't have internal RAM (or we may use the data cache) */ /* Jump to cacheable segment */ lddpc pc, 1f .align 2 1: .long at32ap_low_level_init .size _start, . - _start /* Common CPU bootstrap code after oscillator/cache/etc. init */ .section .text.avr32ap_low_level_init, "ax", @progbits .global at32ap_low_level_init .type at32ap_low_level_init, @function .align 2 at32ap_low_level_init: lddpc sp, sp_init /* Initialize the GOT pointer */ lddpc r6, got_init 3: rsub r6, pc /* Let's go */ rjmp board_init_f .align 2 .type sp_init,@object sp_init: .long CFG_INIT_SP_ADDR got_init: .long 3b - _GLOBAL_OFFSET_TABLE_ /* * void relocate_code(new_sp, new_gd, monitor_addr) * * Relocate the u-boot image into RAM and continue from there. * Does not return. */ .section .text.relocate_code,"ax",@progbits .global relocate_code .type relocate_code,@function relocate_code: mov sp, r12 /* use new stack */ mov r12, r11 /* save new_gd */ mov r11, r10 /* save destination address */ /* copy .text section and flush the cache along the way */ lda.w r8, _text lda.w r9, _etext sub lr, r10, r8 /* relocation offset */ 1: ldm r8++, r0-r3 stm r10, r0-r3 sub r10, -16 ldm r8++, r0-r3 stm r10, r0-r3 sub r10, -16 cp.w r8, r9 cache r10[-4], 0x0d /* dcache clean/invalidate */ cache r10[-4], 0x01 /* icache invalidate */ brlt 1b /* flush write buffer */ sync 0 /* copy data sections */ lda.w r9, _edata 1: ld.d r0, r8++ st.d r10++, r0 cp.w r8, r9 brlt 1b /* zero out .bss */ mov r0, 0 mov r1, 0 lda.w r9, _end sub r9, r8 1: st.d r10++, r0 sub r9, 8 brgt 1b /* jump to RAM */ sub r0, pc, . - in_ram add pc, r0, lr .align 2 in_ram: /* find the new GOT and relocate it */ lddpc r6, got_init_reloc 3: rsub r6, pc mov r8, r6 lda.w r9, _egot lda.w r10, _got sub r9, r10 1: ld.w r0, r8[0] add r0, lr st.w r8++, r0 sub r9, 4 brgt 1b /* Move the exception handlers */ mfsr r2, SYSREG_EVBA add r2, lr mtsr SYSREG_EVBA, r2 /* Do the rest of the initialization sequence */ call board_init_r .align 2 got_init_reloc: .long 3b - _GLOBAL_OFFSET_TABLE_ .size relocate_code, . - relocate_code |