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