RTEMS: cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h Source File

| RTEMS 5.4-rc2

Loading...
Searching...
No Matches
cpuimpl.h
Go to the documentation of this file.
1
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
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
301 typedef union {
302 uint64_t val_64;
303 uint32_t val_32[2];
304} RISCV_CLINT_timer_reg;
305
306 typedef 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
318 typedef struct {
319 uint32_t priority_threshold;
320 uint32_t claim_complete;
321 uint32_t reserved_8[1022];
322} RISCV_PLIC_hart_regs;
323
324 typedef 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 ( "csrr %0, mscratch" : "=r" ( cpu_self ) );
403
404 return cpu_self;
405}
406
407#define _CPU_Get_current_per_CPU_control() _RISCV_Get_current_per_CPU_control()
408
409#endif /* RTEMS_SMP */
410
411void _CPU_Context_volatile_clobber( uintptr_t pattern );
412
413void _CPU_Context_validate( uintptr_t pattern );
414
415 RTEMS_INLINE_ROUTINE void _CPU_Instruction_illegal( void )
416{
417 __asm__ volatile ( "unimp" );
418}
419
420 RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void )
421{
422 __asm__ volatile ( "nop" );
423}
424
425#ifdef __cplusplus
426}
427#endif
428
429#endif /* ASM */
430
433#endif /* _RTEMS_SCORE_CPUIMPL_H */
RTEMS_INLINE_ROUTINE
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:66
CPU_Per_CPU_control
The CPU specific per-CPU control.
Definition: cpuimpl.h:54
Per_CPU_Control
Per CPU Core Structure.
Definition: percpu.h:347
RISCV_CLINT_regs
Definition: cpuimpl.h:306
RISCV_PLIC_hart_regs
Definition: cpuimpl.h:318
RISCV_PLIC_regs
Definition: cpuimpl.h:324
RISCV_CLINT_timer_reg
Definition: cpuimpl.h:301