RTEMS  5.1
nios2-utility.h
Go to the documentation of this file.
1 
6 /*
7  * Copyright (c) 2011 embedded brains GmbH. All rights reserved.
8  *
9  * embedded brains GmbH
10  * Obere Lagerstr. 30
11  * 82178 Puchheim
12  * Germany
13  * <rtems@embedded-brains.de>
14  *
15  * The license and distribution terms for this file may be
16  * found in the file LICENSE in this distribution or at
17  * http://www.rtems.org/license/LICENSE.
18  */
19 
20 #ifndef _RTEMS_SCORE_NIOS2_UTILITY_H
21 #define _RTEMS_SCORE_NIOS2_UTILITY_H
22 
23 #define NIOS2_CTLREG_INDEX_STATUS 0
24 #define NIOS2_CTLREG_INDEX_ESTATUS 1
25 #define NIOS2_CTLREG_INDEX_BSTATUS 2
26 #define NIOS2_CTLREG_INDEX_IENABLE 3
27 #define NIOS2_CTLREG_INDEX_IPENDING 4
28 #define NIOS2_CTLREG_INDEX_CPUID 5
29 #define NIOS2_CTLREG_INDEX_EXCEPTION 7
30 #define NIOS2_CTLREG_INDEX_PTEADDR 8
31 #define NIOS2_CTLREG_INDEX_TLBACC 9
32 #define NIOS2_CTLREG_INDEX_TLBMISC 10
33 #define NIOS2_CTLREG_INDEX_BADADDR 12
34 #define NIOS2_CTLREG_INDEX_CONFIG 13
35 #define NIOS2_CTLREG_INDEX_MPUBASE 14
36 #define NIOS2_CTLREG_INDEX_MPUACC 15
37 
38 #define NIOS2_CONTEXT_OFFSET_R16 0
39 #define NIOS2_CONTEXT_OFFSET_R17 4
40 #define NIOS2_CONTEXT_OFFSET_R18 8
41 #define NIOS2_CONTEXT_OFFSET_R19 12
42 #define NIOS2_CONTEXT_OFFSET_R20 16
43 #define NIOS2_CONTEXT_OFFSET_R21 20
44 #define NIOS2_CONTEXT_OFFSET_R22 24
45 #define NIOS2_CONTEXT_OFFSET_R23 28
46 #define NIOS2_CONTEXT_OFFSET_FP 32
47 #define NIOS2_CONTEXT_OFFSET_STATUS 36
48 #define NIOS2_CONTEXT_OFFSET_SP 40
49 #define NIOS2_CONTEXT_OFFSET_RA 44
50 #define NIOS2_CONTEXT_OFFSET_THREAD_DISPATCH_DISABLED 48
51 #define NIOS2_CONTEXT_OFFSET_STACK_MPUBASE 52
52 #define NIOS2_CONTEXT_OFFSET_STACK_MPUACC 56
53 
54 #define NIOS2_ISR_STATUS_MASK_IIC 0xfffffffe
55 #define NIOS2_ISR_STATUS_BITS_IIC 0x00000000
56 
57 #define NIOS2_ISR_STATUS_MASK_EIC_IL 0xfffffc0f
58 #define NIOS2_ISR_STATUS_BITS_EIC_IL 0x000003f0
59 
60 #define NIOS2_ISR_STATUS_MASK_EIC_RSIE 0xf7ffffff
61 #define NIOS2_ISR_STATUS_BITS_EIC_RSIE 0x00000000
62 
63 #define NIOS2_STATUS_RSIE (1 << 23)
64 #define NIOS2_STATUS_NMI (1 << 22)
65 #define NIOS2_STATUS_PRS_OFFSET 16
66 #define NIOS2_STATUS_PRS_MASK (0x3f << NIOS2_STATUS_PRS_OFFSET)
67 #define NIOS2_STATUS_CRS_OFFSET 10
68 #define NIOS2_STATUS_CRS_MASK (0x3f << NIOS2_STATUS_CRS_OFFSET)
69 #define NIOS2_STATUS_IL_OFFSET 4
70 #define NIOS2_STATUS_IL_MASK (0x3f << NIOS2_STATUS_IL_OFFSET)
71 #define NIOS2_STATUS_IH (1 << 3)
72 #define NIOS2_STATUS_EH (1 << 2)
73 #define NIOS2_STATUS_U (1 << 1)
74 #define NIOS2_STATUS_PIE (1 << 0)
75 
76 #define NIOS2_EXCEPTION_CAUSE_OFFSET 2
77 #define NIOS2_EXCEPTION_CAUSE_MASK (0x1f << NIOS2_EXCEPTION_CAUSE_OFFSET)
78 
79 #define NIOS2_PTEADDR_PTBASE_OFFSET 22
80 #define NIOS2_PTEADDR_PTBASE_MASK (0x3ff << NIOS2_PTEADDR_PTBASE_OFFSET)
81 #define NIOS2_PTEADDR_VPN_OFFSET 2
82 #define NIOS2_PTEADDR_VPN_MASK (0xfffff << NIOS2_PTEADDR_VPN_OFFSET)
83 
84 #define NIOS2_TLBACC_IG_OFFSET 25
85 #define NIOS2_TLBACC_IG_MASK (0x3ff << NIOS2_TLBACC_IG_OFFSET)
86 #define NIOS2_TLBACC_C (1 << 24)
87 #define NIOS2_TLBACC_R (1 << 23)
88 #define NIOS2_TLBACC_W (1 << 22)
89 #define NIOS2_TLBACC_X (1 << 21)
90 #define NIOS2_TLBACC_G (1 << 20)
91 #define NIOS2_TLBACC_PFN_OFFSET 2
92 #define NIOS2_TLBACC_PFN_MASK (0xfffff << NIOS2_TLBACC_PFN_OFFSET)
93 
94 #define NIOS2_TLBMISC_WAY_OFFSET 20
95 #define NIOS2_TLBMISC_WAY_MASK (0xf << NIOS2_TLBMISC_WAY_OFFSET)
96 #define NIOS2_TLBMISC_RD (1 << 19)
97 #define NIOS2_TLBMISC_WE (1 << 18)
98 #define NIOS2_TLBMISC_PID_OFFSET 5
99 #define NIOS2_TLBMISC_PID_MASK (0x3fff << NIOS2_TLBMISC_PID_OFFSET)
100 #define NIOS2_TLBMISC_DBL (1 << 3)
101 #define NIOS2_TLBMISC_BAD (1 << 2)
102 #define NIOS2_TLBMISC_PERM (1 << 1)
103 #define NIOS2_TLBMISC_D (1 << 0)
104 
105 #define NIOS2_CONFIG_ANI (1 << 1)
106 #define NIOS2_CONFIG_PE (1 << 0)
107 
108 #define NIOS2_MPUBASE_BASE_OFFSET 6
109 #define NIOS2_MPUBASE_BASE_MASK (0x1ffffff << NIOS2_MPUBASE_BASE_OFFSET)
110 #define NIOS2_MPUBASE_INDEX_OFFSET 1
111 
112 /* Avoid redefines with Altera HAL */
113 #define NIOS2_MPUBASE_INDEX_MASK (0x0000003e)
114 
115 #define NIOS2_MPUBASE_D (1 << 0)
116 
117 #define NIOS2_MPUACC_MASK_OFFSET 6
118 
119 /* Avoid redefines with Altera HAL */
120 #define NIOS2_MPUACC_MASK_MASK (0x7fffffc0)
121 
122 #define NIOS2_MPUACC_LIMIT_OFFSET 6
123 
124 /* Avoid redefines with Altera HAL */
125 #define NIOS2_MPUACC_LIMIT_MASK (0xffffffc0)
126 
127 #define NIOS2_MPUACC_C (1 << 5)
128 #define NIOS2_MPUACC_PERM_OFFSET 2
129 
130 /* Avoid redefines with Altera HAL */
131 #define NIOS2_MPUACC_PERM_MASK (0x0000001c)
132 
133 #define NIOS2_MPUACC_RD (1 << 1)
134 #define NIOS2_MPUACC_WR (1 << 0)
135 
136 #ifndef ASM
137 
138 #include <stddef.h>
139 #include <stdint.h>
140 #include <stdbool.h>
141 
142 #ifdef __cplusplus
143 extern "C" {
144 #endif /* __cplusplus */
145 
155 extern uint32_t _Nios2_Thread_dispatch_disabled;
156 
164 extern char _Nios2_ISR_Status_mask [];
165 
173 extern char _Nios2_ISR_Status_bits [];
174 
175 static inline void _Nios2_Flush_pipeline( void )
176 {
177  __asm__ volatile ("flushp");
178 }
179 
180 static inline uint32_t _Nios2_Get_ctlreg_status( void )
181 {
182  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_STATUS );
183 }
184 
185 static inline void _Nios2_Set_ctlreg_status( uint32_t value )
186 {
187  __builtin_wrctl( NIOS2_CTLREG_INDEX_STATUS, (int) value );
188 }
189 
190 static inline uint32_t _Nios2_Get_ctlreg_estatus( void )
191 {
192  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_ESTATUS );
193 }
194 
195 static inline void _Nios2_Set_ctlreg_estatus( uint32_t value )
196 {
197  __builtin_wrctl( NIOS2_CTLREG_INDEX_ESTATUS, (int) value );
198 }
199 
200 static inline uint32_t _Nios2_Get_ctlreg_bstatus( void )
201 {
202  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_BSTATUS );
203 }
204 
205 static inline void _Nios2_Set_ctlreg_bstatus( uint32_t value )
206 {
207  __builtin_wrctl( NIOS2_CTLREG_INDEX_BSTATUS, (int) value );
208 }
209 
210 static inline uint32_t _Nios2_Get_ctlreg_ienable( void )
211 {
212  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_IENABLE );
213 }
214 
215 static inline void _Nios2_Set_ctlreg_ienable( uint32_t value )
216 {
217  __builtin_wrctl( NIOS2_CTLREG_INDEX_IENABLE, (int) value );
218 }
219 
220 static inline uint32_t _Nios2_Get_ctlreg_ipending( void )
221 {
222  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_IPENDING );
223 }
224 
225 static inline uint32_t _Nios2_Get_ctlreg_cpuid( void )
226 {
227  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_CPUID );
228 }
229 
230 static inline uint32_t _Nios2_Get_ctlreg_exception( void )
231 {
232  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_EXCEPTION );
233 }
234 
235 static inline uint32_t _Nios2_Get_ctlreg_pteaddr( void )
236 {
237  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_PTEADDR );
238 }
239 
240 static inline void _Nios2_Set_ctlreg_pteaddr( uint32_t value )
241 {
242  __builtin_wrctl( NIOS2_CTLREG_INDEX_PTEADDR, (int) value );
243 }
244 
245 static inline uint32_t _Nios2_Get_ctlreg_tlbacc( void )
246 {
247  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_TLBACC );
248 }
249 
250 static inline void _Nios2_Set_ctlreg_tlbacc( uint32_t value )
251 {
252  __builtin_wrctl( NIOS2_CTLREG_INDEX_TLBACC, (int) value );
253 }
254 
255 static inline uint32_t _Nios2_Get_ctlreg_tlbmisc( void )
256 {
257  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_TLBMISC );
258 }
259 
260 static inline void _Nios2_Set_ctlreg_tlbmisc( uint32_t value )
261 {
262  __builtin_wrctl( NIOS2_CTLREG_INDEX_TLBMISC, (int) value );
263 }
264 
265 static inline uint32_t _Nios2_Get_ctlreg_badaddr( void )
266 {
267  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_BADADDR );
268 }
269 
270 static inline uint32_t _Nios2_Get_ctlreg_config( void )
271 {
272  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_CONFIG );
273 }
274 
275 static inline void _Nios2_Set_ctlreg_config( uint32_t value )
276 {
277  __builtin_wrctl( NIOS2_CTLREG_INDEX_CONFIG, (int) value );
278 }
279 
280 static inline uint32_t _Nios2_Get_ctlreg_mpubase( void )
281 {
282  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_MPUBASE );
283 }
284 
285 static inline void _Nios2_Set_ctlreg_mpubase( uint32_t value )
286 {
287  __builtin_wrctl( NIOS2_CTLREG_INDEX_MPUBASE, (int) value );
288 }
289 
290 static inline uint32_t _Nios2_Get_ctlreg_mpuacc( void )
291 {
292  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_MPUACC );
293 }
294 
295 static inline void _Nios2_Set_ctlreg_mpuacc( uint32_t value )
296 {
297  __builtin_wrctl( NIOS2_CTLREG_INDEX_MPUACC, (int) value );
298 }
299 
300 static inline uint32_t _Nios2_ISR_Get_status_mask( void )
301 {
302  return (uint32_t) &_Nios2_ISR_Status_mask [0];
303 }
304 
305 static inline uint32_t _Nios2_ISR_Get_status_bits( void )
306 {
307  return (uint32_t) &_Nios2_ISR_Status_bits [0];
308 }
309 
310 static inline bool _Nios2_Has_internal_interrupt_controller( void )
311 {
312  return _Nios2_ISR_Get_status_mask() == NIOS2_ISR_STATUS_MASK_IIC;
313 }
314 
315 uint32_t _Nios2_ISR_Set_level( uint32_t new_level, uint32_t status );
316 
317 typedef struct {
318  int data_address_width;
319  int instruction_address_width;
320  int data_region_size_log2;
321  int instruction_region_size_log2;
322  int data_region_count;
323  int instruction_region_count;
324  int data_index_for_stack_protection;
325  bool region_uses_limit;
326  bool enable_data_cache_for_stack;
328 
329 void _Nios2_MPU_Set_configuration( const Nios2_MPU_Configuration *config );
330 
331 const Nios2_MPU_Configuration *_Nios2_MPU_Get_configuration( void );
332 
333 typedef enum {
334  NIOS2_MPU_INST_PERM_SVR_NONE_USER_NONE = 0,
335  NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_NONE,
336  NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_EXECUTE,
337  NIOS2_MPU_DATA_PERM_SVR_NONE_USER_NONE = 0,
338  NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_NONE,
339  NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_READONLY,
340  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE = 4,
341  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_READONLY,
342  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_READWRITE
343 } Nios2_MPU_Region_permissions;
344 
345 typedef struct {
346  int index;
347  const void *base;
348  const void *end;
349  Nios2_MPU_Region_permissions perm;
350  bool data;
351  bool cacheable;
352  bool read;
353  bool write;
355 
356 #define NIOS2_MPU_REGION_DESC_INST( index, base, end ) \
357  { \
358  (index), (base), (end), NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_NONE, \
359  false, false, false, true \
360  }
361 
362 #define NIOS2_MPU_REGION_DESC_DATA_RO( index, base, end ) \
363  { \
364  (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_NONE, \
365  true, true, false, true \
366  }
367 
368 #define NIOS2_MPU_REGION_DESC_DATA_RW( index, base, end ) \
369  { \
370  (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE, \
371  true, true, false, true \
372  }
373 
374 #define NIOS2_MPU_REGION_DESC_DATA_IO( index, base, end ) \
375  { \
376  (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE, \
377  true, false, false, true \
378  }
379 
380 static inline int _Nios2_MPU_Get_region_count(
382  bool data
383 )
384 {
385  return data ?
386  config->data_region_count
387  : config->instruction_region_count;
388 }
389 
390 static inline bool _Nios2_MPU_Is_valid_index(
392  int index,
393  bool data
394 )
395 {
396  return 0 <= index
397  && index < _Nios2_MPU_Get_region_count( config, data );
398 }
399 
400 bool _Nios2_MPU_Setup_region_registers(
402  const Nios2_MPU_Region_descriptor *desc,
403  uint32_t *mpubase,
404  uint32_t *mpuacc
405 );
406 
407 bool _Nios2_MPU_Get_region_descriptor(
409  int index,
410  bool data,
412 );
413 
427  bool data,
428  int begin,
429  int end
430 );
431 
442  const Nios2_MPU_Region_descriptor *desc,
443  bool force
444 );
445 
446 static inline void _Nios2_MPU_Get_region_registers(
447  int index,
448  bool data,
449  uint32_t *mpubase,
450  uint32_t *mpuacc
451 )
452 {
453  uint32_t base = (uint32_t)
454  (((index << NIOS2_MPUBASE_INDEX_OFFSET) & NIOS2_MPUBASE_INDEX_MASK)
455  | (data ? NIOS2_MPUBASE_D : 0));
456 
457  _Nios2_Set_ctlreg_mpubase( base );
458  _Nios2_Set_ctlreg_mpuacc( NIOS2_MPUACC_RD );
459  _Nios2_Flush_pipeline();
460  *mpubase = _Nios2_Get_ctlreg_mpubase() | base;
461  *mpuacc = _Nios2_Get_ctlreg_mpuacc();
462 }
463 
464 static inline void _Nios2_MPU_Set_region_registers(
465  uint32_t mpubase,
466  uint32_t mpuacc
467 )
468 {
469  _Nios2_Set_ctlreg_mpubase( mpubase );
470  _Nios2_Set_ctlreg_mpuacc( mpuacc );
471  _Nios2_Flush_pipeline();
472 }
473 
474 static inline void _Nios2_MPU_Enable( void )
475 {
476  uint32_t config = _Nios2_Get_ctlreg_config();
477 
478  _Nios2_Set_ctlreg_config( config | NIOS2_CONFIG_PE );
479 }
480 
481 static inline uint32_t _Nios2_MPU_Disable( void )
482 {
483  uint32_t config = _Nios2_Get_ctlreg_config();
484  uint32_t config_pe = NIOS2_CONFIG_PE;
485 
486  _Nios2_Set_ctlreg_config( config & ~config_pe );
487 
488  return config;
489 }
490 
491 static inline void _Nios2_MPU_Restore( uint32_t config )
492 {
493  _Nios2_Set_ctlreg_config( config );
494 }
495 
496 uint32_t _Nios2_MPU_Disable_protected( void );
497 
498 void _Nios2_MPU_Reset( const Nios2_MPU_Configuration *config );
499 
500 #ifdef __cplusplus
501 }
502 #endif /* __cplusplus */
503 
504 #else /* ASM */
505 
506  .macro NIOS2_ASM_DISABLE_INTERRUPTS new_status, current_status
507  movhi \new_status, %hiadj(_Nios2_ISR_Status_mask)
508  addi \new_status, \new_status, %lo(_Nios2_ISR_Status_mask)
509  and \new_status, \current_status, \new_status
510  ori \new_status, \new_status, %lo(_Nios2_ISR_Status_bits)
511  wrctl status, \new_status
512  .endm
513 
514 #endif /* ASM */
515 
516 #endif /* _RTEMS_SCORE_NIOS2_UTILITY_H */
ssize_t read(int fd, void *buffer, size_t count)
Definition: read.c:27
Definition: deflate.c:115
ssize_t write(int fd, const void *buffer, size_t count)
Definition: write.c:30
char _Nios2_ISR_Status_mask[]
This global symbol specifies the status register mask used to disable interrupts.
Definition: nios2-utility.h:345
Definition: nios2-utility.h:317
bool _Nios2_MPU_Add_region(const Nios2_MPU_Configuration *config, const Nios2_MPU_Region_descriptor *desc, bool force)
Adds a region according to region descriptor desc.
Definition: nios2-mpu-add-region.c:71
uint32_t _Nios2_Thread_dispatch_disabled
Nios II specific thread dispatch disabled indicator.
Definition: nios2-thread-dispatch-disabled.c:50
char _Nios2_ISR_Status_bits[]
This symbol specifies the status register bits used to disable interrupts.
register struct Per_CPU_Control *_SPARC_Per_CPU_current __asm__("g6")
The pointer to the current per-CPU control is available via register g6.
int _Nios2_MPU_Get_disabled_region_index(const Nios2_MPU_Configuration *config, bool data, int begin, int end)
Searches the region table part for a disabled region.
Definition: nios2-mpu-add-region.c:39