source: rtems/cpukit/score/cpu/nios2/include/rtems/score/nios2-utility.h @ 255fe43

Last change on this file since 255fe43 was 255fe43, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 20:40:44

cpukit/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 14.5 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @brief NIOS II Utility
7 */
8/*
9 * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef _RTEMS_SCORE_NIOS2_UTILITY_H
34#define _RTEMS_SCORE_NIOS2_UTILITY_H
35
36#define NIOS2_CTLREG_INDEX_STATUS 0
37#define NIOS2_CTLREG_INDEX_ESTATUS 1
38#define NIOS2_CTLREG_INDEX_BSTATUS 2
39#define NIOS2_CTLREG_INDEX_IENABLE 3
40#define NIOS2_CTLREG_INDEX_IPENDING 4
41#define NIOS2_CTLREG_INDEX_CPUID 5
42#define NIOS2_CTLREG_INDEX_EXCEPTION 7
43#define NIOS2_CTLREG_INDEX_PTEADDR 8
44#define NIOS2_CTLREG_INDEX_TLBACC 9
45#define NIOS2_CTLREG_INDEX_TLBMISC 10
46#define NIOS2_CTLREG_INDEX_BADADDR 12
47#define NIOS2_CTLREG_INDEX_CONFIG 13
48#define NIOS2_CTLREG_INDEX_MPUBASE 14
49#define NIOS2_CTLREG_INDEX_MPUACC 15
50
51#define NIOS2_CONTEXT_OFFSET_R16 0
52#define NIOS2_CONTEXT_OFFSET_R17 4
53#define NIOS2_CONTEXT_OFFSET_R18 8
54#define NIOS2_CONTEXT_OFFSET_R19 12
55#define NIOS2_CONTEXT_OFFSET_R20 16
56#define NIOS2_CONTEXT_OFFSET_R21 20
57#define NIOS2_CONTEXT_OFFSET_R22 24
58#define NIOS2_CONTEXT_OFFSET_R23 28
59#define NIOS2_CONTEXT_OFFSET_FP 32
60#define NIOS2_CONTEXT_OFFSET_STATUS 36
61#define NIOS2_CONTEXT_OFFSET_SP 40
62#define NIOS2_CONTEXT_OFFSET_RA 44
63#define NIOS2_CONTEXT_OFFSET_ISR_DISPATCH_DISABLE 48
64#define NIOS2_CONTEXT_OFFSET_STACK_MPUBASE 52
65#define NIOS2_CONTEXT_OFFSET_STACK_MPUACC 56
66
67#define NIOS2_ISR_STATUS_MASK_IIC 0xfffffffe
68#define NIOS2_ISR_STATUS_BITS_IIC 0x00000000
69
70#define NIOS2_ISR_STATUS_MASK_EIC_IL 0xfffffc0f
71#define NIOS2_ISR_STATUS_BITS_EIC_IL 0x000003f0
72
73#define NIOS2_ISR_STATUS_MASK_EIC_RSIE 0xf7ffffff
74#define NIOS2_ISR_STATUS_BITS_EIC_RSIE 0x00000000
75
76#define NIOS2_STATUS_RSIE (1 << 23)
77#define NIOS2_STATUS_NMI (1 << 22)
78#define NIOS2_STATUS_PRS_OFFSET 16
79#define NIOS2_STATUS_PRS_MASK (0x3f << NIOS2_STATUS_PRS_OFFSET)
80#define NIOS2_STATUS_CRS_OFFSET 10
81#define NIOS2_STATUS_CRS_MASK (0x3f << NIOS2_STATUS_CRS_OFFSET)
82#define NIOS2_STATUS_IL_OFFSET 4
83#define NIOS2_STATUS_IL_MASK (0x3f << NIOS2_STATUS_IL_OFFSET)
84#define NIOS2_STATUS_IH (1 << 3)
85#define NIOS2_STATUS_EH (1 << 2)
86#define NIOS2_STATUS_U (1 << 1)
87#define NIOS2_STATUS_PIE (1 << 0)
88
89#define NIOS2_EXCEPTION_CAUSE_OFFSET 2
90#define NIOS2_EXCEPTION_CAUSE_MASK (0x1f << NIOS2_EXCEPTION_CAUSE_OFFSET)
91
92#define NIOS2_PTEADDR_PTBASE_OFFSET 22
93#define NIOS2_PTEADDR_PTBASE_MASK (0x3ff << NIOS2_PTEADDR_PTBASE_OFFSET)
94#define NIOS2_PTEADDR_VPN_OFFSET 2
95#define NIOS2_PTEADDR_VPN_MASK (0xfffff << NIOS2_PTEADDR_VPN_OFFSET)
96
97#define NIOS2_TLBACC_IG_OFFSET 25
98#define NIOS2_TLBACC_IG_MASK (0x3ff << NIOS2_TLBACC_IG_OFFSET)
99#define NIOS2_TLBACC_C (1 << 24)
100#define NIOS2_TLBACC_R (1 << 23)
101#define NIOS2_TLBACC_W (1 << 22)
102#define NIOS2_TLBACC_X (1 << 21)
103#define NIOS2_TLBACC_G (1 << 20)
104#define NIOS2_TLBACC_PFN_OFFSET 2
105#define NIOS2_TLBACC_PFN_MASK (0xfffff << NIOS2_TLBACC_PFN_OFFSET)
106
107#define NIOS2_TLBMISC_WAY_OFFSET 20
108#define NIOS2_TLBMISC_WAY_MASK (0xf << NIOS2_TLBMISC_WAY_OFFSET)
109#define NIOS2_TLBMISC_RD (1 << 19)
110#define NIOS2_TLBMISC_WE (1 << 18)
111#define NIOS2_TLBMISC_PID_OFFSET 5
112#define NIOS2_TLBMISC_PID_MASK (0x3fff << NIOS2_TLBMISC_PID_OFFSET)
113#define NIOS2_TLBMISC_DBL (1 << 3)
114#define NIOS2_TLBMISC_BAD (1 << 2)
115#define NIOS2_TLBMISC_PERM (1 << 1)
116#define NIOS2_TLBMISC_D (1 << 0)
117
118#define NIOS2_CONFIG_ANI (1 << 1)
119#define NIOS2_CONFIG_PE (1 << 0)
120
121#define NIOS2_MPUBASE_BASE_OFFSET 6
122#define NIOS2_MPUBASE_BASE_MASK (0x1ffffff << NIOS2_MPUBASE_BASE_OFFSET)
123#define NIOS2_MPUBASE_INDEX_OFFSET 1
124
125/* Avoid redefines with Altera HAL */
126#define NIOS2_MPUBASE_INDEX_MASK (0x0000003e)
127
128#define NIOS2_MPUBASE_D (1 << 0)
129
130#define NIOS2_MPUACC_MASK_OFFSET 6
131
132/* Avoid redefines with Altera HAL */
133#define NIOS2_MPUACC_MASK_MASK (0x7fffffc0)
134
135#define NIOS2_MPUACC_LIMIT_OFFSET 6
136
137/* Avoid redefines with Altera HAL */
138#define NIOS2_MPUACC_LIMIT_MASK (0xffffffc0)
139
140#define NIOS2_MPUACC_C (1 << 5)
141#define NIOS2_MPUACC_PERM_OFFSET 2
142
143/* Avoid redefines with Altera HAL */
144#define NIOS2_MPUACC_PERM_MASK (0x0000001c)
145
146#define NIOS2_MPUACC_RD (1 << 1)
147#define NIOS2_MPUACC_WR (1 << 0)
148
149#ifndef ASM
150
151#include <stddef.h>
152#include <stdint.h>
153#include <stdbool.h>
154
155#ifdef __cplusplus
156extern "C" {
157#endif /* __cplusplus */
158
159/**
160 * @brief This global symbol specifies the status register mask used to disable
161 * interrupts.
162 *
163 * The board support package must provide a global symbol with this name to
164 * specify the status register mask used in _CPU_ISR_Disable().
165 */
166extern char _Nios2_ISR_Status_mask [];
167
168/**
169 * @brief This symbol specifies the status register bits used to disable
170 * interrupts.
171 *
172 * The board support package must provide a global symbol with this name to
173 * specify the status register bits used in _CPU_ISR_Disable().
174 */
175extern char _Nios2_ISR_Status_bits [];
176
177static inline void _Nios2_Flush_pipeline( void )
178{
179  __asm__ volatile ("flushp");
180}
181
182static inline uint32_t _Nios2_Get_ctlreg_status( void )
183{
184  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_STATUS );
185}
186
187static inline void _Nios2_Set_ctlreg_status( uint32_t value )
188{
189  __builtin_wrctl( NIOS2_CTLREG_INDEX_STATUS, (int) value );
190}
191
192static inline uint32_t _Nios2_Get_ctlreg_estatus( void )
193{
194  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_ESTATUS );
195}
196
197static inline void _Nios2_Set_ctlreg_estatus( uint32_t value )
198{
199  __builtin_wrctl( NIOS2_CTLREG_INDEX_ESTATUS, (int) value );
200}
201
202static inline uint32_t _Nios2_Get_ctlreg_bstatus( void )
203{
204  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_BSTATUS );
205}
206
207static inline void _Nios2_Set_ctlreg_bstatus( uint32_t value )
208{
209  __builtin_wrctl( NIOS2_CTLREG_INDEX_BSTATUS, (int) value );
210}
211
212static inline uint32_t _Nios2_Get_ctlreg_ienable( void )
213{
214  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_IENABLE );
215}
216
217static inline void _Nios2_Set_ctlreg_ienable( uint32_t value )
218{
219  __builtin_wrctl( NIOS2_CTLREG_INDEX_IENABLE, (int) value );
220}
221
222static inline uint32_t _Nios2_Get_ctlreg_ipending( void )
223{
224  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_IPENDING );
225}
226
227static inline uint32_t _Nios2_Get_ctlreg_cpuid( void )
228{
229  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_CPUID );
230}
231
232static inline uint32_t _Nios2_Get_ctlreg_exception( void )
233{
234  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_EXCEPTION );
235}
236
237static inline uint32_t _Nios2_Get_ctlreg_pteaddr( void )
238{
239  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_PTEADDR );
240}
241
242static inline void _Nios2_Set_ctlreg_pteaddr( uint32_t value )
243{
244  __builtin_wrctl( NIOS2_CTLREG_INDEX_PTEADDR, (int) value );
245}
246
247static inline uint32_t _Nios2_Get_ctlreg_tlbacc( void )
248{
249  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_TLBACC );
250}
251
252static inline void _Nios2_Set_ctlreg_tlbacc( uint32_t value )
253{
254  __builtin_wrctl( NIOS2_CTLREG_INDEX_TLBACC, (int) value );
255}
256
257static inline uint32_t _Nios2_Get_ctlreg_tlbmisc( void )
258{
259  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_TLBMISC );
260}
261
262static inline void _Nios2_Set_ctlreg_tlbmisc( uint32_t value )
263{
264  __builtin_wrctl( NIOS2_CTLREG_INDEX_TLBMISC, (int) value );
265}
266
267static inline uint32_t _Nios2_Get_ctlreg_badaddr( void )
268{
269  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_BADADDR );
270}
271
272static inline uint32_t _Nios2_Get_ctlreg_config( void )
273{
274  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_CONFIG );
275}
276
277static inline void _Nios2_Set_ctlreg_config( uint32_t value )
278{
279  __builtin_wrctl( NIOS2_CTLREG_INDEX_CONFIG, (int) value );
280}
281
282static inline uint32_t _Nios2_Get_ctlreg_mpubase( void )
283{
284  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_MPUBASE );
285}
286
287static inline void _Nios2_Set_ctlreg_mpubase( uint32_t value )
288{
289  __builtin_wrctl( NIOS2_CTLREG_INDEX_MPUBASE, (int) value );
290}
291
292static inline uint32_t _Nios2_Get_ctlreg_mpuacc( void )
293{
294  return (uint32_t) __builtin_rdctl( NIOS2_CTLREG_INDEX_MPUACC );
295}
296
297static inline void _Nios2_Set_ctlreg_mpuacc( uint32_t value )
298{
299  __builtin_wrctl( NIOS2_CTLREG_INDEX_MPUACC, (int) value );
300}
301
302static inline uint32_t _Nios2_ISR_Get_status_mask( void )
303{
304  return (uint32_t) &_Nios2_ISR_Status_mask [0];
305}
306
307static inline uint32_t _Nios2_ISR_Get_status_bits( void )
308{
309  return (uint32_t) &_Nios2_ISR_Status_bits [0];
310}
311
312static inline bool _Nios2_Has_internal_interrupt_controller( void )
313{
314  return _Nios2_ISR_Get_status_mask() == NIOS2_ISR_STATUS_MASK_IIC;
315}
316
317uint32_t _Nios2_ISR_Set_level( uint32_t new_level, uint32_t status );
318
319typedef struct {
320  int data_address_width;
321  int instruction_address_width;
322  int data_region_size_log2;
323  int instruction_region_size_log2;
324  int data_region_count;
325  int instruction_region_count;
326  int data_index_for_stack_protection;
327  bool region_uses_limit;
328  bool enable_data_cache_for_stack;
329} Nios2_MPU_Configuration;
330
331void _Nios2_MPU_Set_configuration( const Nios2_MPU_Configuration *config );
332
333const Nios2_MPU_Configuration *_Nios2_MPU_Get_configuration( void );
334
335typedef enum {
336  NIOS2_MPU_INST_PERM_SVR_NONE_USER_NONE = 0,
337  NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_NONE,
338  NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_EXECUTE,
339  NIOS2_MPU_DATA_PERM_SVR_NONE_USER_NONE = 0,
340  NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_NONE,
341  NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_READONLY,
342  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE = 4,
343  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_READONLY,
344  NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_READWRITE
345} Nios2_MPU_Region_permissions;
346
347typedef struct {
348  int index;
349  const void *base;
350  const void *end;
351  Nios2_MPU_Region_permissions perm;
352  bool data;
353  bool cacheable;
354  bool read;
355  bool write;
356} Nios2_MPU_Region_descriptor;
357
358#define NIOS2_MPU_REGION_DESC_INST( index, base, end ) \
359  { \
360    (index), (base), (end), NIOS2_MPU_INST_PERM_SVR_EXECUTE_USER_NONE, \
361    false, false, false, true \
362  }
363
364#define NIOS2_MPU_REGION_DESC_DATA_RO( index, base, end ) \
365  { \
366    (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READONLY_USER_NONE, \
367    true, true, false, true \
368  }
369
370#define NIOS2_MPU_REGION_DESC_DATA_RW( index, base, end ) \
371  { \
372    (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE, \
373    true, true, false, true \
374  }
375
376#define NIOS2_MPU_REGION_DESC_DATA_IO( index, base, end ) \
377  { \
378    (index), (base), (end), NIOS2_MPU_DATA_PERM_SVR_READWRITE_USER_NONE, \
379    true, false, false, true \
380  }
381
382static inline int _Nios2_MPU_Get_region_count(
383  const Nios2_MPU_Configuration *config,
384  bool data
385)
386{
387  return data ?
388    config->data_region_count
389      : config->instruction_region_count;
390}
391
392static inline bool _Nios2_MPU_Is_valid_index(
393  const Nios2_MPU_Configuration *config,
394  int index,
395  bool data
396)
397{
398  return 0 <= index
399    && index < _Nios2_MPU_Get_region_count( config, data );
400}
401
402bool _Nios2_MPU_Setup_region_registers(
403  const Nios2_MPU_Configuration *config,
404  const Nios2_MPU_Region_descriptor *desc,
405  uint32_t *mpubase,
406  uint32_t *mpuacc
407);
408
409bool _Nios2_MPU_Get_region_descriptor(
410  const Nios2_MPU_Configuration *config,
411  int index,
412  bool data,
413  Nios2_MPU_Region_descriptor *desc
414);
415
416/**
417 * @brief Searches the region table part for a disabled region.
418 *
419 * The table will be searched between indices @a begin and @a end.  The @a end
420 * index is not part of the search range.  If @a end is negative, then the
421 * region count will be used.  Thus a @a begin of 0 and a @a end of -1 will
422 * specify the complete table.
423 *
424 * @retval -1 No disabled region is available.
425 * @retval other Index of disabled region.
426 */
427int _Nios2_MPU_Get_disabled_region_index(
428  const Nios2_MPU_Configuration *config,
429  bool data,
430  int begin,
431  int end
432);
433
434/**
435 * @brief Adds a region according to region descriptor @a desc.
436 *
437 * If @a force is true, then an enabled region will be overwritten.
438 *
439 * @retval true Successful operation.
440 * @retval false Invalid region descriptor or region already in use.
441 */
442bool _Nios2_MPU_Add_region(
443  const Nios2_MPU_Configuration *config,
444  const Nios2_MPU_Region_descriptor *desc,
445  bool force
446);
447
448static inline void _Nios2_MPU_Get_region_registers(
449  int index,
450  bool data,
451  uint32_t *mpubase,
452  uint32_t *mpuacc
453)
454{
455  uint32_t base = (uint32_t)
456    (((index << NIOS2_MPUBASE_INDEX_OFFSET) & NIOS2_MPUBASE_INDEX_MASK)
457      | (data ? NIOS2_MPUBASE_D : 0));
458
459  _Nios2_Set_ctlreg_mpubase( base );
460  _Nios2_Set_ctlreg_mpuacc( NIOS2_MPUACC_RD );
461  _Nios2_Flush_pipeline();
462  *mpubase = _Nios2_Get_ctlreg_mpubase() | base;
463  *mpuacc = _Nios2_Get_ctlreg_mpuacc();
464}
465
466static inline void _Nios2_MPU_Set_region_registers(
467  uint32_t mpubase,
468  uint32_t mpuacc
469)
470{
471  _Nios2_Set_ctlreg_mpubase( mpubase );
472  _Nios2_Set_ctlreg_mpuacc( mpuacc );
473  _Nios2_Flush_pipeline();
474}
475
476static inline void _Nios2_MPU_Enable( void )
477{
478  uint32_t config = _Nios2_Get_ctlreg_config();
479
480  _Nios2_Set_ctlreg_config( config | NIOS2_CONFIG_PE );
481}
482
483static inline uint32_t _Nios2_MPU_Disable( void )
484{
485  uint32_t config = _Nios2_Get_ctlreg_config();
486  uint32_t config_pe = NIOS2_CONFIG_PE;
487
488  _Nios2_Set_ctlreg_config( config & ~config_pe );
489
490  return config;
491}
492
493static inline void _Nios2_MPU_Restore( uint32_t config )
494{
495  _Nios2_Set_ctlreg_config( config );
496}
497
498uint32_t _Nios2_MPU_Disable_protected( void );
499
500void _Nios2_MPU_Reset( const Nios2_MPU_Configuration *config );
501
502#ifdef __cplusplus
503}
504#endif /* __cplusplus */
505
506#else /* ASM */
507
508        .macro  NIOS2_ASM_DISABLE_INTERRUPTS new_status, current_status
509        movhi   \new_status, %hiadj(_Nios2_ISR_Status_mask)
510        addi    \new_status, \new_status, %lo(_Nios2_ISR_Status_mask)
511        and     \new_status, \current_status, \new_status
512        ori     \new_status, \new_status, %lo(_Nios2_ISR_Status_bits)
513        wrctl   status, \new_status
514        .endm
515
516#endif /* ASM */
517
518#endif /* _RTEMS_SCORE_NIOS2_UTILITY_H */
Note: See TracBrowser for help on using the repository browser.