| /* | |
| * 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; | |
| // Incoming DVM-related requests generated by the sequencer | |
| DvmTlbi_Initiate; | |
| DvmSync_Initiate; | |
| DvmSync_ExternCompleted; | |
| // CHI request types | |
| ReadShared; | |
| ReadNotSharedDirty; | |
| ReadUnique; | |
| ReadOnce; | |
| CleanUnique; | |
| Evict; | |
| WriteBackFull; | |
| WriteCleanFull; | |
| WriteEvictFull; | |
| WriteUniquePtl; | |
| WriteUniqueFull; | |
| SnpSharedFwd; | |
| SnpNotSharedDirtyFwd; | |
| SnpUniqueFwd; | |
| SnpOnceFwd; | |
| SnpOnce; | |
| SnpShared; | |
| SnpUnique; | |
| SnpCleanInvalid; | |
| SnpDvmOpSync_P1; | |
| SnpDvmOpSync_P2; | |
| SnpDvmOpNonSync_P1; | |
| SnpDvmOpNonSync_P2; | |
| WriteNoSnpPtl; | |
| WriteNoSnp; | |
| ReadNoSnp; | |
| ReadNoSnpSep; | |
| DvmOpNonSync; | |
| DvmOpSync; | |
| 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"; | |
| bool usesTxnId, desc="True if using a Transaction ID", default="false"; | |
| Addr txnId, desc="Transaction ID", default="0"; | |
| 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"; | |
| bool usesTxnId, desc="True if using a Transaction ID", default="false"; | |
| Addr txnId, desc="Transaction ID", default="0"; | |
| //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"; | |
| bool usesTxnId, desc="True if using a Transaction ID", default="false"; | |
| Addr txnId, desc="Transaction ID", default="0"; | |
| 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 ((mask.containsMask(test_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); | |
| } | |
| } | |