Index: kernel/arch/arm32/src/exc_handler.S
===================================================================
--- kernel/arch/arm32/src/exc_handler.S	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
+++ kernel/arch/arm32/src/exc_handler.S	(revision 6ac14a70ed101ee9fa8379a5f9ef15a38f08aec5)
@@ -0,0 +1,199 @@
+#
+# Copyright (c) 2009 Vineeth Pillai
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+.text   
+
+.global irq_exception_entry
+.global fiq_exception_entry
+.global data_abort_exception_entry
+.global prefetch_abort_exception_entry
+.global undef_instr_exception_entry
+.global swi_exception_entry
+.global reset_exception_entry
+
+
+# Switches to kernel stack and saves all registers there.
+#
+#  The stack frame created by the function looks like:
+#
+#              |_________________|
+#              |                 |
+#              |     SPSR        |
+#              |                 |
+#              |_________________|
+#              | Stack Pointer   |
+#              |      of         |
+#              | Previous Mode   |
+#              |_________________|
+#              | Return address  |
+#              |      of         |
+#              | Previous Mode   |
+#              |_________________|
+#              |   R0  - R12     |
+#              |      of         |
+#              | Previous Mode   |
+#              |_________________|
+#              | Return address  |
+#              |     from        |
+#              |Exception Handler|
+#              |_________________|
+#              |                 |
+#
+#
+
+.macro SAVE_REGS_TO_STACK
+	stmfd r13!, {r0-r3}
+	mov r3, sp
+	add sp, sp, #16
+	mrs r1, cpsr
+	bic r1, r1, #0x1f
+	mrs r2, spsr
+	and r0, r2, #0x1f
+	cmp r0, #0x10
+	bne 1f
+
+	# prev mode was usermode
+	mov r0, lr
+
+	# Switch to supervisor mode
+	orr r1, r1, #0x13
+	msr cpsr_c, r1
+
+	# Load sp with [supervisor_sp]
+	ldr r13, =supervisor_sp
+	ldr r13, [r13]
+
+	# Populate the stack frame
+	msr spsr, r2
+	mov lr, r0
+	stmfd r13!, {lr}
+	stmfd r13!, {r4-r12}
+	ldmfd r3!, {r4-r7}
+	stmfd r13!, {r4-r7}
+	stmfd r13!, {r13, lr}^
+	stmfd r13!, {r2}
+	b 2f
+
+	# mode was not usermode
+1:
+	# Switch to previous mode which is undoubtedly the supervisor mode
+	orr r1, r1, r0
+	mov r0, lr
+	msr cpsr_c, r1
+
+	# Populate the stack frame
+	mov r1, sp
+	stmfd r13!, {r0}
+	stmfd r13!, {r4-r12}
+
+	# Store r0-r3 in r4-r7 and then push it on to stack
+	ldmfd r3!, {r4-r7}
+	stmfd r13!, {r4-r7}
+
+	# Push return address and stack pointer on to stack
+	stmfd r13!, {lr}
+	stmfd r13!, {r1}
+	mov lr, r0
+	msr spsr, r2
+	stmfd r13!, {r2}
+2:
+.endm
+
+.macro LOAD_REGS_FROM_STACK
+	ldmfd r13!, {r0}
+	msr spsr, r0
+	and r0, r0, #0x1f
+	cmp r0, #0x10
+	bne 1f
+
+	# return to user mode
+	ldmfd r13!, {r13, lr}^
+	b 2f
+
+	# return to non-user mode
+1:
+	ldmfd r13!, {r1, lr}
+
+2:
+	ldmfd r13!, {r0-r12, pc}^
+.endm
+
+reset_exception_entry:
+	SAVE_REGS_TO_STACK
+	mov r0, #0
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+irq_exception_entry:
+	sub lr, lr, #4
+	SAVE_REGS_TO_STACK
+	mov r0, #5
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+fiq_exception_entry:
+	sub lr, lr, #4
+	SAVE_REGS_TO_STACK
+	mov r0, #6
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+undef_instr_exception_entry:
+	SAVE_REGS_TO_STACK
+	mov r0, #1
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+prefetch_abort_exception_entry:
+	sub lr, lr, #4
+	SAVE_REGS_TO_STACK
+	mov r0, #3
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+data_abort_exception_entry:
+	sub lr, lr, #8
+	SAVE_REGS_TO_STACK
+	mov r0, #4
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
+swi_exception_entry:
+	ldr r13, =exc_stack
+	SAVE_REGS_TO_STACK
+	mov r0, #2
+	mov r1, r13
+	bl exc_dispatch
+	LOAD_REGS_FROM_STACK
+
