physical.cc (4490:f9d3db907eec) physical.cc (4626:ed8aacb19c03)
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

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

53
54PhysicalMemory::PhysicalMemory(Params *p)
55 : MemObject(p->name), pmemAddr(NULL), lat(p->latency), _params(p)
56{
57 if (params()->addrRange.size() % TheISA::PageBytes != 0)
58 panic("Memory Size not divisible by page size\n");
59
60 int map_flags = MAP_ANON | MAP_PRIVATE;
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

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

53
54PhysicalMemory::PhysicalMemory(Params *p)
55 : MemObject(p->name), pmemAddr(NULL), lat(p->latency), _params(p)
56{
57 if (params()->addrRange.size() % TheISA::PageBytes != 0)
58 panic("Memory Size not divisible by page size\n");
59
60 int map_flags = MAP_ANON | MAP_PRIVATE;
61 pmemAddr = (uint8_t *)mmap(NULL, params()->addrRange.size(), PROT_READ | PROT_WRITE,
62 map_flags, -1, 0);
61 pmemAddr =
62 (uint8_t *)mmap(NULL, params()->addrRange.size(),
63 PROT_READ | PROT_WRITE, map_flags, -1, 0);
63
64 if (pmemAddr == (void *)MAP_FAILED) {
65 perror("mmap");
66 fatal("Could not mmap!\n");
67 }
68
69 //If requested, initialize all the memory to 0
70 if(params()->zero)

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

116 return lat;
117}
118
119
120
121// Add load-locked to tracking list. Should only be called if the
122// operation is a load and the LOCKED flag is set.
123void
64
65 if (pmemAddr == (void *)MAP_FAILED) {
66 perror("mmap");
67 fatal("Could not mmap!\n");
68 }
69
70 //If requested, initialize all the memory to 0
71 if(params()->zero)

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

117 return lat;
118}
119
120
121
122// Add load-locked to tracking list. Should only be called if the
123// operation is a load and the LOCKED flag is set.
124void
124PhysicalMemory::trackLoadLocked(Request *req)
125PhysicalMemory::trackLoadLocked(PacketPtr pkt)
125{
126{
127 Request *req = pkt->req;
126 Addr paddr = LockedAddr::mask(req->getPaddr());
127
128 // first we check if we already have a locked addr for this
129 // xc. Since each xc only gets one, we just update the
130 // existing record with the new address.
131 list<LockedAddr>::iterator i;
132
133 for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) {

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

146}
147
148
149// Called on *writes* only... both regular stores and
150// store-conditional operations. Check for conventional stores which
151// conflict with locked addresses, and for success/failure of store
152// conditionals.
153bool
128 Addr paddr = LockedAddr::mask(req->getPaddr());
129
130 // first we check if we already have a locked addr for this
131 // xc. Since each xc only gets one, we just update the
132 // existing record with the new address.
133 list<LockedAddr>::iterator i;
134
135 for (i = lockedAddrList.begin(); i != lockedAddrList.end(); ++i) {

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

148}
149
150
151// Called on *writes* only... both regular stores and
152// store-conditional operations. Check for conventional stores which
153// conflict with locked addresses, and for success/failure of store
154// conditionals.
155bool
154PhysicalMemory::checkLockedAddrList(Request *req)
156PhysicalMemory::checkLockedAddrList(PacketPtr pkt)
155{
157{
158 Request *req = pkt->req;
156 Addr paddr = LockedAddr::mask(req->getPaddr());
159 Addr paddr = LockedAddr::mask(req->getPaddr());
157 bool isLocked = req->isLocked();
160 bool isLocked = pkt->isLocked();
158
159 // Initialize return value. Non-conditional stores always
160 // succeed. Assume conditional stores will fail until proven
161 // otherwise.
162 bool success = !isLocked;
163
164 // Iterate over list. Note that there could be multiple matching
165 // records, as more than one context could have done a load locked

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

193
194 if (isLocked) {
195 req->setExtraData(success ? 1 : 0);
196 }
197
198 return success;
199}
200
161
162 // Initialize return value. Non-conditional stores always
163 // succeed. Assume conditional stores will fail until proven
164 // otherwise.
165 bool success = !isLocked;
166
167 // Iterate over list. Note that there could be multiple matching
168 // records, as more than one context could have done a load locked

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

196
197 if (isLocked) {
198 req->setExtraData(success ? 1 : 0);
199 }
200
201 return success;
202}
203
201void
202PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
204
205#if TRACING_ON
206
207#define CASE(A, T) \
208 case sizeof(T): \
209 DPRINTF(MemoryAccess, A " of size %i on address 0x%x data 0x%x\n", \
210 pkt->getSize(), pkt->getAddr(), pkt->get<T>()); \
211 break
212
213
214#define TRACE_PACKET(A) \
215 do { \
216 switch (pkt->getSize()) { \
217 CASE(A, uint64_t); \
218 CASE(A, uint32_t); \
219 CASE(A, uint16_t); \
220 CASE(A, uint8_t); \
221 default: \
222 DPRINTF(MemoryAccess, A " of size %i on address 0x%x\n", \
223 pkt->getSize(), pkt->getAddr()); \
224 } \
225 } while (0)
226
227#else
228
229#define TRACE_PACKET(A)
230
231#endif
232
233Tick
234PhysicalMemory::doAtomicAccess(PacketPtr pkt)
203{
204 assert(pkt->getAddr() >= start() &&
205 pkt->getAddr() + pkt->getSize() <= start() + size());
206
235{
236 assert(pkt->getAddr() >= start() &&
237 pkt->getAddr() + pkt->getSize() <= start() + size());
238
207 if (pkt->isRead()) {
208 if (pkt->req->isLocked()) {
209 trackLoadLocked(pkt->req);
210 }
211 memcpy(pkt->getPtr<uint8_t>(), pmemAddr + pkt->getAddr() - start(),
212 pkt->getSize());
213#if TRACING_ON
214 switch (pkt->getSize()) {
215 case sizeof(uint64_t):
216 DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
217 pkt->getSize(), pkt->getAddr(),pkt->get<uint64_t>());
218 break;
219 case sizeof(uint32_t):
220 DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
221 pkt->getSize(), pkt->getAddr(),pkt->get<uint32_t>());
222 break;
223 case sizeof(uint16_t):
224 DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
225 pkt->getSize(), pkt->getAddr(),pkt->get<uint16_t>());
226 break;
227 case sizeof(uint8_t):
228 DPRINTF(MemoryAccess, "Read of size %i on address 0x%x data 0x%x\n",
229 pkt->getSize(), pkt->getAddr(),pkt->get<uint8_t>());
230 break;
231 default:
232 DPRINTF(MemoryAccess, "Read of size %i on address 0x%x\n",
233 pkt->getSize(), pkt->getAddr());
234 }
235#endif
239 if (pkt->memInhibitAsserted()) {
240 DPRINTF(MemoryAccess, "mem inhibited on 0x%x: not responding\n",
241 pkt->getAddr());
242 return 0;
236 }
243 }
237 else if (pkt->isWrite()) {
238 if (writeOK(pkt->req)) {
239 memcpy(pmemAddr + pkt->getAddr() - start(), pkt->getPtr<uint8_t>(),
240 pkt->getSize());
241#if TRACING_ON
242 switch (pkt->getSize()) {
243 case sizeof(uint64_t):
244 DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
245 pkt->getSize(), pkt->getAddr(),pkt->get<uint64_t>());
246 break;
247 case sizeof(uint32_t):
248 DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
249 pkt->getSize(), pkt->getAddr(),pkt->get<uint32_t>());
250 break;
251 case sizeof(uint16_t):
252 DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
253 pkt->getSize(), pkt->getAddr(),pkt->get<uint16_t>());
254 break;
255 case sizeof(uint8_t):
256 DPRINTF(MemoryAccess, "Write of size %i on address 0x%x data 0x%x\n",
257 pkt->getSize(), pkt->getAddr(),pkt->get<uint8_t>());
258 break;
259 default:
260 DPRINTF(MemoryAccess, "Write of size %i on address 0x%x\n",
261 pkt->getSize(), pkt->getAddr());
262 }
263#endif
264 }
265 } else if (pkt->isInvalidate()) {
266 //upgrade or invalidate
267 pkt->flags |= SATISFIED;
268 } else if (pkt->isReadWrite()) {
244
245 uint8_t *hostAddr = pmemAddr + pkt->getAddr() - start();
246
247 if (pkt->cmd == MemCmd::SwapReq) {
269 IntReg overwrite_val;
270 bool overwrite_mem;
271 uint64_t condition_val64;
272 uint32_t condition_val32;
273
274 assert(sizeof(IntReg) >= pkt->getSize());
275
276 overwrite_mem = true;
277 // keep a copy of our possible write value, and copy what is at the
278 // memory address into the packet
279 std::memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize());
248 IntReg overwrite_val;
249 bool overwrite_mem;
250 uint64_t condition_val64;
251 uint32_t condition_val32;
252
253 assert(sizeof(IntReg) >= pkt->getSize());
254
255 overwrite_mem = true;
256 // keep a copy of our possible write value, and copy what is at the
257 // memory address into the packet
258 std::memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize());
280 std::memcpy(pkt->getPtr<uint8_t>(), pmemAddr + pkt->getAddr() - start(),
281 pkt->getSize());
259 std::memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
282
283 if (pkt->req->isCondSwap()) {
284 if (pkt->getSize() == sizeof(uint64_t)) {
285 condition_val64 = pkt->req->getExtraData();
260
261 if (pkt->req->isCondSwap()) {
262 if (pkt->getSize() == sizeof(uint64_t)) {
263 condition_val64 = pkt->req->getExtraData();
286 overwrite_mem = !std::memcmp(&condition_val64, pmemAddr +
287 pkt->getAddr() - start(), sizeof(uint64_t));
264 overwrite_mem = !std::memcmp(&condition_val64, hostAddr,
265 sizeof(uint64_t));
288 } else if (pkt->getSize() == sizeof(uint32_t)) {
289 condition_val32 = (uint32_t)pkt->req->getExtraData();
266 } else if (pkt->getSize() == sizeof(uint32_t)) {
267 condition_val32 = (uint32_t)pkt->req->getExtraData();
290 overwrite_mem = !std::memcmp(&condition_val32, pmemAddr +
291 pkt->getAddr() - start(), sizeof(uint32_t));
268 overwrite_mem = !std::memcmp(&condition_val32, hostAddr,
269 sizeof(uint32_t));
292 } else
293 panic("Invalid size for conditional read/write\n");
294 }
295
296 if (overwrite_mem)
270 } else
271 panic("Invalid size for conditional read/write\n");
272 }
273
274 if (overwrite_mem)
297 std::memcpy(pmemAddr + pkt->getAddr() - start(),
298 &overwrite_val, pkt->getSize());
275 std::memcpy(hostAddr, &overwrite_val, pkt->getSize());
299
276
300#if TRACING_ON
301 switch (pkt->getSize()) {
302 case sizeof(uint64_t):
303 DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
304 pkt->getSize(), pkt->getAddr(),pkt->get<uint64_t>());
305 DPRINTF(MemoryAccess, "New Data 0x%x %s conditional (0x%x) and %s \n",
306 overwrite_mem, pkt->req->isCondSwap() ? "was" : "wasn't",
307 condition_val64, overwrite_mem ? "happened" : "didn't happen");
308 break;
309 case sizeof(uint32_t):
310 DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
311 pkt->getSize(), pkt->getAddr(),pkt->get<uint32_t>());
312 DPRINTF(MemoryAccess, "New Data 0x%x %s conditional (0x%x) and %s \n",
313 overwrite_mem, pkt->req->isCondSwap() ? "was" : "wasn't",
314 condition_val32, overwrite_mem ? "happened" : "didn't happen");
315 break;
316 case sizeof(uint16_t):
317 DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
318 pkt->getSize(), pkt->getAddr(),pkt->get<uint16_t>());
319 DPRINTF(MemoryAccess, "New Data 0x%x wasn't conditional and happned\n",
320 overwrite_mem);
321 break;
322 case sizeof(uint8_t):
323 DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x old data 0x%x\n",
324 pkt->getSize(), pkt->getAddr(),pkt->get<uint8_t>());
325 DPRINTF(MemoryAccess, "New Data 0x%x wasn't conditional and happned\n",
326 overwrite_mem);
327 break;
328 default:
329 DPRINTF(MemoryAccess, "Read/Write of size %i on address 0x%x\n",
330 pkt->getSize(), pkt->getAddr());
277 TRACE_PACKET("Read/Write");
278 } else if (pkt->isRead()) {
279 assert(!pkt->isWrite());
280 if (pkt->isLocked()) {
281 trackLoadLocked(pkt);
331 }
282 }
332#endif
283 memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
284 TRACE_PACKET("Read");
285 } else if (pkt->isWrite()) {
286 if (writeOK(pkt)) {
287 memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
288 TRACE_PACKET("Write");
289 }
290 } else if (pkt->isInvalidate()) {
291 //upgrade or invalidate
292 if (pkt->needsResponse()) {
293 pkt->makeAtomicResponse();
294 }
333 } else {
334 panic("unimplemented");
335 }
336
295 } else {
296 panic("unimplemented");
297 }
298
299 if (pkt->needsResponse()) {
300 pkt->makeAtomicResponse();
301 }
302 return calculateLatency(pkt);
303}
304
305
306void
307PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
308{
309 assert(pkt->getAddr() >= start() &&
310 pkt->getAddr() + pkt->getSize() <= start() + size());
311
312 uint8_t *hostAddr = pmemAddr + pkt->getAddr() - start();
313
314 if (pkt->cmd == MemCmd::ReadReq) {
315 memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
316 TRACE_PACKET("Read");
317 } else if (pkt->cmd == MemCmd::WriteReq) {
318 memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
319 TRACE_PACKET("Write");
320 } else {
321 panic("PhysicalMemory: unimplemented functional command %s",
322 pkt->cmdString());
323 }
324
337 pkt->result = Packet::Success;
338}
339
325 pkt->result = Packet::Success;
326}
327
328
340Port *
341PhysicalMemory::getPort(const std::string &if_name, int idx)
342{
343 // Accept request for "functional" port for backwards compatibility
344 // with places where this function is called from C++. I'd prefer
345 // to move all these into Python someday.
346 if (if_name == "functional") {
347 return new MemoryPort(csprintf("%s-functional", name()), this);

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

402PhysicalMemory::MemoryPort::deviceBlockSize()
403{
404 return memory->deviceBlockSize();
405}
406
407Tick
408PhysicalMemory::MemoryPort::recvAtomic(PacketPtr pkt)
409{
329Port *
330PhysicalMemory::getPort(const std::string &if_name, int idx)
331{
332 // Accept request for "functional" port for backwards compatibility
333 // with places where this function is called from C++. I'd prefer
334 // to move all these into Python someday.
335 if (if_name == "functional") {
336 return new MemoryPort(csprintf("%s-functional", name()), this);

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

391PhysicalMemory::MemoryPort::deviceBlockSize()
392{
393 return memory->deviceBlockSize();
394}
395
396Tick
397PhysicalMemory::MemoryPort::recvAtomic(PacketPtr pkt)
398{
410 memory->doFunctionalAccess(pkt);
411 return memory->calculateLatency(pkt);
399 return memory->doAtomicAccess(pkt);
412}
413
414void
415PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt)
416{
417 checkFunctional(pkt);
418
419 // Default implementation of SimpleTimingPort::recvFunctional()

--- 156 unchanged lines hidden ---
400}
401
402void
403PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt)
404{
405 checkFunctional(pkt);
406
407 // Default implementation of SimpleTimingPort::recvFunctional()

--- 156 unchanged lines hidden ---