// Called from the processor on a memory write (can be any size with write-through/around) // Just queues the request. bool CDMA::Cache::Write(MCID id, MemAddr address, const MemData& data, WClientID wid) { assert(address % m_lineSize == 0); // We need to arbitrate between the different processes on the cache, // and then between the different clients. There are 2 arbitrators for this. if (!p_bus.Invoke()) { // Arbitration failed DeadlockWrite("Unable to acquire bus for write"); return false; } Request req; req.address = address; req.write = true; req.client = id; req.wid = wid; COMMIT{ std::copy(data.data, data.data + m_lineSize, req.mdata.data); std::copy(data.mask, data.mask + m_lineSize, req.mdata.mask); } // Client should have been registered assert(m_clients[req.client] != NULL); if (!m_requests.Push(req)) { // Buffer was full DeadlockWrite("Unable to push write request into buffer"); return false; } // Snoop the write back to the other clients for (size_t i = 0; i < m_clients.size(); ++i) { IMemoryCallback* client = m_clients[i]; if (client != NULL && i != req.client) { if (!client->OnMemorySnooped(req.address, req.mdata.data, req.mdata.mask)) { DeadlockWrite("Unable to snoop data to cache clients"); return false; } } } return true; }
// Called from the processor on a memory write (can be any size with write-through/around) // Just queues the request. bool ZLCDMA::Cache::Write(MCID id, MemAddr address, const MemData& data, WClientID wid) { // This method can get called by several 'listeners', so we need // to arbitrate and store the request in a buffer to handle it. if (!p_bus.Invoke()) { // Arbitration failed DeadlockWrite("Unable to acquire bus for write"); return false; } Request req; req.address = address; req.write = true; req.client = id; req.wid = wid; COMMIT{ std::copy(data.data, data.data + m_lineSize, req.mdata.data); std::copy(data.mask, data.mask + m_lineSize, req.mdata.mask); } // Client should have been registered assert(m_clients[req.client] != NULL); if (!m_requests.Push(req)) { // Buffer was full DeadlockWrite("Unable to push write request into buffer"); return false; } // Snoop the write back to the other clients for (size_t i = 0; i < m_clients.size(); ++i) { IMemoryCallback* client = m_clients[i]; if (client != NULL && i != req.client) { if (!client->OnMemorySnooped(req.address, req.mdata.data, req.mdata.mask)) { DeadlockWrite("Unable to snoop data to cache clients"); return false; } } } return true; }