PerfectCacheMemory.hh revision 7055
114209Sandreas.sandberg@arm.com/*
211878Sandreas.sandberg@arm.com * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
311878Sandreas.sandberg@arm.com * All rights reserved.
411878Sandreas.sandberg@arm.com *
511878Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
611878Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
711878Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
811878Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
911878Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1011878Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
1111878Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
1211878Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
134126SN/A * contributors may be used to endorse or promote products derived from
148295Snate@binkert.org * this software without specific prior written permission.
154126SN/A *
164126SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
174126SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
184126SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
194126SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
204126SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
214126SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
224126SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234126SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244126SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254126SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
264126SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274126SN/A */
284126SN/A
294126SN/A#ifndef __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
304126SN/A#define __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
314126SN/A
324126SN/A#include "mem/gems_common/Map.hh"
334126SN/A#include "mem/protocol/AccessPermission.hh"
344126SN/A#include "mem/ruby/common/Address.hh"
354126SN/A#include "mem/ruby/common/Global.hh"
364126SN/A
374126SN/Atemplate<class ENTRY>
384126SN/Astruct PerfectCacheLineState
394126SN/A{
404126SN/A    PerfectCacheLineState() { m_permission = AccessPermission_NUM; }
4111878Sandreas.sandberg@arm.com    AccessPermission m_permission;
424126SN/A    ENTRY m_entry;
4314213Sandreas.sandberg@arm.com};
4414213Sandreas.sandberg@arm.com
4514213Sandreas.sandberg@arm.comtemplate<class ENTRY>
468296Snate@binkert.orginline std::ostream&
478296Snate@binkert.orgoperator<<(std::ostream& out, const PerfectCacheLineState<ENTRY>& obj)
4811802Sandreas.sandberg@arm.com{
498295Snate@binkert.org    return out;
5014286Sgabeblack@google.com}
518296Snate@binkert.org
524126SN/Atemplate<class ENTRY>
5311766Sandreas.sandberg@arm.comclass PerfectCacheMemory
5411802Sandreas.sandberg@arm.com{
5511802Sandreas.sandberg@arm.com  public:
5611766Sandreas.sandberg@arm.com    PerfectCacheMemory();
578296Snate@binkert.org
5811878Sandreas.sandberg@arm.com    static void printConfig(std::ostream& out);
5914213Sandreas.sandberg@arm.com
6014213Sandreas.sandberg@arm.com    // perform a cache access and see if we hit or not.  Return true
6114213Sandreas.sandberg@arm.com    // on a hit.
6214213Sandreas.sandberg@arm.com    bool tryCacheAccess(const CacheMsg& msg, bool& block_stc, ENTRY*& entry);
6314213Sandreas.sandberg@arm.com
6414213Sandreas.sandberg@arm.com    // tests to see if an address is present in the cache
6514213Sandreas.sandberg@arm.com    bool isTagPresent(const Address& address) const;
6614213Sandreas.sandberg@arm.com
6714213Sandreas.sandberg@arm.com    // Returns true if there is:
6811878Sandreas.sandberg@arm.com    //   a) a tag match on this address or there is
6911878Sandreas.sandberg@arm.com    //   b) an Invalid line in the same cache "way"
7011878Sandreas.sandberg@arm.com    bool cacheAvail(const Address& address) const;
7111878Sandreas.sandberg@arm.com
7211878Sandreas.sandberg@arm.com    // find an Invalid entry and sets the tag appropriate for the address
7311878Sandreas.sandberg@arm.com    void allocate(const Address& address);
7411878Sandreas.sandberg@arm.com
7511878Sandreas.sandberg@arm.com    void deallocate(const Address& address);
7614213Sandreas.sandberg@arm.com
7714213Sandreas.sandberg@arm.com    // Returns with the physical address of the conflicting cache line
7814213Sandreas.sandberg@arm.com    Address cacheProbe(const Address& newAddress) const;
7914213Sandreas.sandberg@arm.com
8014213Sandreas.sandberg@arm.com    // looks an address up in the cache
8114213Sandreas.sandberg@arm.com    ENTRY& lookup(const Address& address);
8214213Sandreas.sandberg@arm.com    const ENTRY& lookup(const Address& address) const;
8311878Sandreas.sandberg@arm.com
8411878Sandreas.sandberg@arm.com    // Get/Set permission of cache block
8511878Sandreas.sandberg@arm.com    AccessPermission getPermission(const Address& address) const;
8611878Sandreas.sandberg@arm.com    void changePermission(const Address& address, AccessPermission new_perm);
8711878Sandreas.sandberg@arm.com
8811878Sandreas.sandberg@arm.com    // Print cache contents
8911878Sandreas.sandberg@arm.com    void print(std::ostream& out) const;
9011878Sandreas.sandberg@arm.com
9114213Sandreas.sandberg@arm.com  private:
9214213Sandreas.sandberg@arm.com    // Private copy constructor and assignment operator
9314213Sandreas.sandberg@arm.com    PerfectCacheMemory(const PerfectCacheMemory& obj);
9414213Sandreas.sandberg@arm.com    PerfectCacheMemory& operator=(const PerfectCacheMemory& obj);
9514213Sandreas.sandberg@arm.com
9614213Sandreas.sandberg@arm.com    // Data Members (m_prefix)
9714213Sandreas.sandberg@arm.com    Map<Address, PerfectCacheLineState<ENTRY> > m_map;
9814213Sandreas.sandberg@arm.com};
9914213Sandreas.sandberg@arm.com
10011878Sandreas.sandberg@arm.comtemplate<class ENTRY>
10114213Sandreas.sandberg@arm.cominline std::ostream&
10211878Sandreas.sandberg@arm.comoperator<<(std::ostream& out, const PerfectCacheMemory<ENTRY>& obj)
10314213Sandreas.sandberg@arm.com{
10414213Sandreas.sandberg@arm.com    obj.print(out);
10514213Sandreas.sandberg@arm.com    out << std::flush;
10614213Sandreas.sandberg@arm.com    return out;
10714213Sandreas.sandberg@arm.com}
10814213Sandreas.sandberg@arm.com
10914213Sandreas.sandberg@arm.comtemplate<class ENTRY>
11014213Sandreas.sandberg@arm.cominline
11114213Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::PerfectCacheMemory()
11214213Sandreas.sandberg@arm.com{
11314213Sandreas.sandberg@arm.com}
11414213Sandreas.sandberg@arm.com
11514213Sandreas.sandberg@arm.comtemplate<class ENTRY>
11614213Sandreas.sandberg@arm.cominline void
11714213Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::printConfig(std::ostream& out)
11814213Sandreas.sandberg@arm.com{
11914213Sandreas.sandberg@arm.com}
12011878Sandreas.sandberg@arm.com
12114213Sandreas.sandberg@arm.comtemplate<class ENTRY>
12211878Sandreas.sandberg@arm.cominline bool
12314213Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::tryCacheAccess(const CacheMsg& msg,
12414213Sandreas.sandberg@arm.com                                          bool& block_stc, ENTRY*& entry)
12514213Sandreas.sandberg@arm.com{
12614213Sandreas.sandberg@arm.com    ERROR_MSG("not implemented");
12711878Sandreas.sandberg@arm.com}
12814213Sandreas.sandberg@arm.com
12914213Sandreas.sandberg@arm.com// tests to see if an address is present in the cache
13014213Sandreas.sandberg@arm.comtemplate<class ENTRY>
13114213Sandreas.sandberg@arm.cominline bool
13214213Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::isTagPresent(const Address& address) const
13311878Sandreas.sandberg@arm.com{
13414213Sandreas.sandberg@arm.com    return m_map.exist(line_address(address));
13514213Sandreas.sandberg@arm.com}
13614213Sandreas.sandberg@arm.com
13711878Sandreas.sandberg@arm.comtemplate<class ENTRY>
13811878Sandreas.sandberg@arm.cominline bool
13911878Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::cacheAvail(const Address& address) const
14011878Sandreas.sandberg@arm.com{
14111878Sandreas.sandberg@arm.com    return true;
14211878Sandreas.sandberg@arm.com}
14311878Sandreas.sandberg@arm.com
14414213Sandreas.sandberg@arm.com// find an Invalid or already allocated entry and sets the tag
14514213Sandreas.sandberg@arm.com// appropriate for the address
14614213Sandreas.sandberg@arm.comtemplate<class ENTRY>
14714213Sandreas.sandberg@arm.cominline void
14814213Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::allocate(const Address& address)
14911878Sandreas.sandberg@arm.com{
15011878Sandreas.sandberg@arm.com    PerfectCacheLineState<ENTRY> line_state;
15111878Sandreas.sandberg@arm.com    line_state.m_permission = AccessPermission_Busy;
15211878Sandreas.sandberg@arm.com    line_state.m_entry = ENTRY();
15311878Sandreas.sandberg@arm.com    m_map.add(line_address(address), line_state);
15414213Sandreas.sandberg@arm.com}
15514209Sandreas.sandberg@arm.com
15614209Sandreas.sandberg@arm.com// deallocate entry
15714209Sandreas.sandberg@arm.comtemplate<class ENTRY>
15814209Sandreas.sandberg@arm.cominline void
15914209Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::deallocate(const Address& address)
16014209Sandreas.sandberg@arm.com{
16114209Sandreas.sandberg@arm.com    m_map.erase(line_address(address));
16214209Sandreas.sandberg@arm.com}
16314209Sandreas.sandberg@arm.com
16414209Sandreas.sandberg@arm.com// Returns with the physical address of the conflicting cache line
16514209Sandreas.sandberg@arm.comtemplate<class ENTRY>
16614209Sandreas.sandberg@arm.cominline Address
16714209Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::cacheProbe(const Address& newAddress) const
16814209Sandreas.sandberg@arm.com{
16914209Sandreas.sandberg@arm.com    ERROR_MSG("cacheProbe called in perfect cache");
17014209Sandreas.sandberg@arm.com}
17114209Sandreas.sandberg@arm.com
17214209Sandreas.sandberg@arm.com// looks an address up in the cache
17314209Sandreas.sandberg@arm.comtemplate<class ENTRY>
17414209Sandreas.sandberg@arm.cominline ENTRY&
17514209Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::lookup(const Address& address)
17614209Sandreas.sandberg@arm.com{
17714209Sandreas.sandberg@arm.com    return m_map.lookup(line_address(address)).m_entry;
17814209Sandreas.sandberg@arm.com}
17914209Sandreas.sandberg@arm.com
18014209Sandreas.sandberg@arm.com// looks an address up in the cache
18114209Sandreas.sandberg@arm.comtemplate<class ENTRY>
18214209Sandreas.sandberg@arm.cominline const ENTRY&
18314209Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::lookup(const Address& address) const
18414209Sandreas.sandberg@arm.com{
18514209Sandreas.sandberg@arm.com    return m_map.lookup(line_address(address)).m_entry;
18614209Sandreas.sandberg@arm.com}
18714209Sandreas.sandberg@arm.com
18814213Sandreas.sandberg@arm.comtemplate<class ENTRY>
18914209Sandreas.sandberg@arm.cominline AccessPermission
19011878Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::getPermission(const Address& address) const
19111878Sandreas.sandberg@arm.com{
19211878Sandreas.sandberg@arm.com    return m_map.lookup(line_address(address)).m_permission;
19311878Sandreas.sandberg@arm.com}
19411878Sandreas.sandberg@arm.com
19511878Sandreas.sandberg@arm.comtemplate<class ENTRY>
19611878Sandreas.sandberg@arm.cominline void
19711878Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::changePermission(const Address& address,
19811878Sandreas.sandberg@arm.com                                            AccessPermission new_perm)
19911878Sandreas.sandberg@arm.com{
20011878Sandreas.sandberg@arm.com    Address line_address = address;
20111878Sandreas.sandberg@arm.com    line_address.makeLineAddress();
20211878Sandreas.sandberg@arm.com    PerfectCacheLineState<ENTRY>& line_state = m_map.lookup(line_address);
20313712Sandreas.sandberg@arm.com    AccessPermission old_perm = line_state.m_permission;
20413712Sandreas.sandberg@arm.com    line_state.m_permission = new_perm;
20513712Sandreas.sandberg@arm.com}
20613712Sandreas.sandberg@arm.com
20713712Sandreas.sandberg@arm.comtemplate<class ENTRY>
20811878Sandreas.sandberg@arm.cominline void
20911878Sandreas.sandberg@arm.comPerfectCacheMemory<ENTRY>::print(std::ostream& out) const
21011878Sandreas.sandberg@arm.com{
21111878Sandreas.sandberg@arm.com}
21211878Sandreas.sandberg@arm.com
21311878Sandreas.sandberg@arm.com#endif // __MEM_RUBY_SYSTEM_PERFECTCACHEMEMORY_HH__
21414213Sandreas.sandberg@arm.com