1 | /* |
---|
2 | * Copyright (c) 2011 embedded brains GmbH. All rights reserved. |
---|
3 | * |
---|
4 | * embedded brains GmbH |
---|
5 | * Obere Lagerstr. 30 |
---|
6 | * 82178 Puchheim |
---|
7 | * Germany |
---|
8 | * <rtems@embedded-brains.de> |
---|
9 | * |
---|
10 | * The license and distribution terms for this file may be |
---|
11 | * found in the file LICENSE in this distribution or at |
---|
12 | * http://www.rtems.com/license/LICENSE. |
---|
13 | * |
---|
14 | * $Id$ |
---|
15 | */ |
---|
16 | |
---|
17 | #ifdef HAVE_CONFIG_H |
---|
18 | #include "config.h" |
---|
19 | #endif |
---|
20 | |
---|
21 | #include <rtems/score/nios2-utility.h> |
---|
22 | |
---|
23 | static bool _Nios2_Is_power_of_two( uint32_t size ) |
---|
24 | { |
---|
25 | bool ok = false; |
---|
26 | int i = 0; |
---|
27 | |
---|
28 | for ( i = 0; !ok && i < 32; ++i ) { |
---|
29 | ok = size == (1U << i); |
---|
30 | } |
---|
31 | |
---|
32 | return ok; |
---|
33 | } |
---|
34 | |
---|
35 | static bool _Nios2_Is_valid_base_and_end( |
---|
36 | const Nios2_MPU_Configuration *config, |
---|
37 | bool data, |
---|
38 | uint32_t base, |
---|
39 | uint32_t end, |
---|
40 | uint32_t *mask_or_limit |
---|
41 | ) |
---|
42 | { |
---|
43 | uint32_t size = end - base; |
---|
44 | uint32_t end_limit = data ? |
---|
45 | (1U << config->data_address_width) |
---|
46 | : (1U << config->instruction_address_width); |
---|
47 | uint32_t mask = data ? |
---|
48 | ((1U << config->data_region_size_log2)) - 1 |
---|
49 | : ((1U << config->instruction_region_size_log2)) - 1; |
---|
50 | bool ok = base < end && end <= end_limit |
---|
51 | && (base & mask) == 0 && (end & mask) == 0; |
---|
52 | |
---|
53 | if ( config->region_uses_limit ) { |
---|
54 | *mask_or_limit = end; |
---|
55 | } else { |
---|
56 | ok = ok && _Nios2_Is_power_of_two( size ); |
---|
57 | *mask_or_limit = (~(size - 1)) & NIOS2_MPUACC_MASK_MASK; |
---|
58 | } |
---|
59 | |
---|
60 | return ok; |
---|
61 | } |
---|
62 | |
---|
63 | static bool _Nios2_Is_valid_permission( |
---|
64 | bool data, |
---|
65 | int perm |
---|
66 | ) |
---|
67 | { |
---|
68 | int max = data ? 6 : 2; |
---|
69 | |
---|
70 | return 0 <= perm && perm <= max && (!data || (data && perm != 3)); |
---|
71 | } |
---|
72 | |
---|
73 | bool _Nios2_MPU_Setup_region_registers( |
---|
74 | const Nios2_MPU_Configuration *config, |
---|
75 | const Nios2_MPU_Region_descriptor *desc, |
---|
76 | uint32_t *mpubase, |
---|
77 | uint32_t *mpuacc |
---|
78 | ) |
---|
79 | { |
---|
80 | uint32_t base = (uint32_t) desc->base; |
---|
81 | uint32_t end = (uint32_t) desc->end; |
---|
82 | uint32_t mask_or_limit = 0; |
---|
83 | bool is_valid_base_and_end = _Nios2_Is_valid_base_and_end( |
---|
84 | config, |
---|
85 | desc->data, |
---|
86 | base, |
---|
87 | end, |
---|
88 | &mask_or_limit |
---|
89 | ); |
---|
90 | bool ok = is_valid_base_and_end |
---|
91 | && _Nios2_MPU_Is_valid_index( config, desc->index, desc->data ) |
---|
92 | && _Nios2_Is_valid_permission( desc->data, desc->perm ) |
---|
93 | && !(!desc->data && desc->cacheable) |
---|
94 | && !(desc->read && desc->write); |
---|
95 | |
---|
96 | if ( ok ) { |
---|
97 | *mpubase = (base & NIOS2_MPUBASE_BASE_MASK) |
---|
98 | | ((desc->index << NIOS2_MPUBASE_INDEX_OFFSET) & NIOS2_MPUBASE_INDEX_MASK) |
---|
99 | | (desc->data ? NIOS2_MPUBASE_D : 0); |
---|
100 | *mpuacc = mask_or_limit |
---|
101 | | (desc->cacheable ? NIOS2_MPUACC_C : 0) |
---|
102 | | ((desc->perm << NIOS2_MPUACC_PERM_OFFSET) & NIOS2_MPUACC_PERM_MASK) |
---|
103 | | (desc->read ? NIOS2_MPUACC_RD : 0) |
---|
104 | | (desc->write ? NIOS2_MPUACC_WR : 0); |
---|
105 | } |
---|
106 | |
---|
107 | return ok; |
---|
108 | } |
---|