[U-Boot-Users] [PATCH 12/18] avr32: Use the same entry point for reset and exception handling

Haavard Skinnemoen haavard.skinnemoen at atmel.com
Fri May 23 14:36:22 CEST 2008


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 at atmel.com>
---
 board/atmel/atngw100/u-boot.lds  |    1 +
 board/atmel/atstk1000/u-boot.lds |    1 +
 cpu/at32ap/Makefile              |    1 -
 cpu/at32ap/entry.S               |   64 -------------------
 cpu/at32ap/start.S               |  129 +++++++++++++++++++++++++++++++++++---
 5 files changed, 122 insertions(+), 74 deletions(-)
 delete mode 100644 cpu/at32ap/entry.S

diff --git a/board/atmel/atngw100/u-boot.lds b/board/atmel/atngw100/u-boot.lds
index 3c878d8..e736adf 100644
--- a/board/atmel/atngw100/u-boot.lds
+++ b/board/atmel/atngw100/u-boot.lds
@@ -29,6 +29,7 @@ SECTIONS
 	. = 0;
 	_text = .;
 	.text : {
+		*(.exception.text)
 		*(.text)
 		*(.text.*)
 	}
diff --git a/board/atmel/atstk1000/u-boot.lds b/board/atmel/atstk1000/u-boot.lds
index f63bc4f..0d3b19c 100644
--- a/board/atmel/atstk1000/u-boot.lds
+++ b/board/atmel/atstk1000/u-boot.lds
@@ -29,6 +29,7 @@ SECTIONS
 	. = 0;
 	_text = .;
 	.text : {
+		*(.exception.text)
 		*(.text)
 		*(.text.*)
 	}
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
index 8e384c7..29f9c0d 100644
--- a/cpu/at32ap/Makefile
+++ b/cpu/at32ap/Makefile
@@ -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
index a6fc688..0000000
--- a/cpu/at32ap/entry.S
+++ /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, at 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, at 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
diff --git a/cpu/at32ap/start.S b/cpu/at32ap/start.S
index ab8c2b7..907e9b1 100644
--- a/cpu/at32ap/start.S
+++ b/cpu/at32ap/start.S
@@ -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.
@@ -20,12 +20,9 @@
  * 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
 
@@ -34,11 +31,115 @@
 		    | 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, at 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", at progbits
 	.global	relocate_code
 	.type	relocate_code, at function
 relocate_code:
@@ -162,3 +271,5 @@ in_ram:
 	.align	2
 got_init_reloc:
 	.long	3b - _GLOBAL_OFFSET_TABLE_
+
+	.size	relocate_code, . - relocate_code
-- 
1.5.5.1





More information about the U-Boot mailing list