source: rtems/cpukit/score/cpu/riscv/cpu.c @ 5694b0c

Last change on this file since 5694b0c was 5694b0c, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 19, 2018 at 8:15:53 AM

riscv: New CPU_Exception_frame

Use the CPU_Interrupt_frame for the volatile context. Add non-volatile
registers and extra state on top of it.

Update #3433.

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH
3 *
4 * Copyright (c) 2015 University of York.
5 * Hesham ALmatary <hesham@alumni.york.ac.uk>
6 *
7 * COPYRIGHT (c) 1989-1999.
8 * On-Line Applications Research Corporation (OAR).
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <rtems/score/cpuimpl.h>
33#include <rtems/score/isr.h>
34#include <rtems/score/riscv-utility.h>
35
36#define RISCV_ASSERT_CONTEXT_OFFSET( field, off ) \
37  RTEMS_STATIC_ASSERT( \
38    offsetof( Context_Control, field) == RISCV_CONTEXT_ ## off, \
39    riscv_context_offset_ ## field \
40  )
41
42RISCV_ASSERT_CONTEXT_OFFSET( isr_dispatch_disable, ISR_DISPATCH_DISABLE );
43#ifdef RTEMS_SMP
44RISCV_ASSERT_CONTEXT_OFFSET( is_executing, IS_EXECUTING );
45#endif
46RISCV_ASSERT_CONTEXT_OFFSET( ra, RA );
47RISCV_ASSERT_CONTEXT_OFFSET( sp, SP );
48RISCV_ASSERT_CONTEXT_OFFSET( tp, TP );
49RISCV_ASSERT_CONTEXT_OFFSET( s0, S0 );
50RISCV_ASSERT_CONTEXT_OFFSET( s1, S1 );
51RISCV_ASSERT_CONTEXT_OFFSET( s2, S2 );
52RISCV_ASSERT_CONTEXT_OFFSET( s3, S3 );
53RISCV_ASSERT_CONTEXT_OFFSET( s4, S4 );
54RISCV_ASSERT_CONTEXT_OFFSET( s5, S5 );
55RISCV_ASSERT_CONTEXT_OFFSET( s6, S6 );
56RISCV_ASSERT_CONTEXT_OFFSET( s7, S7 );
57RISCV_ASSERT_CONTEXT_OFFSET( s8, S8 );
58RISCV_ASSERT_CONTEXT_OFFSET( s9, S9 );
59RISCV_ASSERT_CONTEXT_OFFSET( s10, S10 );
60RISCV_ASSERT_CONTEXT_OFFSET( s11, S11 );
61
62#if __riscv_flen > 0
63
64RISCV_ASSERT_CONTEXT_OFFSET( fcsr, FCSR );
65RISCV_ASSERT_CONTEXT_OFFSET( fs0, FS0 );
66RISCV_ASSERT_CONTEXT_OFFSET( fs1, FS1 );
67RISCV_ASSERT_CONTEXT_OFFSET( fs2, FS2 );
68RISCV_ASSERT_CONTEXT_OFFSET( fs3, FS3 );
69RISCV_ASSERT_CONTEXT_OFFSET( fs4, FS4 );
70RISCV_ASSERT_CONTEXT_OFFSET( fs5, FS5 );
71RISCV_ASSERT_CONTEXT_OFFSET( fs6, FS6 );
72RISCV_ASSERT_CONTEXT_OFFSET( fs7, FS7 );
73RISCV_ASSERT_CONTEXT_OFFSET( fs8, FS8 );
74RISCV_ASSERT_CONTEXT_OFFSET( fs9, FS9 );
75RISCV_ASSERT_CONTEXT_OFFSET( fs10, FS10 );
76RISCV_ASSERT_CONTEXT_OFFSET( fs11, FS11 );
77
78#endif /* __riscv_flen */
79
80#define RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( field, off ) \
81  RTEMS_STATIC_ASSERT( \
82    offsetof( CPU_Interrupt_frame, field) == RISCV_INTERRUPT_FRAME_ ## off, \
83    riscv_interrupt_frame_offset_ ## field \
84  )
85
86RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( mstatus, MSTATUS );
87RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( mepc, MEPC );
88RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a2, A2 );
89RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( s0, S0 );
90RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( s1, S1 );
91RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ra, RA );
92RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a3, A3 );
93RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a4, A4 );
94RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a5, A5 );
95RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a6, A6 );
96RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a7, A7 );
97RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t0, T0 );
98RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t1, T1 );
99RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t2, T2 );
100RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t3, T3 );
101RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t4, T4 );
102RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t5, T5 );
103RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( t6, T6 );
104RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a0, A0 );
105RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( a1, A1 );
106
107#if __riscv_flen > 0
108
109RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fcsr, FCSR );
110RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft0, FT0 );
111RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft1, FT1 );
112RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft2, FT2 );
113RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft3, FT3 );
114RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft4, FT4 );
115RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft5, FT5 );
116RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft6, FT6 );
117RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft7, FT7 );
118RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft8, FT8 );
119RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft9, FT9 );
120RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft10, FT10 );
121RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( ft11, FT11 );
122RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa0, FA0 );
123RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa1, FA1 );
124RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa2, FA2 );
125RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa3, FA3 );
126RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa4, FA4 );
127RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa5, FA5 );
128RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa6, FA6 );
129RISCV_ASSERT_INTERRUPT_FRAME_OFFSET( fa7, FA7 );
130
131#endif /* __riscv_flen */
132
133#define RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( field, off ) \
134  RTEMS_STATIC_ASSERT( \
135    offsetof( CPU_Exception_frame, field) == RISCV_EXCEPTION_FRAME_ ## off, \
136    riscv_context_offset_ ## field \
137  )
138
139RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( mcause, MCAUSE );
140RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( sp, SP );
141RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( gp, GP );
142RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( tp, TP );
143RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s2, S2 );
144RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s3, S3 );
145RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s4, S4 );
146RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s5, S5 );
147RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s6, S6 );
148RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s7, S7 );
149RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s8, S8 );
150RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s9, S9 );
151RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s10, S10 );
152RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( s11, S11 );
153
154#if __riscv_flen > 0
155
156RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs0, FS0 );
157RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs1, FS1 );
158RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs2, FS2 );
159RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs3, FS3 );
160RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs4, FS4 );
161RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs5, FS5 );
162RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs6, FS6 );
163RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs7, FS7 );
164RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs8, FS8 );
165RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs9, FS9 );
166RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs10, FS10 );
167RISCV_ASSERT_EXCEPTION_FRAME_OFFSET( fs11, FS11 );
168
169#endif /* __riscv_flen */
170
171RTEMS_STATIC_ASSERT(
172  sizeof( CPU_Interrupt_frame ) % CPU_STACK_ALIGNMENT == 0,
173  riscv_interrupt_frame_size
174);
175
176/* bsp_start_vector_table_begin is the start address of the vector table
177 * containing addresses to ISR Handlers. It's defined at the BSP linkcmds
178 * and may differ from one BSP to another.
179 */
180extern char bsp_start_vector_table_begin[];
181
182void _init(void);
183
184void _fini(void);
185
186void _init(void)
187{
188}
189
190void _fini(void)
191{
192}
193
194/**
195 * @brief Performs processor dependent initialization.
196 */
197void _CPU_Initialize(void)
198{
199  /* Do nothing */
200}
201
202uint32_t _CPU_ISR_Get_level( void )
203{
204  if ( _CPU_ISR_Is_enabled( read_csr( mstatus ) ) ) {
205    return 0;
206  }
207
208  return 1;
209}
210
211void _CPU_ISR_install_raw_handler(
212  uint32_t   vector,
213  proc_ptr    new_handler,
214  proc_ptr   *old_handler
215)
216{
217  /* Do nothing */
218}
219
220void _CPU_ISR_install_vector(
221  unsigned long    vector,
222  proc_ptr    new_handler,
223  proc_ptr   *old_handler
224)
225{
226  proc_ptr *table =
227    (proc_ptr *) bsp_start_vector_table_begin;
228  proc_ptr current_handler;
229
230  ISR_Level level;
231
232  _ISR_Local_disable( level );
233
234  current_handler = table [vector];
235
236  /* The current handler is now the old one */
237  if (old_handler != NULL) {
238    *old_handler = (proc_ptr) current_handler;
239  }
240
241  /* Write only if necessary to avoid writes to a maybe read-only
242   * memory */
243  if (current_handler != new_handler) {
244    table [vector] = new_handler;
245  }
246
247  _ISR_Local_enable( level );
248
249}
250
251void *_CPU_Thread_Idle_body( uintptr_t ignored )
252{
253  do {
254  } while (1);
255
256  return NULL;
257}
Note: See TracBrowser for help on using the repository browser.