xref: /OK3568_Linux_fs/u-boot/arch/nios2/cpu/exceptions.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/*
2*4882a593Smuzhiyun * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
3*4882a593Smuzhiyun * Scott McNutt <smcnutt@psyent.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun#include <config.h>
9*4882a593Smuzhiyun#include <asm/opcodes.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun	.text
13*4882a593Smuzhiyun	.align	4
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun	.global _exception
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun	.set noat
18*4882a593Smuzhiyun	.set nobreak
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun_exception:
21*4882a593Smuzhiyun	/* SAVE ALL REGS -- this allows trap and unimplemented
22*4882a593Smuzhiyun	 * instruction handlers to be coded conveniently in C
23*4882a593Smuzhiyun	 */
24*4882a593Smuzhiyun	addi	sp, sp, -(33*4)
25*4882a593Smuzhiyun	stw	r0, 0(sp)
26*4882a593Smuzhiyun	stw	r1, 4(sp)
27*4882a593Smuzhiyun	stw	r2, 8(sp)
28*4882a593Smuzhiyun	stw	r3, 12(sp)
29*4882a593Smuzhiyun	stw	r4, 16(sp)
30*4882a593Smuzhiyun	stw	r5, 20(sp)
31*4882a593Smuzhiyun	stw	r6, 24(sp)
32*4882a593Smuzhiyun	stw	r7, 28(sp)
33*4882a593Smuzhiyun	stw	r8, 32(sp)
34*4882a593Smuzhiyun	stw	r9, 36(sp)
35*4882a593Smuzhiyun	stw	r10, 40(sp)
36*4882a593Smuzhiyun	stw	r11, 44(sp)
37*4882a593Smuzhiyun	stw	r12, 48(sp)
38*4882a593Smuzhiyun	stw	r13, 52(sp)
39*4882a593Smuzhiyun	stw	r14, 56(sp)
40*4882a593Smuzhiyun	stw	r15, 60(sp)
41*4882a593Smuzhiyun	stw	r16, 64(sp)
42*4882a593Smuzhiyun	stw	r17, 68(sp)
43*4882a593Smuzhiyun	stw	r19, 72(sp)
44*4882a593Smuzhiyun	stw	r19, 76(sp)
45*4882a593Smuzhiyun	stw	r20, 80(sp)
46*4882a593Smuzhiyun	stw	r21, 84(sp)
47*4882a593Smuzhiyun	stw	r22, 88(sp)
48*4882a593Smuzhiyun	stw	r23, 92(sp)
49*4882a593Smuzhiyun	stw	r24, 96(sp)
50*4882a593Smuzhiyun	stw	r25, 100(sp)
51*4882a593Smuzhiyun	stw	r26, 104(sp)
52*4882a593Smuzhiyun	stw	r27, 108(sp)
53*4882a593Smuzhiyun	stw	r28, 112(sp)
54*4882a593Smuzhiyun	stw	r29, 116(sp)
55*4882a593Smuzhiyun	stw	r30, 120(sp)
56*4882a593Smuzhiyun	stw	r31, 124(sp)
57*4882a593Smuzhiyun	rdctl	et, estatus
58*4882a593Smuzhiyun	stw	et, 128(sp)
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun	/* If interrupts are disabled -- software interrupt */
61*4882a593Smuzhiyun	rdctl	et, estatus
62*4882a593Smuzhiyun	andi	et, et, 1
63*4882a593Smuzhiyun	beq	et, r0, 0f
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun	/* If no interrupts are pending -- software interrupt */
66*4882a593Smuzhiyun	rdctl	et, ipending
67*4882a593Smuzhiyun	beq	et, r0, 0f
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun	/* HARDWARE INTERRUPT: Call interrupt handler */
70*4882a593Smuzhiyun	movhi	r3, %hi(external_interrupt)
71*4882a593Smuzhiyun	ori	r3, r3, %lo(external_interrupt)
72*4882a593Smuzhiyun	mov	r4, sp		/* ptr to regs */
73*4882a593Smuzhiyun	callr	r3
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun	/* Return address fixup: execution resumes by re-issue of
76*4882a593Smuzhiyun	 * interrupted instruction at ea-4 (ea == r29). Here we do
77*4882a593Smuzhiyun	 * simple fixup to allow common exception return.
78*4882a593Smuzhiyun	 */
79*4882a593Smuzhiyun	ldw	r3, 116(sp)
80*4882a593Smuzhiyun	addi	r3, r3, -4
81*4882a593Smuzhiyun	stw	r3, 116(sp)
82*4882a593Smuzhiyun	br	_exception_return
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun0:
85*4882a593Smuzhiyun	/* TRAP EXCEPTION */
86*4882a593Smuzhiyun	movhi	r3, %hi(OPC_TRAP)
87*4882a593Smuzhiyun	ori	r3, r3, %lo(OPC_TRAP)
88*4882a593Smuzhiyun	addi	r1, ea, -4
89*4882a593Smuzhiyun	ldw	r1, 0(r1)
90*4882a593Smuzhiyun	bne	r1, r3, 1f
91*4882a593Smuzhiyun	movhi	r3, %hi(trap_handler)
92*4882a593Smuzhiyun	ori	r3, r3, %lo(trap_handler)
93*4882a593Smuzhiyun	mov	r4, sp		/* ptr to regs */
94*4882a593Smuzhiyun	callr	r3
95*4882a593Smuzhiyun	br	_exception_return
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun1:
98*4882a593Smuzhiyun	/* UNIMPLEMENTED INSTRUCTION EXCEPTION */
99*4882a593Smuzhiyun	movhi	r3, %hi(soft_emulation)
100*4882a593Smuzhiyun	ori	r3, r3, %lo(soft_emulation)
101*4882a593Smuzhiyun	mov	r4, sp		/* ptr to regs */
102*4882a593Smuzhiyun	callr	r3
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun	/* Restore regsisters and return from exception*/
105*4882a593Smuzhiyun_exception_return:
106*4882a593Smuzhiyun	ldw	r1, 4(sp)
107*4882a593Smuzhiyun	ldw	r2, 8(sp)
108*4882a593Smuzhiyun	ldw	r3, 12(sp)
109*4882a593Smuzhiyun	ldw	r4, 16(sp)
110*4882a593Smuzhiyun	ldw	r5, 20(sp)
111*4882a593Smuzhiyun	ldw	r6, 24(sp)
112*4882a593Smuzhiyun	ldw	r7, 28(sp)
113*4882a593Smuzhiyun	ldw	r8, 32(sp)
114*4882a593Smuzhiyun	ldw	r9, 36(sp)
115*4882a593Smuzhiyun	ldw	r10, 40(sp)
116*4882a593Smuzhiyun	ldw	r11, 44(sp)
117*4882a593Smuzhiyun	ldw	r12, 48(sp)
118*4882a593Smuzhiyun	ldw	r13, 52(sp)
119*4882a593Smuzhiyun	ldw	r14, 56(sp)
120*4882a593Smuzhiyun	ldw	r15, 60(sp)
121*4882a593Smuzhiyun	ldw	r16, 64(sp)
122*4882a593Smuzhiyun	ldw	r17, 68(sp)
123*4882a593Smuzhiyun	ldw	r19, 72(sp)
124*4882a593Smuzhiyun	ldw	r19, 76(sp)
125*4882a593Smuzhiyun	ldw	r20, 80(sp)
126*4882a593Smuzhiyun	ldw	r21, 84(sp)
127*4882a593Smuzhiyun	ldw	r22, 88(sp)
128*4882a593Smuzhiyun	ldw	r23, 92(sp)
129*4882a593Smuzhiyun	ldw	r24, 96(sp)
130*4882a593Smuzhiyun	ldw	r25, 100(sp)
131*4882a593Smuzhiyun	ldw	r26, 104(sp)
132*4882a593Smuzhiyun	ldw	r27, 108(sp)
133*4882a593Smuzhiyun	ldw	r28, 112(sp)
134*4882a593Smuzhiyun	ldw	r29, 116(sp)
135*4882a593Smuzhiyun	ldw	r30, 120(sp)
136*4882a593Smuzhiyun	ldw	r31, 124(sp)
137*4882a593Smuzhiyun	addi	sp, sp, (33*4)
138*4882a593Smuzhiyun	eret
139*4882a593Smuzhiyun/*-------------------------------------------------------------*/
140