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