memtest.cc revision 8853
1955SN/A/* 2955SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan 39812Sandreas.hansson@arm.com * All rights reserved. 49812Sandreas.hansson@arm.com * 59812Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 69812Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 79812Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 89812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 99812Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 109812Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 119812Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 129812Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 139812Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 149812Sandreas.hansson@arm.com * this software without specific prior written permission. 157816Ssteve.reinhardt@amd.com * 165871Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171762SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A * 28955SN/A * Authors: Erik Hallnor 29955SN/A * Steve Reinhardt 30955SN/A */ 31955SN/A 32955SN/A// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded 33955SN/A 34955SN/A#include <iomanip> 35955SN/A#include <set> 36955SN/A#include <string> 37955SN/A#include <vector> 38955SN/A 39955SN/A#include "base/misc.hh" 40955SN/A#include "base/statistics.hh" 41955SN/A#include "cpu/testers/memtest/memtest.hh" 422665Ssaidi@eecs.umich.edu#include "debug/MemTest.hh" 432665Ssaidi@eecs.umich.edu#include "mem/mem_object.hh" 445863Snate@binkert.org#include "mem/packet.hh" 45955SN/A#include "mem/port.hh" 46955SN/A#include "mem/request.hh" 47955SN/A#include "sim/sim_events.hh" 48955SN/A#include "sim/stats.hh" 49955SN/A#include "sim/system.hh" 508878Ssteve.reinhardt@amd.com 512632Sstever@eecs.umich.eduusing namespace std; 528878Ssteve.reinhardt@amd.com 532632Sstever@eecs.umich.eduint TESTER_ALLOCATOR=0; 54955SN/A 558878Ssteve.reinhardt@amd.combool 562632Sstever@eecs.umich.eduMemTest::CpuPort::recvTiming(PacketPtr pkt) 572761Sstever@eecs.umich.edu{ 582632Sstever@eecs.umich.edu if (pkt->isResponse()) { 592632Sstever@eecs.umich.edu memtest->completeRequest(pkt); 602632Sstever@eecs.umich.edu } else { 612761Sstever@eecs.umich.edu // must be snoop upcall 622761Sstever@eecs.umich.edu assert(pkt->isRequest()); 632761Sstever@eecs.umich.edu assert(pkt->getDest() == Packet::Broadcast); 648878Ssteve.reinhardt@amd.com } 658878Ssteve.reinhardt@amd.com return true; 662761Sstever@eecs.umich.edu} 672761Sstever@eecs.umich.edu 682761Sstever@eecs.umich.eduTick 692761Sstever@eecs.umich.eduMemTest::CpuPort::recvAtomic(PacketPtr pkt) 702761Sstever@eecs.umich.edu{ 718878Ssteve.reinhardt@amd.com // must be snoop upcall 728878Ssteve.reinhardt@amd.com assert(pkt->isRequest()); 732632Sstever@eecs.umich.edu assert(pkt->getDest() == Packet::Broadcast); 742632Sstever@eecs.umich.edu return curTick(); 758878Ssteve.reinhardt@amd.com} 768878Ssteve.reinhardt@amd.com 772632Sstever@eecs.umich.eduvoid 78955SN/AMemTest::CpuPort::recvFunctional(PacketPtr pkt) 79955SN/A{ 80955SN/A //Do nothing if we see one come through 815863Snate@binkert.org// if (curTick() != 0)//Supress warning durring initialization 825863Snate@binkert.org// warn("Functional Writes not implemented in MemTester\n"); 835863Snate@binkert.org //Need to find any response values that intersect and update 845863Snate@binkert.org return; 855863Snate@binkert.org} 865863Snate@binkert.org 875863Snate@binkert.orgvoid 885863Snate@binkert.orgMemTest::CpuPort::recvRangeChange() 895863Snate@binkert.org{ 905863Snate@binkert.org} 915863Snate@binkert.org 928878Ssteve.reinhardt@amd.comvoid 935863Snate@binkert.orgMemTest::CpuPort::recvRetry() 945863Snate@binkert.org{ 955863Snate@binkert.org memtest->doRetry(); 969812Sandreas.hansson@arm.com} 979812Sandreas.hansson@arm.com 985863Snate@binkert.orgvoid 999812Sandreas.hansson@arm.comMemTest::sendPkt(PacketPtr pkt) { 1005863Snate@binkert.org if (atomic) { 1015863Snate@binkert.org cachePort.sendAtomic(pkt); 1025863Snate@binkert.org completeRequest(pkt); 1039812Sandreas.hansson@arm.com } 1049812Sandreas.hansson@arm.com else if (!cachePort.sendTiming(pkt)) { 1055863Snate@binkert.org DPRINTF(MemTest, "accessRetry setting to true\n"); 1065863Snate@binkert.org 1078878Ssteve.reinhardt@amd.com // 1085863Snate@binkert.org // dma requests should never be retried 1095863Snate@binkert.org // 1105863Snate@binkert.org if (issueDmas) { 1116654Snate@binkert.org panic("Nacked DMA requests are not supported\n"); 11210196SCurtis.Dunham@arm.com } 113955SN/A accessRetry = true; 1145396Ssaidi@eecs.umich.edu retryPkt = pkt; 1155863Snate@binkert.org } else { 1165863Snate@binkert.org if (issueDmas) { 1174202Sbinkertn@umich.edu dmaOutstanding = true; 1185863Snate@binkert.org } 1195863Snate@binkert.org } 1205863Snate@binkert.org 1215863Snate@binkert.org} 122955SN/A 1236654Snate@binkert.orgMemTest::MemTest(const Params *p) 1245273Sstever@gmail.com : MemObject(p), 1255871Snate@binkert.org tickEvent(this), 1265273Sstever@gmail.com cachePort("test", this), 1276655Snate@binkert.org funcPort("functional", this), 1288878Ssteve.reinhardt@amd.com funcProxy(funcPort), 1296655Snate@binkert.org retryPkt(NULL), 1306655Snate@binkert.org// mainMem(main_mem), 1319219Spower.jg@gmail.com// checkMem(check_mem), 1326655Snate@binkert.org size(p->memory_size), 1335871Snate@binkert.org percentReads(p->percent_reads), 1346654Snate@binkert.org percentFunctional(p->percent_functional), 1358947Sandreas.hansson@arm.com percentUncacheable(p->percent_uncacheable), 1365396Ssaidi@eecs.umich.edu issueDmas(p->issue_dmas), 1378120Sgblack@eecs.umich.edu masterId(p->sys->getMasterId(name())), 1388120Sgblack@eecs.umich.edu progressInterval(p->progress_interval), 1398120Sgblack@eecs.umich.edu nextProgressMessage(p->progress_interval), 1408120Sgblack@eecs.umich.edu percentSourceUnaligned(p->percent_source_unaligned), 1418120Sgblack@eecs.umich.edu percentDestUnaligned(p->percent_dest_unaligned), 1428120Sgblack@eecs.umich.edu maxLoads(p->max_loads), 1438120Sgblack@eecs.umich.edu atomic(p->atomic), 1448120Sgblack@eecs.umich.edu suppress_func_warnings(p->suppress_func_warnings) 1458879Ssteve.reinhardt@amd.com{ 1468879Ssteve.reinhardt@amd.com id = TESTER_ALLOCATOR++; 1478879Ssteve.reinhardt@amd.com 1488879Ssteve.reinhardt@amd.com // Needs to be masked off once we know the block size. 1498879Ssteve.reinhardt@amd.com traceBlockAddr = p->trace_addr; 1508879Ssteve.reinhardt@amd.com baseAddr1 = 0x100000; 1518879Ssteve.reinhardt@amd.com baseAddr2 = 0x400000; 1528879Ssteve.reinhardt@amd.com uncacheAddr = 0x800000; 1538879Ssteve.reinhardt@amd.com 1548879Ssteve.reinhardt@amd.com // set up counters 1558879Ssteve.reinhardt@amd.com noResponseCycles = 0; 1568879Ssteve.reinhardt@amd.com numReads = 0; 1578879Ssteve.reinhardt@amd.com numWrites = 0; 1588120Sgblack@eecs.umich.edu schedule(tickEvent, 0); 1598120Sgblack@eecs.umich.edu 1608120Sgblack@eecs.umich.edu accessRetry = false; 1618120Sgblack@eecs.umich.edu dmaOutstanding = false; 1628120Sgblack@eecs.umich.edu} 1638120Sgblack@eecs.umich.edu 1648120Sgblack@eecs.umich.eduPort * 1658120Sgblack@eecs.umich.eduMemTest::getPort(const std::string &if_name, int idx) 1668120Sgblack@eecs.umich.edu{ 1678120Sgblack@eecs.umich.edu if (if_name == "functional") 1688120Sgblack@eecs.umich.edu return &funcPort; 1698120Sgblack@eecs.umich.edu else if (if_name == "test") 1708120Sgblack@eecs.umich.edu return &cachePort; 1718120Sgblack@eecs.umich.edu else 1728879Ssteve.reinhardt@amd.com panic("No Such Port\n"); 1738879Ssteve.reinhardt@amd.com} 1748879Ssteve.reinhardt@amd.com 1758879Ssteve.reinhardt@amd.comvoid 1768879Ssteve.reinhardt@amd.comMemTest::init() 1778879Ssteve.reinhardt@amd.com{ 1788879Ssteve.reinhardt@amd.com // By the time init() is called, the ports should be hooked up. 1798879Ssteve.reinhardt@amd.com blockSize = cachePort.peerBlockSize(); 1809227Sandreas.hansson@arm.com blockAddrMask = blockSize - 1; 1819227Sandreas.hansson@arm.com traceBlockAddr = blockAddr(traceBlockAddr); 1828879Ssteve.reinhardt@amd.com 1838879Ssteve.reinhardt@amd.com // initial memory contents for both physical memory and functional 1848879Ssteve.reinhardt@amd.com // memory should be 0; no need to initialize them. 1858879Ssteve.reinhardt@amd.com} 1868120Sgblack@eecs.umich.edu 1878947Sandreas.hansson@arm.com 1887816Ssteve.reinhardt@amd.comvoid 1895871Snate@binkert.orgMemTest::completeRequest(PacketPtr pkt) 1905871Snate@binkert.org{ 1916121Snate@binkert.org Request *req = pkt->req; 1925871Snate@binkert.org 1935871Snate@binkert.org if (issueDmas) { 1949926Sstan.czerniawski@arm.com dmaOutstanding = false; 1959926Sstan.czerniawski@arm.com } 1969119Sandreas.hansson@arm.com 19710068Sandreas.hansson@arm.com DPRINTF(MemTest, "completing %s at address %x (blk %x) %s\n", 19810068Sandreas.hansson@arm.com pkt->isWrite() ? "write" : "read", 199955SN/A req->getPaddr(), blockAddr(req->getPaddr()), 2009416SAndreas.Sandberg@ARM.com pkt->isError() ? "error" : "success"); 2019416SAndreas.Sandberg@ARM.com 2029416SAndreas.Sandberg@ARM.com MemTestSenderState *state = 2039416SAndreas.Sandberg@ARM.com dynamic_cast<MemTestSenderState *>(pkt->senderState); 2049416SAndreas.Sandberg@ARM.com 2059416SAndreas.Sandberg@ARM.com uint8_t *data = state->data; 2069416SAndreas.Sandberg@ARM.com uint8_t *pkt_data = pkt->getPtr<uint8_t>(); 2075871Snate@binkert.org 2085871Snate@binkert.org //Remove the address from the list of outstanding 2099416SAndreas.Sandberg@ARM.com std::set<unsigned>::iterator removeAddr = 2109416SAndreas.Sandberg@ARM.com outstandingAddrs.find(req->getPaddr()); 2115871Snate@binkert.org assert(removeAddr != outstandingAddrs.end()); 212955SN/A outstandingAddrs.erase(removeAddr); 2136121Snate@binkert.org 2148881Smarc.orr@gmail.com if (pkt->isError()) { 2156121Snate@binkert.org if (!suppress_func_warnings) { 2166121Snate@binkert.org warn("Functional Access failed for %x at %x\n", 2171533SN/A pkt->isWrite() ? "write" : "read", req->getPaddr()); 2189239Sandreas.hansson@arm.com } 2199239Sandreas.hansson@arm.com } else { 2209239Sandreas.hansson@arm.com if (pkt->isRead()) { 2219239Sandreas.hansson@arm.com if (memcmp(pkt_data, data, pkt->getSize()) != 0) { 2229239Sandreas.hansson@arm.com panic("%s: read of %x (blk %x) @ cycle %d " 2239239Sandreas.hansson@arm.com "returns %x, expected %x\n", name(), 2249239Sandreas.hansson@arm.com req->getPaddr(), blockAddr(req->getPaddr()), curTick(), 2259239Sandreas.hansson@arm.com *pkt_data, *data); 2269239Sandreas.hansson@arm.com } 2279239Sandreas.hansson@arm.com 2289239Sandreas.hansson@arm.com numReads++; 2299239Sandreas.hansson@arm.com numReadsStat++; 2306655Snate@binkert.org 2316655Snate@binkert.org if (numReads == (uint64_t)nextProgressMessage) { 2326655Snate@binkert.org ccprintf(cerr, "%s: completed %d read, %d write accesses @%d\n", 2336655Snate@binkert.org name(), numReads, numWrites, curTick()); 2345871Snate@binkert.org nextProgressMessage += progressInterval; 2355871Snate@binkert.org } 2365863Snate@binkert.org 2375871Snate@binkert.org if (maxLoads != 0 && numReads >= maxLoads) 2388878Ssteve.reinhardt@amd.com exitSimLoop("maximum number of loads reached"); 2395871Snate@binkert.org } else { 2405871Snate@binkert.org assert(pkt->isWrite()); 2415871Snate@binkert.org funcProxy.writeBlob(req->getPaddr(), pkt_data, req->getSize()); 2425863Snate@binkert.org numWrites++; 2436121Snate@binkert.org numWritesStat++; 2445863Snate@binkert.org } 2455871Snate@binkert.org } 2468336Ssteve.reinhardt@amd.com 2478336Ssteve.reinhardt@amd.com noResponseCycles = 0; 2488336Ssteve.reinhardt@amd.com delete state; 2498336Ssteve.reinhardt@amd.com delete [] data; 2504678Snate@binkert.org delete pkt->req; 2518336Ssteve.reinhardt@amd.com delete pkt; 2528336Ssteve.reinhardt@amd.com} 2538336Ssteve.reinhardt@amd.com 2544678Snate@binkert.orgvoid 2554678Snate@binkert.orgMemTest::regStats() 2564678Snate@binkert.org{ 2574678Snate@binkert.org using namespace Stats; 2587827Snate@binkert.org 2597827Snate@binkert.org numReadsStat 2608336Ssteve.reinhardt@amd.com .name(name() + ".num_reads") 2614678Snate@binkert.org .desc("number of read accesses completed") 2628336Ssteve.reinhardt@amd.com ; 2638336Ssteve.reinhardt@amd.com 2648336Ssteve.reinhardt@amd.com numWritesStat 2658336Ssteve.reinhardt@amd.com .name(name() + ".num_writes") 2668336Ssteve.reinhardt@amd.com .desc("number of write accesses completed") 2678336Ssteve.reinhardt@amd.com ; 2685871Snate@binkert.org 2695871Snate@binkert.org numCopiesStat 2708336Ssteve.reinhardt@amd.com .name(name() + ".num_copies") 2718336Ssteve.reinhardt@amd.com .desc("number of copy accesses completed") 2728336Ssteve.reinhardt@amd.com ; 2738336Ssteve.reinhardt@amd.com} 2748336Ssteve.reinhardt@amd.com 2755871Snate@binkert.orgvoid 2768336Ssteve.reinhardt@amd.comMemTest::tick() 2778336Ssteve.reinhardt@amd.com{ 2788336Ssteve.reinhardt@amd.com if (!tickEvent.scheduled()) 2798336Ssteve.reinhardt@amd.com schedule(tickEvent, curTick() + ticks(1)); 2808336Ssteve.reinhardt@amd.com 2814678Snate@binkert.org if (++noResponseCycles >= 500000) { 2825871Snate@binkert.org if (issueDmas) { 2834678Snate@binkert.org cerr << "DMA tester "; 2848336Ssteve.reinhardt@amd.com } 2858336Ssteve.reinhardt@amd.com cerr << name() << ": deadlocked at cycle " << curTick() << endl; 2868336Ssteve.reinhardt@amd.com fatal(""); 2878336Ssteve.reinhardt@amd.com } 2888336Ssteve.reinhardt@amd.com 2898336Ssteve.reinhardt@amd.com if (accessRetry || (issueDmas && dmaOutstanding)) { 2908336Ssteve.reinhardt@amd.com DPRINTF(MemTest, "MemTester waiting on accessRetry or DMA response\n"); 2918336Ssteve.reinhardt@amd.com return; 2928336Ssteve.reinhardt@amd.com } 2938336Ssteve.reinhardt@amd.com 2948336Ssteve.reinhardt@amd.com //make new request 2958336Ssteve.reinhardt@amd.com unsigned cmd = random() % 100; 2968336Ssteve.reinhardt@amd.com unsigned offset = random() % size; 2978336Ssteve.reinhardt@amd.com unsigned base = random() % 2; 2988336Ssteve.reinhardt@amd.com uint64_t data = random(); 2998336Ssteve.reinhardt@amd.com unsigned access_size = random() % 4; 3008336Ssteve.reinhardt@amd.com bool uncacheable = (random() % 100) < percentUncacheable; 3015871Snate@binkert.org 3026121Snate@binkert.org unsigned dma_access_size = random() % 4; 303955SN/A 304955SN/A //If we aren't doing copies, use id as offset, and do a false sharing 3052632Sstever@eecs.umich.edu //mem tester 3062632Sstever@eecs.umich.edu //We can eliminate the lower bits of the offset, and then use the id 307955SN/A //to offset within the blks 308955SN/A offset = blockAddr(offset); 309955SN/A offset += id; 310955SN/A access_size = 0; 3118878Ssteve.reinhardt@amd.com dma_access_size = 0; 312955SN/A 3132632Sstever@eecs.umich.edu Request *req = new Request(); 3142632Sstever@eecs.umich.edu Request::Flags flags; 3152632Sstever@eecs.umich.edu Addr paddr; 3162632Sstever@eecs.umich.edu 3172632Sstever@eecs.umich.edu if (uncacheable) { 3182632Sstever@eecs.umich.edu flags.set(Request::UNCACHEABLE); 3192632Sstever@eecs.umich.edu paddr = uncacheAddr + offset; 3208268Ssteve.reinhardt@amd.com } else { 3218268Ssteve.reinhardt@amd.com paddr = ((base) ? baseAddr1 : baseAddr2) + offset; 3228268Ssteve.reinhardt@amd.com } 3238268Ssteve.reinhardt@amd.com bool do_functional = (random() % 100 < percentFunctional) && !uncacheable; 3248268Ssteve.reinhardt@amd.com 3258268Ssteve.reinhardt@amd.com if (issueDmas) { 3268268Ssteve.reinhardt@amd.com paddr &= ~((1 << dma_access_size) - 1); 3272632Sstever@eecs.umich.edu req->setPhys(paddr, 1 << dma_access_size, flags, masterId); 3282632Sstever@eecs.umich.edu req->setThreadContext(id,0); 3292632Sstever@eecs.umich.edu } else { 3302632Sstever@eecs.umich.edu paddr &= ~((1 << access_size) - 1); 3318268Ssteve.reinhardt@amd.com req->setPhys(paddr, 1 << access_size, flags, masterId); 3322632Sstever@eecs.umich.edu req->setThreadContext(id,0); 3338268Ssteve.reinhardt@amd.com } 3348268Ssteve.reinhardt@amd.com assert(req->getSize() == 1); 3358268Ssteve.reinhardt@amd.com 3368268Ssteve.reinhardt@amd.com uint8_t *result = new uint8_t[8]; 3373718Sstever@eecs.umich.edu 3382634Sstever@eecs.umich.edu if (cmd < percentReads) { 3392634Sstever@eecs.umich.edu // read 3405863Snate@binkert.org 3412638Sstever@eecs.umich.edu // For now we only allow one outstanding request per address 3428268Ssteve.reinhardt@amd.com // per tester This means we assume CPU does write forwarding 3432632Sstever@eecs.umich.edu // to reads that alias something in the cpu store buffer. 3442632Sstever@eecs.umich.edu if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { 3452632Sstever@eecs.umich.edu delete [] result; 3462632Sstever@eecs.umich.edu delete req; 3472632Sstever@eecs.umich.edu return; 3481858SN/A } 3493716Sstever@eecs.umich.edu 3502638Sstever@eecs.umich.edu outstandingAddrs.insert(paddr); 3512638Sstever@eecs.umich.edu 3522638Sstever@eecs.umich.edu // ***** NOTE FOR RON: I'm not sure how to access checkMem. - Kevin 3532638Sstever@eecs.umich.edu funcProxy.readBlob(req->getPaddr(), result, req->getSize()); 3542638Sstever@eecs.umich.edu 3552638Sstever@eecs.umich.edu DPRINTF(MemTest, 3562638Sstever@eecs.umich.edu "id %d initiating %sread at addr %x (blk %x) expecting %x\n", 3575863Snate@binkert.org id, do_functional ? "functional " : "", req->getPaddr(), 3585863Snate@binkert.org blockAddr(req->getPaddr()), *result); 3595863Snate@binkert.org 360955SN/A PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast); 3615341Sstever@gmail.com pkt->setSrc(0); 3625341Sstever@gmail.com pkt->dataDynamicArray(new uint8_t[req->getSize()]); 3635863Snate@binkert.org MemTestSenderState *state = new MemTestSenderState(result); 3647756SAli.Saidi@ARM.com pkt->senderState = state; 3655341Sstever@gmail.com 3666121Snate@binkert.org if (do_functional) { 3674494Ssaidi@eecs.umich.edu assert(pkt->needsResponse()); 3686121Snate@binkert.org pkt->setSuppressFuncError(); 3691105SN/A cachePort.sendFunctional(pkt); 3702667Sstever@eecs.umich.edu completeRequest(pkt); 3712667Sstever@eecs.umich.edu } else { 3722667Sstever@eecs.umich.edu sendPkt(pkt); 3732667Sstever@eecs.umich.edu } 3746121Snate@binkert.org } else { 3752667Sstever@eecs.umich.edu // write 3765341Sstever@gmail.com 3775863Snate@binkert.org // For now we only allow one outstanding request per addreess 3785341Sstever@gmail.com // per tester. This means we assume CPU does write forwarding 3795341Sstever@gmail.com // to reads that alias something in the cpu store buffer. 3805341Sstever@gmail.com if (outstandingAddrs.find(paddr) != outstandingAddrs.end()) { 3818120Sgblack@eecs.umich.edu delete [] result; 3825341Sstever@gmail.com delete req; 3838120Sgblack@eecs.umich.edu return; 3845341Sstever@gmail.com } 3858120Sgblack@eecs.umich.edu 3866121Snate@binkert.org outstandingAddrs.insert(paddr); 3876121Snate@binkert.org 3888980Ssteve.reinhardt@amd.com DPRINTF(MemTest, "initiating %swrite at addr %x (blk %x) value %x\n", 3899396Sandreas.hansson@arm.com do_functional ? "functional " : "", req->getPaddr(), 3905397Ssaidi@eecs.umich.edu blockAddr(req->getPaddr()), data & 0xff); 3915397Ssaidi@eecs.umich.edu 3927727SAli.Saidi@ARM.com PacketPtr pkt = new Packet(req, MemCmd::WriteReq, Packet::Broadcast); 3938268Ssteve.reinhardt@amd.com pkt->setSrc(0); 3946168Snate@binkert.org uint8_t *pkt_data = new uint8_t[req->getSize()]; 3955341Sstever@gmail.com pkt->dataDynamicArray(pkt_data); 3968120Sgblack@eecs.umich.edu memcpy(pkt_data, &data, req->getSize()); 3978120Sgblack@eecs.umich.edu MemTestSenderState *state = new MemTestSenderState(result); 3988120Sgblack@eecs.umich.edu pkt->senderState = state; 3996814Sgblack@eecs.umich.edu 4005863Snate@binkert.org if (do_functional) { 4018120Sgblack@eecs.umich.edu pkt->setSuppressFuncError(); 4025341Sstever@gmail.com cachePort.sendFunctional(pkt); 4035863Snate@binkert.org completeRequest(pkt); 4048268Ssteve.reinhardt@amd.com } else { 4056121Snate@binkert.org sendPkt(pkt); 4066121Snate@binkert.org } 4078268Ssteve.reinhardt@amd.com } 4085742Snate@binkert.org} 4095742Snate@binkert.org 4105341Sstever@gmail.comvoid 4115742Snate@binkert.orgMemTest::doRetry() 4125742Snate@binkert.org{ 4135341Sstever@gmail.com if (cachePort.sendTiming(retryPkt)) { 4146017Snate@binkert.org DPRINTF(MemTest, "accessRetry setting to false\n"); 4156121Snate@binkert.org accessRetry = false; 4166017Snate@binkert.org retryPkt = NULL; 4177816Ssteve.reinhardt@amd.com } 4187756SAli.Saidi@ARM.com} 4197756SAli.Saidi@ARM.com 4207756SAli.Saidi@ARM.com 4217756SAli.Saidi@ARM.comvoid 4227756SAli.Saidi@ARM.comMemTest::printAddr(Addr a) 4237756SAli.Saidi@ARM.com{ 4247756SAli.Saidi@ARM.com cachePort.printAddr(a); 4257756SAli.Saidi@ARM.com} 4267816Ssteve.reinhardt@amd.com 4277816Ssteve.reinhardt@amd.com 4287816Ssteve.reinhardt@amd.comMemTest * 4297816Ssteve.reinhardt@amd.comMemTestParams::create() 4307816Ssteve.reinhardt@amd.com{ 4317816Ssteve.reinhardt@amd.com return new MemTest(this); 4327816Ssteve.reinhardt@amd.com} 4337816Ssteve.reinhardt@amd.com