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