Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / regdef / include / pMap.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: pMap.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23#ifndef __pMap_h
24#define __pMap_h
25
26#include <assert.h>
27#include "Map.h"
28#include "Math.h"
29using namespace std;
30
31/** @file pMap.h
32 * The file pMap.h contains "private" code for methods relating to the
33 * Map class.
34 * This file is considered private to the class implementation and not
35 * part of its interface. This code is in a header file just to
36 * allow the template class to be packaged up into a library.
37 */
38
39static const bool VERBOSE_MAP = false;
40
41static const uint MAP_LEVEL4_SIZE = 1 << MAP_LEVEL4_BITS;
42static const uint MAP_LEVEL4_SHIFT = 0;
43static const Addr MAP_LEVEL4_MASK = MAP_LEVEL4_SIZE - 1;
44
45static const uint MAP_LEVEL3_SIZE = 1 << MAP_LEVEL3_BITS;
46static const uint MAP_LEVEL3_SHIFT = MAP_LEVEL4_SHIFT + MAP_LEVEL4_BITS;
47static const Addr MAP_LEVEL3_MASK = MAP_LEVEL3_SIZE - 1;
48
49static const uint MAP_LEVEL2_SIZE = 1 << MAP_LEVEL2_BITS;
50static const uint MAP_LEVEL2_SHIFT = MAP_LEVEL3_SHIFT + MAP_LEVEL3_BITS;
51static const Addr MAP_LEVEL2_MASK = MAP_LEVEL2_SIZE - 1;
52
53static const uint MAP_LEVEL1_SIZE = 1 << MAP_LEVEL1_BITS;
54static const uint MAP_LEVEL1_SHIFT = MAP_LEVEL2_SHIFT + MAP_LEVEL2_BITS;
55static const Addr MAP_LEVEL1_MASK = MAP_LEVEL1_SIZE - 1;
56
57static const uint MAP_LEVEL0_SIZE = 1 << MAP_LEVEL0_BITS;
58static const uint MAP_LEVEL0_SHIFT = MAP_LEVEL1_SHIFT + MAP_LEVEL1_BITS;
59static const Addr MAP_LEVEL0_MASK = MAP_LEVEL0_SIZE - 1;
60
61// MapLevel4 is an instance of type T
62
63template<class T> struct MapLevel3
64{
65 T *level3[MAP_LEVEL3_SIZE];
66};
67
68template<class T> struct MapLevel2
69{
70 MapLevel3<T> *level2[MAP_LEVEL2_SIZE];
71};
72
73template<class T> struct MapLevel1
74{
75 MapLevel2<T> *level1[MAP_LEVEL1_SIZE];
76};
77
78template<class T> struct MapLevel0
79{
80 MapLevel1<T> *level0[MAP_LEVEL0_SIZE];
81};
82
83template<class T> MapGeneric<T>::MapGeneric (string n, Addr s, Addr e, uint w)
84{
85 assert(s >= MAP_MIN_ADDR && s <= e && e <= MAP_MAX_ADDR);
86 assert(ispow2(w));
87 name = n;
88 start = s;
89 end = e;
90}
91
92template<class T> Map<T>::Map (string n, Addr s, Addr e, uint w) :
93 MapGeneric<T>(n, s, e, w)
94{
95 assert(w == MAP_LEVEL4_SIZE);
96 count_level0 = 0;
97 count_level1 = 0;
98 count_level2 = 0;
99 count_level3 = 0;
100 count_level4 = 0;
101 bytes = 0;
102 map = new MapLevel0<T>;
103 count_level0++;
104 bytes += sizeof(MapLevel0<T>);
105 for (uint l0=0; l0<MAP_LEVEL0_SIZE; l0++)
106 map->level0[l0] = NULL;
107}
108
109template<class T> Map<T>::~Map ()
110{
111 if (VERBOSE_MAP) {
112 cout << "Map " << name << " has " << dec
113 << "bytes = " << bytes
114 << ", count_level0 = " << count_level0
115 << ", count_level1 = " << count_level1
116 << ", count_level2 = " << count_level2
117 << ", count_level3 = " << count_level3
118 << ", count_level4 = " << count_level4 << "\n";
119 }
120
121 for (uint l0=0; l0<MAP_LEVEL0_SIZE; l0++) {
122 if (map->level0[l0] != NULL) {
123 for (uint l1=0; l1<MAP_LEVEL1_SIZE; l1++) {
124 if (map->level0[l0]->level1[l1] != NULL) {
125 for (uint l2=0; l2<MAP_LEVEL2_SIZE; l2++) {
126 if (map->level0[l0]->level1[l1]->level2[l2] != NULL) {
127 delete map->level0[l0]->level1[l1]->level2[l2];
128 }
129 }
130 delete map->level0[l0]->level1[l1];
131 }
132 }
133 delete map->level0[l0];
134 }
135 }
136 delete map;
137}
138
139
140template<class T> bool Map<T>::insert (Addr addr, T *item)
141{
142 assert(item != NULL);
143
144 if (addr < start || addr > end || ((addr & MAP_LEVEL4_MASK) != 0))
145 return false;
146
147 uint level0_index = uint((addr >> MAP_LEVEL0_SHIFT) & MAP_LEVEL0_MASK);
148 uint level1_index = uint((addr >> MAP_LEVEL1_SHIFT) & MAP_LEVEL1_MASK);
149 uint level2_index = uint((addr >> MAP_LEVEL2_SHIFT) & MAP_LEVEL2_MASK);
150 uint level3_index = uint((addr >> MAP_LEVEL3_SHIFT) & MAP_LEVEL3_MASK);
151
152 MapLevel1<T> *l;
153 if ((l = map->level0[level0_index]) == NULL) {
154 l = new MapLevel1<T>;
155 count_level1++;
156 bytes += sizeof(MapLevel1<T>);
157 for (uint l1=0; l1<MAP_LEVEL1_SIZE; l1++)
158 l->level1[l1] = NULL;
159 map->level0[level0_index] = l;
160 }
161
162 MapLevel2<T> *m;
163 if ((m = l->level1[level1_index]) == NULL) {
164 m = new MapLevel2<T>;
165 count_level2++;
166 bytes += sizeof(MapLevel2<T>);
167 for (uint l2=0; l2<MAP_LEVEL2_SIZE; l2++)
168 m->level2[l2] = NULL;
169 l->level1[level1_index] = m;
170 }
171
172 MapLevel3<T> *n;
173 if ((n = m->level2[level2_index]) == NULL) {
174 n = new MapLevel3<T>;
175 count_level3++;
176 bytes += sizeof(MapLevel3<T>);
177 for (uint l3=0; l3<MAP_LEVEL3_SIZE; l3++)
178 n->level3[l3] = NULL;
179 m->level2[level2_index] = n;
180 }
181
182 if (n->level3[level3_index] == NULL) {
183 n->level3[level3_index] = item;
184 count_level4++;
185 return true;
186 }
187 else
188 return false;
189}
190
191template<class T> T *Map<T>::remove (Addr addr)
192{
193 if (addr < start || addr > end || ((addr & MAP_LEVEL4_MASK) != 0))
194 return NULL;
195
196 uint level0_index = uint((addr >> MAP_LEVEL0_SHIFT) & MAP_LEVEL0_MASK);
197 uint level1_index = uint((addr >> MAP_LEVEL1_SHIFT) & MAP_LEVEL1_MASK);
198 uint level2_index = uint((addr >> MAP_LEVEL2_SHIFT) & MAP_LEVEL2_MASK);
199 uint level3_index = uint((addr >> MAP_LEVEL3_SHIFT) & MAP_LEVEL3_MASK);
200
201 MapLevel1<T> *l;
202 if ((l = map->level0[level0_index]) == NULL)
203 return NULL;
204
205 MapLevel2<T> *m;
206 if ((m = l->level1[level1_index]) == NULL)
207 return NULL;
208
209 MapLevel3<T> *n;
210 if ((n = m->level2[level2_index]) == NULL)
211 return NULL;
212
213 T *result = n->level3[level3_index];
214 n->level3[level3_index] = NULL;
215 return result;
216}
217
218template<class T> T *Map<T>::lookup (Addr addr)
219{
220 if (addr < start || addr > end || ((addr & MAP_LEVEL4_MASK) != 0))
221 return NULL;
222
223 uint level0_index = uint((addr >> MAP_LEVEL0_SHIFT) & MAP_LEVEL0_MASK);
224 uint level1_index = uint((addr >> MAP_LEVEL1_SHIFT) & MAP_LEVEL1_MASK);
225 uint level2_index = uint((addr >> MAP_LEVEL2_SHIFT) & MAP_LEVEL2_MASK);
226 uint level3_index = uint((addr >> MAP_LEVEL3_SHIFT) & MAP_LEVEL3_MASK);
227
228 MapLevel1<T> *l;
229 if ((l = map->level0[level0_index]) == NULL)
230 return NULL;
231
232 MapLevel2<T> *m;
233 if ((m = l->level1[level1_index]) == NULL)
234 return NULL;
235
236 MapLevel3<T> *n;
237 if ((n = m->level2[level2_index]) == NULL)
238 return NULL;
239
240 return n->level3[level3_index];
241}
242
243#endif