Address.hh revision 7027
16285Snate@binkert.org 26145Snate@binkert.org/* 36239Snate@binkert.org * Copyright (c) 1999 Mark D. Hill and David A. Wood 46239Snate@binkert.org * All rights reserved. 56145Snate@binkert.org * 66239Snate@binkert.org * Redistribution and use in source and binary forms, with or without 76239Snate@binkert.org * modification, are permitted provided that the following conditions are 86239Snate@binkert.org * met: redistributions of source code must retain the above copyright 96239Snate@binkert.org * notice, this list of conditions and the following disclaimer; 106239Snate@binkert.org * redistributions in binary form must reproduce the above copyright 116239Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 126239Snate@binkert.org * documentation and/or other materials provided with the distribution; 136239Snate@binkert.org * neither the name of the copyright holders nor the names of its 146239Snate@binkert.org * contributors may be used to endorse or promote products derived from 156239Snate@binkert.org * this software without specific prior written permission. 166145Snate@binkert.org * 176239Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186239Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196239Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206239Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216239Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226239Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236239Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246239Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256239Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266239Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276239Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286145Snate@binkert.org */ 296145Snate@binkert.org 306285Snate@binkert.org/* 316285Snate@binkert.org * $Id$ 326285Snate@binkert.org */ 336285Snate@binkert.org 346145Snate@binkert.org#ifndef ADDRESS_H 356145Snate@binkert.org#define ADDRESS_H 366145Snate@binkert.org 376145Snate@binkert.org#include <iomanip> 387002Snate@binkert.org 397002Snate@binkert.org#include "base/hashmap.hh" 406154Snate@binkert.org#include "mem/ruby/common/Global.hh" 416285Snate@binkert.org#include "mem/ruby/system/System.hh" 426154Snate@binkert.org#include "mem/ruby/system/NodeID.hh" 436154Snate@binkert.org#include "mem/ruby/system/MachineID.hh" 446145Snate@binkert.org 456145Snate@binkert.orgconst int ADDRESS_WIDTH = 64; // address width in bytes 466145Snate@binkert.org 476145Snate@binkert.orgclass Address; 486145Snate@binkert.orgtypedef Address PhysAddress; 496145Snate@binkert.orgtypedef Address VirtAddress; 506145Snate@binkert.org 516145Snate@binkert.orgclass Address { 526145Snate@binkert.orgpublic: 536145Snate@binkert.org // Constructors 546145Snate@binkert.org Address() { m_address = 0; } 556145Snate@binkert.org explicit Address(physical_address_t address) { m_address = address; } 566145Snate@binkert.org 576145Snate@binkert.org Address(const Address& obj); 586145Snate@binkert.org Address& operator=(const Address& obj); 596145Snate@binkert.org 606145Snate@binkert.org // Destructor 616145Snate@binkert.org // ~Address(); 626145Snate@binkert.org 636145Snate@binkert.org // Public Methods 646145Snate@binkert.org 656145Snate@binkert.org void setAddress(physical_address_t address) { m_address = address; } 666145Snate@binkert.org physical_address_t getAddress() const {return m_address;} 676145Snate@binkert.org // selects bits inclusive 686145Snate@binkert.org physical_address_t bitSelect(int small, int big) const; 697027SBrad.Beckmann@amd.com physical_address_t bitRemove(int small, int big) const; 706145Snate@binkert.org physical_address_t maskLowOrderBits(int number) const; 716145Snate@binkert.org physical_address_t maskHighOrderBits(int number) const; 726145Snate@binkert.org physical_address_t shiftLowOrderBits(int number) const; 736145Snate@binkert.org physical_address_t getLineAddress() const 746285Snate@binkert.org { return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); } 756145Snate@binkert.org physical_address_t getOffset() const 766285Snate@binkert.org { return bitSelect(0, RubySystem::getBlockSizeBits()-1); } 776145Snate@binkert.org 786285Snate@binkert.org void makeLineAddress() { m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); } 796145Snate@binkert.org // returns the next stride address based on line address 806145Snate@binkert.org void makeNextStrideAddress( int stride) { 816285Snate@binkert.org m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()) 826285Snate@binkert.org + RubySystem::getBlockSizeBytes()*stride; 836145Snate@binkert.org } 846145Snate@binkert.org int getBankSetNum() const; 856145Snate@binkert.org int getBankSetDist() const; 866145Snate@binkert.org 876145Snate@binkert.org Index memoryModuleIndex() const; 886145Snate@binkert.org 896145Snate@binkert.org void print(ostream& out) const; 906145Snate@binkert.org void output(ostream& out) const; 916145Snate@binkert.org void input(istream& in); 926145Snate@binkert.org 936145Snate@binkert.org void setOffset( int offset ){ 946145Snate@binkert.org // first, zero out the offset bits 956145Snate@binkert.org makeLineAddress(); 966145Snate@binkert.org m_address |= (physical_address_t) offset; 976145Snate@binkert.org } 986145Snate@binkert.org 996145Snate@binkert.orgprivate: 1006145Snate@binkert.org // Private Methods 1016145Snate@binkert.org 1026145Snate@binkert.org // Private copy constructor and assignment operator 1036145Snate@binkert.org // Address(const Address& obj); 1046145Snate@binkert.org // Address& operator=(const Address& obj); 1056145Snate@binkert.org 1066145Snate@binkert.org // Data Members (m_ prefix) 1076145Snate@binkert.org physical_address_t m_address; 1086145Snate@binkert.org}; 1096145Snate@binkert.org 1106145Snate@binkert.orginline 1116145Snate@binkert.orgAddress line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; } 1126145Snate@binkert.org 1136145Snate@binkert.org// Output operator declaration 1146145Snate@binkert.orgostream& operator<<(ostream& out, const Address& obj); 1156145Snate@binkert.org// comparison operator declaration 1166145Snate@binkert.orgbool operator==(const Address& obj1, const Address& obj2); 1176145Snate@binkert.orgbool operator!=(const Address& obj1, const Address& obj2); 1186145Snate@binkert.orgbool operator<(const Address& obj1, const Address& obj2); 1196145Snate@binkert.org/* Address& operator=(const physical_address_t address); */ 1206145Snate@binkert.org 1216145Snate@binkert.orginline 1226145Snate@binkert.orgbool operator<(const Address& obj1, const Address& obj2) 1236145Snate@binkert.org{ 1246145Snate@binkert.org return obj1.getAddress() < obj2.getAddress(); 1256145Snate@binkert.org} 1266145Snate@binkert.org 1276145Snate@binkert.org// ******************* Definitions ******************* 1286145Snate@binkert.org 1296145Snate@binkert.org// Output operator definition 1306145Snate@binkert.orginline 1316145Snate@binkert.orgostream& operator<<(ostream& out, const Address& obj) 1326145Snate@binkert.org{ 1336145Snate@binkert.org obj.print(out); 1346145Snate@binkert.org out << flush; 1356145Snate@binkert.org return out; 1366145Snate@binkert.org} 1376145Snate@binkert.org 1386145Snate@binkert.orginline 1396145Snate@binkert.orgbool operator==(const Address& obj1, const Address& obj2) 1406145Snate@binkert.org{ 1416145Snate@binkert.org return (obj1.getAddress() == obj2.getAddress()); 1426145Snate@binkert.org} 1436145Snate@binkert.org 1446145Snate@binkert.orginline 1456145Snate@binkert.orgbool operator!=(const Address& obj1, const Address& obj2) 1466145Snate@binkert.org{ 1476145Snate@binkert.org return (obj1.getAddress() != obj2.getAddress()); 1486145Snate@binkert.org} 1496145Snate@binkert.org 1506145Snate@binkert.orginline 1516145Snate@binkert.orgphysical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive 1526145Snate@binkert.org{ 1536145Snate@binkert.org physical_address_t mask; 1546712Snate@binkert.org assert((unsigned)big >= (unsigned)small); 1556145Snate@binkert.org 1566145Snate@binkert.org if (big >= ADDRESS_WIDTH - 1) { 1576145Snate@binkert.org return (m_address >> small); 1586145Snate@binkert.org } else { 1596145Snate@binkert.org mask = ~((physical_address_t)~0 << (big + 1)); 1606145Snate@binkert.org // FIXME - this is slow to manipulate a 64-bit number using 32-bits 1616145Snate@binkert.org physical_address_t partial = (m_address & mask); 1626145Snate@binkert.org return (partial >> small); 1636145Snate@binkert.org } 1646145Snate@binkert.org} 1656145Snate@binkert.org 1667027SBrad.Beckmann@amd.com// removes bits inclusive 1677027SBrad.Beckmann@amd.cominline 1687027SBrad.Beckmann@amd.comphysical_address_t Address::bitRemove(int small, int big) const 1697027SBrad.Beckmann@amd.com{ 1707027SBrad.Beckmann@amd.com physical_address_t mask; 1717027SBrad.Beckmann@amd.com assert((unsigned)big >= (unsigned)small); 1727027SBrad.Beckmann@amd.com 1737027SBrad.Beckmann@amd.com if (small >= ADDRESS_WIDTH - 1) { 1747027SBrad.Beckmann@amd.com return m_address; 1757027SBrad.Beckmann@amd.com } else if (big >= ADDRESS_WIDTH - 1) { 1767027SBrad.Beckmann@amd.com mask = (physical_address_t)~0 >> small; 1777027SBrad.Beckmann@amd.com return (m_address & mask); 1787027SBrad.Beckmann@amd.com } else if (small == 0) { 1797027SBrad.Beckmann@amd.com mask = (physical_address_t)~0 << big; 1807027SBrad.Beckmann@amd.com return (m_address & mask); 1817027SBrad.Beckmann@amd.com } else { 1827027SBrad.Beckmann@amd.com mask = ~((physical_address_t)~0 << small); 1837027SBrad.Beckmann@amd.com physical_address_t lower_bits = m_address & mask; 1847027SBrad.Beckmann@amd.com mask = (physical_address_t)~0 << (big + 1); 1857027SBrad.Beckmann@amd.com physical_address_t higher_bits = m_address & mask; 1867027SBrad.Beckmann@amd.com 1877027SBrad.Beckmann@amd.com // 1887027SBrad.Beckmann@amd.com // Shift the valid high bits over the removed section 1897027SBrad.Beckmann@amd.com // 1907027SBrad.Beckmann@amd.com higher_bits = higher_bits >> (big - small); 1917027SBrad.Beckmann@amd.com return (higher_bits | lower_bits); 1927027SBrad.Beckmann@amd.com } 1937027SBrad.Beckmann@amd.com} 1947027SBrad.Beckmann@amd.com 1956145Snate@binkert.orginline 1966145Snate@binkert.orgphysical_address_t Address::maskLowOrderBits(int number) const 1976145Snate@binkert.org{ 1986145Snate@binkert.org physical_address_t mask; 1996145Snate@binkert.org 2006145Snate@binkert.org if (number >= ADDRESS_WIDTH - 1) { 2016145Snate@binkert.org mask = ~0; 2026145Snate@binkert.org } else { 2036145Snate@binkert.org mask = (physical_address_t)~0 << number; 2046145Snate@binkert.org } 2056145Snate@binkert.org return (m_address & mask); 2066145Snate@binkert.org} 2076145Snate@binkert.org 2086145Snate@binkert.orginline 2096145Snate@binkert.orgphysical_address_t Address::maskHighOrderBits(int number) const 2106145Snate@binkert.org{ 2116145Snate@binkert.org physical_address_t mask; 2126145Snate@binkert.org 2136145Snate@binkert.org if (number >= ADDRESS_WIDTH - 1) { 2146145Snate@binkert.org mask = ~0; 2156145Snate@binkert.org } else { 2166145Snate@binkert.org mask = (physical_address_t)~0 >> number; 2176145Snate@binkert.org } 2186145Snate@binkert.org return (m_address & mask); 2196145Snate@binkert.org} 2206145Snate@binkert.org 2216145Snate@binkert.orginline 2226145Snate@binkert.orgphysical_address_t Address::shiftLowOrderBits(int number) const 2236145Snate@binkert.org{ 2246145Snate@binkert.org return (m_address >> number); 2256145Snate@binkert.org} 2266145Snate@binkert.org 2276145Snate@binkert.orginline 2286145Snate@binkert.orginteger_t Address::memoryModuleIndex() const 2296145Snate@binkert.org{ 2306285Snate@binkert.org integer_t index = bitSelect(RubySystem::getBlockSizeBits()+RubySystem::getMemorySizeBits(), ADDRESS_WIDTH); 2316145Snate@binkert.org assert (index >= 0); 2326145Snate@binkert.org return index; 2336145Snate@binkert.org 2346145Snate@binkert.org // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS); 2356145Snate@binkert.org // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1); 2366145Snate@binkert.org 2376145Snate@binkert.org //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); 2386145Snate@binkert.org 2396145Snate@binkert.org /* 2406145Snate@binkert.org Round-robin mapping of addresses, at page size granularity 2416145Snate@binkert.org 2426145Snate@binkert.orgADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS 2436145Snate@binkert.org | | | | 2446145Snate@binkert.org \ / \ / \ / \ / 0 2456145Snate@binkert.org ----------------------------------------------------------------------- 2466145Snate@binkert.org | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 2476145Snate@binkert.org | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 2486145Snate@binkert.org ----------------------------------------------------------------------- 2496145Snate@binkert.org indexHighPortion indexLowPortion 2506145Snate@binkert.org <-------> 2516145Snate@binkert.org NUMBER_OF_MEMORY_MODULE_BITS 2526145Snate@binkert.org */ 2536145Snate@binkert.org} 2546145Snate@binkert.org 2556145Snate@binkert.orginline 2566145Snate@binkert.orgvoid Address::print(ostream& out) const 2576145Snate@binkert.org{ 2587002Snate@binkert.org using namespace std; 2597002Snate@binkert.org out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" << flush; 2606145Snate@binkert.org} 2616145Snate@binkert.org 2626145Snate@binkert.orgclass Address; 2637002Snate@binkert.orgnamespace __hash_namespace { 2646145Snate@binkert.org template <> struct hash<Address> 2656145Snate@binkert.org { 2666145Snate@binkert.org size_t operator()(const Address &s) const { return (size_t) s.getAddress(); } 2676145Snate@binkert.org }; 2686145Snate@binkert.org} 2696145Snate@binkert.orgnamespace std { 2706145Snate@binkert.org template <> struct equal_to<Address> 2716145Snate@binkert.org { 2726145Snate@binkert.org bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; } 2736145Snate@binkert.org }; 2746145Snate@binkert.org} 2756145Snate@binkert.org 2766145Snate@binkert.org#endif //ADDRESS_H 2776145Snate@binkert.org 278