atomic.hh revision 11331:cd5c48db28e6
12SN/A/*
21762SN/A * Copyright (c) 2012-2013,2015 ARM Limited
32SN/A * All rights reserved.
42SN/A *
52SN/A * The license below extends only to copyright in the software and shall
62SN/A * not be construed as granting a license to any other intellectual
72SN/A * property including but not limited to intellectual property relating
82SN/A * to a hardware implementation of the functionality of the software
92SN/A * licensed hereunder.  You may use the software subject to the license
102SN/A * terms below provided that you ensure that this notice is replicated
112SN/A * unmodified and in its entirety in all distributions of the software,
122SN/A * modified or unmodified, in source code or in binary form.
132SN/A *
142SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
152SN/A * All rights reserved.
162SN/A *
172SN/A * Redistribution and use in source and binary forms, with or without
182SN/A * modification, are permitted provided that the following conditions are
192SN/A * met: redistributions of source code must retain the above copyright
202SN/A * notice, this list of conditions and the following disclaimer;
212SN/A * redistributions in binary form must reproduce the above copyright
222SN/A * notice, this list of conditions and the following disclaimer in the
232SN/A * documentation and/or other materials provided with the distribution;
242SN/A * neither the name of the copyright holders nor the names of its
252SN/A * contributors may be used to endorse or promote products derived from
262SN/A * this software without specific prior written permission.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292665Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302665Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
368229Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372984Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382171SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39146SN/A *
40146SN/A * Authors: Steve Reinhardt
41146SN/A */
422680Sktlim@umich.edu
432SN/A#ifndef __CPU_SIMPLE_ATOMIC_HH__
442SN/A#define __CPU_SIMPLE_ATOMIC_HH__
452SN/A
464088Sbinkertn@umich.edu#include "cpu/simple/base.hh"
475569Snate@binkert.org#include "cpu/simple/exec_context.hh"
483838Shsul@eecs.umich.edu#include "params/AtomicSimpleCPU.hh"
493838Shsul@eecs.umich.edu#include "sim/probe/probe.hh"
503838Shsul@eecs.umich.edu
513838Shsul@eecs.umich.educlass AtomicSimpleCPU : public BaseSimpleCPU
525569Snate@binkert.org{
53860SN/A  public:
543838Shsul@eecs.umich.edu
553838Shsul@eecs.umich.edu    AtomicSimpleCPU(AtomicSimpleCPUParams *params);
56860SN/A    virtual ~AtomicSimpleCPU();
57860SN/A
585569Snate@binkert.org    void init() override;
591147SN/A
605034Smilesck@eecs.umich.edu  private:
615358Sgblack@eecs.umich.edu
623838Shsul@eecs.umich.edu    struct TickEvent : public Event
635004Sgblack@eecs.umich.edu    {
645004Sgblack@eecs.umich.edu        AtomicSimpleCPU *cpu;
654957Sacolyte@umich.edu
663838Shsul@eecs.umich.edu        TickEvent(AtomicSimpleCPU *c);
672SN/A        void process();
683838Shsul@eecs.umich.edu        const char *description() const;
693838Shsul@eecs.umich.edu    };
703838Shsul@eecs.umich.edu
713838Shsul@eecs.umich.edu    TickEvent tickEvent;
723838Shsul@eecs.umich.edu
732SN/A    const int width;
746022Sgblack@eecs.umich.edu    bool locked;
756022Sgblack@eecs.umich.edu    const bool simulate_data_stalls;
766022Sgblack@eecs.umich.edu    const bool simulate_inst_stalls;
776022Sgblack@eecs.umich.edu
786022Sgblack@eecs.umich.edu    // main simulation loop (one cycle)
796022Sgblack@eecs.umich.edu    void tick();
806022Sgblack@eecs.umich.edu
816022Sgblack@eecs.umich.edu    /**
826022Sgblack@eecs.umich.edu     * Check if a system is in a drained state.
836022Sgblack@eecs.umich.edu     *
846022Sgblack@eecs.umich.edu     * We need to drain if:
856022Sgblack@eecs.umich.edu     * <ul>
866022Sgblack@eecs.umich.edu     * <li>We are in the middle of a microcode sequence as some CPUs
876022Sgblack@eecs.umich.edu     *     (e.g., HW accelerated CPUs) can't be started in the middle
886022Sgblack@eecs.umich.edu     *     of a gem5 microcode sequence.
896022Sgblack@eecs.umich.edu     *
906022Sgblack@eecs.umich.edu     * <li>The CPU is in a LLSC region. This shouldn't normally happen
916022Sgblack@eecs.umich.edu     *     as these are executed atomically within a single tick()
926022Sgblack@eecs.umich.edu     *     call. The only way this can happen at the moment is if
936022Sgblack@eecs.umich.edu     *     there is an event in the PC event queue that affects the
946022Sgblack@eecs.umich.edu     *     CPU state while it is in an LLSC region.
956022Sgblack@eecs.umich.edu     *
966022Sgblack@eecs.umich.edu     * <li>Stay at PC is true.
976022Sgblack@eecs.umich.edu     * </ul>
986022Sgblack@eecs.umich.edu     */
996022Sgblack@eecs.umich.edu    bool isDrained() {
1006022Sgblack@eecs.umich.edu        SimpleExecContext &t_info = *threadInfo[curThread];
1016022Sgblack@eecs.umich.edu
1026022Sgblack@eecs.umich.edu        return t_info.thread->microPC() == 0 &&
1036022Sgblack@eecs.umich.edu            !locked &&
1046022Sgblack@eecs.umich.edu            !t_info.stayAtPC;
1056022Sgblack@eecs.umich.edu    }
1066022Sgblack@eecs.umich.edu
1076022Sgblack@eecs.umich.edu    /**
1086022Sgblack@eecs.umich.edu     * Try to complete a drain request.
1096022Sgblack@eecs.umich.edu     *
1106022Sgblack@eecs.umich.edu     * @returns true if the CPU is drained, false otherwise.
1116022Sgblack@eecs.umich.edu     */
1126022Sgblack@eecs.umich.edu    bool tryCompleteDrain();
1136022Sgblack@eecs.umich.edu
1146022Sgblack@eecs.umich.edu    /**
1156022Sgblack@eecs.umich.edu     * An AtomicCPUPort overrides the default behaviour of the
1166022Sgblack@eecs.umich.edu     * recvAtomicSnoop and ignores the packet instead of panicking. It
1176022Sgblack@eecs.umich.edu     * also provides an implementation for the purely virtual timing
1186022Sgblack@eecs.umich.edu     * functions and panics on either of these.
1196022Sgblack@eecs.umich.edu     */
1206022Sgblack@eecs.umich.edu    class AtomicCPUPort : public MasterPort
1216022Sgblack@eecs.umich.edu    {
1226022Sgblack@eecs.umich.edu
1236022Sgblack@eecs.umich.edu      public:
1246022Sgblack@eecs.umich.edu
1256022Sgblack@eecs.umich.edu        AtomicCPUPort(const std::string &_name, BaseSimpleCPU* _cpu)
1266022Sgblack@eecs.umich.edu            : MasterPort(_name, _cpu)
1276022Sgblack@eecs.umich.edu        { }
1286022Sgblack@eecs.umich.edu
1296022Sgblack@eecs.umich.edu      protected:
1306022Sgblack@eecs.umich.edu
1316022Sgblack@eecs.umich.edu        bool recvTimingResp(PacketPtr pkt)
1326022Sgblack@eecs.umich.edu        {
1336022Sgblack@eecs.umich.edu            panic("Atomic CPU doesn't expect recvTimingResp!\n");
1346022Sgblack@eecs.umich.edu            return true;
1356022Sgblack@eecs.umich.edu        }
1366022Sgblack@eecs.umich.edu
1376022Sgblack@eecs.umich.edu        void recvReqRetry()
1386022Sgblack@eecs.umich.edu        {
1396022Sgblack@eecs.umich.edu            panic("Atomic CPU doesn't expect recvRetry!\n");
1406022Sgblack@eecs.umich.edu        }
1416022Sgblack@eecs.umich.edu
1426022Sgblack@eecs.umich.edu    };
1436022Sgblack@eecs.umich.edu
1446022Sgblack@eecs.umich.edu    class AtomicCPUDPort : public AtomicCPUPort
1456022Sgblack@eecs.umich.edu    {
1466022Sgblack@eecs.umich.edu
1476022Sgblack@eecs.umich.edu      public:
1486022Sgblack@eecs.umich.edu
1496022Sgblack@eecs.umich.edu        AtomicCPUDPort(const std::string &_name, BaseSimpleCPU* _cpu)
1506022Sgblack@eecs.umich.edu            : AtomicCPUPort(_name, _cpu), cpu(_cpu)
1516022Sgblack@eecs.umich.edu        {
1526022Sgblack@eecs.umich.edu            cacheBlockMask = ~(cpu->cacheLineSize() - 1);
1536022Sgblack@eecs.umich.edu        }
1546022Sgblack@eecs.umich.edu
1556022Sgblack@eecs.umich.edu        bool isSnooping() const { return true; }
1566022Sgblack@eecs.umich.edu
1576022Sgblack@eecs.umich.edu        Addr cacheBlockMask;
1583838Shsul@eecs.umich.edu      protected:
1595004Sgblack@eecs.umich.edu        BaseSimpleCPU *cpu;
1604967Sacolyte@umich.edu
1613838Shsul@eecs.umich.edu        virtual Tick recvAtomicSnoop(PacketPtr pkt);
1623838Shsul@eecs.umich.edu        virtual void recvFunctionalSnoop(PacketPtr pkt);
1635004Sgblack@eecs.umich.edu    };
1642SN/A
1655004Sgblack@eecs.umich.edu
1665004Sgblack@eecs.umich.edu    AtomicCPUPort icachePort;
1675004Sgblack@eecs.umich.edu    AtomicCPUDPort dcachePort;
1685004Sgblack@eecs.umich.edu
1695004Sgblack@eecs.umich.edu    bool fastmem;
1705004Sgblack@eecs.umich.edu    Request ifetch_req;
1715004Sgblack@eecs.umich.edu    Request data_read_req;
1725004Sgblack@eecs.umich.edu    Request data_write_req;
1735004Sgblack@eecs.umich.edu
1745004Sgblack@eecs.umich.edu    bool dcache_access;
1755004Sgblack@eecs.umich.edu    Tick dcache_latency;
1764962Sacolyte@umich.edu
1774962Sacolyte@umich.edu    /** Probe Points. */
1784962Sacolyte@umich.edu    ProbePointArg<std::pair<SimpleThread*, const StaticInstPtr>> *ppCommit;
1794967Sacolyte@umich.edu
1804957Sacolyte@umich.edu  protected:
1814957Sacolyte@umich.edu
1824957Sacolyte@umich.edu    /** Return a reference to the data port. */
1834957Sacolyte@umich.edu    MasterPort &getDataPort() override { return dcachePort; }
1845004Sgblack@eecs.umich.edu
1855004Sgblack@eecs.umich.edu    /** Return a reference to the instruction port. */
1865004Sgblack@eecs.umich.edu    MasterPort &getInstPort() override { return icachePort; }
1875004Sgblack@eecs.umich.edu
1884957Sacolyte@umich.edu    /** Perform snoop for other cpu-local thread contexts. */
1894957Sacolyte@umich.edu    void threadSnoop(PacketPtr pkt, ThreadID sender);
1904957Sacolyte@umich.edu
1914957Sacolyte@umich.edu  public:
1921413SN/A
1931413SN/A    DrainState drain() override;
1942SN/A    void drainResume() override;
1952SN/A
1963838Shsul@eecs.umich.edu    void switchOut() override;
1973838Shsul@eecs.umich.edu    void takeOverFrom(BaseCPU *oldCPU) override;
1983838Shsul@eecs.umich.edu
1993838Shsul@eecs.umich.edu    void verifyMemoryMode() const override;
2002SN/A
2013838Shsul@eecs.umich.edu    void activateContext(ThreadID thread_num) override;
2025532Ssaidi@eecs.umich.edu    void suspendContext(ThreadID thread_num) override;
2033838Shsul@eecs.umich.edu
2045569Snate@binkert.org    Fault readMem(Addr addr, uint8_t *data, unsigned size,
2055569Snate@binkert.org                  unsigned flags) override;
2063838Shsul@eecs.umich.edu
2075569Snate@binkert.org    Fault initiateMemRead(Addr addr, unsigned size, unsigned flags) override;
2085569Snate@binkert.org
2095569Snate@binkert.org    Fault writeMem(uint8_t *data, unsigned size,
2105569Snate@binkert.org                   Addr addr, unsigned flags, uint64_t *res) override;
2115569Snate@binkert.org
2125569Snate@binkert.org    void regProbePoints() override;
2135569Snate@binkert.org
2145569Snate@binkert.org    /**
2153838Shsul@eecs.umich.edu     * Print state of address in memory system via PrintReq (for
2163838Shsul@eecs.umich.edu     * debugging).
2176025Snate@binkert.org     */
2183838Shsul@eecs.umich.edu    void printAddr(Addr a);
2193838Shsul@eecs.umich.edu};
2203838Shsul@eecs.umich.edu
2213838Shsul@eecs.umich.edu#endif // __CPU_SIMPLE_ATOMIC_HH__
2223838Shsul@eecs.umich.edu