diff source/exception.S @ 0:ed10291ff195

first commit
author mir3636
date Sun, 06 Jan 2019 19:27:03 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/exception.S	Sun Jan 06 19:27:03 2019 +0900
@@ -0,0 +1,226 @@
+/*****************************************************************
+*       exception.s
+*       by Zhiyi Huang, hzy@cs.otago.ac.nz
+*       University of Otago
+*
+********************************************************************/
+
+
+.align 4
+.section .text
+
+.global vectors
+vectors:
+	ldr pc, reset_handler 
+	ldr pc, undefintr_handler
+	ldr pc, swi_handler
+	ldr pc, prefetch_handler
+	ldr pc, data_handler
+	ldr pc, unused_handler
+	ldr pc, irq_handler
+	ldr pc, fiq_handler
+reset_handler:
+	.word hang    /* reset, in svc mode already */
+undefintr_handler:
+	.word do_und      /* undefined instruction */
+swi_handler:
+	.word do_svc    /* SWI & SVC */
+prefetch_handler:
+	.word do_pabt      /* prefetch abort */
+data_handler:
+	.word do_dabt     /* data abort */
+unused_handler:
+	.word hang      /* reserved */
+irq_handler:
+	.word do_irq    /* IRQ */
+fiq_handler:
+	.word hang    /* FIQ */
+
+hang:
+        bl NotOkLoop;
+	b hang
+do_svc:
+	push {lr}
+        mrs lr, spsr
+        push {lr}
+        mrs lr, cpsr
+        push {lr}
+        mrc p15, 0, lr, c6, c0, 2  /* read Instruction Fault Address Register (IFAR) */
+        push {lr}
+        mov lr, #0x40
+        push {lr}
+	STMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14}
+	sub sp, sp, #60
+	mov r0, sp   /* save sp */
+	STMFD r0, {r13}^   /* save user mode sp */
+	mov r1, r1 /* three nops after STM with user mode banked registers */
+	mov r1, r1
+	mov r1, r1
+	mov sp, r0  /* restore sp */
+	sub sp, sp, #4
+	mov r0, sp
+	bl trap
+
+.global trapret
+trapret:
+	mov r0, sp /* save sp in case it is changed to sp_usr after the following LDMFD instruction */
+	LDMFD r0, {r13}^ /* restore user mode sp */
+	mov r1, r1  /* three nops after LDMFD */
+	mov r1, r1
+	mov r1, r1
+	mov sp, r0  /* restore sp */
+	add sp, sp, #4
+	LDMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12}
+	add sp, sp, #72
+	pop {lr}
+        msr spsr, lr
+	pop {lr}
+	movs pc, lr  /* subs pc,lr,#0 */
+
+do_und:
+	STMFD sp, {r0-r4}
+	mov r0, #0x01
+	b _switchtosvc
+
+do_pabt:
+	STMFD sp, {r0-r4}
+	mov r0, #0x02
+	b _switchtosvc
+
+do_dabt:
+	STMFD sp, {r0-r4}
+	mov r0, #0x04
+	b _switchtosvc
+
+do_irq:
+	STMFD sp, {r0-r4}
+	mov r0, #0x80
+	b _switchtosvc
+_switchtosvc:
+	mrs r1, spsr
+	sub r2, lr, #4
+	mov r3, sp
+	mrs lr, cpsr
+	bic lr, #0x0000001F /* PSR_MASK */
+	orr lr, #0x00000080 /* PSR_DISABLE_IRQ */
+	orr lr, #0x00000013 /* PSR_MODE_SVC */
+	msr cpsr, lr /* switch to svc */
+	push {r2}
+	push {r1}
+	mrs r1, cpsr
+	push {r1}
+        mrc p15, 0, r1, c6, c0, 2  /* read Instruction Fault Address Register (I
+FAR) */
+        push {r1}
+        push {r0}
+	sub r1, r3, #20
+	LDMFD r1, {r0-r4}
+	STMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14}
+	sub sp, sp, #60
+        mov r0, sp   /* save sp */
+        STMFD r0, {r13}^    /* save user mode sp */
+        mov r1, r1 /* three nops after STM with user mode banked registers */
+        mov r1, r1
+        mov r1, r1
+        mov sp, r0  /* restore sp */
+        sub sp, sp, #4
+        mov r0, sp
+
+	bl trap
+
+	mov r0, sp
+	add r0, #76
+	LDMIA r0, {r1}
+	mov r2, r1
+	and r2, #0xf
+	cmp r2, #0
+	beq _backtouser
+	msr cpsr, r1
+        add sp, #4
+	LDMFD sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12}
+	add sp, sp, #56
+	pop {r14}
+	add sp, sp, #16
+	pop {pc}
+
+_backtouser:
+	mov r0, sp /* save sp in case it is changed to sp_usr after the following LDMFD instruction */
+	LDMFD r0, {r13}^ /* restore user mode sp */
+	mov r1, r1  /* three nops after LDMFD */
+	mov r1, r1
+	mov r1, r1
+	mov sp, r0  /* restore sp */
+	add sp, sp, #4
+	LDMIA sp, {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12}
+	add sp, sp, #72
+	pop {lr}
+	msr spsr, lr
+	pop {lr}
+	movs pc, lr  /* subs pc,lr,#0 */
+
+
+.global set_mode_sp
+set_mode_sp:
+	mrs r2, cpsr
+	msr cpsr_c,r1
+	mov sp, r0
+	mrs r0, cpsr
+	orr r0, #0x00000080 /* PSR_DISABLE_IRQ */
+	orr r0, #0x00000040 /* PSR_DISABLE_FIQ */
+	msr cpsr, r0
+	msr cpsr_c, r2
+	bx lr
+
+.global readcpsr
+readcpsr:
+	mrs r0, cpsr
+	bx lr
+
+.global cli
+cli:
+        mrs r0, cpsr
+        orr r0, #0x00000080 /* PSR_DISABLE_IRQ */
+        msr cpsr, r0
+        bx lr
+
+.global sti
+sti:
+	mrs r0, cpsr
+	bic r0, r0, #0x00000080 /* PSR_DISABLE_IRQ */
+	msr cpsr, r0
+	bx lr
+
+.global swtch
+swtch:
+	push {lr}  /* save the return address */
+	push {lr}
+	/* save old callee-save registers */
+	push {r12}
+	push {r11}
+	push {r10}
+	push {r9}
+	push {r8}
+	push {r7}
+	push {r6}
+	push {r5}
+	push {r4}
+
+	/* switch stacks */
+	str sp, [r0]
+	mov sp, r1
+
+	/* load new callee-save registers */
+	pop {r4}
+	pop {r5}
+	pop {r6}
+	pop {r7}
+	pop {r8}
+	pop {r9}
+	pop {r10}
+	pop {r11}
+	pop {r12}
+
+	/* return to previously saved pc */
+	pop {lr}
+	pop {pc}
+