40#include "debug/TLM.hh"
41#include "mem/ruby/protocol/CHI/CHIDataMsg.hh"
42#include "mem/ruby/protocol/CHI/CHIRequestMsg.hh"
43#include "mem/ruby/protocol/CHI/CHIResponseMsg.hh"
50using namespace ruby::CHI;
53 : CHIGenericController(
p)
60 panic(
"recvRequestMsg");
67 ARM::CHI::Phase phase;
68 ARM::CHI::Payload *payload = ARM::CHI::Payload::new_payload();
70 payload->address = msg->m_addr;
71 payload->ns = msg->m_ns;
72 phase.channel = ARM::CHI::CHANNEL_SNP;
74 phase.txn_id = msg->m_txnId % 1024;
85 ARM::CHI::Phase phase;
86 ARM::CHI::Payload *payload = ARM::CHI::Payload::new_payload();
87 phase.channel = ARM::CHI::CHANNEL_RSP;
88 phase.rsp_opcode = ARM::CHI::RSP_OPCODE_PCRD_GRANT;
100 if (msg->m_type == CHIResponseType_PCrdGrant) {
106 auto txn_id = msg->m_txnId;
110 auto& transaction = it->second;
111 if (transaction->handle(msg))
114 panic(
"recvResponseMsg");
122 auto txn_id = msg->m_txnId;
125 auto& transaction = it->second;
126 if (transaction->handle(msg))
129 panic(
"Not able to find transaction");
138 phase.channel = ARM::CHI::CHANNEL_RSP;
141 phase.txn_id = msg->m_txnId % 1024;
144 return opcode != ARM::CHI::RSP_OPCODE_RETRY_ACK;
152 for (
auto byte = 0;
byte < controller->cacheLineSize;
byte++) {
153 if (msg->m_bitMask.test(
byte))
154 payload->data[byte] = msg->m_dataBlk.getByte(
byte);
158 phase.channel = ARM::CHI::CHANNEL_DAT;
161 phase.txn_id = msg->m_txnId % 1024;
162 phase.data_id =
dataId(msg->m_addr + msg->m_bitMask.firstBitSet(
true));
166 controller->bw(payload, &phase);
169 if (dataMsgCnt == controller->dataMsgsPerLine) {
170 if (phase.exp_comp_ack ==
false) {
173 controller->sendCompAck(*payload, phase);
185 phase.dbid = msg->m_dbid % 1024;
192 if (payload->size == 6) {
195 if (msg->m_bitMask.test(payload->address - msg->m_addr)) {
209 assert(
opcode == ARM::CHI::RSP_OPCODE_COMP ||
210 opcode == ARM::CHI::RSP_OPCODE_RETRY_ACK);
219 if (
opcode == ARM::CHI::RSP_OPCODE_COMP_DBID_RESP) {
223 if (
opcode == ARM::CHI::RSP_OPCODE_COMP) {
226 if (
opcode == ARM::CHI::RSP_OPCODE_DBID_RESP) {
230 phase.dbid = msg->m_dbid % 1024;
233 return recvComp && recvDBID;
238 ARM::CHI::Phase &phase)
240 auto res_msg = std::make_shared<CHIResponseMsg>(
244 res_msg->m_type = CHIResponseType_CompAck;
248 res_msg->m_txnId = phase.txn_id;
256 switch (phase.channel) {
257 case ARM::CHI::CHANNEL_REQ:
260 case ARM::CHI::CHANNEL_DAT:
263 case ARM::CHI::CHANNEL_RSP:
267 panic(
"Unimplemented channel: %d", phase.channel);
273 ARM::CHI::Phase &phase)
const
275 switch (phase.req_opcode) {
276 case ARM::CHI::REQ_OPCODE_WRITE_NO_SNP_PTL:
278 ctz64(payload.byte_enable);
280 return payload.address;
286 ARM::CHI::Phase &phase)
const
288 switch (phase.req_opcode) {
289 case ARM::CHI::REQ_OPCODE_WRITE_NO_SNP_PTL:
291 return popCount(payload.byte_enable);
299 ARM::CHI::Phase &phase)
301 auto req_msg = std::make_shared<CHIRequestMsg>(
305 req_msg->m_accAddr =
reqAddr(payload, phase);
306 req_msg->m_accSize =
reqSize(payload, phase);
309 req_msg->m_dataToFwdRequestor =
false;
311 req_msg->m_isSeqReqValid =
false;
312 req_msg->m_is_local_pf =
false;
313 req_msg->m_is_remote_pf =
false;
314 req_msg->m_allowRetry = phase.allow_retry;
317 req_msg->m_txnId = phase.txn_id + (payload.lpid * 1024);
318 req_msg->m_ns = payload.ns;
323 this, payload, phase);
328 ARM::CHI::Phase &phase)
330 auto data_msg = std::make_shared<CHIDataMsg>(
336 data_msg->m_Destination.add(
338 data_msg->m_txnId = phase.txn_id + (payload.lpid * 1024);
343 const Addr data_id_offset = phase.data_id * 16;
344 for (
int bit = data_id_offset; bit < data_id_offset + 32; bit++) {
345 if (
bits(payload.byte_enable, bit)) {
346 byte_enabled[bit] =
true;
350 data_msg->m_bitMask =
ruby::WriteMask(byte_enabled.size(), byte_enabled);
357 ARM::CHI::Phase &phase)
359 auto res_msg = std::make_shared<CHIResponseMsg>(
366 res_msg->m_txnId = phase.txn_id + (payload.lpid * 1024);
372 ARM::CHI::Payload &_payload,
373 ARM::CHI::Phase &_phase)
374 : controller(_controller), payload(&_payload), phase(_phase)
384std::unique_ptr<CacheController::Transaction>
386 ARM::CHI::Payload &payload,
387 ARM::CHI::Phase &phase)
389 switch (phase.req_opcode) {
390 case ARM::CHI::REQ_OPCODE_READ_SHARED:
391 case ARM::CHI::REQ_OPCODE_READ_CLEAN:
392 case ARM::CHI::REQ_OPCODE_READ_ONCE:
393 case ARM::CHI::REQ_OPCODE_READ_NO_SNP:
394 case ARM::CHI::REQ_OPCODE_READ_UNIQUE:
395 case ARM::CHI::REQ_OPCODE_READ_NOT_SHARED_DIRTY:
396 case ARM::CHI::REQ_OPCODE_READ_PREFER_UNIQUE:
397 case ARM::CHI::REQ_OPCODE_MAKE_READ_UNIQUE:
398 return std::make_unique<ReadTransaction>(controller, payload, phase);
399 case ARM::CHI::REQ_OPCODE_WRITE_NO_SNP_PTL:
400 case ARM::CHI::REQ_OPCODE_WRITE_NO_SNP_FULL:
401 case ARM::CHI::REQ_OPCODE_WRITE_UNIQUE_ZERO:
402 case ARM::CHI::REQ_OPCODE_WRITE_UNIQUE_FULL:
403 case ARM::CHI::REQ_OPCODE_WRITE_BACK_FULL:
407 case ARM::CHI::REQ_OPCODE_WRITE_EVICT_OR_EVICT:
408 return std::make_unique<WriteTransaction>(
409 controller, payload, phase);
410 case ARM::CHI::REQ_OPCODE_CLEAN_UNIQUE:
411 case ARM::CHI::REQ_OPCODE_MAKE_UNIQUE:
412 case ARM::CHI::REQ_OPCODE_EVICT:
413 case ARM::CHI::REQ_OPCODE_STASH_ONCE_SEP_SHARED:
414 case ARM::CHI::REQ_OPCODE_STASH_ONCE_SEP_UNIQUE:
415 return std::make_unique<DatalessTransaction>(
416 controller, payload, phase);
418 panic(
"Impossible to generate transaction object");
ClockedObjectParams Params
Parameters of ClockedObject.
RubySystem * m_ruby_system
MachineID getMachineID() const
MachineID mapAddressToDownstreamMachine(Addr addr, MachineType mtype=MachineType_NUM) const
Maps an address to the correct dowstream MachineID (i.e.
CHI::CHIRequestMsg CHIRequestMsg
CHI::CHIDataMsg CHIDataMsg
CHI::CHIResponseMsg CHIResponseMsg
The tlm::chi::CacheController is a ruby CacheController which acts as a bridge between the AMBA TLM 2...
bool recvRequestMsg(const CHIRequestMsg *msg) override
CacheController(const Params &p)
void sendResponseMsg(ARM::CHI::Payload &payload, ARM::CHI::Phase &phase)
Addr reqSize(ARM::CHI::Payload &payload, ARM::CHI::Phase &phase) const
bool recvDataMsg(const CHIDataMsg *msg) override
void pCreditGrant(const CHIResponseMsg *msg)
bool recvSnoopMsg(const CHIRequestMsg *msg) override
void sendCompAck(ARM::CHI::Payload &payload, ARM::CHI::Phase &phase)
void sendMsg(ARM::CHI::Payload &payload, ARM::CHI::Phase &phase)
bool recvResponseMsg(const CHIResponseMsg *msg) override
void sendDataMsg(ARM::CHI::Payload &payload, ARM::CHI::Phase &phase)
void sendRequestMsg(ARM::CHI::Payload &payload, ARM::CHI::Phase &phase)
Addr reqAddr(ARM::CHI::Payload &payload, ARM::CHI::Phase &phase) const
std::function< void(ARM::CHI::Payload *payload, ARM::CHI::Phase *phase)> bw
Set this to send data upstream.
std::unordered_map< uint16_t, std::unique_ptr< Transaction > > pendingTransactions
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
constexpr int popCount(uint64_t val)
Returns the number of set ones in the provided value.
constexpr int ctz64(uint64_t value)
Count trailing zeros in a 64-bit value.
#define panic(...)
This implements a cprintf based panic() function.
Bitfield< 24, 21 > opcode
Addr makeLineAddress(Addr addr, int cacheLineBits)
uint8_t snpOpcode(CHIRequestType snp)
uint8_t rspOpcode(CHIResponseType rsp)
Resp rspResp(CHIResponseType rsp)
Resp datResp(CHIDataType dat)
uint8_t datOpcode(CHIDataType dat)
CHIDataType datOpcode(DatOpcode dat, Resp resp)
CHIResponseType rspOpcode(RspOpcode opc, Resp resp)
CHIRequestType reqOpcode(ReqOpcode req)
Addr transactionSize(Size sz)
uint8_t dataId(Addr address)
Copyright (c) 2024 Arm Limited All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
bool handle(const CHIResponseMsg *msg) override
bool handle(const CHIDataMsg *msg) override
bool forward(const CHIDataMsg *msg)
ARM::CHI::Payload * payload
CacheController * controller
Transaction(CacheController *parent, ARM::CHI::Payload &_payload, ARM::CHI::Phase &_phase)
static std::unique_ptr< Transaction > gen(CacheController *parent, ARM::CHI::Payload &_payload, ARM::CHI::Phase &_phase)
virtual bool handle(const CHIDataMsg *msg)
bool handle(const CHIResponseMsg *msg) override