InvalidateGenerator.cc revision 11320:42ecb523c64a
11897Sstever@eecs.umich.edu/*
24130Ssaidi@eecs.umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
31897Sstever@eecs.umich.edu * Copyright (c) 2009-2010 Advanced Micro Devices, Inc.
41897Sstever@eecs.umich.edu * All rights reserved.
51897Sstever@eecs.umich.edu *
61897Sstever@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
71897Sstever@eecs.umich.edu * modification, are permitted provided that the following conditions are
81897Sstever@eecs.umich.edu * met: redistributions of source code must retain the above copyright
91897Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
101897Sstever@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
111897Sstever@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
121897Sstever@eecs.umich.edu * documentation and/or other materials provided with the distribution;
131897Sstever@eecs.umich.edu * neither the name of the copyright holders nor the names of its
141897Sstever@eecs.umich.edu * contributors may be used to endorse or promote products derived from
151897Sstever@eecs.umich.edu * this software without specific prior written permission.
161897Sstever@eecs.umich.edu *
171897Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181897Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191897Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
201897Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
211897Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
221897Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
231897Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241897Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251897Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261897Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
271897Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
281897Sstever@eecs.umich.edu */
291897Sstever@eecs.umich.edu
301897Sstever@eecs.umich.edu#include "cpu/testers/directedtest/DirectedGenerator.hh"
311897Sstever@eecs.umich.edu#include "cpu/testers/directedtest/InvalidateGenerator.hh"
321897Sstever@eecs.umich.edu#include "cpu/testers/directedtest/RubyDirectedTester.hh"
331897Sstever@eecs.umich.edu#include "debug/DirectedTest.hh"
344961Ssaidi@eecs.umich.edu
351897Sstever@eecs.umich.eduInvalidateGenerator::InvalidateGenerator(const Params *p)
361897Sstever@eecs.umich.edu    : DirectedGenerator(p)
371897Sstever@eecs.umich.edu{
381897Sstever@eecs.umich.edu    //
391897Sstever@eecs.umich.edu    // First, issue loads to bring the block into S state
401897Sstever@eecs.umich.edu    //
411897Sstever@eecs.umich.edu    m_status = InvalidateGeneratorStatus_Load_Waiting;
421897Sstever@eecs.umich.edu    m_active_read_node = 0;
434130Ssaidi@eecs.umich.edu    m_active_inv_node = 0;
443099Sstever@eecs.umich.edu    m_address = 0x0;
453099Sstever@eecs.umich.edu    m_addr_increment_size = p->addr_increment_size;
461897Sstever@eecs.umich.edu}
473709Sstever@eecs.umich.edu
483099Sstever@eecs.umich.eduInvalidateGenerator::~InvalidateGenerator()
493099Sstever@eecs.umich.edu{
501897Sstever@eecs.umich.edu}
513099Sstever@eecs.umich.edu
523725Sstever@eecs.umich.edubool
533725Sstever@eecs.umich.eduInvalidateGenerator::initiate()
541897Sstever@eecs.umich.edu{
551897Sstever@eecs.umich.edu    MasterPort* port;
561897Sstever@eecs.umich.edu    Request::Flags flags;
571897Sstever@eecs.umich.edu    PacketPtr pkt;
581897Sstever@eecs.umich.edu    Packet::Command cmd;
591897Sstever@eecs.umich.edu
601897Sstever@eecs.umich.edu    // For simplicity, requests are assumed to be 1 byte-sized
611897Sstever@eecs.umich.edu    Request *req = new Request(m_address, 1, flags, masterId);
621897Sstever@eecs.umich.edu
631897Sstever@eecs.umich.edu    //
644961Ssaidi@eecs.umich.edu    // Based on the current state, issue a load or a store
654961Ssaidi@eecs.umich.edu    //
664961Ssaidi@eecs.umich.edu    if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
674961Ssaidi@eecs.umich.edu        DPRINTF(DirectedTest, "initiating read\n");
684961Ssaidi@eecs.umich.edu        cmd = MemCmd::ReadReq;
694961Ssaidi@eecs.umich.edu        port = m_directed_tester->getCpuPort(m_active_read_node);
704961Ssaidi@eecs.umich.edu        pkt = new Packet(req, cmd);
714961Ssaidi@eecs.umich.edu    } else if (m_status == InvalidateGeneratorStatus_Inv_Waiting) {
724961Ssaidi@eecs.umich.edu        DPRINTF(DirectedTest, "initiating invalidating write\n");
734961Ssaidi@eecs.umich.edu        cmd = MemCmd::WriteReq;
744961Ssaidi@eecs.umich.edu        port = m_directed_tester->getCpuPort(m_active_inv_node);
754961Ssaidi@eecs.umich.edu        pkt = new Packet(req, cmd);
764961Ssaidi@eecs.umich.edu    } else {
774961Ssaidi@eecs.umich.edu        panic("initiate was unexpectedly called\n");
781897Sstever@eecs.umich.edu    }
791897Sstever@eecs.umich.edu    pkt->allocate();
801897Sstever@eecs.umich.edu
811897Sstever@eecs.umich.edu    if (port->sendTimingReq(pkt)) {
821897Sstever@eecs.umich.edu        DPRINTF(DirectedTest, "initiating request - successful\n");
831897Sstever@eecs.umich.edu        if (m_status == InvalidateGeneratorStatus_Load_Waiting) {
841897Sstever@eecs.umich.edu            m_status = InvalidateGeneratorStatus_Load_Pending;
854975Ssaidi@eecs.umich.edu        } else {
864961Ssaidi@eecs.umich.edu            m_status = InvalidateGeneratorStatus_Inv_Pending;
874961Ssaidi@eecs.umich.edu        }
884961Ssaidi@eecs.umich.edu        return true;
894961Ssaidi@eecs.umich.edu    } else {
904961Ssaidi@eecs.umich.edu        // If the packet did not issue, must delete
914961Ssaidi@eecs.umich.edu        // Note: No need to delete the data, the packet destructor
924961Ssaidi@eecs.umich.edu        // will delete it
934961Ssaidi@eecs.umich.edu        delete pkt->req;
944961Ssaidi@eecs.umich.edu        delete pkt;
954961Ssaidi@eecs.umich.edu
964961Ssaidi@eecs.umich.edu        DPRINTF(DirectedTest, "failed to issue request - sequencer not ready\n");
974961Ssaidi@eecs.umich.edu        return false;
984961Ssaidi@eecs.umich.edu    }
994961Ssaidi@eecs.umich.edu}
1004961Ssaidi@eecs.umich.edu
1014961Ssaidi@eecs.umich.eduvoid
1024961Ssaidi@eecs.umich.eduInvalidateGenerator::performCallback(uint32_t proc, Addr address)
1034961Ssaidi@eecs.umich.edu{
1041897Sstever@eecs.umich.edu    assert(m_address == address);
1054961Ssaidi@eecs.umich.edu
1064961Ssaidi@eecs.umich.edu    if (m_status == InvalidateGeneratorStatus_Load_Pending) {
1074961Ssaidi@eecs.umich.edu        assert(m_active_read_node == proc);
1083725Sstever@eecs.umich.edu        m_active_read_node++;
1094975Ssaidi@eecs.umich.edu        //
1101897Sstever@eecs.umich.edu        // Once all cpus have the block in S state, issue the invalidate
1114961Ssaidi@eecs.umich.edu        //
112        if (m_active_read_node == m_num_cpus) {
113            m_status = InvalidateGeneratorStatus_Inv_Waiting;
114            m_active_read_node = 0;
115        } else {
116            m_status = InvalidateGeneratorStatus_Load_Waiting;
117        }
118    } else if (m_status == InvalidateGeneratorStatus_Inv_Pending) {
119        assert(m_active_inv_node == proc);
120        m_active_inv_node++;
121        if (m_active_inv_node == m_num_cpus) {
122            m_address += m_addr_increment_size;
123            m_active_inv_node = 0;
124        }
125        //
126        // Invalidate completed, send that info to the tester and restart
127        // the cycle
128        //
129        m_directed_tester->incrementCycleCompletions();
130        m_status = InvalidateGeneratorStatus_Load_Waiting;
131    }
132
133}
134
135InvalidateGenerator *
136InvalidateGeneratorParams::create()
137{
138    return new InvalidateGenerator(this);
139}
140