source: rtems/cpukit/score/cpu/riscv/riscv-exception-handler.S @ 11ff3a9

Last change on this file since 11ff3a9 was 11ff3a9, checked in by Hesham Almatary <heshamelmatary@…>, on Oct 27, 2017 at 4:18:40 AM

cpukit: RISC-V - make riscv32 code work for riscv64 - v2

  • Use #ifdefs for 32/64 bit code
  • Use unsigned long which is 32-bit on riscv32 and 64-bit on riscv64 (register size)
  • Move the code to a new shared riscv folder to be shared between riscv32 and riscv64
  • Rename RTEMS_CPU extracted from command line to shared riscv target s/riscv*/riscv

Update #3109

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreCPU
5 *
6 * @brief RISC-V 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
44EXTERN(bsp_start_vector_table_begin)
45EXTERN(_Thread_Dispatch)
46PUBLIC(ISR_Handler)
47
48.section .text, "ax"
49.align 4
50TYPE_FUNC(ISR_Handler)
51SYM(ISR_Handler):
52  addi sp, sp, -1 * 36 * CPU_SIZEOF_POINTER
53
54  SREG x1, (1 * CPU_SIZEOF_POINTER)(sp)
55  /* Skip x2/sp */
56  SREG x3, (3 * CPU_SIZEOF_POINTER)(sp)
57  SREG x4, (4 * CPU_SIZEOF_POINTER)(sp)
58  SREG x5, (5 * CPU_SIZEOF_POINTER)(sp)
59  SREG x6, (6 * CPU_SIZEOF_POINTER)(sp)
60  SREG x7, (7 * CPU_SIZEOF_POINTER)(sp)
61  SREG x8, (8 * CPU_SIZEOF_POINTER)(sp)
62  SREG x9, (9 * CPU_SIZEOF_POINTER)(sp)
63  SREG x10, (10 * CPU_SIZEOF_POINTER)(sp)
64  SREG x11, (11 * CPU_SIZEOF_POINTER)(sp)
65  SREG x12, (12 * CPU_SIZEOF_POINTER)(sp)
66  SREG x13, (13 * CPU_SIZEOF_POINTER)(sp)
67  SREG x14, (14 * CPU_SIZEOF_POINTER)(sp)
68  SREG x15, (15 * CPU_SIZEOF_POINTER)(sp)
69  SREG x16, (16 * CPU_SIZEOF_POINTER)(sp)
70  SREG x17, (17 * CPU_SIZEOF_POINTER)(sp)
71  SREG x18, (18 * CPU_SIZEOF_POINTER)(sp)
72  SREG x19, (19 * CPU_SIZEOF_POINTER)(sp)
73  SREG x20, (20 * CPU_SIZEOF_POINTER)(sp)
74  SREG x21, (21 * CPU_SIZEOF_POINTER)(sp)
75  SREG x22, (22 * CPU_SIZEOF_POINTER)(sp)
76  SREG x23, (23 * CPU_SIZEOF_POINTER)(sp)
77  SREG x24, (24 * CPU_SIZEOF_POINTER)(sp)
78  SREG x25, (25 * CPU_SIZEOF_POINTER)(sp)
79  SREG x26, (26 * CPU_SIZEOF_POINTER)(sp)
80  SREG x27, (27 * CPU_SIZEOF_POINTER)(sp)
81  SREG x28, (28 * CPU_SIZEOF_POINTER)(sp)
82  SREG x29, (28 * CPU_SIZEOF_POINTER)(sp)
83  SREG x30, (30 * CPU_SIZEOF_POINTER)(sp)
84  SREG x31, (31 * CPU_SIZEOF_POINTER)(sp)
85
86  /* Exception level related registers */
87  csrr a0, mstatus
88  SREG a0, (32 * CPU_SIZEOF_POINTER)(sp)
89  csrr a0, mcause
90  SREG a0, (33 * CPU_SIZEOF_POINTER)(sp)
91  csrr a1, mepc
92  SREG a1, (34 * CPU_SIZEOF_POINTER)(sp)
93
94  /* FIXME Only handle interrupts for now (MSB = 1) */
95  andi a0, a0, 0xf
96
97  /* Increment nesting level */
98  la t0, ISR_NEST_LEVEL
99
100  /* Disable multitasking */
101  la t1, THREAD_DISPATCH_DISABLE_LEVEL
102
103  lw t2, (t0)
104  lw t3, (t1)
105  addi t2, t2, 1
106  addi t3, t3, 1
107  sw t2, (t0)
108  sw t3, (t1)
109
110  /* Save interrupted task stack pointer */
111  addi t4, sp, 36 * CPU_SIZEOF_POINTER
112  SREG t4, (2 * CPU_SIZEOF_POINTER)(sp)
113
114  /* Keep sp (Exception frame address) in s1 */
115  mv   s1, sp
116
117  /* Call the exception handler from vector table */
118
119  /* First function arg for C handler is vector number,
120   * and the second is a pointer to exception frame.
121   * a0/mcause/vector number is already loaded above */
122  mv a1, sp
123
124  /* calculate the offset */
125  la   t5, bsp_start_vector_table_begin
126#if __riscv_xlen == 32
127  slli t6, a0, 2
128#else /* xlen = 64 */
129  slli t6, a0, 3
130#endif
131  add  t5, t5, t6
132  LREG t5, (t5)
133
134  /* Do not switch stacks if we are in a nested interrupt. At
135   * this point t2 should be holding ISR_NEST_LEVEL value.
136   */
137  li   s0, 1
138  bgtu t2, s0, jump_to_c_handler
139
140  /* Switch to RTEMS dedicated interrupt stack */
141  la     sp, INTERRUPT_STACK_HIGH
142  LREG   sp, (sp)
143
144jump_to_c_handler:
145  jalr t5
146
147  /* Switch back to the interrupted task stack */
148  mv sp, s1
149
150  /* Decrement nesting level */
151  la t0, ISR_NEST_LEVEL
152
153  /* Enable multitasking */
154  la t1, THREAD_DISPATCH_DISABLE_LEVEL
155
156  Lw t2, (t0)
157  lw t3, (t1)
158  addi t2, t2, -1
159  addi t3, t3, -1
160  sw t2, (t0)
161  sw t3, (t1)
162
163  /* Check if _ISR_Nest_level > 0 */
164  bgtz t2, exception_frame_restore
165
166  /* Check if _Thread_Dispatch_disable_level > 0 */
167  bgtz t3, exception_frame_restore
168
169  /* Check if dispatch needed */
170  la   x31, DISPATCH_NEEDED
171  lw x31, (x31)
172  beqz x31, exception_frame_restore
173
174  la x31, _Thread_Dispatch
175  jalr x31
176
177  SYM(exception_frame_restore):
178  LREG x1, (1 * CPU_SIZEOF_POINTER)(sp)
179  /* Skip sp/x2 */
180  LREG x3, (3 * CPU_SIZEOF_POINTER)(sp)
181  LREG x4, (4 * CPU_SIZEOF_POINTER)(sp)
182  LREG x5, (5 * CPU_SIZEOF_POINTER)(sp)
183  LREG x6, (6 * CPU_SIZEOF_POINTER)(sp)
184  LREG x7, (7 * CPU_SIZEOF_POINTER)(sp)
185  LREG x8, (8 * CPU_SIZEOF_POINTER)(sp)
186  LREG x9, (9 * CPU_SIZEOF_POINTER)(sp)
187  LREG x10, (10 * CPU_SIZEOF_POINTER)(sp)
188  LREG x11, (11 * CPU_SIZEOF_POINTER)(sp)
189  LREG x12, (12 * CPU_SIZEOF_POINTER)(sp)
190  LREG x13, (13 * CPU_SIZEOF_POINTER)(sp)
191  LREG x14, (14 * CPU_SIZEOF_POINTER)(sp)
192  LREG x15, (15 * CPU_SIZEOF_POINTER)(sp)
193  LREG x16, (16 * CPU_SIZEOF_POINTER)(sp)
194  LREG x17, (17 * CPU_SIZEOF_POINTER)(sp)
195  LREG x18, (18 * CPU_SIZEOF_POINTER)(sp)
196  LREG x19, (19 * CPU_SIZEOF_POINTER)(sp)
197  LREG x20, (20 * CPU_SIZEOF_POINTER)(sp)
198  LREG x21, (21 * CPU_SIZEOF_POINTER)(sp)
199  LREG x22, (22 * CPU_SIZEOF_POINTER)(sp)
200  LREG x23, (23 * CPU_SIZEOF_POINTER)(sp)
201  LREG x24, (24 * CPU_SIZEOF_POINTER)(sp)
202  LREG x25, (25 * CPU_SIZEOF_POINTER)(sp)
203  LREG x26, (26 * CPU_SIZEOF_POINTER)(sp)
204  LREG x27, (27 * CPU_SIZEOF_POINTER)(sp)
205  LREG x28, (28 * CPU_SIZEOF_POINTER)(sp)
206  LREG x29, (29 * CPU_SIZEOF_POINTER)(sp)
207  LREG x30, (30 * CPU_SIZEOF_POINTER)(sp)
208
209  /* Load mstatus */
210  LREG x31, (32 * CPU_SIZEOF_POINTER)(sp)
211  csrw mstatus, x31
212  /* Load mepc */
213  LREG x31, (34 * CPU_SIZEOF_POINTER)(sp)
214  csrw mepc, x31
215
216  LREG x31, (31 * CPU_SIZEOF_POINTER)(sp)
217
218  /* Unwind exception frame */
219  addi sp, sp, 36 * CPU_SIZEOF_POINTER
220
221  mret
Note: See TracBrowser for help on using the repository browser.