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 --- |