16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
311307Santhony.gutierrez@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
46145Snate@binkert.org * All rights reserved.
56145Snate@binkert.org *
66145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
76145Snate@binkert.org * modification, are permitted provided that the following conditions are
86145Snate@binkert.org * met: redistributions of source code must retain the above copyright
96145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
106145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
116145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
126145Snate@binkert.org * documentation and/or other materials provided with the distribution;
136145Snate@binkert.org * neither the name of the copyright holders nor the names of its
146145Snate@binkert.org * contributors may be used to endorse or promote products derived from
156145Snate@binkert.org * this software without specific prior written permission.
166145Snate@binkert.org *
176145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286145Snate@binkert.org */
296145Snate@binkert.org
306145Snate@binkert.org/*
317039Snate@binkert.org * These are the functions that exported to slicc from ruby.
326145Snate@binkert.org */
336145Snate@binkert.org
3412492Sodanrc@yahoo.com.br#ifndef __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_UTIL_HH__
3512492Sodanrc@yahoo.com.br#define __MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_UTIL_HH__
366145Snate@binkert.org
377832Snate@binkert.org#include <cassert>
387832Snate@binkert.org
399302Snilay@cs.wisc.edu#include "debug/RubySlicc.hh"
4011025Snilay@cs.wisc.edu#include "mem/packet.hh"
417039Snate@binkert.org#include "mem/ruby/common/Address.hh"
4211208Sjoseph.gross@amd.com#include "mem/ruby/common/BoolVec.hh"
4310086Snilay@cs.wisc.edu#include "mem/ruby/common/DataBlock.hh"
4411025Snilay@cs.wisc.edu#include "mem/ruby/common/TypeDefines.hh"
4511307Santhony.gutierrez@amd.com#include "mem/ruby/common/WriteMask.hh"
466145Snate@binkert.org
479507Snilay@cs.wisc.eduinline Cycles zero_time() { return Cycles(0); }
489499Snilay@cs.wisc.edu
497039Snate@binkert.orginline NodeID
507039Snate@binkert.orgintToID(int nodenum)
516145Snate@binkert.org{
527039Snate@binkert.org    NodeID id = nodenum;
537039Snate@binkert.org    return id;
546145Snate@binkert.org}
556145Snate@binkert.org
567039Snate@binkert.orginline int
577039Snate@binkert.orgIDToInt(NodeID id)
586145Snate@binkert.org{
597039Snate@binkert.org    int nodenum = id;
607039Snate@binkert.org    return nodenum;
616145Snate@binkert.org}
626145Snate@binkert.org
6310956SBrad.Beckmann@amd.cominline int
6411025Snilay@cs.wisc.eduaddressToInt(Addr addr)
6510956SBrad.Beckmann@amd.com{
6611025Snilay@cs.wisc.edu    assert(!(addr & 0xffffffff00000000));
6711025Snilay@cs.wisc.edu    return addr;
686467Sdrh5@cs.wisc.edu}
696467Sdrh5@cs.wisc.edu
7011209Santhony.gutierrez@amd.cominline Addr
7111209Santhony.gutierrez@amd.comintToAddress(int addr)
7211209Santhony.gutierrez@amd.com{
7311209Santhony.gutierrez@amd.com    assert(!(addr & 0xffffffff00000000));
7411209Santhony.gutierrez@amd.com    return addr;
7511209Santhony.gutierrez@amd.com}
7611209Santhony.gutierrez@amd.com
778131SLisa.Hsu@amd.cominline int
788131SLisa.Hsu@amd.commod(int val, int mod)
798131SLisa.Hsu@amd.com{
808131SLisa.Hsu@amd.com    return val % mod;
818131SLisa.Hsu@amd.com}
828131SLisa.Hsu@amd.com
839466Snilay@cs.wisc.eduinline int max_tokens()
849466Snilay@cs.wisc.edu{
859466Snilay@cs.wisc.edu  return 1024;
869466Snilay@cs.wisc.edu}
879466Snilay@cs.wisc.edu
889302Snilay@cs.wisc.edu/**
899302Snilay@cs.wisc.edu * This function accepts an address, a data block and a packet. If the address
909302Snilay@cs.wisc.edu * range for the data block contains the address which the packet needs to
919302Snilay@cs.wisc.edu * read, then the data from the data block is written to the packet. True is
929302Snilay@cs.wisc.edu * returned if the data block was read, otherwise false is returned.
9311307Santhony.gutierrez@amd.com *
9411307Santhony.gutierrez@amd.com * This is used during a functional access "search the world" operation. The
9511307Santhony.gutierrez@amd.com * functional access looks in every place that might hold a valid data block
9611307Santhony.gutierrez@amd.com * and, if it finds one, checks to see if it is holding the address the access
9711307Santhony.gutierrez@amd.com * is searching for. During the access check, the WriteMask could be in any
9811307Santhony.gutierrez@amd.com * state, including empty.
999302Snilay@cs.wisc.edu */
1009302Snilay@cs.wisc.eduinline bool
10111025Snilay@cs.wisc.edutestAndRead(Addr addr, DataBlock& blk, Packet *pkt)
1029302Snilay@cs.wisc.edu{
10311025Snilay@cs.wisc.edu    Addr pktLineAddr = makeLineAddress(pkt->getAddr());
10411025Snilay@cs.wisc.edu    Addr lineAddr = makeLineAddress(addr);
1059302Snilay@cs.wisc.edu
1069302Snilay@cs.wisc.edu    if (pktLineAddr == lineAddr) {
10710562Sandreas.hansson@arm.com        uint8_t *data = pkt->getPtr<uint8_t>();
1089302Snilay@cs.wisc.edu        unsigned int size_in_bytes = pkt->getSize();
10911025Snilay@cs.wisc.edu        unsigned startByte = pkt->getAddr() - lineAddr;
1109302Snilay@cs.wisc.edu
1119302Snilay@cs.wisc.edu        for (unsigned i = 0; i < size_in_bytes; ++i) {
1129302Snilay@cs.wisc.edu            data[i] = blk.getByte(i + startByte);
1139302Snilay@cs.wisc.edu        }
1149302Snilay@cs.wisc.edu        return true;
1159302Snilay@cs.wisc.edu    }
1169302Snilay@cs.wisc.edu    return false;
1179302Snilay@cs.wisc.edu}
1189302Snilay@cs.wisc.edu
1199302Snilay@cs.wisc.edu/**
12011307Santhony.gutierrez@amd.com * This function accepts an address, a data block, a write mask and a packet.
12111307Santhony.gutierrez@amd.com * If the valid address range for the data block contains the address which
12211307Santhony.gutierrez@amd.com * the packet needs to read, then the data from the data block is written to
12311307Santhony.gutierrez@amd.com * the packet. True is returned if any part of the data block was read,
12411307Santhony.gutierrez@amd.com * otherwise false is returned.
12511307Santhony.gutierrez@amd.com */
12611307Santhony.gutierrez@amd.cominline bool
12711307Santhony.gutierrez@amd.comtestAndReadMask(Addr addr, DataBlock& blk, WriteMask& mask, Packet *pkt)
12811307Santhony.gutierrez@amd.com{
12911307Santhony.gutierrez@amd.com    Addr pktLineAddr = makeLineAddress(pkt->getAddr());
13011307Santhony.gutierrez@amd.com    Addr lineAddr = makeLineAddress(addr);
13111307Santhony.gutierrez@amd.com
13211307Santhony.gutierrez@amd.com    if (pktLineAddr == lineAddr) {
13311307Santhony.gutierrez@amd.com        uint8_t *data = pkt->getPtr<uint8_t>();
13411307Santhony.gutierrez@amd.com        unsigned int size_in_bytes = pkt->getSize();
13511307Santhony.gutierrez@amd.com        unsigned startByte = pkt->getAddr() - lineAddr;
13611307Santhony.gutierrez@amd.com        bool was_read = false;
13711307Santhony.gutierrez@amd.com
13811307Santhony.gutierrez@amd.com        for (unsigned i = 0; i < size_in_bytes; ++i) {
13911307Santhony.gutierrez@amd.com            if (mask.test(i + startByte)) {
14011307Santhony.gutierrez@amd.com                was_read = true;
14111307Santhony.gutierrez@amd.com                data[i] = blk.getByte(i + startByte);
14211307Santhony.gutierrez@amd.com            }
14311307Santhony.gutierrez@amd.com        }
14411307Santhony.gutierrez@amd.com        return was_read;
14511307Santhony.gutierrez@amd.com    }
14611307Santhony.gutierrez@amd.com    return false;
14711307Santhony.gutierrez@amd.com}
14811307Santhony.gutierrez@amd.com
14911307Santhony.gutierrez@amd.com/**
1509302Snilay@cs.wisc.edu * This function accepts an address, a data block and a packet. If the address
1519302Snilay@cs.wisc.edu * range for the data block contains the address which the packet needs to
1529302Snilay@cs.wisc.edu * write, then the data from the packet is written to the data block. True is
1539302Snilay@cs.wisc.edu * returned if the data block was written, otherwise false is returned.
1549302Snilay@cs.wisc.edu */
1559302Snilay@cs.wisc.eduinline bool
15611025Snilay@cs.wisc.edutestAndWrite(Addr addr, DataBlock& blk, Packet *pkt)
1579302Snilay@cs.wisc.edu{
15811025Snilay@cs.wisc.edu    Addr pktLineAddr = makeLineAddress(pkt->getAddr());
15911025Snilay@cs.wisc.edu    Addr lineAddr = makeLineAddress(addr);
1609302Snilay@cs.wisc.edu
1619302Snilay@cs.wisc.edu    if (pktLineAddr == lineAddr) {
16210563Sandreas.hansson@arm.com        const uint8_t *data = pkt->getConstPtr<uint8_t>();
1639302Snilay@cs.wisc.edu        unsigned int size_in_bytes = pkt->getSize();
16411025Snilay@cs.wisc.edu        unsigned startByte = pkt->getAddr() - lineAddr;
1659302Snilay@cs.wisc.edu
1669302Snilay@cs.wisc.edu        for (unsigned i = 0; i < size_in_bytes; ++i) {
1679302Snilay@cs.wisc.edu            blk.setByte(i + startByte, data[i]);
1689302Snilay@cs.wisc.edu        }
1699302Snilay@cs.wisc.edu        return true;
1709302Snilay@cs.wisc.edu    }
1719302Snilay@cs.wisc.edu    return false;
1729302Snilay@cs.wisc.edu}
1739302Snilay@cs.wisc.edu
17411208Sjoseph.gross@amd.cominline int
17511208Sjoseph.gross@amd.comcountBoolVec(BoolVec bVec)
17611208Sjoseph.gross@amd.com{
17711208Sjoseph.gross@amd.com    int count = 0;
17811208Sjoseph.gross@amd.com    for (const auto &it: bVec) {
17911208Sjoseph.gross@amd.com        if (it) {
18011208Sjoseph.gross@amd.com            count++;
18111208Sjoseph.gross@amd.com        }
18211208Sjoseph.gross@amd.com    }
18311208Sjoseph.gross@amd.com    return count;
18411208Sjoseph.gross@amd.com}
18511208Sjoseph.gross@amd.com
18612492Sodanrc@yahoo.com.br#endif //__MEM_RUBY_SLICC_INTERFACE_RUBYSLICC_UTIL_HH__
187