RTEMS 6.1-rc1
cpu.h
Go to the documentation of this file.
1
9/*
10 * Copyright (c) 2018.
11 * Amaan Cheval <amaan.cheval@gmail.com>
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#ifndef _RTEMS_SCORE_CPU_H
36#define _RTEMS_SCORE_CPU_H
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
43#include <rtems/score/cpu_asm.h>
44#include <rtems/score/x86_64.h>
45
46#define CPU_SIMPLE_VECTORED_INTERRUPTS FALSE
47#define CPU_ISR_PASSES_FRAME_POINTER FALSE
48#define CPU_HARDWARE_FP FALSE
49#define CPU_SOFTWARE_FP FALSE
50#define CPU_ALL_TASKS_ARE_FP FALSE
51#define CPU_IDLE_TASK_IS_FP FALSE
52#define CPU_USE_DEFERRED_FP_SWITCH FALSE
53#define CPU_ENABLE_ROBUST_THREAD_DISPATCH FALSE
54#define CPU_STACK_GROWS_UP FALSE
55
56#define CPU_STRUCTURE_ALIGNMENT RTEMS_ALIGNED(64)
57#define CPU_CACHE_LINE_BYTES 64
58#define CPU_MODES_INTERRUPT_MASK 0x00000001
59#define CPU_MAXIMUM_PROCESSORS 32
60
61#define CPU_EFLAGS_INTERRUPTS_ON 0x00003202
62#define CPU_EFLAGS_INTERRUPTS_OFF 0x00003002
63
64#ifndef ASM
65
66typedef struct {
67 uint64_t rflags;
68
73 uint64_t rbx;
74 void *rsp;
75 void *rbp;
76 uint64_t r12;
77 uint64_t r13;
78 uint64_t r14;
79 uint64_t r15;
80
81 // XXX: FS segment descriptor for TLS
82
83#ifdef RTEMS_SMP
84 volatile bool is_executing;
85#endif
87
88#define _CPU_Context_Get_SP( _context ) \
89 (_context)->rsp
90
91/*
92 * Caller-saved registers for interrupt frames
93 */
94typedef struct {
103 uint64_t rax;
104 uint64_t rcx;
105 uint64_t rdx;
106 uint64_t rsi;
107 uint64_t r8;
108 uint64_t r9;
109 uint64_t r10;
110 uint64_t r11;
111
112 /*
113 * This holds the rsp just before _ISR_Handler is called; it's needed because
114 * in the handler, we align the stack to make further calls, and we're not
115 * sure how alignment may move the stack-pointer around, leaving no way to get
116 * back to the stack, and therefore the interrupt frame.
117 */
118 uint64_t saved_rsp;
119
120 /* XXX:
121 * - FS segment selector for TLS
122 * - x87 status word?
123 * - MMX?
124 * - XMM?
125 */
127
128#endif /* !ASM */
129
130#define CPU_INTERRUPT_FRAME_SIZE 72
131
132/*
133 * When SMP is enabled, percpuasm.c has a similar assert, but since we use the
134 * interrupt frame regardless of SMP, we'll confirm it here.
135 */
136#ifndef ASM
140 );
141#endif
142
143#define CPU_MPCI_RECEIVE_SERVER_EXTRA_STACK 0
144#define CPU_PROVIDES_ISR_IS_IN_PROGRESS FALSE
145#define CPU_STACK_MINIMUM_SIZE (1024*4)
146#define CPU_SIZEOF_POINTER 8
147#define CPU_ALIGNMENT 16
148#define CPU_HEAP_ALIGNMENT CPU_ALIGNMENT
149#define CPU_STACK_ALIGNMENT 16
150#define CPU_INTERRUPT_STACK_ALIGNMENT CPU_CACHE_LINE_BYTES
151
152/*
153 * ISR handler macros
154 */
155
156#ifndef ASM
157
158#define _CPU_ISR_Enable(_level) \
159{ \
160 amd64_enable_interrupts(); \
161 _level = 0; \
162 (void) _level; /* Prevent -Wunused-but-set-variable */ \
163}
164
165#define _CPU_ISR_Disable(_level) \
166{ \
167 amd64_enable_interrupts(); \
168 _level = 1; \
169 (void) _level; /* Prevent -Wunused-but-set-variable */ \
170}
171
172#define _CPU_ISR_Flash(_level) \
173{ \
174 amd64_enable_interrupts(); \
175 amd64_disable_interrupts(); \
176 _level = 1; \
177 (void) _level; /* Prevent -Wunused-but-set-variable */ \
178}
179
180static inline bool _CPU_ISR_Is_enabled(uint32_t level)
181{
182 return (level & EFLAGS_INTR_ENABLE) != 0;
183}
184
185static inline void _CPU_ISR_Set_level(uint32_t new_level)
186{
187 if ( new_level ) {
188 amd64_disable_interrupts();
189 }
190 else {
191 amd64_enable_interrupts();
192 }
193}
194
195static inline uint32_t _CPU_ISR_Get_level(void)
196{
197 uint64_t rflags;
198
199 __asm__ volatile ( "pushf; \
200 popq %0"
201 : "=rm" (rflags)
202 );
203
204 uint32_t level = (rflags & EFLAGS_INTR_ENABLE) ? 0 : 1;
205 return level;
206}
207
208/* end of ISR handler macros */
209
210/* Context handler macros */
211#define _CPU_Context_Destroy( _the_thread, _the_context ) \
212 { \
213 }
214
216 Context_Control *the_context,
217 void *stack_area_begin,
218 size_t stack_area_size,
219 uint32_t new_level,
220 void (*entry_point)( void ),
221 bool is_fp,
222 void *tls_area
223);
224
225#define _CPU_Context_Restart_self( _the_context ) \
226 _CPU_Context_restore( (_the_context) );
227
228#define _CPU_Context_Initialize_fp( _destination ) \
229 { \
230 *(*(_destination)) = _CPU_Null_fp_context; \
231 }
232
233/* end of Context handler macros */
234
235#define CPU_USE_LIBC_INIT_FINI_ARRAY FALSE
236
237/* Bitfield handler macros */
238
239#define CPU_USE_GENERIC_BITFIELD_CODE TRUE
240
241#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
242#define _CPU_Bitfield_Find_first_bit( _value, _output ) \
243 { \
244 (_output) = 0; /* do something to prevent warnings */ \
245 }
246#endif
247
248/* end of Bitfield handler macros */
249
250#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
251#define _CPU_Priority_Mask( _bit_number ) \
252 ( 1 << (_bit_number) )
253#endif
254
255#if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
256#define _CPU_Priority_bits_index( _priority ) \
257 (_priority)
258#endif
259
260/* end of Priority handler macros */
261
262/* functions */
263
264void _CPU_Initialize(void);
265
266void *_CPU_Thread_Idle_body( uintptr_t ignored );
267
269 Context_Control *run,
270 Context_Control *heir
271);
272
274
275typedef struct {
276 uint32_t processor_state_register;
277 uint32_t integer_registers [1];
278 double float_registers [1];
280
282
283static inline uint32_t CPU_swap_u32(
284 uint32_t value
285)
286{
287 uint32_t byte1, byte2, byte3, byte4, swapped;
288
289 byte4 = (value >> 24) & 0xff;
290 byte3 = (value >> 16) & 0xff;
291 byte2 = (value >> 8) & 0xff;
292 byte1 = value & 0xff;
293
294 swapped = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
295 return swapped;
296}
297
298#define CPU_swap_u16( value ) \
299 (((value&0xff) << 8) | ((value >> 8)&0xff))
300
301typedef uint32_t CPU_Counter_ticks;
302
303uint32_t _CPU_Counter_frequency( void );
304
305CPU_Counter_ticks _CPU_Counter_read( void );
306
307#ifdef RTEMS_SMP
308 *
309 uint32_t _CPU_SMP_Initialize( void );
310
311 bool _CPU_SMP_Start_processor( uint32_t cpu_index );
312
313 void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
314
315 void _CPU_SMP_Prepare_start_multitasking( void );
316
317 static inline uint32_t _CPU_SMP_Get_current_processor( void )
318 {
319 return 123;
320 }
321
322 void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
323
324 static inline bool _CPU_Context_Get_is_executing(
326 )
327 return context->is_executing;
328 }
329
330 static inline void _CPU_Context_Set_is_executing(
332 bool is_executing
333 )
334 {
335 }
336
337#endif /* RTEMS_SMP */
338
339typedef uintptr_t CPU_Uint32ptr;
340
341#ifdef __cplusplus
342}
343#endif
344
345#endif /* ASM */
346
347#endif /* _RTEMS_SCORE_CPU_H */
This header file provides basic definitions used by the API and the implementation.
#define RTEMS_STATIC_ASSERT(_cond, _msg)
It is defined if a static analysis run is performed.
Definition: basedefs.h:841
#define RTEMS_NO_RETURN
Tells the compiler in a function declaration that this function does not return.
Definition: basedefs.h:386
void _CPU_ISR_Set_level(uint32_t level)
Sets the hardware interrupt level by the level value.
Definition: cpu.c:149
void * _CPU_Thread_Idle_body(uintptr_t ignored)
Definition: idle-mcf5272.c:39
void _CPU_Initialize(void)
CPU initialization.
Definition: cpu.c:45
uintptr_t CPU_Uint32ptr
Definition: cpu.h:557
void _CPU_Exception_frame_print(const CPU_Exception_frame *frame)
Definition: vectorexceptions.c:64
uint32_t _CPU_Counter_frequency(void)
Gets the current CPU counter frequency in Hz.
Definition: system-clocks.c:125
void _CPU_Context_switch(Context_Control *run, Context_Control *heir)
CPU switch context.
Definition: cpu_asm.c:110
CPU_Counter_ticks _CPU_Counter_read(void)
Gets the current CPU counter value.
Definition: system-clocks.c:130
void _CPU_Context_Initialize(Context_Control *context, void *stack_area_begin, size_t stack_area_size, uint32_t new_level, void(*entry_point)(void), bool is_fp, void *tls_area)
Initializes the CPU context.
Definition: cpu.c:167
RTEMS_NO_RETURN void _CPU_Context_restore(Context_Control *new_context)
Definition: cpu_asm.c:130
uint32_t _CPU_ISR_Get_level(void)
Definition: cpu.c:165
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
#define CPU_INTERRUPT_FRAME_SIZE
Definition: cpuimpl.h:100
uint32_t CPU_Counter_ticks
Unsigned integer type for CPU counter values.
Definition: cpu.h:1294
rtems_termios_device_context * context
Definition: console-config.c:62
The set of registers that specifies the complete processor state.
Definition: cpu.h:446
Interrupt stack frame (ISF).
Definition: cpuimpl.h:66
uint64_t rax
Definition: cpu.h:103
Thread register context.
Definition: cpu.h:169
uint64_t rbx
Definition: cpu.h:73