RTEMS
6.3
Toggle main menu visibility
Loading...
Searching...
No Matches
cpukit
score
cpu
riscv
include
rtems
score
cpuimpl.h
Go to the documentation of this file.
1
6
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
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
#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
298
extern
"C"
{
299
#endif
300
301
static
inline
uint32_t _RISCV_Map_hardid_to_cpu_index( uint32_t hardid )
302
{
303
return
hardid - RISCV_BOOT_HARTID;
304
}
305
306
static
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
313
typedef
union
{
314
uint64_t val_64;
315
uint32_t val_32[2];
316
}
RISCV_CLINT_timer_reg
;
317
318
typedef
struct
{
319
uint32_t msip[4096];
320
RISCV_CLINT_timer_reg
mtimecmp[2048];
321
uint32_t reserved_8000[4094];
322
RISCV_CLINT_timer_reg
mtime;
323
uint32_t reserved_c000[4096];
324
}
RISCV_CLINT_regs
;
325
326
/* Platform-Level Interrupt Controller (PLIC) */
327
328
#define RISCV_PLIC_MAX_INTERRUPTS 1024
329
330
typedef
struct
{
331
uint32_t priority_threshold;
332
uint32_t claim_complete;
333
uint32_t reserved_8[1022];
334
}
RISCV_PLIC_hart_regs
;
335
336
typedef
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];
341
}
RISCV_PLIC_regs
;
342
343
typedef
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;
352
}
CPU_Per_CPU_control
;
353
354
struct
Per_CPU_Control
;
355
356
void
_RISCV_Interrupt_dispatch(
357
uintptr_t mcause,
358
struct
Per_CPU_Control
*cpu_self
359
);
360
361
static
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
*/
400
extern
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
*/
406
extern
volatile
uint32_t _RISCV_Counter_register;
407
408
#ifdef RTEMS_SMP
409
410
static
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
429
void
_CPU_Context_volatile_clobber( uintptr_t pattern );
430
431
void
_CPU_Context_validate( uintptr_t pattern );
432
433
static
inline
void
_CPU_Instruction_illegal(
void
)
434
{
435
__asm__
volatile
(
"unimp"
);
436
}
437
438
static
inline
void
_CPU_Instruction_no_operation(
void
)
439
{
440
__asm__
volatile
(
"nop"
);
441
}
442
443
static
inline
void
_CPU_Use_thread_local_storage(
444
const
Context_Control
*
context
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
455
static
inline
void
*_CPU_Get_TLS_thread_pointer(
456
const
Context_Control
*
context
457
)
458
{
459
return
(
void
*)
context
->tp;
460
}
461
462
#ifdef __cplusplus
463
}
464
#endif
465
466
#endif
/* ASM */
467
469
470
#endif
/* _RTEMS_SCORE_CPUIMPL_H */
CPU_Per_CPU_control
The CPU specific per-CPU control.
Definition
cpuimpl.h:91
Context_Control
Thread register context.
Definition
cpu.h:173
Per_CPU_Control
Per CPU Core Structure.
Definition
percpu.h:384
RISCV_CLINT_regs
Definition
cpuimpl.h:318
RISCV_PLIC_hart_regs
Definition
cpuimpl.h:330
RISCV_PLIC_regs
Definition
cpuimpl.h:336
context
unsigned context
Definition
tlb.h:1
RISCV_CLINT_timer_reg
Definition
cpuimpl.h:313
Generated by
1.18.0