/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Erik Hallnor
 *          Steve Reinhardt
 *          Ron Dreslinski
 */

/**
 * @file
 * Definitions of CoherenceProtocol.
 */

#include <string>

#include "base/misc.hh"
#include "mem/cache/miss/mshr.hh"
#include "mem/cache/cache.hh"
#include "mem/cache/coherence/coherence_protocol.hh"
#include "sim/builder.hh"

using namespace std;


CoherenceProtocol::StateTransition::StateTransition()
    : busCmd(MemCmd::InvalidCmd), newState(-1), snoopFunc(invalidTransition)
{
}


void
CoherenceProtocol::regStats()
{
    // Even though we count all the possible transitions in the
    // requestCount and snoopCount arrays, most of these are invalid,
    // so we just select the interesting ones to print here.

    requestCount[Invalid][MemCmd::ReadReq]
        .name(name() + ".read_invalid")
        .desc("read misses to invalid blocks")
        ;

    requestCount[Invalid][MemCmd::WriteReq]
        .name(name() +".write_invalid")
        .desc("write misses to invalid blocks")
        ;

    requestCount[Invalid][MemCmd::SoftPFReq]
        .name(name() +".swpf_invalid")
        .desc("soft prefetch misses to invalid blocks")
        ;

    requestCount[Invalid][MemCmd::HardPFReq]
        .name(name() +".hwpf_invalid")
        .desc("hard prefetch misses to invalid blocks")
        ;

    requestCount[Shared][MemCmd::WriteReq]
        .name(name() + ".write_shared")
        .desc("write misses to shared blocks")
        ;

    requestCount[Owned][MemCmd::WriteReq]
        .name(name() + ".write_owned")
        .desc("write misses to owned blocks")
        ;

    snoopCount[Shared][MemCmd::ReadReq]
        .name(name() + ".snoop_read_shared")
        .desc("read snoops on shared blocks")
        ;

    snoopCount[Shared][MemCmd::ReadExReq]
        .name(name() + ".snoop_readex_shared")
        .desc("readEx snoops on shared blocks")
        ;

    snoopCount[Shared][MemCmd::UpgradeReq]
        .name(name() + ".snoop_upgrade_shared")
        .desc("upgradee snoops on shared blocks")
        ;

    snoopCount[Modified][MemCmd::ReadReq]
        .name(name() + ".snoop_read_modified")
        .desc("read snoops on modified blocks")
        ;

    snoopCount[Modified][MemCmd::ReadExReq]
        .name(name() + ".snoop_readex_modified")
        .desc("readEx snoops on modified blocks")
        ;

    snoopCount[Owned][MemCmd::ReadReq]
        .name(name() + ".snoop_read_owned")
        .desc("read snoops on owned blocks")
        ;

    snoopCount[Owned][MemCmd::ReadExReq]
        .name(name() + ".snoop_readex_owned")
        .desc("readEx snoops on owned blocks")
        ;

    snoopCount[Owned][MemCmd::UpgradeReq]
        .name(name() + ".snoop_upgrade_owned")
        .desc("upgrade snoops on owned blocks")
        ;

    snoopCount[Exclusive][MemCmd::ReadReq]
        .name(name() + ".snoop_read_exclusive")
        .desc("read snoops on exclusive blocks")
        ;

    snoopCount[Exclusive][MemCmd::ReadExReq]
        .name(name() + ".snoop_readex_exclusive")
        .desc("readEx snoops on exclusive blocks")
        ;

    snoopCount[Shared][MemCmd::InvalidateReq]
        .name(name() + ".snoop_inv_shared")
        .desc("Invalidate snoops on shared blocks")
        ;

    snoopCount[Owned][MemCmd::InvalidateReq]
        .name(name() + ".snoop_inv_owned")
        .desc("Invalidate snoops on owned blocks")
        ;

    snoopCount[Exclusive][MemCmd::InvalidateReq]
        .name(name() + ".snoop_inv_exclusive")
        .desc("Invalidate snoops on exclusive blocks")
        ;

    snoopCount[Modified][MemCmd::InvalidateReq]
        .name(name() + ".snoop_inv_modified")
        .desc("Invalidate snoops on modified blocks")
        ;

    snoopCount[Invalid][MemCmd::InvalidateReq]
        .name(name() + ".snoop_inv_invalid")
        .desc("Invalidate snoops on invalid blocks")
        ;

    snoopCount[Shared][MemCmd::WriteInvalidateReq]
        .name(name() + ".snoop_writeinv_shared")
        .desc("WriteInvalidate snoops on shared blocks")
        ;

    snoopCount[Owned][MemCmd::WriteInvalidateReq]
        .name(name() + ".snoop_writeinv_owned")
        .desc("WriteInvalidate snoops on owned blocks")
        ;

    snoopCount[Exclusive][MemCmd::WriteInvalidateReq]
        .name(name() + ".snoop_writeinv_exclusive")
        .desc("WriteInvalidate snoops on exclusive blocks")
        ;

    snoopCount[Modified][MemCmd::WriteInvalidateReq]
        .name(name() + ".snoop_writeinv_modified")
        .desc("WriteInvalidate snoops on modified blocks")
        ;

    snoopCount[Invalid][MemCmd::WriteInvalidateReq]
        .name(name() + ".snoop_writeinv_invalid")
        .desc("WriteInvalidate snoops on invalid blocks")
        ;
}


