source: rtems/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h @ a660e9dc

Last change on this file since a660e9dc was a660e9dc, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/22 at 08:37:05

Do not use RTEMS_INLINE_ROUTINE

Directly use "static inline" which is available in C99 and later. This brings
the RTEMS implementation closer to standard C.

Close #3935.

  • Property mode set to 100644
File size: 13.0 KB
Line 
1/**
2 * @file
3 *
4 * @brief CPU Port Implementation API
5 */
6
7/*
8 * Copyright (c) 2013, 2018 embedded brains GmbH
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#ifndef _RTEMS_SCORE_CPUIMPL_H
33#define _RTEMS_SCORE_CPUIMPL_H
34
35#include <rtems/score/cpu.h>
36
37/**
38 * @defgroup RTEMSScoreCPURISCV RISC-V
39 *
40 * @ingroup RTEMSScoreCPU
41 *
42 * @brief RISCV Architecture Support
43 *
44 * @{
45 */
46
47#if defined(__riscv_atomic) && __riscv_xlen == 64
48#define CPU_PER_CPU_CONTROL_SIZE 48
49#elif defined(__riscv_atomic) && __riscv_xlen == 32
50#define CPU_PER_CPU_CONTROL_SIZE 32
51#elif __riscv_xlen == 64
52#define CPU_PER_CPU_CONTROL_SIZE 32
53#elif __riscv_xlen == 32
54#define CPU_PER_CPU_CONTROL_SIZE 16
55#endif
56
57#ifdef RTEMS_SMP
58#define RISCV_CONTEXT_IS_EXECUTING 0
59#endif
60
61#define RISCV_CONTEXT_ISR_DISPATCH_DISABLE 4
62
63#if __riscv_xlen == 32
64
65#define RISCV_CONTEXT_RA 8
66#define RISCV_CONTEXT_SP 12
67#define RISCV_CONTEXT_TP 16
68#define RISCV_CONTEXT_S0 20
69#define RISCV_CONTEXT_S1 24
70#define RISCV_CONTEXT_S2 28
71#define RISCV_CONTEXT_S3 32
72#define RISCV_CONTEXT_S4 36
73#define RISCV_CONTEXT_S5 40
74#define RISCV_CONTEXT_S6 44
75#define RISCV_CONTEXT_S7 48
76#define RISCV_CONTEXT_S8 52
77#define RISCV_CONTEXT_S9 56
78#define RISCV_CONTEXT_S10 60
79#define RISCV_CONTEXT_S11 64
80
81#define RISCV_INTERRUPT_FRAME_MSTATUS 0
82#define RISCV_INTERRUPT_FRAME_MEPC 4
83#define RISCV_INTERRUPT_FRAME_A2 8
84#define RISCV_INTERRUPT_FRAME_S0 12
85#define RISCV_INTERRUPT_FRAME_S1 16
86#define RISCV_INTERRUPT_FRAME_RA 20
87#define RISCV_INTERRUPT_FRAME_A3 24
88#define RISCV_INTERRUPT_FRAME_A4 28
89#define RISCV_INTERRUPT_FRAME_A5 32
90#define RISCV_INTERRUPT_FRAME_A6 36
91#define RISCV_INTERRUPT_FRAME_A7 40
92#define RISCV_INTERRUPT_FRAME_T0 44
93#define RISCV_INTERRUPT_FRAME_T1 48
94#define RISCV_INTERRUPT_FRAME_T2 52
95#define RISCV_INTERRUPT_FRAME_T3 56
96#define RISCV_INTERRUPT_FRAME_T4 60
97#define RISCV_INTERRUPT_FRAME_T5 64
98#define RISCV_INTERRUPT_FRAME_T6 68
99
100#if __riscv_flen == 0
101
102#define RISCV_INTERRUPT_FRAME_A0 72
103#define RISCV_INTERRUPT_FRAME_A1 76
104
105#define CPU_INTERRUPT_FRAME_SIZE 80
106
107#elif __riscv_flen == 32
108
109#define RISCV_CONTEXT_FCSR 68
110
111#define RISCV_CONTEXT_F( x ) ( 72 + 4 * x )
112
113#define RISCV_INTERRUPT_FRAME_FCSR 72
114
115#define RISCV_INTERRUPT_FRAME_F( x ) ( 76 + 4 * x )
116
117#define RISCV_INTERRUPT_FRAME_A0 156
118#define RISCV_INTERRUPT_FRAME_A1 160
119
120#define CPU_INTERRUPT_FRAME_SIZE 176
121
122#elif __riscv_flen == 64
123
124#define RISCV_CONTEXT_FCSR 68
125
126#define RISCV_CONTEXT_F( x ) ( 72 + 8 * x )
127
128#define RISCV_INTERRUPT_FRAME_FCSR 72
129
130#define RISCV_INTERRUPT_FRAME_F( x ) ( 80 + 8 * x )
131
132#define RISCV_INTERRUPT_FRAME_A0 240
133#define RISCV_INTERRUPT_FRAME_A1 244
134
135#define CPU_INTERRUPT_FRAME_SIZE 256
136
137#endif /* __riscv_flen */
138
139#define RISCV_EXCEPTION_FRAME_X( x ) ( CPU_INTERRUPT_FRAME_SIZE + 4 * x )
140
141#elif __riscv_xlen == 64
142
143#define RISCV_CONTEXT_RA 8
144#define RISCV_CONTEXT_SP 16
145#define RISCV_CONTEXT_TP 24
146#define RISCV_CONTEXT_S0 32
147#define RISCV_CONTEXT_S1 40
148#define RISCV_CONTEXT_S2 48
149#define RISCV_CONTEXT_S3 56
150#define RISCV_CONTEXT_S4 64
151#define RISCV_CONTEXT_S5 72
152#define RISCV_CONTEXT_S6 80
153#define RISCV_CONTEXT_S7 88
154#define RISCV_CONTEXT_S8 96
155#define RISCV_CONTEXT_S9 104
156#define RISCV_CONTEXT_S10 112
157#define RISCV_CONTEXT_S11 120
158
159#define RISCV_INTERRUPT_FRAME_MSTATUS 0
160#define RISCV_INTERRUPT_FRAME_MEPC 8
161#define RISCV_INTERRUPT_FRAME_A2 16
162#define RISCV_INTERRUPT_FRAME_S0 24
163#define RISCV_INTERRUPT_FRAME_S1 32
164#define RISCV_INTERRUPT_FRAME_RA 40
165#define RISCV_INTERRUPT_FRAME_A3 48
166#define RISCV_INTERRUPT_FRAME_A4 56
167#define RISCV_INTERRUPT_FRAME_A5 64
168#define RISCV_INTERRUPT_FRAME_A6 72
169#define RISCV_INTERRUPT_FRAME_A7 80
170#define RISCV_INTERRUPT_FRAME_T0 88
171#define RISCV_INTERRUPT_FRAME_T1 96
172#define RISCV_INTERRUPT_FRAME_T2 104
173#define RISCV_INTERRUPT_FRAME_T3 112
174#define RISCV_INTERRUPT_FRAME_T4 120
175#define RISCV_INTERRUPT_FRAME_T5 128
176#define RISCV_INTERRUPT_FRAME_T6 136
177
178#if __riscv_flen == 0
179
180#define RISCV_INTERRUPT_FRAME_A0 144
181#define RISCV_INTERRUPT_FRAME_A1 152
182
183#define CPU_INTERRUPT_FRAME_SIZE 160
184
185#elif __riscv_flen == 32
186
187#define RISCV_CONTEXT_FCSR 128
188
189#define RISCV_CONTEXT_F( x ) ( 132 + 4 * x )
190
191#define RISCV_INTERRUPT_FRAME_FCSR 144
192
193#define RISCV_INTERRUPT_FRAME_F( x ) ( 148 + 4 * x )
194
195#define RISCV_INTERRUPT_FRAME_A0 232
196#define RISCV_INTERRUPT_FRAME_A1 240
197
198#define CPU_INTERRUPT_FRAME_SIZE 256
199
200#elif __riscv_flen == 64
201
202#define RISCV_CONTEXT_FCSR 128
203
204#define RISCV_CONTEXT_F( x ) ( 136 + 8 * x )
205
206#define RISCV_INTERRUPT_FRAME_FCSR 144
207
208#define RISCV_INTERRUPT_FRAME_F( x ) ( 152 + 8 * x )
209
210#define RISCV_INTERRUPT_FRAME_A0 312
211#define RISCV_INTERRUPT_FRAME_A1 320
212
213#define CPU_INTERRUPT_FRAME_SIZE 336
214
215#endif /* __riscv_flen */
216
217#define RISCV_EXCEPTION_FRAME_X( x ) ( CPU_INTERRUPT_FRAME_SIZE + 8 * x )
218
219#endif /* __riscv_xlen */
220
221#define RISCV_EXCEPTION_FRAME_MCAUSE RISCV_EXCEPTION_FRAME_X( 0 )
222#define RISCV_EXCEPTION_FRAME_SP RISCV_EXCEPTION_FRAME_X( 1 )
223#define RISCV_EXCEPTION_FRAME_GP RISCV_EXCEPTION_FRAME_X( 2 )
224#define RISCV_EXCEPTION_FRAME_TP RISCV_EXCEPTION_FRAME_X( 3 )
225#define RISCV_EXCEPTION_FRAME_S2 RISCV_EXCEPTION_FRAME_X( 4 )
226#define RISCV_EXCEPTION_FRAME_S3 RISCV_EXCEPTION_FRAME_X( 5 )
227#define RISCV_EXCEPTION_FRAME_S4 RISCV_EXCEPTION_FRAME_X( 6 )
228#define RISCV_EXCEPTION_FRAME_S5 RISCV_EXCEPTION_FRAME_X( 7 )
229#define RISCV_EXCEPTION_FRAME_S6 RISCV_EXCEPTION_FRAME_X( 8 )
230#define RISCV_EXCEPTION_FRAME_S7 RISCV_EXCEPTION_FRAME_X( 9 )
231#define RISCV_EXCEPTION_FRAME_S8 RISCV_EXCEPTION_FRAME_X( 10 )
232#define RISCV_EXCEPTION_FRAME_S9 RISCV_EXCEPTION_FRAME_X( 11 )
233#define RISCV_EXCEPTION_FRAME_S10 RISCV_EXCEPTION_FRAME_X( 12 )
234#define RISCV_EXCEPTION_FRAME_S11 RISCV_EXCEPTION_FRAME_X( 13 )
235
236#if __riscv_flen > 0
237
238#define RISCV_CONTEXT_FS0 RISCV_CONTEXT_F( 0 )
239#define RISCV_CONTEXT_FS1 RISCV_CONTEXT_F( 1 )
240#define RISCV_CONTEXT_FS2 RISCV_CONTEXT_F( 2 )
241#define RISCV_CONTEXT_FS3 RISCV_CONTEXT_F( 3 )
242#define RISCV_CONTEXT_FS4 RISCV_CONTEXT_F( 4 )
243#define RISCV_CONTEXT_FS5 RISCV_CONTEXT_F( 5 )
244#define RISCV_CONTEXT_FS6 RISCV_CONTEXT_F( 6 )
245#define RISCV_CONTEXT_FS7 RISCV_CONTEXT_F( 7 )
246#define RISCV_CONTEXT_FS8 RISCV_CONTEXT_F( 8 )
247#define RISCV_CONTEXT_FS9 RISCV_CONTEXT_F( 9 )
248#define RISCV_CONTEXT_FS10 RISCV_CONTEXT_F( 10 )
249#define RISCV_CONTEXT_FS11 RISCV_CONTEXT_F( 11 )
250
251#define RISCV_INTERRUPT_FRAME_FT0 RISCV_INTERRUPT_FRAME_F( 0 )
252#define RISCV_INTERRUPT_FRAME_FT1 RISCV_INTERRUPT_FRAME_F( 1 )
253#define RISCV_INTERRUPT_FRAME_FT2 RISCV_INTERRUPT_FRAME_F( 2 )
254#define RISCV_INTERRUPT_FRAME_FT3 RISCV_INTERRUPT_FRAME_F( 3 )
255#define RISCV_INTERRUPT_FRAME_FT4 RISCV_INTERRUPT_FRAME_F( 4 )
256#define RISCV_INTERRUPT_FRAME_FT5 RISCV_INTERRUPT_FRAME_F( 5 )
257#define RISCV_INTERRUPT_FRAME_FT6 RISCV_INTERRUPT_FRAME_F( 6 )
258#define RISCV_INTERRUPT_FRAME_FT7 RISCV_INTERRUPT_FRAME_F( 7 )
259#define RISCV_INTERRUPT_FRAME_FT8 RISCV_INTERRUPT_FRAME_F( 8 )
260#define RISCV_INTERRUPT_FRAME_FT9 RISCV_INTERRUPT_FRAME_F( 9 )
261#define RISCV_INTERRUPT_FRAME_FT10 RISCV_INTERRUPT_FRAME_F( 10 )
262#define RISCV_INTERRUPT_FRAME_FT11 RISCV_INTERRUPT_FRAME_F( 11 )
263#define RISCV_INTERRUPT_FRAME_FA0 RISCV_INTERRUPT_FRAME_F( 12 )
264#define RISCV_INTERRUPT_FRAME_FA1 RISCV_INTERRUPT_FRAME_F( 13 )
265#define RISCV_INTERRUPT_FRAME_FA2 RISCV_INTERRUPT_FRAME_F( 14 )
266#define RISCV_INTERRUPT_FRAME_FA3 RISCV_INTERRUPT_FRAME_F( 15 )
267#define RISCV_INTERRUPT_FRAME_FA4 RISCV_INTERRUPT_FRAME_F( 16 )
268#define RISCV_INTERRUPT_FRAME_FA5 RISCV_INTERRUPT_FRAME_F( 17 )
269#define RISCV_INTERRUPT_FRAME_FA6 RISCV_INTERRUPT_FRAME_F( 18 )
270#define RISCV_INTERRUPT_FRAME_FA7 RISCV_INTERRUPT_FRAME_F( 19 )
271
272#if __riscv_flen == 32
273#define RISCV_EXCEPTION_FRAME_F( x ) ( RISCV_EXCEPTION_FRAME_X( 14 ) + 4 * x )
274#elif __riscv_flen == 64
275#define RISCV_EXCEPTION_FRAME_F( x ) ( RISCV_EXCEPTION_FRAME_X( 14 ) + 8 * x )
276#endif
277
278#define RISCV_EXCEPTION_FRAME_FS0 RISCV_EXCEPTION_FRAME_F( 0 )
279#define RISCV_EXCEPTION_FRAME_FS1 RISCV_EXCEPTION_FRAME_F( 1 )
280#define RISCV_EXCEPTION_FRAME_FS2 RISCV_EXCEPTION_FRAME_F( 2 )
281#define RISCV_EXCEPTION_FRAME_FS3 RISCV_EXCEPTION_FRAME_F( 3 )
282#define RISCV_EXCEPTION_FRAME_FS4 RISCV_EXCEPTION_FRAME_F( 4 )
283#define RISCV_EXCEPTION_FRAME_FS5 RISCV_EXCEPTION_FRAME_F( 5 )
284#define RISCV_EXCEPTION_FRAME_FS6 RISCV_EXCEPTION_FRAME_F( 6 )
285#define RISCV_EXCEPTION_FRAME_FS7 RISCV_EXCEPTION_FRAME_F( 7 )
286#define RISCV_EXCEPTION_FRAME_FS8 RISCV_EXCEPTION_FRAME_F( 8 )
287#define RISCV_EXCEPTION_FRAME_FS9 RISCV_EXCEPTION_FRAME_F( 9 )
288#define RISCV_EXCEPTION_FRAME_FS10 RISCV_EXCEPTION_FRAME_F( 10 )
289#define RISCV_EXCEPTION_FRAME_FS11 RISCV_EXCEPTION_FRAME_F( 11 )
290
291#endif /* __riscv_flen */
292
293#ifndef ASM
294
295#ifdef __cplusplus
296extern "C" {
297#endif
298
299/* Core Local Interruptor (CLINT) */
300
301typedef union {
302  uint64_t val_64;
303  uint32_t val_32[2];
304} RISCV_CLINT_timer_reg;
305
306typedef struct {
307  uint32_t msip[4096];
308  RISCV_CLINT_timer_reg mtimecmp[2048];
309  uint32_t reserved_8000[4094];
310  RISCV_CLINT_timer_reg mtime;
311  uint32_t reserved_c000[4096];
312} RISCV_CLINT_regs;
313
314/* Platform-Level Interrupt Controller (PLIC) */
315
316#define RISCV_PLIC_MAX_INTERRUPTS 1024
317
318typedef struct {
319  uint32_t priority_threshold;
320  uint32_t claim_complete;
321  uint32_t reserved_8[1022];
322} RISCV_PLIC_hart_regs;
323
324typedef struct {
325  uint32_t priority[RISCV_PLIC_MAX_INTERRUPTS];
326  uint32_t pending[1024];
327  uint32_t enable[16320][32];
328  RISCV_PLIC_hart_regs harts[CPU_MAXIMUM_PROCESSORS];
329} RISCV_PLIC_regs;
330
331typedef struct {
332#ifdef __riscv_atomic
333  uint64_t clear_reservations;
334  uint32_t reserved_for_alignment_of_interrupt_frame[ 2 ];
335#endif
336  volatile RISCV_PLIC_hart_regs *plic_hart_regs;
337  volatile uint32_t *plic_m_ie;
338  volatile RISCV_CLINT_timer_reg *clint_mtimecmp;
339  volatile uint32_t *clint_msip;
340} CPU_Per_CPU_control;
341
342struct Per_CPU_Control;
343
344void _RISCV_Interrupt_dispatch(
345  uintptr_t               mcause,
346  struct Per_CPU_Control *cpu_self
347);
348
349static inline uint32_t _RISCV_Read_FCSR( void )
350{
351  uint32_t fcsr;
352
353  __asm__ volatile ( "frcsr %0" : "=&r" ( fcsr ) );
354
355  return fcsr;
356}
357
358/*
359 * The RISC-V ISA provides a rdtime instruction, however, it is implemented in
360 * most chips via a trap-and-emulate.  Using this in machine mode makes no
361 * sense.  Use the memory-mapped mtime register directly instead.  The address
362 * of this register is platform-specific and provided via the device tree.
363 *
364 * To allow better code generation provide a const (_RISCV_Counter) and a
365 * mutable (_RISCV_Counter_mutable) declaration for this pointer variable
366 * (defined in assembler code).
367 *
368 * See code generated for this test case:
369 *
370 * extern volatile int * const c;
371 *
372 * extern volatile int *v;
373 *
374 * int fc(void)
375 * {
376 *   int a = *c;
377 *   __asm__ volatile("" ::: "memory");
378 *   return *c - a;
379 * }
380 *
381 * int fv(void)
382 * {
383 *   int a = *v;
384 *   __asm__ volatile("" ::: "memory");
385 *   return *v - a;
386 * }
387 */
388extern volatile uint32_t *_RISCV_Counter_mutable;
389
390/*
391 * Initial value of _RISCV_Counter and _RISCV_Counter_mutable.  Must be
392 * provided by the BSP.
393 */
394extern volatile uint32_t _RISCV_Counter_register;
395
396#ifdef RTEMS_SMP
397
398static inline struct Per_CPU_Control *_RISCV_Get_current_per_CPU_control( void )
399{
400  struct Per_CPU_Control *cpu_self;
401
402  __asm__ volatile (
403    ".option push\n"
404    ".option arch, +zicsr\n"
405    "csrr %0, mscratch\n"
406    ".option pop" :
407    "=r" ( cpu_self )
408  );
409
410  return cpu_self;
411}
412
413#define _CPU_Get_current_per_CPU_control() _RISCV_Get_current_per_CPU_control()
414
415#endif /* RTEMS_SMP */
416
417RTEMS_NO_RETURN void _CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr error );
418
419void _CPU_Context_volatile_clobber( uintptr_t pattern );
420
421void _CPU_Context_validate( uintptr_t pattern );
422
423static inline void _CPU_Instruction_illegal( void )
424{
425  __asm__ volatile ( "unimp" );
426}
427
428static inline void _CPU_Instruction_no_operation( void )
429{
430  __asm__ volatile ( "nop" );
431}
432
433static inline void _CPU_Use_thread_local_storage(
434  const Context_Control *context
435)
436{
437   register uintptr_t tp __asm__( "tp" );
438
439   tp = context->tp;
440
441   /* Make sure that the register assignment is not optimized away */
442   __asm__ volatile ( "" : : "r" ( tp ) );
443}
444
445#ifdef __cplusplus
446}
447#endif
448
449#endif /* ASM */
450
451/** @} */
452
453#endif /* _RTEMS_SCORE_CPUIMPL_H */
Note: See TracBrowser for help on using the repository browser.