blob: d51fb76ca9a908727665f67403d83fdc6e371fb8 [file] [log] [blame]
/*
* 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);
}
}