RubySlicc_Util.hh revision 11307
12155SN/A/*
22155SN/A * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
32155SN/A * Copyright (c) 2013 Advanced Micro Devices, Inc.
42155SN/A * All rights reserved.
52155SN/A *
62155SN/A * Redistribution and use in source and binary forms, with or without
72155SN/A * modification, are permitted provided that the following conditions are
82155SN/A * met: redistributions of source code must retain the above copyright
92155SN/A * notice, this list of conditions and the following disclaimer;
102155SN/A * redistributions in binary form must reproduce the above copyright
112155SN/A * notice, this list of conditions and the following disclaimer in the
122155SN/A * documentation and/or other materials provided with the distribution;
132155SN/A * neither the name of the copyright holders nor the names of its
142155SN/A * contributors may be used to endorse or promote products derived from
152155SN/A * this software without specific prior written permission.
162155SN/A *
172155SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182155SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192155SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202155SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212155SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222155SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232155SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242155SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252155SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262155SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272155SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu */
292665Ssaidi@eecs.umich.edu
302155SN/A/*
314202Sbinkertn@umich.edu * These are the functions that exported to slicc from ruby.
322155SN/A */
337768SAli.Saidi@ARM.com
347768SAli.Saidi@ARM.com#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__
357768SAli.Saidi@ARM.com#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__
362178SN/A
372178SN/A#include <cassert>
382178SN/A
392178SN/A#include "debug/RubySlicc.hh"
402178SN/A#include "mem/packet.hh"
412178SN/A#include "mem/ruby/common/Address.hh"
422178SN/A#include "mem/ruby/common/BoolVec.hh"
432178SN/A#include "mem/ruby/common/DataBlock.hh"
442178SN/A#include "mem/ruby/common/TypeDefines.hh"
452178SN/A#include "mem/ruby/common/WriteMask.hh"
462178SN/A
472155SN/Ainline Cycles zero_time() { return Cycles(0); }
485865Sksewell@umich.edu
496181Sksewell@umich.eduinline NodeID
506181Sksewell@umich.eduintToID(int nodenum)
515865Sksewell@umich.edu{
523918Ssaidi@eecs.umich.edu    NodeID id = nodenum;
535865Sksewell@umich.edu    return id;
542623SN/A}
553918Ssaidi@eecs.umich.edu
562155SN/Ainline int
572155SN/AIDToInt(NodeID id)
582292SN/A{
596181Sksewell@umich.edu    int nodenum = id;
606181Sksewell@umich.edu    return nodenum;
613918Ssaidi@eecs.umich.edu}
622292SN/A
632292SN/Ainline int
642292SN/AaddressToInt(Addr addr)
653918Ssaidi@eecs.umich.edu{
662292SN/A    assert(!(addr & 0xffffffff00000000));
672292SN/A    return addr;
682766Sktlim@umich.edu}
692766Sktlim@umich.edu
702766Sktlim@umich.eduinline Addr
712921Sktlim@umich.eduintToAddress(int addr)
728887Sgeoffrey.blake@arm.com{
738887Sgeoffrey.blake@arm.com    assert(!(addr & 0xffffffff00000000));
742766Sktlim@umich.edu    return addr;
754762Snate@binkert.org}
762155SN/A
772155SN/Ainline int
782155SN/Amod(int val, int mod)
792155SN/A{
802155SN/A    return val % mod;
812155SN/A}
822766Sktlim@umich.edu
832155SN/Ainline int max_tokens()
845865Sksewell@umich.edu{
852155SN/A  return 1024;
862155SN/A}
872155SN/A
882155SN/A/**
892178SN/A * This function accepts an address, a data block and a packet. If the address
902178SN/A * range for the data block contains the address which the packet needs to
917756SAli.Saidi@ARM.com * read, then the data from the data block is written to the packet. True is
922766Sktlim@umich.edu * returned if the data block was read, otherwise false is returned.
932178SN/A *
942178SN/A * This is used during a functional access "search the world" operation. The
956994Snate@binkert.org * functional access looks in every place that might hold a valid data block
962178SN/A * and, if it finds one, checks to see if it is holding the address the access
972766Sktlim@umich.edu * is searching for. During the access check, the WriteMask could be in any
982766Sktlim@umich.edu * state, including empty.
992788Sktlim@umich.edu */
1002178SN/Ainline bool
1014486Sbinkertn@umich.edutestAndRead(Addr addr, DataBlock& blk, Packet *pkt)
1024486Sbinkertn@umich.edu{
1034776Sgblack@eecs.umich.edu    Addr pktLineAddr = makeLineAddress(pkt->getAddr());
1044776Sgblack@eecs.umich.edu    Addr lineAddr = makeLineAddress(addr);
1058739Sgblack@eecs.umich.edu
1066365Sgblack@eecs.umich.edu    if (pktLineAddr == lineAddr) {
1074486Sbinkertn@umich.edu        uint8_t *data = pkt->getPtr<uint8_t>();
1084202Sbinkertn@umich.edu        unsigned int size_in_bytes = pkt->getSize();
1094202Sbinkertn@umich.edu        unsigned startByte = pkt->getAddr() - lineAddr;
1104202Sbinkertn@umich.edu
1118541Sgblack@eecs.umich.edu        for (unsigned i = 0; i < size_in_bytes; ++i) {
1124202Sbinkertn@umich.edu            data[i] = blk.getByte(i + startByte);
1134202Sbinkertn@umich.edu        }
1144776Sgblack@eecs.umich.edu        return true;
1158739Sgblack@eecs.umich.edu    }
1166365Sgblack@eecs.umich.edu    return false;
1174202Sbinkertn@umich.edu}
1188777Sgblack@eecs.umich.edu
1194202Sbinkertn@umich.edu/**
1204202Sbinkertn@umich.edu * This function accepts an address, a data block, a write mask and a packet.
1214202Sbinkertn@umich.edu * If the valid address range for the data block contains the address which
1225217Ssaidi@eecs.umich.edu * the packet needs to read, then the data from the data block is written to
1234202Sbinkertn@umich.edu * the packet. True is returned if any part of the data block was read,
1242155SN/A * otherwise false is returned.
1258793Sgblack@eecs.umich.edu */
1268793Sgblack@eecs.umich.eduinline bool
1278793Sgblack@eecs.umich.edutestAndReadMask(Addr addr, DataBlock& blk, WriteMask& mask, Packet *pkt)
1284776Sgblack@eecs.umich.edu{
1298887Sgeoffrey.blake@arm.com    Addr pktLineAddr = makeLineAddress(pkt->getAddr());
1308887Sgeoffrey.blake@arm.com    Addr lineAddr = makeLineAddress(addr);
1318887Sgeoffrey.blake@arm.com
1328887Sgeoffrey.blake@arm.com    if (pktLineAddr == lineAddr) {
1335192Ssaidi@eecs.umich.edu        uint8_t *data = pkt->getPtr<uint8_t>();
1348335Snate@binkert.org        unsigned int size_in_bytes = pkt->getSize();
1358335Snate@binkert.org        unsigned startByte = pkt->getAddr() - lineAddr;
1368335Snate@binkert.org        bool was_read = false;
1378335Snate@binkert.org
1388335Snate@binkert.org        for (unsigned i = 0; i < size_in_bytes; ++i) {
1398335Snate@binkert.org            if (mask.test(i + startByte)) {
1408335Snate@binkert.org                was_read = true;
1418335Snate@binkert.org                data[i] = blk.getByte(i + startByte);
1428335Snate@binkert.org            }
1438335Snate@binkert.org        }
1448335Snate@binkert.org        return was_read;
1458335Snate@binkert.org    }
1468335Snate@binkert.org    return false;
1478335Snate@binkert.org}
1488335Snate@binkert.org
1498335Snate@binkert.org/**
1508335Snate@binkert.org * This function accepts an address, a data block and a packet. If the address
1518335Snate@binkert.org * range for the data block contains the address which the packet needs to
1528335Snate@binkert.org * write, then the data from the packet is written to the data block. True is
1538335Snate@binkert.org * returned if the data block was written, otherwise false is returned.
1548335Snate@binkert.org */
1558335Snate@binkert.orginline bool
1568335Snate@binkert.orgtestAndWrite(Addr addr, DataBlock& blk, Packet *pkt)
1578335Snate@binkert.org{
1588471SGiacomo.Gabrielli@arm.com    Addr pktLineAddr = makeLineAddress(pkt->getAddr());
1598335Snate@binkert.org    Addr lineAddr = makeLineAddress(addr);
1608335Snate@binkert.org
1615192Ssaidi@eecs.umich.edu    if (pktLineAddr == lineAddr) {
1628232Snate@binkert.org        const uint8_t *data = pkt->getConstPtr<uint8_t>();
1638232Snate@binkert.org        unsigned int size_in_bytes = pkt->getSize();
1648232Snate@binkert.org        unsigned startByte = pkt->getAddr() - lineAddr;
1658300Schander.sudanthi@arm.com
1668300Schander.sudanthi@arm.com        for (unsigned i = 0; i < size_in_bytes; ++i) {
1675192Ssaidi@eecs.umich.edu            blk.setByte(i + startByte, data[i]);
1688300Schander.sudanthi@arm.com        }
1698300Schander.sudanthi@arm.com        return true;
1706036Sksewell@umich.edu    }
1718300Schander.sudanthi@arm.com    return false;
1728300Schander.sudanthi@arm.com}
173
174inline int
175countBoolVec(BoolVec bVec)
176{
177    int count = 0;
178    for (const auto &it: bVec) {
179        if (it) {
180            count++;
181        }
182    }
183    return count;
184}
185
186#endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__
187