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