bool
CoherenceProtocol::invalidateTrans(BaseCache *cache, PacketPtr &pkt,
                                   CacheBlk *blk, MSHR *mshr,
                                   CacheBlk::State & new_state)
{
    // invalidate the block
    new_state = (blk->status & ~stateMask) | Invalid;
    return false;
}


bool
CoherenceProtocol::supplyTrans(BaseCache *cache, PacketPtr &pkt,
                               CacheBlk *blk,
                               MSHR *mshr,
                               CacheBlk::State & new_state)
{
    return true;
}


bool
CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, PacketPtr &pkt,
                                            CacheBlk *blk,
                                            MSHR *mshr,
                                            CacheBlk::State & new_state)
{
    new_state = (blk->status & ~stateMask) | Shared;
    pkt->flags |= SHARED_LINE;
    return supplyTrans(cache, pkt, blk, mshr, new_state);
}


bool
CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, PacketPtr &pkt,
                                           CacheBlk *blk,
                                           MSHR *mshr,
                                           CacheBlk::State & new_state)
{
    new_state = (blk->status & ~stateMask) | Owned;
    pkt->flags |= SHARED_LINE;
    return supplyTrans(cache, pkt, blk, mshr, new_state);
}


bool
CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, PacketPtr &pkt,
                                            CacheBlk *blk,
                                            MSHR *mshr,
                                            CacheBlk::State & new_state)
{
    new_state = (blk->status & ~stateMask) | Invalid;
    return supplyTrans(cache, pkt, blk, mshr, new_state);
}

bool
CoherenceProtocol::assertShared(BaseCache *cache, PacketPtr &pkt,
                                            CacheBlk *blk,
                                            MSHR *mshr,
                                            CacheBlk::State & new_state)
{
    new_state = (blk->status & ~stateMask) | Shared;
    pkt->flags |= SHARED_LINE;
    return false;
}

