source: rtems/cpukit/score/cpu/riscv32/riscv-exception-handler.S @ 660db8c8

Last change on this file since 660db8c8 was 660db8c8, checked in by Hesham Almatary <hesham@…>, on Oct 26, 2017 at 11:12:41 PM

cpukit: Add basic riscv32 architecture port v3

Limitations:

  • NO FPU support [TODO]

Update #3109

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreCPU
5 *
6 * @brief riscv32 exception support implementation.
7 */
8
9/*
10 * Copyright (c) 2015 University of York.
11 * Hesham Almatary <hesham@alumni.york.ac.uk>
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include <rtems/score/cpu.h>
40
41#include <rtems/asm.h>
42#include <rtems/score/percpu.h>
43
44# define LREG lw
45# define SREG sw
46
47EXTERN(bsp_start_vector_table_begin)
48EXTERN(_Thread_Dispatch)
49PUBLIC(ISR_Handler)
50
51.section .text, "ax"
52.align 4
53TYPE_FUNC(ISR_Handler)
54SYM(ISR_Handler):
55  addi sp, sp, -144
56
57  SREG x1, (1 * CPU_SIZEOF_POINTER)(sp)
58  /* Skip x2/sp */
59  SREG x3, (3 * CPU_SIZEOF_POINTER)(sp)
60  SREG x4, (4 * CPU_SIZEOF_POINTER)(sp)
61  SREG x5, (5 * CPU_SIZEOF_POINTER)(sp)
62  SREG x6, (6 * CPU_SIZEOF_POINTER)(sp)
63  SREG x7, (7 * CPU_SIZEOF_POINTER)(sp)
64  SREG x8, (8 * CPU_SIZEOF_POINTER)(sp)
65  SREG x9, (9 * CPU_SIZEOF_POINTER)(sp)
66  SREG x10, (10 * CPU_SIZEOF_POINTER)(sp)
67  SREG x11, (11 * CPU_SIZEOF_POINTER)(sp)
68  SREG x12, (12 * CPU_SIZEOF_POINTER)(sp)
69  SREG x13, (13 * CPU_SIZEOF_POINTER)(sp)
70  SREG x14, (14 * CPU_SIZEOF_POINTER)(sp)
71  SREG x15, (15 * CPU_SIZEOF_POINTER)(sp)
72  SREG x16, (16 * CPU_SIZEOF_POINTER)(sp)
73  SREG x17, (17 * CPU_SIZEOF_POINTER)(sp)
74  SREG x18, (18 * CPU_SIZEOF_POINTER)(sp)
75  SREG x19, (19 * CPU_SIZEOF_POINTER)(sp)
76  SREG x20, (20 * CPU_SIZEOF_POINTER)(sp)
77  SREG x21, (21 * CPU_SIZEOF_POINTER)(sp)
78  SREG x22, (22 * CPU_SIZEOF_POINTER)(sp)
79  SREG x23, (23 * CPU_SIZEOF_POINTER)(sp)
80  SREG x24, (24 * CPU_SIZEOF_POINTER)(sp)
81  SREG x25, (25 * CPU_SIZEOF_POINTER)(sp)
82  SREG x26, (26 * CPU_SIZEOF_POINTER)(sp)
83  SREG x27, (27 * CPU_SIZEOF_POINTER)(sp)
84  SREG x28, (28 * CPU_SIZEOF_POINTER)(sp)
85  SREG x29, (28 * CPU_SIZEOF_POINTER)(sp)
86  SREG x30, (30 * CPU_SIZEOF_POINTER)(sp)
87  SREG x31, (31 * CPU_SIZEOF_POINTER)(sp)
88
89  /* Exception level related registers */
90  csrr a0, mstatus
91  SREG a0, (32 * CPU_SIZEOF_POINTER)(sp)
92  csrr a0, mcause
93  SREG a0, (33 * CPU_SIZEOF_POINTER)(sp)
94  csrr a1, mepc
95  SREG a1, (34 * CPU_SIZEOF_POINTER)(sp)
96
97  /* FIXME Only handle interrupts for now (MSB = 1) */
98  andi a0, a0, 0xf
99
100  /* Increment nesting level */
101  la t0, ISR_NEST_LEVEL
102
103  /* Disable multitasking */
104  la t1, THREAD_DISPATCH_DISABLE_LEVEL
105
106  LREG t2, (t0)
107  LREG t3, (t1)
108  addi t2, t2, 1
109  addi t3, t3, 1
110  SREG t2, (t0)
111  SREG t3, (t1)
112
113  /* Save interrupted task stack pointer */
114  addi t4, sp, 144
115  SREG t4, (2 * CPU_SIZEOF_POINTER)(sp)
116
117  /* Keep sp (Exception frame address) in s1 */
118  mv   s1, sp
119
120  /* Call the exception handler from vector table */
121
122  /* First function arg for C handler is vector number,
123   * and the second is a pointer to exception frame.
124   * a0/mcause/vector number is already loaded above */
125  mv a1, sp
126
127  /* calculate the offset */
128  la   t5, bsp_start_vector_table_begin
129  slli t6, a0, 2
130  add  t5, t5, t6
131  LREG t5, (t5)
132
133  /* Do not switch stacks if we are in a nested interrupt. At
134   * this point t2 should be holding ISR_NEST_LEVEL value.
135   */
136  li   s0, 1
137  bgtu t2, s0, jump_to_c_handler
138
139  /* Switch to RTEMS dedicated interrupt stack */
140  la     sp, INTERRUPT_STACK_HIGH
141  LREG   sp, (sp)
142
143jump_to_c_handler:
144  jalr t5
145
146  /* Switch back to the interrupted task stack */
147  mv sp, s1
148
149  /* Decrement nesting level */
150  la t0, ISR_NEST_LEVEL
151
152  /* Enable multitasking */
153  la t1, THREAD_DISPATCH_DISABLE_LEVEL
154
155  LREG t2, (t0)
156  LREG t3, (t1)
157  addi t2, t2, -1
158  addi t3, t3, -1
159  SREG t2, (t0)
160  SREG t3, (t1)
161
162  /* Check if _ISR_Nest_level > 0 */
163  bgtz t2, exception_frame_restore
164
165  /* Check if _Thread_Dispatch_disable_level > 0 */
166  bgtz t3, exception_frame_restore
167
168  /* Check if dispatch needed */
169  la   x31, DISPATCH_NEEDED
170  LREG x31, (x31)
171  beqz x31, exception_frame_restore
172
173  la x31, _Thread_Dispatch
174  jalr x31
175
176  SYM(exception_frame_restore):
177  LREG x1, (1 * CPU_SIZEOF_POINTER)(sp)
178  /* Skip sp/x2 */
179  LREG x3, (3 * CPU_SIZEOF_POINTER)(sp)
180  LREG x4, (4 * CPU_SIZEOF_POINTER)(sp)
181  LREG x5, (5 * CPU_SIZEOF_POINTER)(sp)
182  LREG x6, (6 * CPU_SIZEOF_POINTER)(sp)
183  LREG x7, (7 * CPU_SIZEOF_POINTER)(sp)
184  LREG x8, (8 * CPU_SIZEOF_POINTER)(sp)
185  LREG x9, (9 * CPU_SIZEOF_POINTER)(sp)
186  LREG x10, (10 * CPU_SIZEOF_POINTER)(sp)
187  LREG x11, (11 * CPU_SIZEOF_POINTER)(sp)
188  LREG x12, (12 * CPU_SIZEOF_POINTER)(sp)
189  LREG x13, (13 * CPU_SIZEOF_POINTER)(sp)
190  LREG x14, (14 * CPU_SIZEOF_POINTER)(sp)
191  LREG x15, (15 * CPU_SIZEOF_POINTER)(sp)
192  LREG x16, (16 * CPU_SIZEOF_POINTER)(sp)
193  LREG x17, (17 * CPU_SIZEOF_POINTER)(sp)
194  LREG x18, (18 * CPU_SIZEOF_POINTER)(sp)
195  LREG x19, (19 * CPU_SIZEOF_POINTER)(sp)
196  LREG x20, (20 * CPU_SIZEOF_POINTER)(sp)
197  LREG x21, (21 * CPU_SIZEOF_POINTER)(sp)
198  LREG x22, (22 * CPU_SIZEOF_POINTER)(sp)
199  LREG x23, (23 * CPU_SIZEOF_POINTER)(sp)
200  LREG x24, (24 * CPU_SIZEOF_POINTER)(sp)
201  LREG x25, (25 * CPU_SIZEOF_POINTER)(sp)
202  LREG x26, (26 * CPU_SIZEOF_POINTER)(sp)
203  LREG x27, (27 * CPU_SIZEOF_POINTER)(sp)
204  LREG x28, (28 * CPU_SIZEOF_POINTER)(sp)
205  LREG x29, (29 * CPU_SIZEOF_POINTER)(sp)
206  LREG x30, (30 * CPU_SIZEOF_POINTER)(sp)
207
208  /* Load mstatus */
209  LREG x31, (32 * CPU_SIZEOF_POINTER)(sp)
210  csrw mstatus, x31
211  /* Load mepc */
212  LREG x31, (34 * CPU_SIZEOF_POINTER)(sp)
213  csrw mepc, x31
214
215  LREG x31, (31 * CPU_SIZEOF_POINTER)(sp)
216
217  /* Unwind exception frame */
218  addi sp, sp, 144
219
220  mret
Note: See TracBrowser for help on using the repository browser.