Address.hh revision 6285:ce086eca1ede
1 2/* 3 * Copyright (c) 1999 Mark D. Hill and David A. Wood 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30/* 31 * $Id$ 32 */ 33 34#ifndef ADDRESS_H 35#define ADDRESS_H 36 37#include <iomanip> 38#include "mem/ruby/common/Global.hh" 39#include "mem/ruby/system/System.hh" 40#include "mem/ruby/system/NodeID.hh" 41#include "mem/ruby/system/MachineID.hh" 42 43const int ADDRESS_WIDTH = 64; // address width in bytes 44 45class Address; 46typedef Address PhysAddress; 47typedef Address VirtAddress; 48 49class Address { 50public: 51 // Constructors 52 Address() { m_address = 0; } 53 explicit Address(physical_address_t address) { m_address = address; } 54 55 Address(const Address& obj); 56 Address& operator=(const Address& obj); 57 58 // Destructor 59 // ~Address(); 60 61 // Public Methods 62 63 void setAddress(physical_address_t address) { m_address = address; } 64 physical_address_t getAddress() const {return m_address;} 65 // selects bits inclusive 66 physical_address_t bitSelect(int small, int big) const; 67 physical_address_t maskLowOrderBits(int number) const; 68 physical_address_t maskHighOrderBits(int number) const; 69 physical_address_t shiftLowOrderBits(int number) const; 70 physical_address_t getLineAddress() const 71 { return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); } 72 physical_address_t getOffset() const 73 { return bitSelect(0, RubySystem::getBlockSizeBits()-1); } 74 75 void makeLineAddress() { m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); } 76 // returns the next stride address based on line address 77 void makeNextStrideAddress( int stride) { 78 m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()) 79 + RubySystem::getBlockSizeBytes()*stride; 80 } 81 int getBankSetNum() const; 82 int getBankSetDist() const; 83 84 Index memoryModuleIndex() const; 85 86 void print(ostream& out) const; 87 void output(ostream& out) const; 88 void input(istream& in); 89 90 void setOffset( int offset ){ 91 // first, zero out the offset bits 92 makeLineAddress(); 93 m_address |= (physical_address_t) offset; 94 } 95 96private: 97 // Private Methods 98 99 // Private copy constructor and assignment operator 100 // Address(const Address& obj); 101 // Address& operator=(const Address& obj); 102 103 // Data Members (m_ prefix) 104 physical_address_t m_address; 105}; 106 107inline 108Address line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; } 109 110/* 111inline 112Address next_stride_address(const Address& addr, int stride) { 113 Address temp = addr; 114 temp.makeNextStrideAddress(stride); 115 temp.setAddress(temp.maskHighOrderBits(ADDRESS_WIDTH-RubyConfig::memorySizeBits())); // surpress wrap-around problem 116 return temp; 117} 118*/ 119 120// Output operator declaration 121ostream& operator<<(ostream& out, const Address& obj); 122// comparison operator declaration 123bool operator==(const Address& obj1, const Address& obj2); 124bool operator!=(const Address& obj1, const Address& obj2); 125bool operator<(const Address& obj1, const Address& obj2); 126/* Address& operator=(const physical_address_t address); */ 127 128inline 129bool operator<(const Address& obj1, const Address& obj2) 130{ 131 return obj1.getAddress() < obj2.getAddress(); 132} 133 134// ******************* Definitions ******************* 135 136// Output operator definition 137inline 138ostream& operator<<(ostream& out, const Address& obj) 139{ 140 obj.print(out); 141 out << flush; 142 return out; 143} 144 145inline 146bool operator==(const Address& obj1, const Address& obj2) 147{ 148 return (obj1.getAddress() == obj2.getAddress()); 149} 150 151inline 152bool operator!=(const Address& obj1, const Address& obj2) 153{ 154 return (obj1.getAddress() != obj2.getAddress()); 155} 156 157inline 158physical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive 159{ 160 physical_address_t mask; 161 assert(big >= small); 162 163 if (big >= ADDRESS_WIDTH - 1) { 164 return (m_address >> small); 165 } else { 166 mask = ~((physical_address_t)~0 << (big + 1)); 167 // FIXME - this is slow to manipulate a 64-bit number using 32-bits 168 physical_address_t partial = (m_address & mask); 169 return (partial >> small); 170 } 171} 172 173inline 174physical_address_t Address::maskLowOrderBits(int number) const 175{ 176 physical_address_t mask; 177 178 if (number >= ADDRESS_WIDTH - 1) { 179 mask = ~0; 180 } else { 181 mask = (physical_address_t)~0 << number; 182 } 183 return (m_address & mask); 184} 185 186inline 187physical_address_t Address::maskHighOrderBits(int number) const 188{ 189 physical_address_t mask; 190 191 if (number >= ADDRESS_WIDTH - 1) { 192 mask = ~0; 193 } else { 194 mask = (physical_address_t)~0 >> number; 195 } 196 return (m_address & mask); 197} 198 199inline 200physical_address_t Address::shiftLowOrderBits(int number) const 201{ 202 return (m_address >> number); 203} 204 205inline 206integer_t Address::memoryModuleIndex() const 207{ 208 integer_t index = bitSelect(RubySystem::getBlockSizeBits()+RubySystem::getMemorySizeBits(), ADDRESS_WIDTH); 209 assert (index >= 0); 210 /* 211 if (index >= RubyConfig::memoryModuleBlocks()) { 212 cerr << " memoryBits: " << RubySystem::getMemorySizeBits() << " memorySizeBits: " << RubySystem::getMemorySizeBits() 213 << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush 214 << "error: limit exceeded. " << 215 " getDataBlockBits: " << RubySystem::getBlockSizeBits() << 216 " memoryModuleBlocks: " << RubyConfig::memoryModuleBlocks() << 217 " index: " << index << endl; 218 } 219 assert (index < RubyConfig::memoryModuleBlocks()); 220 */ 221 return index; 222 223 // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS); 224 // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1); 225 226 //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); 227 228 /* 229 Round-robin mapping of addresses, at page size granularity 230 231ADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS 232 | | | | 233 \ / \ / \ / \ / 0 234 ----------------------------------------------------------------------- 235 | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 236 | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 237 ----------------------------------------------------------------------- 238 indexHighPortion indexLowPortion 239 <-------> 240 NUMBER_OF_MEMORY_MODULE_BITS 241 */ 242} 243 244inline 245void Address::print(ostream& out) const 246{ 247 out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush; 248} 249 250class Address; 251namespace __gnu_cxx { 252 template <> struct hash<Address> 253 { 254 size_t operator()(const Address &s) const { return (size_t) s.getAddress(); } 255 }; 256} 257namespace std { 258 template <> struct equal_to<Address> 259 { 260 bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; } 261 }; 262} 263 264#endif //ADDRESS_H 265 266