| /* |
| * 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); |
| } |
| } |
| |
| |