RubyPort.cc (6899:f8057af86bf7) RubyPort.cc (6922:1620cffaa3b6)
1
2/*
3 * Copyright (c) 2009 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "mem/physical.hh"
31#include "mem/ruby/system/RubyPort.hh"
32#include "mem/ruby/slicc_interface/AbstractController.hh"
33#include "cpu/rubytest/RubyTester.hh"
34
1
2/*
3 * Copyright (c) 2009 Advanced Micro Devices, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "mem/physical.hh"
31#include "mem/ruby/system/RubyPort.hh"
32#include "mem/ruby/slicc_interface/AbstractController.hh"
33#include "cpu/rubytest/RubyTester.hh"
34
35uint16_t RubyPort::m_num_ports = 0;
36
37RubyPort::RequestMap RubyPort::pending_cpu_requests;
38
39RubyPort::RubyPort(const Params *p)
40 : MemObject(p)
41{
42 m_version = p->version;
43 assert(m_version != -1);
44
45 physmem = p->physmem;
46
47 m_controller = NULL;
48 m_mandatory_q_ptr = NULL;
49
35RubyPort::RubyPort(const Params *p)
36 : MemObject(p)
37{
38 m_version = p->version;
39 assert(m_version != -1);
40
41 physmem = p->physmem;
42
43 m_controller = NULL;
44 m_mandatory_q_ptr = NULL;
45
50 m_port_id = m_num_ports++;
51 m_request_cnt = 0;
46 m_request_cnt = 0;
52 m_hit_callback = ruby_hit_callback;
53 pio_port = NULL;
54 physMemPort = NULL;
47 pio_port = NULL;
48 physMemPort = NULL;
55 assert(m_num_ports <= 2048); // see below for reason
56}
57
58void RubyPort::init()
59{
60 assert(m_controller != NULL);
61 m_mandatory_q_ptr = m_controller->getMandatoryQueue();
62}
63

--- 100 unchanged lines hidden (view full) ---

164{
165 DPRINTF(MemoryAccess,
166 "Timing access caught for address %#x\n",
167 pkt->getAddr());
168
169 //dsm: based on SimpleTimingPort::recvTiming(pkt);
170
171 //
49}
50
51void RubyPort::init()
52{
53 assert(m_controller != NULL);
54 m_mandatory_q_ptr = m_controller->getMandatoryQueue();
55}
56

--- 100 unchanged lines hidden (view full) ---

157{
158 DPRINTF(MemoryAccess,
159 "Timing access caught for address %#x\n",
160 pkt->getAddr());
161
162 //dsm: based on SimpleTimingPort::recvTiming(pkt);
163
164 //
172 // After checking for pio responses, the remainder of packets
173 // received by ruby should only be M5 requests, which should never
165 // The received packets should only be M5 requests, which should never
174 // get nacked. There used to be code to hanldle nacks here, but
175 // I'm pretty sure it didn't work correctly with the drain code,
176 // so that would need to be fixed if we ever added it back.
177 //
178 assert(pkt->isRequest());
179
180 if (pkt->memInhibitAsserted()) {
181 warn("memInhibitAsserted???");
182 // snooper will supply based on copy of packet
183 // still target's responsibility to delete packet
184 delete pkt;
185 return true;
186 }
187
188 //
166 // get nacked. There used to be code to hanldle nacks here, but
167 // I'm pretty sure it didn't work correctly with the drain code,
168 // so that would need to be fixed if we ever added it back.
169 //
170 assert(pkt->isRequest());
171
172 if (pkt->memInhibitAsserted()) {
173 warn("memInhibitAsserted???");
174 // snooper will supply based on copy of packet
175 // still target's responsibility to delete packet
176 delete pkt;
177 return true;
178 }
179
180 //
181 // Save the port in the sender state object to be used later to
182 // route the response
183 //
184 pkt->senderState = new SenderState(this, pkt->senderState);
185
186 //
189 // Check for pio requests and directly send them to the dedicated
190 // pio port.
191 //
192 if (!isPhysMemAddress(pkt->getAddr())) {
193 assert(ruby_port->pio_port != NULL);
187 // Check for pio requests and directly send them to the dedicated
188 // pio port.
189 //
190 if (!isPhysMemAddress(pkt->getAddr())) {
191 assert(ruby_port->pio_port != NULL);
192 DPRINTF(MemoryAccess,
193 "Request for address 0x%#x is assumed to be a pio request\n",
194 pkt->getAddr());
194
195
195 //
196 // Save the port in the sender state object to be used later to
197 // route the response
198 //
199 pkt->senderState = new SenderState(this, pkt->senderState);
200
201 return ruby_port->pio_port->sendTiming(pkt);
202 }
203
204 //
205 // For DMA and CPU requests, translate them to ruby requests before
206 // sending them to our assigned ruby port.
207 //
208 RubyRequestType type = RubyRequestType_NULL;

--- 11 unchanged lines hidden (view full) ---

220 type = RubyRequestType_IFETCH;
221 } else {
222 type = RubyRequestType_LD;
223 }
224 } else if (pkt->isWrite()) {
225 type = RubyRequestType_ST;
226 } else if (pkt->isReadWrite()) {
227 type = RubyRequestType_RMW_Write;
196 return ruby_port->pio_port->sendTiming(pkt);
197 }
198
199 //
200 // For DMA and CPU requests, translate them to ruby requests before
201 // sending them to our assigned ruby port.
202 //
203 RubyRequestType type = RubyRequestType_NULL;

--- 11 unchanged lines hidden (view full) ---

215 type = RubyRequestType_IFETCH;
216 } else {
217 type = RubyRequestType_LD;
218 }
219 } else if (pkt->isWrite()) {
220 type = RubyRequestType_ST;
221 } else if (pkt->isReadWrite()) {
222 type = RubyRequestType_RMW_Write;
223 } else {
224 panic("Unsupported ruby packet type\n");
228 }
229
225 }
226
230 RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
231 pkt->getSize(), pc, type,
232 RubyAccessMode_Supervisor);
227 RubyRequest ruby_request(pkt->getAddr(),
228 pkt->getPtr<uint8_t>(),
229 pkt->getSize(),
230 pc,
231 type,
232 RubyAccessMode_Supervisor,
233 pkt);
233
234 // Submit the ruby request
234
235 // Submit the ruby request
235 int64_t req_id = ruby_port->makeRequest(ruby_request);
236 if (req_id == -1) {
237 return false;
236 RequestStatus requestStatus = ruby_port->makeRequest(ruby_request);
237 if (requestStatus == RequestStatus_Issued) {
238 return true;
238 }
239 }
239
240 // Save the request for the callback
241 RubyPort::pending_cpu_requests[req_id] = new RequestCookie(pkt, this);
242
243 return true;
240
241 DPRINTF(MemoryAccess,
242 "Request for address #x did not issue because %s\n",
243 pkt->getAddr(),
244 RequestStatus_to_string(requestStatus));
245
246 SenderState* senderState = safe_cast<SenderState*>(pkt->senderState);
247 pkt->senderState = senderState->saved;
248 delete senderState;
249 return false;
244}
245
246void
250}
251
252void
247RubyPort::ruby_hit_callback(int64_t req_id)
253RubyPort::ruby_hit_callback(PacketPtr pkt)
248{
249 //
254{
255 //
250 // Note: This single fuction can be called by cpu and dma ports,
251 // as well as the functional port.
256 // Retrieve the request port from the sender State
252 //
257 //
253 RequestMap::iterator i = pending_cpu_requests.find(req_id);
254 if (i == pending_cpu_requests.end())
255 panic("could not find pending request %d\n", req_id);
258 RubyPort::SenderState *senderState =
259 safe_cast<RubyPort::SenderState *>(pkt->senderState);
260 M5Port *port = senderState->port;
261 assert(port != NULL);
262
263 // pop the sender state from the packet
264 pkt->senderState = senderState->saved;
265 delete senderState;
256
266
257 RequestCookie *cookie = i->second;
258 pending_cpu_requests.erase(i);
259
260 Packet *pkt = cookie->pkt;
261 M5Port *port = cookie->m5Port;
262 delete cookie;
263
264 port->hitCallback(pkt);
265}
266
267void
268RubyPort::M5Port::hitCallback(PacketPtr pkt)
269{
270
271 bool needsResponse = pkt->needsResponse();

--- 50 unchanged lines hidden ---
267 port->hitCallback(pkt);
268}
269
270void
271RubyPort::M5Port::hitCallback(PacketPtr pkt)
272{
273
274 bool needsResponse = pkt->needsResponse();

--- 50 unchanged lines hidden ---