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;
--- 300 unchanged lines hidden (view full) ---
309 dataSize = secondAddr - addr; 310 311 dcache_latency = 0; 312 313 while(1) { 314 req->setVirt(0, addr, dataSize, flags, thread->readPC()); 315 316 // translate to physical address
|
317 Fault fault = thread->translateDataReadReq(req);
|
317 Fault fault = thread->dtb->translate(req, tc, false); |
318 319 // Now do the access. 320 if (fault == NoFault) { 321 Packet pkt = Packet(req, 322 req->isLocked() ? MemCmd::LoadLockedReq : MemCmd::ReadReq, 323 Packet::Broadcast); 324 pkt.dataStatic(dataPtr); 325
--- 39 unchanged lines hidden (view full) ---
365 dataPtr += dataSize; 366 //Adjust the size to get the remaining bytes. 367 dataSize = addr + sizeof(T) - secondAddr; 368 //And access the right address. 369 addr = secondAddr; 370 } 371} 372
|
373Fault
374AtomicSimpleCPU::translateDataReadAddr(Addr vaddr, Addr & paddr,
375 int size, unsigned flags)
376{
377 // use the CPU's statically allocated read request and packet objects
378 Request *req = &data_read_req;
379
380 if (traceData) {
381 traceData->setAddr(vaddr);
382 }
383
384 //The block size of our peer.
385 int blockSize = dcachePort.peerBlockSize();
386 //The size of the data we're trying to read.
387 int dataSize = size;
388
389 bool firstTimeThrough = true;
390
391 //The address of the second part of this access if it needs to be split
392 //across a cache line boundary.
393 Addr secondAddr = roundDown(vaddr + dataSize - 1, blockSize);
394
395 if(secondAddr > vaddr)
396 dataSize = secondAddr - vaddr;
397
398 while(1) {
399 req->setVirt(0, vaddr, dataSize, flags, thread->readPC());
400
401 // translate to physical address
402 Fault fault = thread->translateDataReadReq(req);
403
404 //If there's a fault, return it
405 if (fault != NoFault)
406 return fault;
407
408 if (firstTimeThrough) {
409 paddr = req->getPaddr();
410 firstTimeThrough = false;
411 }
412
413 //If we don't need to access a second cache line, stop now.
414 if (secondAddr <= vaddr)
415 return fault;
416
417 /*
418 * Set up for accessing the second cache line.
419 */
420
421 //Adjust the size to get the remaining bytes.
422 dataSize = vaddr + size - secondAddr;
423 //And access the right address.
424 vaddr = secondAddr;
425 }
426}
427
|
373#ifndef DOXYGEN_SHOULD_SKIP_THIS 374 375template 376Fault 377AtomicSimpleCPU::read(Addr addr, Twin32_t &data, unsigned flags); 378 379template 380Fault
--- 66 unchanged lines hidden (view full) ---
447 dataSize = secondAddr - addr; 448 449 dcache_latency = 0; 450 451 while(1) { 452 req->setVirt(0, addr, dataSize, flags, thread->readPC()); 453 454 // translate to physical address
|
510 Fault fault = thread->translateDataWriteReq(req);
|
455 Fault fault = thread->dtb->translate(req, tc, true); |
456 457 // Now do the access. 458 if (fault == NoFault) { 459 MemCmd cmd = MemCmd::WriteReq; // default 460 bool do_access = true; // flag to suppress cache access 461 462 if (req->isLocked()) { 463 cmd = MemCmd::StoreCondReq;
--- 62 unchanged lines hidden (view full) ---
526 dataPtr += dataSize; 527 //Adjust the size to get the remaining bytes. 528 dataSize = addr + sizeof(T) - secondAddr; 529 //And access the right address. 530 addr = secondAddr; 531 } 532} 533
|
589Fault
590AtomicSimpleCPU::translateDataWriteAddr(Addr vaddr, Addr &paddr,
591 int size, unsigned flags)
592{
593 // use the CPU's statically allocated write request and packet objects
594 Request *req = &data_write_req;
|
534
|
596 if (traceData) {
597 traceData->setAddr(vaddr);
598 }
599
600 //The block size of our peer.
601 int blockSize = dcachePort.peerBlockSize();
602
603 //The address of the second part of this access if it needs to be split
604 //across a cache line boundary.
605 Addr secondAddr = roundDown(vaddr + size - 1, blockSize);
606
607 //The size of the data we're trying to read.
608 int dataSize = size;
609
610 bool firstTimeThrough = true;
611
612 if(secondAddr > vaddr)
613 dataSize = secondAddr - vaddr;
614
615 dcache_latency = 0;
616
617 while(1) {
618 req->setVirt(0, vaddr, dataSize, flags, thread->readPC());
619
620 // translate to physical address
621 Fault fault = thread->translateDataWriteReq(req);
622
623 //If there's a fault or we don't need to access a second cache line,
624 //stop now.
625 if (fault != NoFault)
626 return fault;
627
628 if (firstTimeThrough) {
629 paddr = req->getPaddr();
630 firstTimeThrough = false;
631 }
632
633 if (secondAddr <= vaddr)
634 return fault;
635
636 /*
637 * Set up for accessing the second cache line.
638 */
639
640 //Adjust the size to get the remaining bytes.
641 dataSize = vaddr + size - secondAddr;
642 //And access the right address.
643 vaddr = secondAddr;
644 }
645}
646
647
|
535#ifndef DOXYGEN_SHOULD_SKIP_THIS 536 537template 538Fault 539AtomicSimpleCPU::write(Twin32_t data, Addr addr, 540 unsigned flags, uint64_t *res); 541 542template
--- 174 unchanged lines hidden --- |