summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/or1k/or1k-exception-handler-low.S
blob: 7108ff65b5607c910340ebdd8800caa8916c965d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/**
 * @file
 *
 * @ingroup ScoreCPU
 *
 * @brief OR1K exception support implementation.
 */

/*
 *  COPYRIGHT (c) 2014 Hesham ALMatary <heshamelmatary@gmail.com>
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <rtems/asm.h>
#include <rtems/score/percpu.h>
#include "rtems/score/or1k-utility.h"

.align 4
.text
PUBLIC(_ISR_Handler)
.type    _ISR_Handler,@function

 SYM(_ISR_Handler):

  l.addi  r1, r1, -140

  l.sw  8(r1),r2
  /* r3 is saved by BSP exception handler */
  l.sw  16(r1),r4
  l.sw  20(r1),r5
  l.sw  24(r1),r6
  l.sw  28(r1),r7
  l.sw  32(r1),r8
  l.sw  36(r1),r9
  l.sw  40(r1),r10
  l.sw  44(r1),r11
  l.sw  48(r1),r12
  l.sw  52(r1),r13
  l.sw  56(r1),r14
  l.sw  60(r1),r15
  l.sw  64(r1),r16
  l.sw  68(r1),r17
  l.sw  72(r1),r18
  l.sw  76(r1),r19
  l.sw  80(r1),r20
  l.sw  84(r1),r21
  l.sw  88(r1),r22
  l.sw  92(r1),r23
  l.sw  96(r1),r24
  l.sw  100(r1),r25
  l.sw  104(r1),r26
  l.sw  108(r1),r27
  l.sw  112(r1),r28
  l.sw  116(r1),r29
  l.sw  120(r1),r30
  l.sw  124(r1),r31

  /* Exception level related registers */

  /* EPCR */
  l.mfspr r13, r0, CPU_OR1K_SPR_EPCR0
  l.sw  128(r1), r13 /* epcr */

  /* EEAR */
  l.mfspr r13, r0, CPU_OR1K_SPR_EEAR0
  l.sw  132(r1), r13 /* eear */

  /* ESR */
  l.mfspr r13, r0, CPU_OR1K_SPR_ESR0
  l.sw  136(r1), r13  /* esr */

  /* Increment nesting level */
  l.movhi r6, hi(ISR_NEST_LEVEL)
  l.ori   r6, r6, lo(ISR_NEST_LEVEL)

  /* Disable multitasking */
  l.movhi r8, hi(THREAD_DISPATCH_DISABLE_LEVEL)
  l.ori   r8, r8, lo(THREAD_DISPATCH_DISABLE_LEVEL)

  l.lwz   r5, 0(r6)
  l.lwz   r7, 0(r8)
  l.addi  r5, r5, 1
  l.addi  r7, r7, 1
  l.sw    0(r6), r5
  l.sw    0(r8), r7

  /* Save interrupted task stack pointer */
  l.addi r4, r1, 144
  l.sw   4(r1), r4

  /* Save interrupted task r3 (first arg) value */
  l.addi r4, r1, 140
  l.lwz  r4, 0(r4)
  l.sw  12(r1), r4

  /* Keep r1 (Exception frame address) in r14 */
  l.add   r14, r1, r0

  /* Call the exception handler from vector table */

  /* First function arg for C handler is vector number,
   * and the second is a pointer to exception frame.
   */
  l.add  r13, r3, r0
  l.add  r4, r1, r0
  l.slli r13, r13, 2
  l.addi r13, r13, lo(bsp_start_vector_table_begin)
  l.lwz  r13, 0(r13)

  /* Do not switch stacks if we are in a nested interrupt. At
   * this point r5 should be holding ISR_NEST_LEVEL value.
   */
  l.sfgtui r5, 2
  l.bf jump_to_c_handler
  l.nop

   /* Switch to RTEMS dedicated interrupt stack */
  l.movhi r1, hi(INTERRUPT_STACK_HIGH)
  l.ori   r1, r1, lo(INTERRUPT_STACK_HIGH)
  l.lwz   r1, 0(r1)

jump_to_c_handler:
  l.jalr r13
  l.nop

  /* Switch back to the interrupted task stack */
  l.add r1, r14, r0

  /* Check if dispatch needed */
  l.movhi r31, hi(DISPATCH_NEEDED)
  l.ori   r31, r31, lo(DISPATCH_NEEDED)
  l.lwz   r31, 0(r31)
  l.sfeq  r31, r0
  l.bf    exception_frame_restore
  l.nop

  l.movhi r13, hi(_Thread_Dispatch)
  l.ori   r13, r13, lo(_Thread_Dispatch)
  l.jalr  r13
  l.nop

 SYM(exception_frame_restore):

  /* Exception level related registers */

  /* EPCR */
  l.lwz  r13,  128(r1)
  l.mtspr r0, r13, CPU_OR1K_SPR_EPCR0

  /* EEAR */
  l.lwz  r13,  132(r1)
  l.mtspr r0, r13, CPU_OR1K_SPR_EEAR0

  /* ESR */
  l.lwz  r13,  136(r1)
  l.mtspr r0, r13, CPU_OR1K_SPR_ESR0

  /* Increment nesting level */
  l.movhi r6, hi(ISR_NEST_LEVEL)
  l.ori   r6, r6, lo(ISR_NEST_LEVEL)

  /* Disable multitasking */
  l.movhi r8, hi(THREAD_DISPATCH_DISABLE_LEVEL)
  l.ori   r8, r8, lo(THREAD_DISPATCH_DISABLE_LEVEL)

  l.lwz   r5, 0(r6)
  l.lwz   r7, 0(r8)
  l.addi  r5, r5, -1
  l.addi  r7, r7, -1
  l.sw    0(r6), r5
  l.sw    0(r8), r7

  l.lwz  r2,  8(r1)
  l.lwz  r3,  12(r1)
  l.lwz  r4,  16(r1)
  l.lwz  r5,  20(r1)
  l.lwz  r6,  24(r1)
  l.lwz  r7,  28(r1)
  l.lwz  r8,  32(r1)
  l.lwz  r9,  36(r1)
  l.lwz  r10, 40(r1)
  l.lwz  r11, 44(r1)
  l.lwz  r12, 48(r1)
  l.lwz  r13, 52(r1)
  l.lwz  r14, 56(r1)
  l.lwz  r15, 60(r1)
  l.lwz  r16, 64(r1)
  l.lwz  r17, 68(r1)
  l.lwz  r18, 72(r1)
  l.lwz  r19, 76(r1)
  l.lwz  r20, 80(r1)
  l.lwz  r21, 84(r1)
  l.lwz  r22, 88(r1)
  l.lwz  r23, 92(r1)
  l.lwz  r24, 96(r1)
  l.lwz  r25, 100(r1)
  l.lwz  r26, 104(r1)
  l.lwz  r27, 108(r1)
  l.lwz  r28, 112(r1)
  l.lwz  r29, 116(r1)
  l.lwz  r30, 120(r1)
  l.lwz  r31, 124(r1)

  l.addi r1, r1, 140

  l.addi r1, r1, 4

  l.rfe
  l.nop