/*
 * Copyright (c) 2021 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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.
 */

// All CHI request and response types match the name style in the standard doc.
// For a description of a specific message type, refer to the Arm's AMBA 5
// CHI specification (issue D):
// https://static.docs.arm.com/ihi0050/d/
// IHI0050D_amba_5_chi_architecture_spec.pdf

enumeration(CHIRequestType, desc="") {
  // Incoming requests generated by the sequencer
  Load;
  Store;
  StoreLine;

  // CHI request types
  ReadShared;
  ReadNotSharedDirty;
  ReadUnique;
  ReadOnce;
  CleanUnique;

  Evict;

  WriteBackFull;
  WriteCleanFull;
  WriteEvictFull;
  WriteUniquePtl;
  WriteUniqueFull;

  SnpSharedFwd;
  SnpNotSharedDirtyFwd;
  SnpUniqueFwd;
  SnpOnceFwd;
  SnpOnce;
  SnpShared;
  SnpUnique;
  SnpCleanInvalid;

  WriteNoSnpPtl;
  WriteNoSnp;
  ReadNoSnp;
  ReadNoSnpSep;

  null;
}

structure(CHIRequestMsg, desc="", interface="Message") {
  Addr addr,                desc="Request line address";
  Addr accAddr,             desc="Original access address. Set for Write*Ptl and requests from the sequencer";
  int  accSize,             desc="Access size. Set for Write*Ptl and requests from the sequencer";
  CHIRequestType type,      desc="Request type";
  MachineID requestor,      desc="Requestor ID";
  MachineID fwdRequestor,   desc="Where to send data for DMT/DCT requests";
  bool dataToFwdRequestor,  desc="Data has to be forwarded to fwdRequestor";
  bool retToSrc,            desc="Affects whether or not a snoop resp returns data";
  bool allowRetry,          desc="This request can be retried";
  NetDest Destination,      desc="Message destination";

  RequestPtr seqReq,        default="nullptr", desc="Pointer to original request from CPU/sequencer (nullptr if not valid)";
  bool isSeqReqValid,       default="false",   desc="Set if seqReq is valid (not nullptr)";

  bool is_local_pf,         desc="Request generated by a local prefetcher";
  bool is_remote_pf,        desc="Request generated a prefetcher in another cache";

  MessageSizeType MessageSize, default="MessageSizeType_Control";

  // No data for functional access
  bool functionalRead(Packet *pkt) { return false; }
  bool functionalRead(Packet *pkt, WriteMask &mask) { return false; }
  bool functionalWrite(Packet *pkt) { return false; }
}

enumeration(CHIResponseType, desc="...") {
  // CHI response types
  Comp_I;
  Comp_UC;
  Comp_SC;
  CompAck;
  CompDBIDResp;
  DBIDResp;
  Comp;
  ReadReceipt;
  RespSepData;

  SnpResp_I;
  SnpResp_I_Fwded_UC;
  SnpResp_I_Fwded_UD_PD;
  SnpResp_SC;
  SnpResp_SC_Fwded_SC;
  SnpResp_SC_Fwded_SD_PD;
  SnpResp_UC_Fwded_I;
  SnpResp_UD_Fwded_I;
  SnpResp_SC_Fwded_I;
  SnpResp_SD_Fwded_I;

  RetryAck;
  PCrdGrant;

  null;
}

structure(CHIResponseMsg, desc="", interface="Message") {
  Addr addr,            desc="Line address";
  CHIResponseType type, desc="Response type";
  MachineID responder,  desc="Responder ID";
  NetDest Destination,  desc="Response destination";
  bool stale,           desc="Response to a stale request";
  //NOTE: not in CHI and for debuging only

  MessageSizeType MessageSize, default="MessageSizeType_Control";

  // No data for functional access
  bool functionalRead(Packet *pkt) { return false; }
  bool functionalRead(Packet *pkt, WriteMask &mask) { return false; }
  bool functionalWrite(Packet *pkt) { return false; }
}

enumeration(CHIDataType, desc="...") {
  // CHI data response types
  CompData_I;
  CompData_UC;
  CompData_SC;
  CompData_UD_PD;
  CompData_SD_PD;
  DataSepResp_UC;
  CBWrData_UC;
  CBWrData_SC;
  CBWrData_UD_PD;
  CBWrData_SD_PD;
  CBWrData_I;
  NCBWrData;
  SnpRespData_I;
  SnpRespData_I_PD;
  SnpRespData_SC;
  SnpRespData_SC_PD;
  SnpRespData_SD;
  SnpRespData_UC;
  SnpRespData_UD;
  SnpRespData_SC_Fwded_SC;
  SnpRespData_SC_Fwded_SD_PD;
  SnpRespData_SC_PD_Fwded_SC;
  SnpRespData_I_Fwded_SD_PD;
  SnpRespData_I_PD_Fwded_SC;
  SnpRespData_I_Fwded_SC;
  null;
}

structure(CHIDataMsg, desc="", interface="Message") {
  Addr addr,            desc="Line address";
  CHIDataType type,     desc="Response type";
  MachineID responder,  desc="Responder ID";
  NetDest Destination,  desc="Response destination";
  DataBlock dataBlk,    desc="Line data";
  WriteMask bitMask,    desc="Which bytes in the data block are valid";


  MessageSizeType MessageSize, default="MessageSizeType_Data";

  bool functionalRead(Packet *pkt) {
    if(bitMask.isFull()) {
      return testAndRead(addr, dataBlk, pkt);
    } else {
      return false;
    }
  }

  bool functionalRead(Packet *pkt, WriteMask &mask) {
    // read if bitmask has bytes not in mask or if data is dirty
    bool is_dirty := (type == CHIDataType:CompData_UD_PD) ||
                    (type == CHIDataType:CompData_SD_PD) ||
                    (type == CHIDataType:CBWrData_UD_PD) ||
                    (type == CHIDataType:CBWrData_SD_PD) ||
                    (type == CHIDataType:NCBWrData) ||
                    (type == CHIDataType:SnpRespData_I_PD) ||
                    (type == CHIDataType:SnpRespData_SC_PD) ||
                    (type == CHIDataType:SnpRespData_SD) ||
                    (type == CHIDataType:SnpRespData_UD) ||
                    (type == CHIDataType:SnpRespData_SC_Fwded_SD_PD) ||
                    (type == CHIDataType:SnpRespData_SC_PD_Fwded_SC) ||
                    (type == CHIDataType:SnpRespData_I_Fwded_SD_PD) ||
                    (type == CHIDataType:SnpRespData_I_PD_Fwded_SC);
    assert(bitMask.isEmpty() == false);
    WriteMask test_mask := mask;
    test_mask.orMask(bitMask);
    if ((test_mask.cmpMask(mask) == false) || is_dirty) {
      if (testAndReadMask(addr, dataBlk, bitMask, pkt)) {
        mask.orMask(bitMask);
        return true;
      }
    }
    return false;
  }

  bool functionalWrite(Packet *pkt) {
    return testAndWrite(addr, dataBlk, pkt);
  }
}


