* ========== Copyright Header Begin ==========================================
* OpenSPARC T2 Processor File: pMap.h
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* The above named program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* ========== Copyright Header End ============================================
* The file pMap.h contains "private" code for methods relating to the
* This file is considered private to the class implementation and not
* part of its interface. This code is in a header file just to
* allow the template class to be packaged up into a library.
static const bool VERBOSE_MAP
= false;
static const uint MAP_LEVEL4_SIZE
= 1 << MAP_LEVEL4_BITS
;
static const uint MAP_LEVEL4_SHIFT
= 0;
static const Addr MAP_LEVEL4_MASK
= MAP_LEVEL4_SIZE
- 1;
static const uint MAP_LEVEL3_SIZE
= 1 << MAP_LEVEL3_BITS
;
static const uint MAP_LEVEL3_SHIFT
= MAP_LEVEL4_SHIFT
+ MAP_LEVEL4_BITS
;
static const Addr MAP_LEVEL3_MASK
= MAP_LEVEL3_SIZE
- 1;
static const uint MAP_LEVEL2_SIZE
= 1 << MAP_LEVEL2_BITS
;
static const uint MAP_LEVEL2_SHIFT
= MAP_LEVEL3_SHIFT
+ MAP_LEVEL3_BITS
;
static const Addr MAP_LEVEL2_MASK
= MAP_LEVEL2_SIZE
- 1;
static const uint MAP_LEVEL1_SIZE
= 1 << MAP_LEVEL1_BITS
;
static const uint MAP_LEVEL1_SHIFT
= MAP_LEVEL2_SHIFT
+ MAP_LEVEL2_BITS
;
static const Addr MAP_LEVEL1_MASK
= MAP_LEVEL1_SIZE
- 1;
static const uint MAP_LEVEL0_SIZE
= 1 << MAP_LEVEL0_BITS
;
static const uint MAP_LEVEL0_SHIFT
= MAP_LEVEL1_SHIFT
+ MAP_LEVEL1_BITS
;
static const Addr MAP_LEVEL0_MASK
= MAP_LEVEL0_SIZE
- 1;
// MapLevel4 is an instance of type T
template<class T
> struct MapLevel3
T
*level3
[MAP_LEVEL3_SIZE
];
template<class T
> struct MapLevel2
MapLevel3
<T
> *level2
[MAP_LEVEL2_SIZE
];
template<class T
> struct MapLevel1
MapLevel2
<T
> *level1
[MAP_LEVEL1_SIZE
];
template<class T
> struct MapLevel0
MapLevel1
<T
> *level0
[MAP_LEVEL0_SIZE
];
template<class T
> MapGeneric
<T
>::MapGeneric (string n
, Addr s
, Addr e
, uint w
)
assert(s
>= MAP_MIN_ADDR
&& s
<= e
&& e
<= MAP_MAX_ADDR
);
template<class T
> Map
<T
>::Map (string n
, Addr s
, Addr e
, uint w
) :
MapGeneric
<T
>(n
, s
, e
, w
)
assert(w
== MAP_LEVEL4_SIZE
);
bytes
+= sizeof(MapLevel0
<T
>);
for (uint l0
=0; l0
<MAP_LEVEL0_SIZE
; l0
++)
template<class T
> Map
<T
>::~Map ()
cout
<< "Map " << name
<< " has " << dec
<< ", count_level0 = " << count_level0
<< ", count_level1 = " << count_level1
<< ", count_level2 = " << count_level2
<< ", count_level3 = " << count_level3
<< ", count_level4 = " << count_level4
<< "\n";
for (uint l0
=0; l0
<MAP_LEVEL0_SIZE
; l0
++) {
if (map
->level0
[l0
] != NULL
) {
for (uint l1
=0; l1
<MAP_LEVEL1_SIZE
; l1
++) {
if (map
->level0
[l0
]->level1
[l1
] != NULL
) {
for (uint l2
=0; l2
<MAP_LEVEL2_SIZE
; l2
++) {
if (map
->level0
[l0
]->level1
[l1
]->level2
[l2
] != NULL
) {
delete map
->level0
[l0
]->level1
[l1
]->level2
[l2
];
delete map
->level0
[l0
]->level1
[l1
];
template<class T
> bool Map
<T
>::insert (Addr addr
, T
*item
)
if (addr
< start
|| addr
> end
|| ((addr
& MAP_LEVEL4_MASK
) != 0))
uint level0_index
= uint((addr
>> MAP_LEVEL0_SHIFT
) & MAP_LEVEL0_MASK
);
uint level1_index
= uint((addr
>> MAP_LEVEL1_SHIFT
) & MAP_LEVEL1_MASK
);
uint level2_index
= uint((addr
>> MAP_LEVEL2_SHIFT
) & MAP_LEVEL2_MASK
);
uint level3_index
= uint((addr
>> MAP_LEVEL3_SHIFT
) & MAP_LEVEL3_MASK
);
if ((l
= map
->level0
[level0_index
]) == NULL
) {
bytes
+= sizeof(MapLevel1
<T
>);
for (uint l1
=0; l1
<MAP_LEVEL1_SIZE
; l1
++)
map
->level0
[level0_index
] = l
;
if ((m
= l
->level1
[level1_index
]) == NULL
) {
bytes
+= sizeof(MapLevel2
<T
>);
for (uint l2
=0; l2
<MAP_LEVEL2_SIZE
; l2
++)
l
->level1
[level1_index
] = m
;
if ((n
= m
->level2
[level2_index
]) == NULL
) {
bytes
+= sizeof(MapLevel3
<T
>);
for (uint l3
=0; l3
<MAP_LEVEL3_SIZE
; l3
++)
m
->level2
[level2_index
] = n
;
if (n
->level3
[level3_index
] == NULL
) {
n
->level3
[level3_index
] = item
;
template<class T
> T
*Map
<T
>::remove (Addr addr
)
if (addr
< start
|| addr
> end
|| ((addr
& MAP_LEVEL4_MASK
) != 0))
uint level0_index
= uint((addr
>> MAP_LEVEL0_SHIFT
) & MAP_LEVEL0_MASK
);
uint level1_index
= uint((addr
>> MAP_LEVEL1_SHIFT
) & MAP_LEVEL1_MASK
);
uint level2_index
= uint((addr
>> MAP_LEVEL2_SHIFT
) & MAP_LEVEL2_MASK
);
uint level3_index
= uint((addr
>> MAP_LEVEL3_SHIFT
) & MAP_LEVEL3_MASK
);
if ((l
= map
->level0
[level0_index
]) == NULL
)
if ((m
= l
->level1
[level1_index
]) == NULL
)
if ((n
= m
->level2
[level2_index
]) == NULL
)
T
*result
= n
->level3
[level3_index
];
n
->level3
[level3_index
] = NULL
;
template<class T
> T
*Map
<T
>::lookup (Addr addr
)
if (addr
< start
|| addr
> end
|| ((addr
& MAP_LEVEL4_MASK
) != 0))
uint level0_index
= uint((addr
>> MAP_LEVEL0_SHIFT
) & MAP_LEVEL0_MASK
);
uint level1_index
= uint((addr
>> MAP_LEVEL1_SHIFT
) & MAP_LEVEL1_MASK
);
uint level2_index
= uint((addr
>> MAP_LEVEL2_SHIFT
) & MAP_LEVEL2_MASK
);
uint level3_index
= uint((addr
>> MAP_LEVEL3_SHIFT
) & MAP_LEVEL3_MASK
);
if ((l
= map
->level0
[level0_index
]) == NULL
)
if ((m
= l
->level1
[level1_index
]) == NULL
)
if ((n
= m
->level2
[level2_index
]) == NULL
)
return n
->level3
[level3_index
];