1/* 2 * Copyright (c) 2002-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; --- 248 unchanged lines hidden (view full) --- 257 } else { 258 _status = DcacheWaitResponse; 259 // memory system takes ownership of packet 260 dcache_pkt = NULL; 261 } 262 return dcache_pkt == NULL; 263} 264 |
265Fault 266TimingSimpleCPU::buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2, 267 RequestPtr &req, Addr split_addr, uint8_t *data, bool read) 268{ 269 Fault fault; 270 RequestPtr req1, req2; 271 assert(!req->isLocked() && !req->isSwap()); 272 req->splitOnVaddr(split_addr, req1, req2); 273 274 pkt1 = pkt2 = NULL; 275 if ((fault = buildPacket(pkt1, req1, read)) != NoFault || 276 (fault = buildPacket(pkt2, req2, read)) != NoFault) { 277 delete req; 278 delete pkt1; 279 req = NULL; 280 pkt1 = NULL; 281 return fault; 282 } 283 284 assert(!req1->isMmapedIpr() && !req2->isMmapedIpr()); 285 286 req->setPhys(req1->getPaddr(), req->getSize(), req1->getFlags()); 287 PacketPtr pkt = new Packet(req, pkt1->cmd.responseCommand(), 288 Packet::Broadcast); 289 290 pkt->dataDynamic<uint8_t>(data); 291 pkt1->dataStatic<uint8_t>(data); 292 pkt2->dataStatic<uint8_t>(data + req1->getSize()); 293 294 SplitMainSenderState * main_send_state = new SplitMainSenderState; 295 pkt->senderState = main_send_state; 296 main_send_state->fragments[0] = pkt1; 297 main_send_state->fragments[1] = pkt2; 298 main_send_state->outstanding = 2; 299 pkt1->senderState = new SplitFragmentSenderState(pkt, 0); 300 pkt2->senderState = new SplitFragmentSenderState(pkt, 1); 301 return fault; 302} 303 304Fault 305TimingSimpleCPU::buildPacket(PacketPtr &pkt, RequestPtr &req, bool read) 306{ 307 Fault fault = read ? thread->translateDataReadReq(req) : 308 thread->translateDataWriteReq(req); 309 MemCmd cmd; 310 if (fault != NoFault) { 311 delete req; 312 req = NULL; 313 pkt = NULL; 314 return fault; 315 } else if (read) { 316 cmd = MemCmd::ReadReq; 317 if (req->isLocked()) 318 cmd = MemCmd::LoadLockedReq; 319 } else { 320 cmd = MemCmd::WriteReq; 321 if (req->isLocked()) { 322 cmd = MemCmd::StoreCondReq; 323 } else if (req->isSwap()) { 324 cmd = MemCmd::SwapReq; 325 } 326 } 327 pkt = new Packet(req, cmd, Packet::Broadcast); 328 return NoFault; 329} 330 |
331template <class T> 332Fault 333TimingSimpleCPU::read(Addr addr, T &data, unsigned flags) 334{ 335 Fault fault; 336 const int asid = 0; 337 const int thread_id = 0; 338 const Addr pc = thread->readPC(); |
339 int block_size = dcachePort.peerBlockSize(); 340 int data_size = sizeof(T); 341 |
342 PacketPtr pkt; 343 RequestPtr req = new Request(asid, addr, data_size, 344 flags, pc, _cpuId, thread_id); |
345 |
346 Addr split_addr = roundDown(addr + data_size - 1, block_size); 347 assert(split_addr <= addr || split_addr - addr < block_size); |
348 |
349 if (split_addr > addr) { 350 PacketPtr pkt1, pkt2; 351 this->buildSplitPacket(pkt1, pkt2, req, 352 split_addr, (uint8_t *)(new T), true); 353 if (handleReadPacket(pkt1)) { 354 SplitFragmentSenderState * send_state = 355 dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState); 356 send_state->clearFromParent(); 357 if (handleReadPacket(pkt2)) { 358 send_state = 359 dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState); 360 send_state->clearFromParent(); 361 } |
362 } |
363 } else { |
364 Fault fault = buildPacket(pkt, req, true); |
365 if (fault != NoFault) { |
366 return fault; 367 } |
368 pkt->dataDynamic<T>(new T); 369 370 handleReadPacket(pkt); 371 } 372 373 if (traceData) { 374 traceData->setData(data); 375 traceData->setAddr(addr); --- 97 unchanged lines hidden (view full) --- 473} 474 475template <class T> 476Fault 477TimingSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) 478{ 479 const int asid = 0; 480 const int thread_id = 0; |
481 const Addr pc = thread->readPC(); |
482 int block_size = dcachePort.peerBlockSize(); 483 int data_size = sizeof(T); 484 |
485 RequestPtr req = new Request(asid, addr, data_size, 486 flags, pc, _cpuId, thread_id); |
487 |
488 Addr split_addr = roundDown(addr + data_size - 1, block_size); 489 assert(split_addr <= addr || split_addr - addr < block_size); |
490 |
491 if (split_addr > addr) { 492 PacketPtr pkt1, pkt2; 493 T *dataP = new T; 494 *dataP = data; 495 Fault fault = this->buildSplitPacket(pkt1, pkt2, req, split_addr, 496 (uint8_t *)dataP, false); 497 if (fault != NoFault) |
498 return fault; |
499 dcache_pkt = pkt1; 500 if (handleWritePacket()) { 501 SplitFragmentSenderState * send_state = 502 dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState); 503 send_state->clearFromParent(); 504 dcache_pkt = pkt2; 505 if (handleReadPacket(pkt2)) { 506 send_state = 507 dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState); 508 send_state->clearFromParent(); 509 } |
510 } |
511 } else { |
512 bool do_access = true; // flag to suppress cache access |
513 |
514 Fault fault = buildPacket(dcache_pkt, req, false); 515 if (fault != NoFault) |
516 return fault; |
517 |
518 if (req->isLocked()) { |
519 do_access = TheISA::handleLockedWrite(thread, req); |
520 } else if (req->isCondSwap()) { 521 assert(res); 522 req->setExtraData(*res); |
523 } 524 |
525 dcache_pkt->allocate(); 526 if (req->isMmapedIpr()) 527 dcache_pkt->set(htog(data)); 528 else 529 dcache_pkt->set(data); 530 531 if (do_access) 532 handleWritePacket(); --- 505 unchanged lines hidden --- |