Deleted Added
sdiff udiff text old ( 13652:45d94ac03a27 ) new ( 13954:2f400a5f2627 )
full compact
1/*
2 * Copyright (c) 2013-2014,2017-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

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

44
45#include "arch/locked_mem.hh"
46#include "arch/mmapped_ipr.hh"
47#include "base/logging.hh"
48#include "cpu/minor/cpu.hh"
49#include "cpu/minor/exec_context.hh"
50#include "cpu/minor/execute.hh"
51#include "cpu/minor/pipeline.hh"
52#include "cpu/utils.hh"
53#include "debug/Activity.hh"
54#include "debug/MinorMem.hh"
55
56namespace Minor
57{
58
59LSQ::LSQRequest::LSQRequest(LSQ &port_, MinorDynInstPtr inst_, bool isLoad_,
60 PacketDataPtr data_, uint64_t *res_) :
61 SenderState(),
62 port(port_),
63 inst(inst_),
64 isLoad(isLoad_),
65 data(data_),
66 packet(NULL),
67 request(),
68 fault(NoFault),
69 res(res_),
70 skipped(false),
71 issuedToMemory(false),
72 state(NotIssued)
73{
74 request = std::make_shared<Request>();
75}
76
77void
78LSQ::LSQRequest::disableMemAccess()
79{
80 port.cpu.threads[inst->id.threadId]->setMemAccPredicate(false);
81 DPRINTFS(MinorMem, (&port), "Disable mem access for inst:%s\n", *inst);
82}
83
84LSQ::AddrRangeCoverage
85LSQ::LSQRequest::containsAddrRangeOf(
86 Addr req1_addr, unsigned int req1_size,
87 Addr req2_addr, unsigned int req2_size)
88{
89 /* 'end' here means the address of the byte just past the request
90 * blocks */
91 Addr req2_end_addr = req2_addr + req2_size;

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

