Address.hh revision 7811
16145Snate@binkert.org/* 26239Snate@binkert.org * Copyright (c) 1999 Mark D. Hill and David A. Wood 36239Snate@binkert.org * All rights reserved. 46145Snate@binkert.org * 56239Snate@binkert.org * Redistribution and use in source and binary forms, with or without 66239Snate@binkert.org * modification, are permitted provided that the following conditions are 76239Snate@binkert.org * met: redistributions of source code must retain the above copyright 86239Snate@binkert.org * notice, this list of conditions and the following disclaimer; 96239Snate@binkert.org * redistributions in binary form must reproduce the above copyright 106239Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 116239Snate@binkert.org * documentation and/or other materials provided with the distribution; 126239Snate@binkert.org * neither the name of the copyright holders nor the names of its 136239Snate@binkert.org * contributors may be used to endorse or promote products derived from 146239Snate@binkert.org * this software without specific prior written permission. 156145Snate@binkert.org * 166239Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176239Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186239Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196239Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206239Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216239Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226239Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236239Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246239Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256239Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266239Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276145Snate@binkert.org */ 286145Snate@binkert.org 297039Snate@binkert.org#ifndef __MEM_RUBY_COMMON_ADDRESS_HH__ 307039Snate@binkert.org#define __MEM_RUBY_COMMON_ADDRESS_HH__ 316145Snate@binkert.org 326145Snate@binkert.org#include <iomanip> 337002Snate@binkert.org 347002Snate@binkert.org#include "base/hashmap.hh" 356154Snate@binkert.org#include "mem/ruby/common/Global.hh" 367039Snate@binkert.org#include "mem/ruby/system/MachineID.hh" 377039Snate@binkert.org#include "mem/ruby/system/NodeID.hh" 386285Snate@binkert.org#include "mem/ruby/system/System.hh" 396145Snate@binkert.org 406145Snate@binkert.orgconst int ADDRESS_WIDTH = 64; // address width in bytes 416145Snate@binkert.org 426145Snate@binkert.orgclass Address; 436145Snate@binkert.orgtypedef Address PhysAddress; 446145Snate@binkert.orgtypedef Address VirtAddress; 456145Snate@binkert.org 467039Snate@binkert.orgclass Address 477039Snate@binkert.org{ 487039Snate@binkert.org public: 497039Snate@binkert.org Address() 507039Snate@binkert.org : m_address(0) 517039Snate@binkert.org { } 526145Snate@binkert.org 537039Snate@binkert.org explicit 547039Snate@binkert.org Address(physical_address_t address) 557039Snate@binkert.org : m_address(address) 567039Snate@binkert.org { } 576145Snate@binkert.org 587039Snate@binkert.org Address(const Address& obj); 597039Snate@binkert.org Address& operator=(const Address& obj); 606145Snate@binkert.org 617039Snate@binkert.org void setAddress(physical_address_t address) { m_address = address; } 627039Snate@binkert.org physical_address_t getAddress() const {return m_address;} 637039Snate@binkert.org // selects bits inclusive 647039Snate@binkert.org physical_address_t bitSelect(int small, int big) const; 657039Snate@binkert.org physical_address_t bitRemove(int small, int big) const; 667039Snate@binkert.org physical_address_t maskLowOrderBits(int number) const; 677039Snate@binkert.org physical_address_t maskHighOrderBits(int number) const; 687039Snate@binkert.org physical_address_t shiftLowOrderBits(int number) const; 696145Snate@binkert.org 707039Snate@binkert.org physical_address_t 717039Snate@binkert.org getLineAddress() const 727039Snate@binkert.org { 737039Snate@binkert.org return bitSelect(RubySystem::getBlockSizeBits(), ADDRESS_WIDTH); 747039Snate@binkert.org } 756145Snate@binkert.org 767039Snate@binkert.org physical_address_t 777039Snate@binkert.org getOffset() const 787039Snate@binkert.org { 797039Snate@binkert.org return bitSelect(0, RubySystem::getBlockSizeBits() - 1); 807039Snate@binkert.org } 816145Snate@binkert.org 827039Snate@binkert.org void 837039Snate@binkert.org makeLineAddress() 847039Snate@binkert.org { 857039Snate@binkert.org m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()); 867039Snate@binkert.org } 876145Snate@binkert.org 887039Snate@binkert.org // returns the next stride address based on line address 897039Snate@binkert.org void 907039Snate@binkert.org makeNextStrideAddress(int stride) 917039Snate@binkert.org { 927039Snate@binkert.org m_address = maskLowOrderBits(RubySystem::getBlockSizeBits()) 937039Snate@binkert.org + RubySystem::getBlockSizeBytes()*stride; 947039Snate@binkert.org } 956145Snate@binkert.org 967039Snate@binkert.org int getBankSetNum() const; 977039Snate@binkert.org int getBankSetDist() const; 986145Snate@binkert.org 997039Snate@binkert.org Index memoryModuleIndex() const; 1006145Snate@binkert.org 1017055Snate@binkert.org void print(std::ostream& out) const; 1027055Snate@binkert.org void output(std::ostream& out) const; 1037055Snate@binkert.org void input(std::istream& in); 1046145Snate@binkert.org 1057039Snate@binkert.org void 1067039Snate@binkert.org setOffset(int offset) 1077039Snate@binkert.org { 1087039Snate@binkert.org // first, zero out the offset bits 1097039Snate@binkert.org makeLineAddress(); 1107039Snate@binkert.org m_address |= (physical_address_t) offset; 1117039Snate@binkert.org } 1127039Snate@binkert.org 1137039Snate@binkert.org private: 1147039Snate@binkert.org physical_address_t m_address; 1156145Snate@binkert.org}; 1166145Snate@binkert.org 1177039Snate@binkert.orginline Address 1187039Snate@binkert.orgline_address(const Address& addr) 1196145Snate@binkert.org{ 1207039Snate@binkert.org Address temp(addr); 1217039Snate@binkert.org temp.makeLineAddress(); 1227039Snate@binkert.org return temp; 1236145Snate@binkert.org} 1246145Snate@binkert.org 1257039Snate@binkert.orginline bool 1267039Snate@binkert.orgoperator<(const Address& obj1, const Address& obj2) 1276145Snate@binkert.org{ 1287039Snate@binkert.org return obj1.getAddress() < obj2.getAddress(); 1296145Snate@binkert.org} 1306145Snate@binkert.org 1317055Snate@binkert.orginline std::ostream& 1327055Snate@binkert.orgoperator<<(std::ostream& out, const Address& obj) 1336145Snate@binkert.org{ 1347039Snate@binkert.org obj.print(out); 1357055Snate@binkert.org out << std::flush; 1367039Snate@binkert.org return out; 1376145Snate@binkert.org} 1386145Snate@binkert.org 1397039Snate@binkert.orginline bool 1407039Snate@binkert.orgoperator==(const Address& obj1, const Address& obj2) 1416145Snate@binkert.org{ 1427039Snate@binkert.org return (obj1.getAddress() == obj2.getAddress()); 1436145Snate@binkert.org} 1446145Snate@binkert.org 1457039Snate@binkert.orginline bool 1467039Snate@binkert.orgoperator!=(const Address& obj1, const Address& obj2) 1476145Snate@binkert.org{ 1487039Snate@binkert.org return (obj1.getAddress() != obj2.getAddress()); 1497039Snate@binkert.org} 1506145Snate@binkert.org 1517039Snate@binkert.org// rips bits inclusive 1527039Snate@binkert.orginline physical_address_t 1537039Snate@binkert.orgAddress::bitSelect(int small, int big) const 1547039Snate@binkert.org{ 1557039Snate@binkert.org physical_address_t mask; 1567039Snate@binkert.org assert((unsigned)big >= (unsigned)small); 1577039Snate@binkert.org 1587039Snate@binkert.org if (big >= ADDRESS_WIDTH - 1) { 1597039Snate@binkert.org return (m_address >> small); 1607039Snate@binkert.org } else { 1617039Snate@binkert.org mask = ~((physical_address_t)~0 << (big + 1)); 1627039Snate@binkert.org // FIXME - this is slow to manipulate a 64-bit number using 32-bits 1637039Snate@binkert.org physical_address_t partial = (m_address & mask); 1647039Snate@binkert.org return (partial >> small); 1657039Snate@binkert.org } 1666145Snate@binkert.org} 1676145Snate@binkert.org 1687027SBrad.Beckmann@amd.com// removes bits inclusive 1697039Snate@binkert.orginline physical_address_t 1707039Snate@binkert.orgAddress::bitRemove(int small, int big) const 1717027SBrad.Beckmann@amd.com{ 1727027SBrad.Beckmann@amd.com physical_address_t mask; 1737027SBrad.Beckmann@amd.com assert((unsigned)big >= (unsigned)small); 1747054Snate@binkert.org 1757027SBrad.Beckmann@amd.com if (small >= ADDRESS_WIDTH - 1) { 1767027SBrad.Beckmann@amd.com return m_address; 1777027SBrad.Beckmann@amd.com } else if (big >= ADDRESS_WIDTH - 1) { 1787027SBrad.Beckmann@amd.com mask = (physical_address_t)~0 >> small; 1797027SBrad.Beckmann@amd.com return (m_address & mask); 1807027SBrad.Beckmann@amd.com } else if (small == 0) { 1817027SBrad.Beckmann@amd.com mask = (physical_address_t)~0 << big; 1827027SBrad.Beckmann@amd.com return (m_address & mask); 1837027SBrad.Beckmann@amd.com } else { 1847027SBrad.Beckmann@amd.com mask = ~((physical_address_t)~0 << small); 1857027SBrad.Beckmann@amd.com physical_address_t lower_bits = m_address & mask; 1867027SBrad.Beckmann@amd.com mask = (physical_address_t)~0 << (big + 1); 1877027SBrad.Beckmann@amd.com physical_address_t higher_bits = m_address & mask; 1887027SBrad.Beckmann@amd.com 1897027SBrad.Beckmann@amd.com // Shift the valid high bits over the removed section 1907563SBrad.Beckmann@amd.com higher_bits = higher_bits >> (big - small + 1); 1917027SBrad.Beckmann@amd.com return (higher_bits | lower_bits); 1927027SBrad.Beckmann@amd.com } 1937027SBrad.Beckmann@amd.com} 1947027SBrad.Beckmann@amd.com 1957039Snate@binkert.orginline physical_address_t 1967039Snate@binkert.orgAddress::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) { 2017039Snate@binkert.org mask = ~0; 2026145Snate@binkert.org } else { 2037039Snate@binkert.org mask = (physical_address_t)~0 << number; 2046145Snate@binkert.org } 2056145Snate@binkert.org return (m_address & mask); 2066145Snate@binkert.org} 2076145Snate@binkert.org 2087039Snate@binkert.orginline physical_address_t 2097039Snate@binkert.orgAddress::maskHighOrderBits(int number) const 2106145Snate@binkert.org{ 2117039Snate@binkert.org physical_address_t mask; 2126145Snate@binkert.org 2137039Snate@binkert.org if (number >= ADDRESS_WIDTH - 1) { 2147039Snate@binkert.org mask = ~0; 2157039Snate@binkert.org } else { 2167039Snate@binkert.org mask = (physical_address_t)~0 >> number; 2177039Snate@binkert.org } 2187039Snate@binkert.org return (m_address & mask); 2196145Snate@binkert.org} 2206145Snate@binkert.org 2217039Snate@binkert.orginline physical_address_t 2227039Snate@binkert.orgAddress::shiftLowOrderBits(int number) const 2236145Snate@binkert.org{ 2247039Snate@binkert.org return (m_address >> number); 2256145Snate@binkert.org} 2266145Snate@binkert.org 2277039Snate@binkert.orginline integer_t 2287039Snate@binkert.orgAddress::memoryModuleIndex() const 2296145Snate@binkert.org{ 2307039Snate@binkert.org integer_t index = 2317054Snate@binkert.org bitSelect(RubySystem::getBlockSizeBits() + 2327039Snate@binkert.org RubySystem::getMemorySizeBits(), ADDRESS_WIDTH); 2337039Snate@binkert.org assert (index >= 0); 2347039Snate@binkert.org return index; 2356145Snate@binkert.org 2367039Snate@binkert.org // Index indexHighPortion = 2377039Snate@binkert.org // address.bitSelect(MEMORY_SIZE_BITS - 1, 2387039Snate@binkert.org // PAGE_SIZE_BITS + NUMBER_OF_MEMORY_MODULE_BITS); 2397039Snate@binkert.org // Index indexLowPortion = 2407039Snate@binkert.org // address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS - 1); 2417039Snate@binkert.org // 2427039Snate@binkert.org // Index index = indexLowPortion | 2437039Snate@binkert.org // (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); 2446145Snate@binkert.org 2457039Snate@binkert.org /* 2467039Snate@binkert.org Round-robin mapping of addresses, at page size granularity 2476145Snate@binkert.org 2486145Snate@binkert.orgADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS 2496145Snate@binkert.org | | | | 2506145Snate@binkert.org \ / \ / \ / \ / 0 2516145Snate@binkert.org ----------------------------------------------------------------------- 2526145Snate@binkert.org | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 2536145Snate@binkert.org | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 2546145Snate@binkert.org ----------------------------------------------------------------------- 2556145Snate@binkert.org indexHighPortion indexLowPortion 2566145Snate@binkert.org <-------> 2576145Snate@binkert.org NUMBER_OF_MEMORY_MODULE_BITS 2587039Snate@binkert.org */ 2596145Snate@binkert.org} 2606145Snate@binkert.org 2617039Snate@binkert.orginline void 2627055Snate@binkert.orgAddress::print(std::ostream& out) const 2636145Snate@binkert.org{ 2647002Snate@binkert.org using namespace std; 2657039Snate@binkert.org out << "[" << hex << "0x" << m_address << "," << " line 0x" 2667039Snate@binkert.org << maskLowOrderBits(RubySystem::getBlockSizeBits()) << dec << "]" 2677039Snate@binkert.org << flush; 2686145Snate@binkert.org} 2696145Snate@binkert.org 2706145Snate@binkert.orgclass Address; 2717002Snate@binkert.orgnamespace __hash_namespace { 2727039Snate@binkert.orgtemplate <> struct hash<Address> 2737039Snate@binkert.org{ 2747039Snate@binkert.org size_t 2757039Snate@binkert.org operator()(const Address &s) const 2767039Snate@binkert.org { 2777039Snate@binkert.org return (size_t)s.getAddress(); 2787039Snate@binkert.org } 2797039Snate@binkert.org}; 2807811Ssteve.reinhardt@amd.com} // namespace __hash_namespace 2817039Snate@binkert.org 2826145Snate@binkert.orgnamespace std { 2837039Snate@binkert.orgtemplate <> struct equal_to<Address> 2847039Snate@binkert.org{ 2857039Snate@binkert.org bool 2867039Snate@binkert.org operator()(const Address& s1, const Address& s2) const 2877039Snate@binkert.org { 2887039Snate@binkert.org return s1 == s2; 2897039Snate@binkert.org } 2907039Snate@binkert.org}; 2917811Ssteve.reinhardt@amd.com} // namespace std 2926145Snate@binkert.org 2937039Snate@binkert.org#endif // __MEM_RUBY_COMMON_ADDRESS_HH__ 294