112608Sjason@lowepower.com/*
212608Sjason@lowepower.com * Copyright (c) 2017 Jason Lowe-Power
312608Sjason@lowepower.com * All rights reserved.
412608Sjason@lowepower.com *
512608Sjason@lowepower.com * Redistribution and use in source and binary forms, with or without
612608Sjason@lowepower.com * modification, are permitted provided that the following conditions are
712608Sjason@lowepower.com * met: redistributions of source code must retain the above copyright
812608Sjason@lowepower.com * notice, this list of conditions and the following disclaimer;
912608Sjason@lowepower.com * redistributions in binary form must reproduce the above copyright
1012608Sjason@lowepower.com * notice, this list of conditions and the following disclaimer in the
1112608Sjason@lowepower.com * documentation and/or other materials provided with the distribution;
1212608Sjason@lowepower.com * neither the name of the copyright holders nor the names of its
1312608Sjason@lowepower.com * contributors may be used to endorse or promote products derived from
1412608Sjason@lowepower.com * this software without specific prior written permission.
1512608Sjason@lowepower.com *
1612608Sjason@lowepower.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712608Sjason@lowepower.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812608Sjason@lowepower.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912608Sjason@lowepower.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012608Sjason@lowepower.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112608Sjason@lowepower.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212608Sjason@lowepower.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312608Sjason@lowepower.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412608Sjason@lowepower.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512608Sjason@lowepower.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612608Sjason@lowepower.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712608Sjason@lowepower.com */
2812608Sjason@lowepower.com
2912608Sjason@lowepower.com/**
3012608Sjason@lowepower.com * This file contains the messages and other types for a simple MSI protocol.
3112608Sjason@lowepower.com *
3212608Sjason@lowepower.com * The protocol in this file is based off of the MSI protocol found in
3312608Sjason@lowepower.com * A Primer on Memory Consistency and Cache Coherence
3412608Sjason@lowepower.com *      Daniel J. Sorin, Mark D. Hill, and David A. Wood
3512608Sjason@lowepower.com *      Synthesis Lectures on Computer Architecture 2011 6:3, 141-149
3612608Sjason@lowepower.com *
3712608Sjason@lowepower.com * See Learning gem5 Part 3: Ruby for more details.
3812608Sjason@lowepower.com *
3912608Sjason@lowepower.com * Authors: Jason Lowe-Power
4012608Sjason@lowepower.com */
4112608Sjason@lowepower.com
4212608Sjason@lowepower.comenumeration(CoherenceRequestType, desc="Types of request messages") {
4312608Sjason@lowepower.com    GetS,       desc="Request from cache for a block with read permission";
4412608Sjason@lowepower.com    GetM,       desc="Request from cache for a block with write permission";
4512608Sjason@lowepower.com    PutS,       desc="Sent to directory when evicting a block in S (clean WB)";
4612608Sjason@lowepower.com    PutM,       desc="Sent to directory when evicting a block in M";
4712608Sjason@lowepower.com
4812608Sjason@lowepower.com    // "Requests" from the directory to the caches on the fwd network
4912608Sjason@lowepower.com    Inv,        desc="Probe the cache and invalidate any matching blocks";
5012608Sjason@lowepower.com    PutAck,     desc="The put request has been processed.";
5112608Sjason@lowepower.com}
5212608Sjason@lowepower.com
5312608Sjason@lowepower.comenumeration(CoherenceResponseType, desc="Types of response messages") {
5412608Sjason@lowepower.com    Data,       desc="Contains the most up-to-date data";
5512608Sjason@lowepower.com    InvAck,     desc="Message from another cache that they have inv. the blk";
5612608Sjason@lowepower.com}
5712608Sjason@lowepower.com
5812608Sjason@lowepower.comstructure(RequestMsg, desc="Used for Cache->Dir and Fwd messages",
5912608Sjason@lowepower.com          interface="Message") {
6012608Sjason@lowepower.com    // NOTE: You can't name addr "Addr" because it would conflict with the
6112608Sjason@lowepower.com    // Addr *type*.
6212608Sjason@lowepower.com    Addr addr,                   desc="Physical address for this request";
6312608Sjason@lowepower.com    CoherenceRequestType Type,   desc="Type of request";
6412608Sjason@lowepower.com    MachineID Requestor,         desc="Node who initiated the request";
6512608Sjason@lowepower.com    NetDest Destination,         desc="Multicast destination mask";
6612608Sjason@lowepower.com    DataBlock DataBlk,           desc="data for the cache line";
6712608Sjason@lowepower.com    // NOTE: You *must* use MessageSize as the name of this variable, and it's
6812608Sjason@lowepower.com    // required that you have a MessageSize for each type of message. You will
6912608Sjason@lowepower.com    // the the error "panic: MessageSizeType() called on wrong message!"
7012608Sjason@lowepower.com    MessageSizeType MessageSize, desc="size category of the message";
7112608Sjason@lowepower.com
7212608Sjason@lowepower.com    // This must be overridden here to support functional accesses
7312608Sjason@lowepower.com    bool functionalRead(Packet *pkt) {
7412608Sjason@lowepower.com        // Requests should never have the only copy of the most up-to-date data
7512608Sjason@lowepower.com        return false;
7612608Sjason@lowepower.com    }
7712608Sjason@lowepower.com
7812608Sjason@lowepower.com    bool functionalWrite(Packet *pkt) {
7912608Sjason@lowepower.com        // No check on message type required since the protocol should read
8012608Sjason@lowepower.com        // data block from only those messages that contain valid data
8112608Sjason@lowepower.com        return testAndWrite(addr, DataBlk, pkt);
8212608Sjason@lowepower.com    }
8312608Sjason@lowepower.com}
8412608Sjason@lowepower.com
8512608Sjason@lowepower.comstructure(ResponseMsg, desc="Used for Cache->Dir and Fwd messages",
8612608Sjason@lowepower.com          interface="Message") {
8712608Sjason@lowepower.com    Addr addr,                   desc="Physical address for this response";
8812608Sjason@lowepower.com    CoherenceResponseType Type,  desc="Type of response";
8912608Sjason@lowepower.com    MachineID Sender,            desc="Node who is responding to the request";
9012608Sjason@lowepower.com    NetDest Destination,         desc="Multicast destination mask";
9112608Sjason@lowepower.com    DataBlock DataBlk,           desc="data for the cache line";
9212608Sjason@lowepower.com    MessageSizeType MessageSize, desc="size category of the message";
9312608Sjason@lowepower.com    int Acks,                    desc="Number of acks required from others";
9412608Sjason@lowepower.com
9512608Sjason@lowepower.com    // This must be overridden here to support functional accesses
9612608Sjason@lowepower.com    bool functionalRead(Packet *pkt) {
9712608Sjason@lowepower.com        if (Type == CoherenceResponseType:Data) {
9812608Sjason@lowepower.com            return testAndRead(addr, DataBlk, pkt);
9912608Sjason@lowepower.com        }
10012608Sjason@lowepower.com        return false;
10112608Sjason@lowepower.com    }
10212608Sjason@lowepower.com
10312608Sjason@lowepower.com    bool functionalWrite(Packet *pkt) {
10412608Sjason@lowepower.com        // No check on message type required since the protocol should read
10512608Sjason@lowepower.com        // data block from only those messages that contain valid data
10612608Sjason@lowepower.com        return testAndWrite(addr, DataBlk, pkt);
10712608Sjason@lowepower.com    }
10812608Sjason@lowepower.com}
109