Address.hh revision 6285:ce086eca1ede
14661Sksewell@umich.edu 24661Sksewell@umich.edu/* 34661Sksewell@umich.edu * Copyright (c) 1999 Mark D. Hill and David A. Wood 44661Sksewell@umich.edu * All rights reserved. 54661Sksewell@umich.edu * 64661Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without 74661Sksewell@umich.edu * modification, are permitted provided that the following conditions are 84661Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 94661Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 104661Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 114661Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 124661Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 134661Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 144661Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 154661Sksewell@umich.edu * this software without specific prior written permission. 164661Sksewell@umich.edu * 174661Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 184661Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 194661Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 204661Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 214661Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 224661Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 234661Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 244661Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 254661Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 264661Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 274661Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 284661Sksewell@umich.edu */ 294661Sksewell@umich.edu 304661Sksewell@umich.edu/* 314661Sksewell@umich.edu * $Id$ 324661Sksewell@umich.edu */ 334661Sksewell@umich.edu 344661Sksewell@umich.edu#ifndef ADDRESS_H 354661Sksewell@umich.edu#define ADDRESS_H 364661Sksewell@umich.edu 374661Sksewell@umich.edu#include <iomanip> 384661Sksewell@umich.edu#include "mem/ruby/common/Global.hh" 394661Sksewell@umich.edu#include "mem/ruby/system/System.hh" 404661Sksewell@umich.edu#include "mem/ruby/system/NodeID.hh" 414661Sksewell@umich.edu#include "mem/ruby/system/MachineID.hh" 424661Sksewell@umich.edu 434661Sksewell@umich.educonst int ADDRESS_WIDTH = 64; // address width in bytes 444661Sksewell@umich.edu 454661Sksewell@umich.educlass Address; 464661Sksewell@umich.edutypedef Address PhysAddress; 474661Sksewell@umich.edutypedef Address VirtAddress; 484661Sksewell@umich.edu 494661Sksewell@umich.educlass Address { 504661Sksewell@umich.edupublic: 514661Sksewell@umich.edu // Constructors 524661Sksewell@umich.edu Address() { m_address = 0; } 534661Sksewell@umich.edu explicit Address(physical_address_t address) { m_address = address; } 544661Sksewell@umich.edu 554661Sksewell@umich.edu Address(const Address& obj); 564661Sksewell@umich.edu Address& operator=(const Address& obj); 574661Sksewell@umich.edu 584661Sksewell@umich.edu // Destructor 594661Sksewell@umich.edu // ~Address(); 604661Sksewell@umich.edu 614661Sksewell@umich.edu // Public Methods 624661Sksewell@umich.edu 634661Sksewell@umich.edu void setAddress(physical_address_t address) { m_address = address; } 644661Sksewell@umich.edu physical_address_t getAddress() const {return m_address;} 654661Sksewell@umich.edu // selects bits inclusive 664661Sksewell@umich.edu physical_address_t bitSelect(int small, int big) const; 674661Sksewell@umich.edu physical_address_t maskLowOrderBits(int number) const; 684661Sksewell@umich.edu physical_address_t maskHighOrderBits(int number) const; 694661Sksewell@umich.edu physical_address_t shiftLowOrderBits(int number) const; 704661Sksewell@umich.edu physical_address_t getLineAddress() const 714661Sksewell@umich.edu { return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); } 724661Sksewell@umich.edu physical_address_t getOffset() const 734661Sksewell@umich.edu { return bitSelect(0, RubySystem::getBlockSizeBits()-1); } 744661Sksewell@umich.edu 754661Sksewell@umich.edu void makeLineAddress() { m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); } 764661Sksewell@umich.edu // returns the next stride address based on line address 774661Sksewell@umich.edu void makeNextStrideAddress( int stride) { 784661Sksewell@umich.edu m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()) 794661Sksewell@umich.edu + RubySystem::getBlockSizeBytes()*stride; 804661Sksewell@umich.edu } 814661Sksewell@umich.edu int getBankSetNum() const; 824661Sksewell@umich.edu int getBankSetDist() const; 834661Sksewell@umich.edu 844661Sksewell@umich.edu Index memoryModuleIndex() const; 854661Sksewell@umich.edu 864661Sksewell@umich.edu void print(ostream& out) const; 874661Sksewell@umich.edu void output(ostream& out) const; 884661Sksewell@umich.edu void input(istream& in); 894661Sksewell@umich.edu 904661Sksewell@umich.edu void setOffset( int offset ){ 914661Sksewell@umich.edu // first, zero out the offset bits 924661Sksewell@umich.edu makeLineAddress(); 934661Sksewell@umich.edu m_address |= (physical_address_t) offset; 944661Sksewell@umich.edu } 954661Sksewell@umich.edu 964661Sksewell@umich.eduprivate: 974661Sksewell@umich.edu // Private Methods 984661Sksewell@umich.edu 994661Sksewell@umich.edu // Private copy constructor and assignment operator 1004661Sksewell@umich.edu // Address(const Address& obj); 1014661Sksewell@umich.edu // Address& operator=(const Address& obj); 1024661Sksewell@umich.edu 1034661Sksewell@umich.edu // Data Members (m_ prefix) 1044661Sksewell@umich.edu physical_address_t m_address; 1054661Sksewell@umich.edu}; 1064661Sksewell@umich.edu 1074661Sksewell@umich.eduinline 1084661Sksewell@umich.eduAddress line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; } 1094661Sksewell@umich.edu 1104661Sksewell@umich.edu/* 1114661Sksewell@umich.eduinline 1124661Sksewell@umich.eduAddress next_stride_address(const Address& addr, int stride) { 1134661Sksewell@umich.edu Address temp = addr; 1144661Sksewell@umich.edu temp.makeNextStrideAddress(stride); 1154661Sksewell@umich.edu temp.setAddress(temp.maskHighOrderBits(ADDRESS_WIDTH-RubyConfig::memorySizeBits())); // surpress wrap-around problem 1164661Sksewell@umich.edu return temp; 1174661Sksewell@umich.edu} 1184661Sksewell@umich.edu*/ 1194661Sksewell@umich.edu 1204661Sksewell@umich.edu// Output operator declaration 1214661Sksewell@umich.eduostream& operator<<(ostream& out, const Address& obj); 1224661Sksewell@umich.edu// comparison operator declaration 1234661Sksewell@umich.edubool operator==(const Address& obj1, const Address& obj2); 1244661Sksewell@umich.edubool operator!=(const Address& obj1, const Address& obj2); 1254661Sksewell@umich.edubool operator<(const Address& obj1, const Address& obj2); 1264661Sksewell@umich.edu/* Address& operator=(const physical_address_t address); */ 1274661Sksewell@umich.edu 1284661Sksewell@umich.eduinline 1294661Sksewell@umich.edubool operator<(const Address& obj1, const Address& obj2) 1304661Sksewell@umich.edu{ 1314661Sksewell@umich.edu return obj1.getAddress() < obj2.getAddress(); 1324661Sksewell@umich.edu} 1334661Sksewell@umich.edu 1344661Sksewell@umich.edu// ******************* Definitions ******************* 1354661Sksewell@umich.edu 1364661Sksewell@umich.edu// Output operator definition 1374661Sksewell@umich.eduinline 1384661Sksewell@umich.eduostream& operator<<(ostream& out, const Address& obj) 1394661Sksewell@umich.edu{ 1404661Sksewell@umich.edu obj.print(out); 1414661Sksewell@umich.edu out << flush; 1424661Sksewell@umich.edu return out; 1434661Sksewell@umich.edu} 1444661Sksewell@umich.edu 1454661Sksewell@umich.eduinline 1464661Sksewell@umich.edubool operator==(const Address& obj1, const Address& obj2) 1474661Sksewell@umich.edu{ 1484661Sksewell@umich.edu return (obj1.getAddress() == obj2.getAddress()); 1494661Sksewell@umich.edu} 1504661Sksewell@umich.edu 1514661Sksewell@umich.eduinline 1524661Sksewell@umich.edubool operator!=(const Address& obj1, const Address& obj2) 1534661Sksewell@umich.edu{ 1544661Sksewell@umich.edu return (obj1.getAddress() != obj2.getAddress()); 1554661Sksewell@umich.edu} 1564661Sksewell@umich.edu 1574661Sksewell@umich.eduinline 1584661Sksewell@umich.eduphysical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive 1594661Sksewell@umich.edu{ 1604661Sksewell@umich.edu physical_address_t mask; 1614661Sksewell@umich.edu assert(big >= small); 1624661Sksewell@umich.edu 1634661Sksewell@umich.edu if (big >= ADDRESS_WIDTH - 1) { 1644661Sksewell@umich.edu return (m_address >> small); 1654661Sksewell@umich.edu } else { 1664661Sksewell@umich.edu mask = ~((physical_address_t)~0 << (big + 1)); 1674661Sksewell@umich.edu // FIXME - this is slow to manipulate a 64-bit number using 32-bits 1684661Sksewell@umich.edu physical_address_t partial = (m_address & mask); 1694661Sksewell@umich.edu return (partial >> small); 1704661Sksewell@umich.edu } 1714661Sksewell@umich.edu} 1724661Sksewell@umich.edu 1734661Sksewell@umich.eduinline 1744661Sksewell@umich.eduphysical_address_t Address::maskLowOrderBits(int number) const 1754661Sksewell@umich.edu{ 1764661Sksewell@umich.edu physical_address_t mask; 1774661Sksewell@umich.edu 1784661Sksewell@umich.edu if (number >= ADDRESS_WIDTH - 1) { 1794661Sksewell@umich.edu mask = ~0; 1804661Sksewell@umich.edu } else { 1814661Sksewell@umich.edu mask = (physical_address_t)~0 << number; 1824661Sksewell@umich.edu } 1834661Sksewell@umich.edu return (m_address & mask); 1844661Sksewell@umich.edu} 1854661Sksewell@umich.edu 1864661Sksewell@umich.eduinline 1874661Sksewell@umich.eduphysical_address_t Address::maskHighOrderBits(int number) const 1884661Sksewell@umich.edu{ 1894661Sksewell@umich.edu physical_address_t mask; 1904661Sksewell@umich.edu 1914661Sksewell@umich.edu if (number >= ADDRESS_WIDTH - 1) { 1924661Sksewell@umich.edu mask = ~0; 1934661Sksewell@umich.edu } else { 1944661Sksewell@umich.edu mask = (physical_address_t)~0 >> number; 1954661Sksewell@umich.edu } 1964661Sksewell@umich.edu return (m_address & mask); 1974661Sksewell@umich.edu} 1984661Sksewell@umich.edu 1994661Sksewell@umich.eduinline 2004661Sksewell@umich.eduphysical_address_t Address::shiftLowOrderBits(int number) const 2014661Sksewell@umich.edu{ 2024661Sksewell@umich.edu return (m_address >> number); 2034661Sksewell@umich.edu} 2044661Sksewell@umich.edu 2054661Sksewell@umich.eduinline 2064661Sksewell@umich.eduinteger_t Address::memoryModuleIndex() const 2074661Sksewell@umich.edu{ 2084661Sksewell@umich.edu integer_t index = bitSelect(RubySystem::getBlockSizeBits()+RubySystem::getMemorySizeBits(), ADDRESS_WIDTH); 2094661Sksewell@umich.edu assert (index >= 0); 2104661Sksewell@umich.edu /* 2114661Sksewell@umich.edu if (index >= RubyConfig::memoryModuleBlocks()) { 2124661Sksewell@umich.edu cerr << " memoryBits: " << RubySystem::getMemorySizeBits() << " memorySizeBits: " << RubySystem::getMemorySizeBits() 2134661Sksewell@umich.edu << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush 2144661Sksewell@umich.edu << "error: limit exceeded. " << 2154661Sksewell@umich.edu " getDataBlockBits: " << RubySystem::getBlockSizeBits() << 2164661Sksewell@umich.edu " 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