avr32: Use the same entry point for reset and exception handling
authorHaavard Skinnemoen <haavard.skinnemoen@atmel.com>
Fri, 2 May 2008 13:32:57 +0000 (15:32 +0200)
committerHaavard Skinnemoen <haavard.skinnemoen@atmel.com>
Tue, 27 May 2008 13:27:30 +0000 (15:27 +0200)
Since the reset vector is always aligned to a very large boundary, we
can save a couple of KB worth of alignment padding by placing the
exception vectors at the same address.

Deciding which one it is is easy: If we're handling an exception, the
CPU is in Exception mode. If we're starting up after reset, the CPU is
in Supervisor mode. So this adds a very minimal overhead to the reset
path (only executed once) and the exception handling path (normally
never executed at all.)

Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
board/atmel/atngw100/u-boot.lds
board/atmel/atstk1000/u-boot.lds
cpu/at32ap/Makefile
cpu/at32ap/entry.S [deleted file]
cpu/at32ap/start.S

index 3c878d8657a17c731c6b7222dec942c8148366db..e736adf0fcdf2c592c215e6e746c3120ce7d75cb 100644 (file)
@@ -29,6 +29,7 @@ SECTIONS
        . = 0;
        _text = .;
        .text : {
+               *(.exception.text)
                *(.text)
                *(.text.*)
        }
index f63bc4ff27ad1d23d473c46cb85b9918c541b84d..0d3b19c6402cb4ecff494b00c4a4424bc806ad99 100644 (file)
@@ -29,6 +29,7 @@ SECTIONS
        . = 0;
        _text = .;
        .text : {
+               *(.exception.text)
                *(.text)
                *(.text.*)
        }
index 8e384c7e07f2bc99fc3434d476562d94d4063e4c..29f9c0d04aee7470190640cf200be4c87acd6cc7 100644 (file)
@@ -29,7 +29,6 @@ LIB   := $(obj)lib$(CPU).a
 
 START-y                        += start.o
 
-SOBJS-y                        += entry.o
 COBJS-y                        += cpu.o
 COBJS-y                        += hsdramc.o
 COBJS-y                        += exception.o
diff --git a/cpu/at32ap/entry.S b/cpu/at32ap/entry.S
deleted file mode 100644 (file)
index a6fc688..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2004-2006 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 <asm/sysreg.h>
-#include <asm/ptrace.h>
-
-       .section .text.exception,"ax"
-       .global _evba
-       .type   _evba,@function
-       .align  10
-_evba:
-       .irp    x,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
-       .align  2
-       rjmp    unknown_exception
-       .endr
-
-       .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
-
-       .type   unknown_exception, @function
-unknown_exception:
-       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
index ab8c2b73d8933737f67000119ee4f3412aa5a346..907e9b1534decb37bde51a695c5e0c436e8ee588 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2006 Atmel Corporation
+ * Copyright (C) 2005-2008 Atmel Corporation
  *
  * See file CREDITS for list of people who contributed to this
  * project.
  * MA 02111-1307 USA
  */
 #include <config.h>
+#include <asm/ptrace.h>
 #include <asm/sysreg.h>
 
-#ifndef PART_SPECIFIC_BOOTSTRAP
-# define PART_SPECIFIC_BOOTSTRAP
-#endif
-
 #define SYSREG_MMUCR_I_OFFSET  2
 #define SYSREG_MMUCR_S_OFFSET  4
 
                    | SYSREG_BIT(FE) | SYSREG_BIT(RE)           \
                    | SYSREG_BIT(IBE) | SYSREG_BIT(IEE))
 
-       .text
+       /*
+        * 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:
-       PART_SPECIFIC_BOOTSTRAP
+       .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)
@@ -66,9 +167,16 @@ _start:
        lddpc   pc, 1f
 
        .align  2
-1:     .long   2f
+1:     .long   at32ap_low_level_init
+       .size   _start, . - _start
 
-2:     lddpc   sp, sp_init
+       /* 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
@@ -90,6 +198,7 @@ got_init:
         * 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:
@@ -162,3 +271,5 @@ in_ram:
        .align  2
 got_init_reloc:
        .long   3b - _GLOBAL_OFFSET_TABLE_
+
+       .size   relocate_code, . - relocate_code