source: rtems/cpukit/score/cpu/nios2/nios2-mpu-descriptor.c @ 5c6edee

5
Last change on this file since 5c6edee was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/**
2 * @file
3 *
4 * @brief NIOS2 MPU Descriptor
5 */
6
7/*
8 * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
9 *
10 *  embedded brains GmbH
11 *  Obere Lagerstr. 30
12 *  82178 Puchheim
13 *  Germany
14 *  <rtems@embedded-brains.de>
15 *
16 * The license and distribution terms for this file may be
17 * found in the file LICENSE in this distribution or at
18 * http://www.rtems.org/license/LICENSE.
19 */
20
21#ifdef HAVE_CONFIG_H
22  #include "config.h"
23#endif
24
25#include <rtems/score/nios2-utility.h>
26
27static bool _Nios2_Is_power_of_two( uint32_t size )
28{
29  bool ok = false;
30  int i = 0;
31
32  for ( i = 0; !ok && i < 32; ++i ) {
33    ok = size == (1U << i);
34  }
35
36  return ok;
37}
38
39static bool _Nios2_Is_valid_base_and_end(
40  const Nios2_MPU_Configuration *config,
41  bool data,
42  uint32_t base,
43  uint32_t end,
44  uint32_t *mask_or_limit
45)
46{
47  uint32_t size = end - base;
48  uint32_t end_limit = data ?
49    (1U << config->data_address_width)
50      : (1U << config->instruction_address_width);
51  uint32_t mask = data ?
52    ((1U << config->data_region_size_log2)) - 1
53      : ((1U << config->instruction_region_size_log2)) - 1;
54  bool ok = base < end && end <= end_limit
55    && (base & mask) == 0 && (end & mask) == 0;
56
57  if ( config->region_uses_limit ) {
58    *mask_or_limit = end;
59  } else {
60    ok = ok && _Nios2_Is_power_of_two( size );
61    *mask_or_limit = (~(size - 1)) & NIOS2_MPUACC_MASK_MASK;
62  }
63
64  return ok;
65}
66
67static bool _Nios2_Is_valid_permission(
68  bool data,
69  int perm
70)
71{
72  int max = data ? 6 : 2;
73
74  return 0 <= perm && perm <= max && (!data || (data && perm != 3));
75}
76
77bool _Nios2_MPU_Setup_region_registers(
78  const Nios2_MPU_Configuration *config,
79  const Nios2_MPU_Region_descriptor *desc,
80  uint32_t *mpubase,
81  uint32_t *mpuacc
82)
83{
84  uint32_t base = (uint32_t) desc->base;
85  uint32_t end = (uint32_t) desc->end;
86  uint32_t mask_or_limit = 0;
87  bool is_valid_base_and_end = _Nios2_Is_valid_base_and_end(
88    config,
89    desc->data,
90    base,
91    end,
92    &mask_or_limit
93  );
94  bool ok = is_valid_base_and_end
95    && _Nios2_MPU_Is_valid_index( config, desc->index, desc->data )
96    && _Nios2_Is_valid_permission( desc->data, desc->perm )
97    && !(!desc->data && desc->cacheable)
98    && !(desc->read && desc->write);
99
100  if ( ok ) {
101    *mpubase = (base & NIOS2_MPUBASE_BASE_MASK)
102      | ((desc->index << NIOS2_MPUBASE_INDEX_OFFSET) & NIOS2_MPUBASE_INDEX_MASK)
103      | (desc->data ? NIOS2_MPUBASE_D : 0);
104    *mpuacc = mask_or_limit
105      | (desc->cacheable ? NIOS2_MPUACC_C : 0)
106      | ((desc->perm << NIOS2_MPUACC_PERM_OFFSET) & NIOS2_MPUACC_PERM_MASK)
107      | (desc->read ? NIOS2_MPUACC_RD : 0)
108      | (desc->write ? NIOS2_MPUACC_WR : 0);
109  }
110
111  return ok;
112}
113
114bool _Nios2_MPU_Get_region_descriptor(
115  const Nios2_MPU_Configuration *config,
116  int index,
117  bool data,
118  Nios2_MPU_Region_descriptor *desc
119)
120{
121  bool ok = _Nios2_MPU_Is_valid_index( config, index, data );
122
123  if ( ok ) {
124    uint32_t mpubase;
125    uint32_t mpuacc;
126
127    _Nios2_MPU_Get_region_registers( index, data, &mpubase, &mpuacc );
128
129    desc->index = index;
130    desc->base = (void *) (mpubase & NIOS2_MPUBASE_BASE_MASK);
131    if ( config->region_uses_limit ) {
132      desc->end = (void *) (mpuacc & NIOS2_MPUACC_LIMIT_MASK);
133    } else {
134      desc->end = (void *) ((mpuacc & NIOS2_MPUACC_MASK_MASK) + 1);
135    }
136    desc->perm = (mpuacc & NIOS2_MPUACC_PERM_MASK) >> NIOS2_MPUACC_PERM_OFFSET;
137    desc->data = data;
138    desc->cacheable = (mpuacc & NIOS2_MPUACC_C) != 0;
139    desc->read = (mpuacc & NIOS2_MPUACC_RD) != 0;
140    desc->write = (mpuacc & NIOS2_MPUACC_WR) != 0;
141  }
142
143  return ok;
144}
Note: See TracBrowser for help on using the repository browser.