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; --- 261 unchanged lines hidden (view full) --- 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 req1; |
279 delete pkt1; 280 req = NULL; 281 pkt1 = NULL; 282 return fault; 283 } 284 285 assert(!req1->isMmapedIpr() && !req2->isMmapedIpr()); 286 287 req->setPhys(req1->getPaddr(), req->getSize(), req1->getFlags()); 288 PacketPtr pkt = new Packet(req, pkt1->cmd.responseCommand(), 289 Packet::Broadcast); |
290 if (req->getFlags().isSet(Request::NO_ACCESS)) { 291 delete req1; 292 delete pkt1; 293 delete req2; 294 delete pkt2; 295 pkt1 = pkt; 296 pkt2 = NULL; 297 return NoFault; 298 } |
299 300 pkt->dataDynamic<uint8_t>(data); 301 pkt1->dataStatic<uint8_t>(data); 302 pkt2->dataStatic<uint8_t>(data + req1->getSize()); 303 304 SplitMainSenderState * main_send_state = new SplitMainSenderState; 305 pkt->senderState = main_send_state; 306 main_send_state->fragments[0] = pkt1; 307 main_send_state->fragments[1] = pkt2; 308 main_send_state->outstanding = 2; 309 pkt1->senderState = new SplitFragmentSenderState(pkt, 0); 310 pkt2->senderState = new SplitFragmentSenderState(pkt, 1); 311 return fault; 312} 313 314Fault 315TimingSimpleCPU::buildPacket(PacketPtr &pkt, RequestPtr &req, bool read) 316{ |
317 Fault fault = thread->dtb->translate(req, tc, !read); |
318 MemCmd cmd; 319 if (fault != NoFault) { 320 delete req; 321 req = NULL; 322 pkt = NULL; 323 return fault; 324 } else if (read) { 325 cmd = MemCmd::ReadReq; --- 26 unchanged lines hidden (view full) --- 352 RequestPtr req = new Request(asid, addr, data_size, 353 flags, pc, _cpuId, thread_id); 354 355 Addr split_addr = roundDown(addr + data_size - 1, block_size); 356 assert(split_addr <= addr || split_addr - addr < block_size); 357 358 if (split_addr > addr) { 359 PacketPtr pkt1, pkt2; |
360 Fault fault = this->buildSplitPacket(pkt1, pkt2, req, |
361 split_addr, (uint8_t *)(new T), true); |
362 if (fault != NoFault) 363 return fault; 364 if (req->getFlags().isSet(Request::NO_ACCESS)) { 365 dcache_pkt = pkt1; 366 } else if (handleReadPacket(pkt1)) { |
367 SplitFragmentSenderState * send_state = 368 dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState); 369 send_state->clearFromParent(); 370 if (handleReadPacket(pkt2)) { 371 send_state = 372 dynamic_cast<SplitFragmentSenderState *>(pkt1->senderState); 373 send_state->clearFromParent(); 374 } 375 } 376 } else { 377 Fault fault = buildPacket(pkt, req, true); 378 if (fault != NoFault) { 379 return fault; 380 } |
381 if (req->getFlags().isSet(Request::NO_ACCESS)) { 382 dcache_pkt = pkt; 383 } else { 384 pkt->dataDynamic<T>(new T); 385 handleReadPacket(pkt); 386 } |
387 } 388 389 if (traceData) { 390 traceData->setData(data); 391 traceData->setAddr(addr); 392 } 393 394 // This will need a new way to tell if it has a dcache attached. 395 if (req->isUncacheable()) 396 recordEvent("Uncached Read"); 397 398 return NoFault; 399} 400 |
401#ifndef DOXYGEN_SHOULD_SKIP_THIS 402 403template 404Fault 405TimingSimpleCPU::read(Addr addr, Twin64_t &data, unsigned flags); 406 407template 408Fault --- 79 unchanged lines hidden (view full) --- 488 PacketPtr pkt1, pkt2; 489 T *dataP = new T; 490 *dataP = data; 491 Fault fault = this->buildSplitPacket(pkt1, pkt2, req, split_addr, 492 (uint8_t *)dataP, false); 493 if (fault != NoFault) 494 return fault; 495 dcache_pkt = pkt1; |
496 if (!req->getFlags().isSet(Request::NO_ACCESS)) { 497 if (handleWritePacket()) { 498 SplitFragmentSenderState * send_state = 499 dynamic_cast<SplitFragmentSenderState *>( 500 pkt1->senderState); |
501 send_state->clearFromParent(); |
502 dcache_pkt = pkt2; 503 if (handleReadPacket(pkt2)) { 504 send_state = 505 dynamic_cast<SplitFragmentSenderState *>( 506 pkt1->senderState); 507 send_state->clearFromParent(); 508 } |
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->getFlags().isSet(Request::NO_ACCESS)) { 519 if (req->isLocked()) { 520 do_access = TheISA::handleLockedWrite(thread, req); 521 } else if (req->isCondSwap()) { 522 assert(res); 523 req->setExtraData(*res); 524 } |
525 |
526 dcache_pkt->allocate(); 527 if (req->isMmapedIpr()) 528 dcache_pkt->set(htog(data)); 529 else 530 dcache_pkt->set(data); |
531 |
532 if (do_access) 533 handleWritePacket(); 534 } |
535 } 536 537 if (traceData) { 538 traceData->setAddr(req->getVaddr()); 539 traceData->setData(data); 540 } 541 542 // This will need a new way to tell if it's hooked up to a cache or not. 543 if (req->isUncacheable()) 544 recordEvent("Uncached Write"); 545 546 // If the write needs to have a fault on the access, consider calling 547 // changeStatus() and changing it to "bad addr write" or something. 548 return NoFault; 549} 550 |
551 |
552#ifndef DOXYGEN_SHOULD_SKIP_THIS 553template 554Fault 555TimingSimpleCPU::write(Twin32_t data, Addr addr, 556 unsigned flags, uint64_t *res); 557 558template 559Fault --- 460 unchanged lines hidden --- |