CoherenceProtocol::CoherenceProtocol(const string &name,
                                     const string &protocol,
                                     const bool doUpgrades)
    : SimObject(name)
{
    // Python should catch this, but in case it doesn't...
    if (!(protocol == "msi"  || protocol == "mesi" ||
          protocol == "mosi" || protocol == "moesi")) {
        fatal("CoherenceProtocol: unrecognized protocol %s\n",  protocol);
    }

    bool hasOwned = (protocol == "mosi" || protocol == "moesi");
    bool hasExclusive = (protocol == "mesi" || protocol == "moesi");

    if (hasOwned && !doUpgrades) {
        fatal("CoherenceProtocol: ownership protocols require upgrade "
              "transactions\n(write miss on owned block generates ReadExcl, "
              "which will clobber dirty block)\n");
    }

    // set up a few shortcuts to save typing & visual clutter
    typedef MemCmd MC;
    StateTransition (&tt)[stateMax+1][MC::NUM_MEM_CMDS] = transitionTable;

    MC::Command writeToSharedCmd =
        doUpgrades ? MC::UpgradeReq : MC::ReadExReq;
    MC::Command writeToSharedResp =
        doUpgrades ? MC::UpgradeReq : MC::ReadExResp;

    // Note that all transitions by default cause a panic.
    // Override the valid transitions with the appropriate actions here.

    //
    // ----- incoming requests: specify outgoing bus request -----
    //
    tt[Invalid][MC::ReadReq].onRequest(MC::ReadReq);
    // we only support write allocate right now
    tt[Invalid][MC::WriteReq].onRequest(MC::ReadExReq);
    tt[Shared][MC::WriteReq].onRequest(writeToSharedCmd);
    if (hasOwned) {
        tt[Owned][MC::WriteReq].onRequest(writeToSharedCmd);
    }

    // Prefetching causes a read
    tt[Invalid][MC::SoftPFReq].onRequest(MC::ReadReq);
    tt[Invalid][MC::HardPFReq].onRequest(MC::ReadReq);

    //
    // ----- on response to given request: specify new state -----
    //
    tt[Invalid][MC::ReadExResp].onResponse(Modified);
    tt[Shared][writeToSharedResp].onResponse(Modified);
    // Go to Exclusive state on read response if we have one (will
    // move into shared if the shared line is asserted in the
    // getNewState function)
    //
    // originally had this as:
    // tt[Invalid][MC::ReadResp].onResponse(hasExclusive ? Exclusive: Shared);
    // ...but for some reason that caused a link error...
    if (hasExclusive) {
        tt[Invalid][MC::ReadResp].onResponse(Exclusive);
    } else {
        tt[Invalid][MC::ReadResp].onResponse(Shared);
    }
    if (hasOwned) {
        tt[Owned][writeToSharedResp].onResponse(Modified);
    }

    //
    // ----- bus snoop transition functions -----
    //
    tt[Invalid][MC::ReadReq].onSnoop(nullTransition);
    tt[Invalid][MC::ReadExReq].onSnoop(nullTransition);
    tt[Invalid][MC::InvalidateReq].onSnoop(invalidateTrans);
    tt[Invalid][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
    tt[Shared][MC::ReadReq].onSnoop(hasExclusive
                                   ? assertShared : nullTransition);
    tt[Shared][MC::ReadExReq].onSnoop(invalidateTrans);
    tt[Shared][MC::InvalidateReq].onSnoop(invalidateTrans);
    tt[Shared][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
    if (doUpgrades) {
        tt[Invalid][MC::UpgradeReq].onSnoop(nullTransition);
        tt[Shared][MC::UpgradeReq].onSnoop(invalidateTrans);
    }
    tt[Modified][MC::ReadExReq].onSnoop(supplyAndInvalidateTrans);
    tt[Modified][MC::ReadReq].onSnoop(hasOwned
                                     ? supplyAndGotoOwnedTrans
                                     : supplyAndGotoSharedTrans);
    tt[Modified][MC::InvalidateReq].onSnoop(invalidateTrans);
    tt[Modified][MC::WriteInvalidateReq].onSnoop(invalidateTrans);

    if (hasExclusive) {
        tt[Exclusive][MC::ReadReq].onSnoop(assertShared);
        tt[Exclusive][MC::ReadExReq].onSnoop(invalidateTrans);
        tt[Exclusive][MC::InvalidateReq].onSnoop(invalidateTrans);
        tt[Exclusive][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
    }

    if (hasOwned) {
        tt[Owned][MC::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
        tt[Owned][MC::ReadExReq].onSnoop(supplyAndInvalidateTrans);
        tt[Owned][MC::UpgradeReq].onSnoop(invalidateTrans);
        tt[Owned][MC::InvalidateReq].onSnoop(invalidateTrans);
        tt[Owned][MC::WriteInvalidateReq].onSnoop(invalidateTrans);
    }

    // @todo add in hardware prefetch to this list
}


MemCmd
CoherenceProtocol::getBusCmd(MemCmd cmdIn, CacheBlk::State state,
                             MSHR *mshr)
{
    state &= stateMask;
    int cmd_idx = cmdIn.toInt();

    assert(0 <= state && state <= stateMax);
    assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);

    MemCmd::Command cmdOut = transitionTable[state][cmd_idx].busCmd;

    assert(cmdOut != MemCmd::InvalidCmd);

    ++requestCount[state][cmd_idx];

    return cmdOut;
}


CacheBlk::State
CoherenceProtocol::getNewState(PacketPtr &pkt, CacheBlk::State oldState)
{
    CacheBlk::State state = oldState & stateMask;
    int cmd_idx = pkt->cmdToIndex();

    assert(0 <= state && state <= stateMax);
    assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);

    CacheBlk::State newState = transitionTable[state][cmd_idx].newState;

    //Check if it's exclusive and the shared line was asserted,
    //then  goto shared instead
    if (newState == Exclusive && (pkt->flags & SHARED_LINE)) {
        newState = Shared;
    }

    assert(newState != -1);

    //Make sure not to loose any other state information
    newState = (oldState & ~stateMask) | newState;
    return newState;
}


bool
CoherenceProtocol::handleBusRequest(BaseCache *cache, PacketPtr &pkt,
                                    CacheBlk *blk,
                                    MSHR *mshr,
                                    CacheBlk::State & new_state)
{
    if (blk == NULL) {
        // nothing to do if we don't have a block
        return false;
    }

    CacheBlk::State state = blk->status & stateMask;
    int cmd_idx = pkt->cmdToIndex();

    assert(0 <= state && state <= stateMax);
    assert(0 <= cmd_idx && cmd_idx < MemCmd::NUM_MEM_CMDS);

//    assert(mshr == NULL); // can't currently handle outstanding requests
    //Check first if MSHR, and also insure, if there is one, that it is not in service
    assert(!mshr || mshr->inService == 0);
    ++snoopCount[state][cmd_idx];

    bool ret = transitionTable[state][cmd_idx].snoopFunc(cache, pkt, blk, mshr,
                                                     new_state);



    return ret;
}

bool
CoherenceProtocol::nullTransition(BaseCache *cache, PacketPtr &pkt,
                                  CacheBlk *blk, MSHR *mshr,
                                  CacheBlk::State & new_state)
{
    // do nothing
    if (blk)
        new_state = blk->status;
    return false;
}


bool
CoherenceProtocol::invalidTransition(BaseCache *cache, PacketPtr &pkt,
                                     CacheBlk *blk, MSHR *mshr,
                                     CacheBlk::State & new_state)
{
    panic("Invalid transition");
    return false;
}

#ifndef DOXYGEN_SHOULD_SKIP_THIS

BEGIN_DECLARE_SIM_OBJECT_PARAMS(CoherenceProtocol)

    Param<string> protocol;
    Param<bool> do_upgrades;

END_DECLARE_SIM_OBJECT_PARAMS(CoherenceProtocol)


BEGIN_INIT_SIM_OBJECT_PARAMS(CoherenceProtocol)

    INIT_PARAM(protocol, "name of coherence protocol"),
    INIT_PARAM_DFLT(do_upgrades, "use upgrade transactions?", true)

END_INIT_SIM_OBJECT_PARAMS(CoherenceProtocol)


CREATE_SIM_OBJECT(CoherenceProtocol)
{
    return new CoherenceProtocol(getInstanceName(), protocol,
                                 do_upgrades);
}

REGISTER_SIM_OBJECT("CoherenceProtocol", CoherenceProtocol)

#endif // DOXYGEN_SHOULD_SKIP_THIS