244}
245
246void
247LSQ::SingleDataRequest::startAddrTranslation()
248{
249 ThreadContext *thread = port.cpu.getContext(
250 inst->id.threadId);
251
252 const auto &byteEnable = request->getByteEnable();
253 if (byteEnable.size() == 0 ||
254 isAnyActiveElement(byteEnable.cbegin(), byteEnable.cend())) {
255 port.numAccessesInDTLB++;
256
257 setState(LSQ::LSQRequest::InTranslation);
258
259 DPRINTFS(MinorMem, (&port), "Submitting DTLB request\n");
260 /* Submit the translation request. The response will come through
261 * finish/markDelayed on the LSQRequest as it bears the Translation
262 * interface */
263 thread->getDTBPtr()->translateTiming(
264 request, thread, this, (isLoad ? BaseTLB::Read : BaseTLB::Write));
265 } else {
266 disableMemAccess();
267 setState(LSQ::LSQRequest::Complete);
268 }
269}
270
271void
272LSQ::SingleDataRequest::retireResponse(PacketPtr packet_)
273{
274 DPRINTFS(MinorMem, (&port), "Retiring packet\n");
275 packet = packet_;
276 packetInFlight = false;

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

352{
353 Addr base_addr = request->getVaddr();
354 unsigned int whole_size = request->getSize();
355 unsigned int line_width = port.lineWidth;
356
357 unsigned int fragment_size;
358 Addr fragment_addr;
359
360 std::vector<bool> fragment_write_byte_en;
361
362 /* Assume that this transfer is across potentially many block snap
363 * boundaries:
364 *
365 * | _|________|________|________|___ |
366 * | |0| 1 | 2 | 3 | 4 | |
367 * | |_|________|________|________|___| |
368 * | | | | | |
369 *

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

398 first_fragment_size + last_fragment_size) == whole_size);
399
400 fragment_addr = base_addr;
401 fragment_size = first_fragment_size;
402
403 /* Just past the last address in the request */
404 Addr end_addr = base_addr + whole_size;
405
406 auto& byte_enable = request->getByteEnable();
407 unsigned int num_disabled_fragments = 0;
408
409 for (unsigned int fragment_index = 0; fragment_index < numFragments;
410 fragment_index++)
411 {
412 bool M5_VAR_USED is_last_fragment = false;
413
414 if (fragment_addr == base_addr) {
415 /* First fragment */
416 fragment_size = first_fragment_size;

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

421 is_last_fragment = true;
422 } else {
423 /* Middle fragments */
424 fragment_size = line_width;
425 }
426 }
427
428 RequestPtr fragment = std::make_shared<Request>();
429 bool disabled_fragment = false;
430
431 fragment->setContext(request->contextId());
432 if (byte_enable.empty()) {
433 fragment->setVirt(0 /* asid */,
434 fragment_addr, fragment_size, request->getFlags(),
435 request->masterId(),
436 request->getPC());
437 } else {
438 // Set up byte-enable mask for the current fragment
439 auto it_start = byte_enable.begin() +
440 (fragment_addr - base_addr);
441 auto it_end = byte_enable.begin() +
442 (fragment_addr - base_addr) + fragment_size;
443 if (isAnyActiveElement(it_start, it_end)) {
444 fragment->setVirt(0 /* asid */,
445 fragment_addr, fragment_size, request->getFlags(),
446 request->masterId(),
447 request->getPC());
448 fragment->setByteEnable(std::vector<bool>(it_start, it_end));
449 } else {
450 disabled_fragment = true;
451 }
452 }
453
454 if (!disabled_fragment) {
455 DPRINTFS(MinorMem, (&port), "Generating fragment addr: 0x%x"
456 " size: %d (whole request addr: 0x%x size: %d) %s\n",
457 fragment_addr, fragment_size, base_addr, whole_size,
458 (is_last_fragment ? "last fragment" : ""));
459
460 fragmentRequests.push_back(fragment);
461 } else {
462 num_disabled_fragments++;
463 }
464
465 fragment_addr += fragment_size;
466 }
467 assert(numFragments >= num_disabled_fragments);
468 numFragments -= num_disabled_fragments;
469}
470
471void
472LSQ::SplitDataRequest::makeFragmentPackets()
473{
474 assert(numTranslatedFragments > 0);
475 Addr base_addr = request->getVaddr();
476
477 DPRINTFS(MinorMem, (&port), "Making packets for request: %s\n", *inst);
478
479 for (unsigned int fragment_index = 0;
480 fragment_index < numTranslatedFragments;
481 fragment_index++)
482 {
483 RequestPtr fragment = fragmentRequests[fragment_index];
484
485 DPRINTFS(MinorMem, (&port), "Making packet %d for request: %s"
486 " (%d, 0x%x)\n",
487 fragment_index, *inst,
488 (fragment->hasPaddr() ? "has paddr" : "no paddr"),

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

516 * fragment */
517 request->setPaddr(fragmentRequests[0]->getPaddr());
518 makePacket();
519}
520
521void
522LSQ::SplitDataRequest::startAddrTranslation()
523{
524 makeFragmentRequests();
525
526 if (numFragments > 0) {
527 setState(LSQ::LSQRequest::InTranslation);
528 numInTranslationFragments = 0;
529 numTranslatedFragments = 0;
530
531 /* @todo, just do these in sequence for now with
532 * a loop of:
533 * do {
534 * sendNextFragmentToTranslation ; translateTiming ; finish
535 * } while (numTranslatedFragments != numFragments);
536 */
537
538 /* Do first translation */
539 sendNextFragmentToTranslation();
540 } else {
541 disableMemAccess();
542 setState(LSQ::LSQRequest::Complete);
543 }
544}
545
546PacketPtr
547LSQ::SplitDataRequest::getHeadPacket()
548{
549 assert(numIssuedFragments < numTranslatedFragments);
550
551 return fragmentPackets[numIssuedFragments];
552}
553
554void
555LSQ::SplitDataRequest::stepToNextPacket()
556{
557 assert(numIssuedFragments < numTranslatedFragments);
558
559 numIssuedFragments++;
560}
561
562void
563LSQ::SplitDataRequest::retireResponse(PacketPtr response)
564{
565 assert(numRetiredFragments < numTranslatedFragments);
566
567 DPRINTFS(MinorMem, (&port), "Retiring fragment addr: 0x%x size: %d"
568 " offset: 0x%x (retired fragment num: %d)\n",
569 response->req->getVaddr(), response->req->getSize(),
570 request->getVaddr() - response->req->getVaddr(),
571 numRetiredFragments);
572
573 numRetiredFragments++;
574
575 if (skipped) {
576 /* Skip because we already knew the request had faulted or been
577 * skipped */
578 DPRINTFS(MinorMem, (&port), "Skipping this fragment\n");
579 } else if (response->isError()) {

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

602 /* Complete early if we're skipping are no more in-flight accesses */
603 if (skipped && !hasPacketsInMemSystem()) {
604 DPRINTFS(MinorMem, (&port), "Completed skipped burst\n");
605 setState(Complete);
606 if (packet->needsResponse())
607 packet->makeResponse();
608 }
609
610 if (numRetiredFragments == numTranslatedFragments)
611 setState(Complete);
612
613 if (!skipped && isComplete()) {
614 DPRINTFS(MinorMem, (&port), "Completed burst %d\n", packet != NULL);
615
616 DPRINTFS(MinorMem, (&port), "Retired packet isRead: %d isWrite: %d"
617 " needsResponse: %d packetSize: %s requestSize: %s responseSize:"
618 " %s\n", packet->isRead(), packet->isWrite(),

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

1506 DPRINTF(Activity, "Need to tick\n");
1507
1508 return ret;
1509}
1510
1511void
1512LSQ::pushRequest(MinorDynInstPtr inst, bool isLoad, uint8_t *data,
1513 unsigned int size, Addr addr, Request::Flags flags,
1514 uint64_t *res, AtomicOpFunctor *amo_op,
1515 const std::vector<bool>& byteEnable)
1516{
1517 bool needs_burst = transferNeedsBurst(addr, size, lineWidth);
1518
1519 if (needs_burst && inst->staticInst->isAtomic()) {
1520 // AMO requests that access across a cache line boundary are not
1521 // allowed since the cache does not guarantee AMO ops to be executed
1522 // atomically in two cache lines
1523 // For ISAs such as x86 that requires AMO operations to work on

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

1563 inst->traceData->setMem(addr, size, flags);
1564
1565 int cid = cpu.threads[inst->id.threadId]->getTC()->contextId();
1566 request->request->setContext(cid);
1567 request->request->setVirt(0 /* asid */,
1568 addr, size, flags, cpu.dataMasterId(),
1569 /* I've no idea why we need the PC, but give it */
1570 inst->pc.instAddr(), amo_op);
1571 if (!byteEnable.empty()) {
1572 request->request->setByteEnable(byteEnable);
1573 }
1574
1575 requests.push(request);
1576 request->startAddrTranslation();
1577}
1578
1579void
1580LSQ::pushFailedRequest(MinorDynInstPtr inst)
1581{

--- 141 unchanged lines hidden ---