Address.hh revision 6145
16145Snate@binkert.org 26145Snate@binkert.org/* 36145Snate@binkert.org * Copyright (c) 1999 by Mark Hill and David Wood for the Wisconsin 46145Snate@binkert.org * Multifacet Project. ALL RIGHTS RESERVED. 56145Snate@binkert.org * 66145Snate@binkert.org * ##HEADER## 76145Snate@binkert.org * 86145Snate@binkert.org * This software is furnished under a license and may be used and 96145Snate@binkert.org * copied only in accordance with the terms of such license and the 106145Snate@binkert.org * inclusion of the above copyright notice. This software or any 116145Snate@binkert.org * other copies thereof or any derivative works may not be provided or 126145Snate@binkert.org * otherwise made available to any other persons. Title to and 136145Snate@binkert.org * ownership of the software is retained by Mark Hill and David Wood. 146145Snate@binkert.org * Any use of this software must include the above copyright notice. 156145Snate@binkert.org * 166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED "AS IS". THE LICENSOR MAKES NO 176145Snate@binkert.org * WARRANTIES ABOUT ITS CORRECTNESS OR PERFORMANCE. 186145Snate@binkert.org * */ 196145Snate@binkert.org 206145Snate@binkert.org/* 216145Snate@binkert.org * $Id$ 226145Snate@binkert.org */ 236145Snate@binkert.org 246145Snate@binkert.org#ifndef ADDRESS_H 256145Snate@binkert.org#define ADDRESS_H 266145Snate@binkert.org 276145Snate@binkert.org#include <iomanip> 286145Snate@binkert.org#include "Global.hh" 296145Snate@binkert.org#include "RubyConfig.hh" 306145Snate@binkert.org#include "NodeID.hh" 316145Snate@binkert.org#include "MachineID.hh" 326145Snate@binkert.org 336145Snate@binkert.orgconst int ADDRESS_WIDTH = 64; // address width in bytes 346145Snate@binkert.org 356145Snate@binkert.orgclass Address; 366145Snate@binkert.orgtypedef Address PhysAddress; 376145Snate@binkert.orgtypedef Address VirtAddress; 386145Snate@binkert.org 396145Snate@binkert.orgclass Address { 406145Snate@binkert.orgpublic: 416145Snate@binkert.org // Constructors 426145Snate@binkert.org Address() { m_address = 0; } 436145Snate@binkert.org explicit Address(physical_address_t address) { m_address = address; } 446145Snate@binkert.org 456145Snate@binkert.org Address(const Address& obj); 466145Snate@binkert.org Address& operator=(const Address& obj); 476145Snate@binkert.org 486145Snate@binkert.org // Destructor 496145Snate@binkert.org // ~Address(); 506145Snate@binkert.org 516145Snate@binkert.org // Public Methods 526145Snate@binkert.org 536145Snate@binkert.org void setAddress(physical_address_t address) { m_address = address; } 546145Snate@binkert.org physical_address_t getAddress() const {return m_address;} 556145Snate@binkert.org // selects bits inclusive 566145Snate@binkert.org physical_address_t bitSelect(int small, int big) const; 576145Snate@binkert.org physical_address_t maskLowOrderBits(int number) const; 586145Snate@binkert.org physical_address_t maskHighOrderBits(int number) const; 596145Snate@binkert.org physical_address_t shiftLowOrderBits(int number) const; 606145Snate@binkert.org physical_address_t getLineAddress() const 616145Snate@binkert.org { return bitSelect(RubyConfig::dataBlockBits(), ADDRESS_WIDTH); } 626145Snate@binkert.org physical_address_t getOffset() const 636145Snate@binkert.org { return bitSelect(0, RubyConfig::dataBlockBits()-1); } 646145Snate@binkert.org 656145Snate@binkert.org void makeLineAddress() { m_address = maskLowOrderBits(RubyConfig::dataBlockBits()); } 666145Snate@binkert.org // returns the next stride address based on line address 676145Snate@binkert.org void makeNextStrideAddress( int stride) { 686145Snate@binkert.org m_address = maskLowOrderBits(RubyConfig::dataBlockBits()) 696145Snate@binkert.org + RubyConfig::dataBlockBytes()*stride; 706145Snate@binkert.org } 716145Snate@binkert.org void makePageAddress() { m_address = maskLowOrderBits(RubyConfig::pageSizeBits()); } 726145Snate@binkert.org int getBankSetNum() const; 736145Snate@binkert.org int getBankSetDist() const; 746145Snate@binkert.org 756145Snate@binkert.org Index memoryModuleIndex() const; 766145Snate@binkert.org 776145Snate@binkert.org void print(ostream& out) const; 786145Snate@binkert.org void output(ostream& out) const; 796145Snate@binkert.org void input(istream& in); 806145Snate@binkert.org 816145Snate@binkert.org void setOffset( int offset ){ 826145Snate@binkert.org // first, zero out the offset bits 836145Snate@binkert.org makeLineAddress(); 846145Snate@binkert.org m_address |= (physical_address_t) offset; 856145Snate@binkert.org } 866145Snate@binkert.org 876145Snate@binkert.orgprivate: 886145Snate@binkert.org // Private Methods 896145Snate@binkert.org 906145Snate@binkert.org // Private copy constructor and assignment operator 916145Snate@binkert.org // Address(const Address& obj); 926145Snate@binkert.org // Address& operator=(const Address& obj); 936145Snate@binkert.org 946145Snate@binkert.org // Data Members (m_ prefix) 956145Snate@binkert.org physical_address_t m_address; 966145Snate@binkert.org}; 976145Snate@binkert.org 986145Snate@binkert.orginline 996145Snate@binkert.orgAddress line_address(const Address& addr) { Address temp(addr); temp.makeLineAddress(); return temp; } 1006145Snate@binkert.org 1016145Snate@binkert.orginline 1026145Snate@binkert.orgAddress next_stride_address(const Address& addr, int stride) { 1036145Snate@binkert.org Address temp = addr; 1046145Snate@binkert.org temp.makeNextStrideAddress(stride); 1056145Snate@binkert.org temp.setAddress(temp.maskHighOrderBits(ADDRESS_WIDTH-RubyConfig::memorySizeBits())); // surpress wrap-around problem 1066145Snate@binkert.org return temp; 1076145Snate@binkert.org} 1086145Snate@binkert.org 1096145Snate@binkert.orginline 1106145Snate@binkert.orgAddress page_address(const Address& addr) { Address temp(addr); temp.makePageAddress(); return temp; } 1116145Snate@binkert.org 1126145Snate@binkert.org// Output operator declaration 1136145Snate@binkert.orgostream& operator<<(ostream& out, const Address& obj); 1146145Snate@binkert.org// comparison operator declaration 1156145Snate@binkert.orgbool operator==(const Address& obj1, const Address& obj2); 1166145Snate@binkert.orgbool operator!=(const Address& obj1, const Address& obj2); 1176145Snate@binkert.orgbool operator<(const Address& obj1, const Address& obj2); 1186145Snate@binkert.org/* Address& operator=(const physical_address_t address); */ 1196145Snate@binkert.org 1206145Snate@binkert.orginline 1216145Snate@binkert.orgbool operator<(const Address& obj1, const Address& obj2) 1226145Snate@binkert.org{ 1236145Snate@binkert.org return obj1.getAddress() < obj2.getAddress(); 1246145Snate@binkert.org} 1256145Snate@binkert.org 1266145Snate@binkert.org// ******************* Definitions ******************* 1276145Snate@binkert.org 1286145Snate@binkert.org// Output operator definition 1296145Snate@binkert.orginline 1306145Snate@binkert.orgostream& operator<<(ostream& out, const Address& obj) 1316145Snate@binkert.org{ 1326145Snate@binkert.org obj.print(out); 1336145Snate@binkert.org out << flush; 1346145Snate@binkert.org return out; 1356145Snate@binkert.org} 1366145Snate@binkert.org 1376145Snate@binkert.orginline 1386145Snate@binkert.orgbool operator==(const Address& obj1, const Address& obj2) 1396145Snate@binkert.org{ 1406145Snate@binkert.org return (obj1.getAddress() == obj2.getAddress()); 1416145Snate@binkert.org} 1426145Snate@binkert.org 1436145Snate@binkert.orginline 1446145Snate@binkert.orgbool operator!=(const Address& obj1, const Address& obj2) 1456145Snate@binkert.org{ 1466145Snate@binkert.org return (obj1.getAddress() != obj2.getAddress()); 1476145Snate@binkert.org} 1486145Snate@binkert.org 1496145Snate@binkert.orginline 1506145Snate@binkert.orgphysical_address_t Address::bitSelect(int small, int big) const // rips bits inclusive 1516145Snate@binkert.org{ 1526145Snate@binkert.org physical_address_t mask; 1536145Snate@binkert.org assert(big >= small); 1546145Snate@binkert.org 1556145Snate@binkert.org if (big >= ADDRESS_WIDTH - 1) { 1566145Snate@binkert.org return (m_address >> small); 1576145Snate@binkert.org } else { 1586145Snate@binkert.org mask = ~((physical_address_t)~0 << (big + 1)); 1596145Snate@binkert.org // FIXME - this is slow to manipulate a 64-bit number using 32-bits 1606145Snate@binkert.org physical_address_t partial = (m_address & mask); 1616145Snate@binkert.org return (partial >> small); 1626145Snate@binkert.org } 1636145Snate@binkert.org} 1646145Snate@binkert.org 1656145Snate@binkert.orginline 1666145Snate@binkert.orgphysical_address_t Address::maskLowOrderBits(int number) const 1676145Snate@binkert.org{ 1686145Snate@binkert.org physical_address_t mask; 1696145Snate@binkert.org 1706145Snate@binkert.org if (number >= ADDRESS_WIDTH - 1) { 1716145Snate@binkert.org mask = ~0; 1726145Snate@binkert.org } else { 1736145Snate@binkert.org mask = (physical_address_t)~0 << number; 1746145Snate@binkert.org } 1756145Snate@binkert.org return (m_address & mask); 1766145Snate@binkert.org} 1776145Snate@binkert.org 1786145Snate@binkert.orginline 1796145Snate@binkert.orgphysical_address_t Address::maskHighOrderBits(int number) const 1806145Snate@binkert.org{ 1816145Snate@binkert.org physical_address_t mask; 1826145Snate@binkert.org 1836145Snate@binkert.org if (number >= ADDRESS_WIDTH - 1) { 1846145Snate@binkert.org mask = ~0; 1856145Snate@binkert.org } else { 1866145Snate@binkert.org mask = (physical_address_t)~0 >> number; 1876145Snate@binkert.org } 1886145Snate@binkert.org return (m_address & mask); 1896145Snate@binkert.org} 1906145Snate@binkert.org 1916145Snate@binkert.orginline 1926145Snate@binkert.orgphysical_address_t Address::shiftLowOrderBits(int number) const 1936145Snate@binkert.org{ 1946145Snate@binkert.org return (m_address >> number); 1956145Snate@binkert.org} 1966145Snate@binkert.org 1976145Snate@binkert.orginline 1986145Snate@binkert.orginteger_t Address::memoryModuleIndex() const 1996145Snate@binkert.org{ 2006145Snate@binkert.org integer_t index = bitSelect(RubyConfig::dataBlockBits()+RubyConfig::memoryBits(), ADDRESS_WIDTH); 2016145Snate@binkert.org assert (index >= 0); 2026145Snate@binkert.org if (index >= RubyConfig::memoryModuleBlocks()) { 2036145Snate@binkert.org cerr << " memoryBits: " << RubyConfig::memoryBits() << " memorySizeBits: " << RubyConfig::memorySizeBits() 2046145Snate@binkert.org << " Address: " << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush 2056145Snate@binkert.org << "error: limit exceeded. " << 2066145Snate@binkert.org " dataBlockBits: " << RubyConfig::dataBlockBits() << 2076145Snate@binkert.org " memoryModuleBlocks: " << RubyConfig::memoryModuleBlocks() << 2086145Snate@binkert.org " index: " << index << endl; 2096145Snate@binkert.org } 2106145Snate@binkert.org assert (index < RubyConfig::memoryModuleBlocks()); 2116145Snate@binkert.org return index; 2126145Snate@binkert.org 2136145Snate@binkert.org // Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS); 2146145Snate@binkert.org // Index indexLowPortion = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1); 2156145Snate@binkert.org 2166145Snate@binkert.org //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS)); 2176145Snate@binkert.org 2186145Snate@binkert.org /* 2196145Snate@binkert.org Round-robin mapping of addresses, at page size granularity 2206145Snate@binkert.org 2216145Snate@binkert.orgADDRESS_WIDTH MEMORY_SIZE_BITS PAGE_SIZE_BITS DATA_BLOCK_BITS 2226145Snate@binkert.org | | | | 2236145Snate@binkert.org \ / \ / \ / \ / 0 2246145Snate@binkert.org ----------------------------------------------------------------------- 2256145Snate@binkert.org | unused |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 2266145Snate@binkert.org | |xxxxxxxxxxxxxxx| |xxxxxxxxxxxxxxx| | 2276145Snate@binkert.org ----------------------------------------------------------------------- 2286145Snate@binkert.org indexHighPortion indexLowPortion 2296145Snate@binkert.org <-------> 2306145Snate@binkert.org NUMBER_OF_MEMORY_MODULE_BITS 2316145Snate@binkert.org */ 2326145Snate@binkert.org} 2336145Snate@binkert.org 2346145Snate@binkert.orginline 2356145Snate@binkert.orgvoid Address::print(ostream& out) const 2366145Snate@binkert.org{ 2376145Snate@binkert.org out << "[" << hex << "0x" << m_address << "," << " line 0x" << maskLowOrderBits(RubyConfig::dataBlockBits()) << dec << "]" << flush; 2386145Snate@binkert.org} 2396145Snate@binkert.org 2406145Snate@binkert.orgclass Address; 2416145Snate@binkert.orgnamespace __gnu_cxx { 2426145Snate@binkert.org template <> struct hash<Address> 2436145Snate@binkert.org { 2446145Snate@binkert.org size_t operator()(const Address &s) const { return (size_t) s.getAddress(); } 2456145Snate@binkert.org }; 2466145Snate@binkert.org} 2476145Snate@binkert.orgnamespace std { 2486145Snate@binkert.org template <> struct equal_to<Address> 2496145Snate@binkert.org { 2506145Snate@binkert.org bool operator()(const Address& s1, const Address& s2) const { return s1 == s2; } 2516145Snate@binkert.org }; 2526145Snate@binkert.org} 2536145Snate@binkert.org 2546145Snate@binkert.org#endif //ADDRESS_H 2556145Snate@binkert.org 256