2c2
< * Copyright (c) 2013-2014,2017 ARM Limited
---
> * Copyright (c) 2013-2014,2017-2018 ARM Limited
51a52
> #include "cpu/utils.hh"
58,72d58
< /** Returns the offset of addr into an aligned a block of size block_size */
< static Addr
< addrBlockOffset(Addr addr, unsigned int block_size)
< {
< return addr & (block_size - 1);
< }
<
< /** Returns true if the given [addr .. addr+size-1] transfer needs to be
< * fragmented across a block size of block_size */
< static bool
< transferNeedsBurst(Addr addr, unsigned int size, unsigned int block_size)
< {
< return (addrBlockOffset(addr, block_size) + size) > block_size;
< }
<
90a77,83
> void
> LSQ::LSQRequest::disableMemAccess()
> {
> port.cpu.threads[inst->id.threadId]->setMemAccPredicate(false);
> DPRINTFS(MinorMem, (&port), "Disable mem access for inst:%s\n", *inst);
> }
>
259c252,255
< port.numAccessesInDTLB++;
---
> const auto &byteEnable = request->getByteEnable();
> if (byteEnable.size() == 0 ||
> isAnyActiveElement(byteEnable.cbegin(), byteEnable.cend())) {
> port.numAccessesInDTLB++;
261c257
< setState(LSQ::LSQRequest::InTranslation);
---
> setState(LSQ::LSQRequest::InTranslation);
263,268c259,268
< DPRINTFS(MinorMem, (&port), "Submitting DTLB request\n");
< /* Submit the translation request. The response will come through
< * finish/markDelayed on the LSQRequest as it bears the Translation
< * interface */
< thread->getDTBPtr()->translateTiming(
< request, thread, this, (isLoad ? BaseTLB::Read : BaseTLB::Write));
---
> DPRINTFS(MinorMem, (&port), "Submitting DTLB request\n");
> /* Submit the translation request. The response will come through
> * finish/markDelayed on the LSQRequest as it bears the Translation
> * interface */
> thread->getDTBPtr()->translateTiming(
> request, thread, this, (isLoad ? BaseTLB::Read : BaseTLB::Write));
> } else {
> disableMemAccess();
> setState(LSQ::LSQRequest::Complete);
> }
359a360,361
> std::vector<bool> fragment_write_byte_en;
>
403a406,408
> auto& byte_enable = request->getByteEnable();
> unsigned int num_disabled_fragments = 0;
>
423a429
> bool disabled_fragment = false;
426,429c432,452
< fragment->setVirt(0 /* asid */,
< fragment_addr, fragment_size, request->getFlags(),
< request->masterId(),
< request->getPC());
---
> if (byte_enable.empty()) {
> fragment->setVirt(0 /* asid */,
> fragment_addr, fragment_size, request->getFlags(),
> request->masterId(),
> request->getPC());
> } else {
> // Set up byte-enable mask for the current fragment
> auto it_start = byte_enable.begin() +
> (fragment_addr - base_addr);
> auto it_end = byte_enable.begin() +
> (fragment_addr - base_addr) + fragment_size;
> if (isAnyActiveElement(it_start, it_end)) {
> fragment->setVirt(0 /* asid */,
> fragment_addr, fragment_size, request->getFlags(),
> request->masterId(),
> request->getPC());
> fragment->setByteEnable(std::vector<bool>(it_start, it_end));
> } else {
> disabled_fragment = true;
> }
> }
431,434c454,458
< DPRINTFS(MinorMem, (&port), "Generating fragment addr: 0x%x size: %d"
< " (whole request addr: 0x%x size: %d) %s\n",
< fragment_addr, fragment_size, base_addr, whole_size,
< (is_last_fragment ? "last fragment" : ""));
---
> if (!disabled_fragment) {
> DPRINTFS(MinorMem, (&port), "Generating fragment addr: 0x%x"
> " size: %d (whole request addr: 0x%x size: %d) %s\n",
> fragment_addr, fragment_size, base_addr, whole_size,
> (is_last_fragment ? "last fragment" : ""));
436c460,463
< fragment_addr += fragment_size;
---
> fragmentRequests.push_back(fragment);
> } else {
> num_disabled_fragments++;
> }
438c465
< fragmentRequests.push_back(fragment);
---
> fragment_addr += fragment_size;
439a467,468
> assert(numFragments >= num_disabled_fragments);
> numFragments -= num_disabled_fragments;
444a474
> assert(numTranslatedFragments > 0);
449c479,480
< for (unsigned int fragment_index = 0; fragment_index < numFragments;
---
> for (unsigned int fragment_index = 0;
> fragment_index < numTranslatedFragments;
493,494d523
< setState(LSQ::LSQRequest::InTranslation);
<
497,498c526,529
< numInTranslationFragments = 0;
< numTranslatedFragments = 0;
---
> if (numFragments > 0) {
> setState(LSQ::LSQRequest::InTranslation);
> numInTranslationFragments = 0;
> numTranslatedFragments = 0;
500,505c531,536
< /* @todo, just do these in sequence for now with
< * a loop of:
< * do {
< * sendNextFragmentToTranslation ; translateTiming ; finish
< * } while (numTranslatedFragments != numFragments);
< */
---
> /* @todo, just do these in sequence for now with
> * a loop of:
> * do {
> * sendNextFragmentToTranslation ; translateTiming ; finish
> * } while (numTranslatedFragments != numFragments);
> */
507,508c538,543
< /* Do first translation */
< sendNextFragmentToTranslation();
---
> /* Do first translation */
> sendNextFragmentToTranslation();
> } else {
> disableMemAccess();
> setState(LSQ::LSQRequest::Complete);
> }
514c549
< assert(numIssuedFragments < numFragments);
---
> assert(numIssuedFragments < numTranslatedFragments);
522c557
< assert(numIssuedFragments < numFragments);
---
> assert(numIssuedFragments < numTranslatedFragments);
530c565
< assert(numRetiredFragments < numFragments);
---
> assert(numRetiredFragments < numTranslatedFragments);
533c568
< " offset: 0x%x (retired fragment num: %d) %s\n",
---
> " offset: 0x%x (retired fragment num: %d)\n",
536,537c571
< numRetiredFragments,
< (fault == NoFault ? "" : fault->name()));
---
> numRetiredFragments);
576c610
< if (numRetiredFragments == numFragments)
---
> if (numRetiredFragments == numTranslatedFragments)
1480c1514,1515
< uint64_t *res, AtomicOpFunctor *amo_op)
---
> uint64_t *res, AtomicOpFunctor *amo_op,
> const std::vector<bool>& byteEnable)
1535a1571,1573
> if (!byteEnable.empty()) {
> request->request->setByteEnable(byteEnable);
> }