base.hh revision 217
12SN/A/*
21762SN/A * Copyright (c) 2003 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#ifndef __SIMPLE_CPU_HH__
302665Ssaidi@eecs.umich.edu#define __SIMPLE_CPU_HH__
312SN/A
322SN/A#include "cpu/base_cpu.hh"
332623SN/A#include "sim/eventq.hh"
342623SN/A#include "base/loader/symtab.hh"
352SN/A#include "cpu/pc_event.hh"
361354SN/A#include "base/statistics.hh"
371858SN/A
381717SN/A
392683Sktlim@umich.edu// forward declarations
401354SN/A#ifdef FULL_SYSTEM
411354SN/Aclass Processor;
422387SN/Aclass Kernel;
432387SN/Aclass AlphaItb;
442387SN/Aclass AlphaDtb;
4556SN/Aclass PhysicalMemory;
462SN/A
472SN/Aclass RemoteGDB;
481858SN/Aclass GDBListener;
492SN/A#endif // FULL_SYSTEM
503453Sgblack@eecs.umich.edu
513453Sgblack@eecs.umich.educlass MemInterface;
523453Sgblack@eecs.umich.educlass IniFile;
533453Sgblack@eecs.umich.edu
543453Sgblack@eecs.umich.edunamespace Trace {
552462SN/A    class InstRecord;
562SN/A}
57715SN/A
58715SN/Aclass SimpleCPU : public BaseCPU
59715SN/A{
60715SN/A  public:
612SN/A    // main simulation loop (one cycle)
622SN/A    void tick();
633960Sgblack@eecs.umich.edu
643960Sgblack@eecs.umich.edu  private:
653960Sgblack@eecs.umich.edu    class TickEvent : public Event
662680Sktlim@umich.edu    {
67237SN/A      private:
682SN/A        SimpleCPU *cpu;
692SN/A
702SN/A      public:
712SN/A        TickEvent(SimpleCPU *c)
722SN/A            : Event(&mainEventQueue, 100), cpu(c) { }
732420SN/A        void process() { cpu->tick(); }
742623SN/A        virtual const char *description() { return "tick event"; }
752SN/A    };
762107SN/A
772107SN/A    TickEvent tickEvent;
782159SN/A
792455SN/A  private:
802455SN/A    Trace::InstRecord *traceData;
812386SN/A    template<typename T>
822623SN/A    void trace_data(T data) {
832SN/A      if (traceData) {
841371SN/A        traceData->setData(data);
852SN/A      }
862SN/A    };
872SN/A
882SN/A  public:
892SN/A    //
902SN/A    enum Status {
912SN/A        Running,
922SN/A        Idle,
932SN/A        IcacheMissStall,
942SN/A        IcacheMissComplete,
952SN/A        DcacheMissStall,
961400SN/A        SwitchedOut
971400SN/A    };
981400SN/A
991858SN/A  private:
1003453Sgblack@eecs.umich.edu    Status _status;
1013453Sgblack@eecs.umich.edu
1022SN/A  public:
1031400SN/A    void post_interrupt(int int_num, int index);
1042SN/A
1051400SN/A    void zero_fill_64(Addr addr) {
1062623SN/A      static int warned = 0;
1072623SN/A      if (!warned) {
1082SN/A        warn ("WH64 is not implemented");
1091400SN/A        warned = 1;
1102683Sktlim@umich.edu      }
1112683Sktlim@umich.edu    };
1122190SN/A
1132683Sktlim@umich.edu#ifdef FULL_SYSTEM
1142683Sktlim@umich.edu
1152683Sktlim@umich.edu    SimpleCPU(const std::string &_name,
1162680Sktlim@umich.edu              System *_system,
1172SN/A              Counter max_insts_any_thread, Counter max_insts_all_threads,
1181858SN/A              Counter max_loads_any_thread, Counter max_loads_all_threads,
1192SN/A              AlphaItb *itb, AlphaDtb *dtb, FunctionalMemory *mem,
1202SN/A              MemInterface *icache_interface, MemInterface *dcache_interface,
1212SN/A              Tick freq);
1222SN/A
1232SN/A#else
1242SN/A
1252SN/A    SimpleCPU(const std::string &_name, Process *_process,
1262SN/A              Counter max_insts_any_thread,
1272566SN/A              Counter max_insts_all_threads,
1284040Ssaidi@eecs.umich.edu              Counter max_loads_any_thread,
1292566SN/A              Counter max_loads_all_threads,
1302107SN/A              MemInterface *icache_interface, MemInterface *dcache_interface);
1313276Sgblack@eecs.umich.edu
1321469SN/A#endif
1332623SN/A
1342662Sstever@eecs.umich.edu    virtual ~SimpleCPU();
1352623SN/A
1362623SN/A    // execution context
1372623SN/A    ExecContext *xc;
138180SN/A
139393SN/A    void switchOut();
140393SN/A    void takeOverFrom(BaseCPU *oldCPU);
1412SN/A
1422SN/A#ifdef FULL_SYSTEM
143334SN/A    Addr dbg_vtophys(Addr addr);
144334SN/A
1452SN/A    bool interval_stats;
1462SN/A#endif
1472SN/A
148334SN/A    // L1 instruction cache
149729SN/A    MemInterface *icacheInterface;
150707SN/A
151707SN/A    // L1 data cache
152707SN/A    MemInterface *dcacheInterface;
153707SN/A
154707SN/A    // current instruction
1552SN/A    MachInst inst;
1562SN/A
157729SN/A    // Refcounted pointer to the one memory request.
1582SN/A    MemReqPtr memReq;
159124SN/A
160124SN/A    class CacheCompletionEvent : public Event
161334SN/A    {
162124SN/A      private:
1632SN/A        SimpleCPU *cpu;
164729SN/A
165729SN/A      public:
1662SN/A        CacheCompletionEvent(SimpleCPU *_cpu);
1672390SN/A
168729SN/A        virtual void process();
1692SN/A        virtual const char *description();
1702SN/A    };
1712390SN/A
1722390SN/A    CacheCompletionEvent cacheCompletionEvent;
1732390SN/A
1742390SN/A    Status status() const { return _status; }
1752390SN/A
176729SN/A    virtual void execCtxStatusChg(int thread_num);
1772SN/A
1782SN/A    void setStatus(Status new_status) {
1792390SN/A        Status old_status = status();
1802390SN/A
1812390SN/A        // We should never even get here if the CPU has been switched out.
1822390SN/A        assert(old_status != SwitchedOut);
183217SN/A
184237SN/A        _status = new_status;
1852SN/A
1861371SN/A        switch (status()) {
1871371SN/A          case IcacheMissStall:
1882623SN/A            assert(old_status == Running);
1893918Ssaidi@eecs.umich.edu            lastIcacheStall = curTick;
1903918Ssaidi@eecs.umich.edu            if (tickEvent.scheduled())
1911371SN/A                tickEvent.squash();
192581SN/A            break;
1932SN/A
1942SN/A          case IcacheMissComplete:
1952SN/A            assert(old_status == IcacheMissStall);
1962SN/A            if (tickEvent.squashed())
197753SN/A                tickEvent.reschedule(curTick + 1);
1982SN/A            else if (!tickEvent.scheduled())
1992SN/A                tickEvent.schedule(curTick + 1);
2002SN/A            break;
201594SN/A
202595SN/A          case DcacheMissStall:
203594SN/A            assert(old_status == Running);
204595SN/A            lastDcacheStall = curTick;
205705SN/A            if (tickEvent.scheduled())
206726SN/A                tickEvent.squash();
207726SN/A            break;
208726SN/A
209726SN/A          case Idle:
210726SN/A            assert(old_status == Running);
211726SN/A            last_idle = curTick;
212726SN/A            if (tickEvent.scheduled())
213726SN/A                tickEvent.squash();
214726SN/A            break;
215726SN/A
216705SN/A          case Running:
2173735Sstever@eecs.umich.edu            assert(old_status == Idle ||
218726SN/A                   old_status == DcacheMissStall ||
2192683Sktlim@umich.edu                   old_status == IcacheMissComplete);
220726SN/A            if (old_status == Idle)
221705SN/A                idleCycles += curTick - last_idle;
2223735Sstever@eecs.umich.edu
223726SN/A            if (tickEvent.squashed())
224726SN/A                tickEvent.reschedule(curTick + 1);
2252683Sktlim@umich.edu            else if (!tickEvent.scheduled())
226726SN/A                tickEvent.schedule(curTick + 1);
227705SN/A            break;
2283735Sstever@eecs.umich.edu
229726SN/A          default:
230726SN/A            panic("can't get here");
2312683Sktlim@umich.edu        }
232726SN/A    }
233705SN/A
2343735Sstever@eecs.umich.edu    // statistics
2353735Sstever@eecs.umich.edu    void regStats();
236726SN/A
237726SN/A    // number of simulated instructions
2382683Sktlim@umich.edu    Counter numInst;
2392455SN/A    Statistics::Formula numInsts;
2402455SN/A
2413735Sstever@eecs.umich.edu    // number of simulated memory references
2422455SN/A    Statistics::Scalar<> numMemRefs;
2432455SN/A
2442683Sktlim@umich.edu    // number of simulated loads
245726SN/A    Counter numLoad;
246705SN/A
2473735Sstever@eecs.umich.edu    // number of idle cycles
248726SN/A    Statistics::Scalar<> idleCycles;
2492683Sktlim@umich.edu    Statistics::Formula idleFraction;
250726SN/A    Counter last_idle;
251705SN/A
2523735Sstever@eecs.umich.edu    // number of cycles stalled for I-cache misses
2533735Sstever@eecs.umich.edu    Statistics::Scalar<> icacheStallCycles;
254726SN/A    Counter lastIcacheStall;
255726SN/A
2562683Sktlim@umich.edu    // number of cycles stalled for D-cache misses
257726SN/A    Statistics::Scalar<> dcacheStallCycles;
258705SN/A    Counter lastDcacheStall;
2593735Sstever@eecs.umich.edu
260726SN/A    void processCacheCompletion();
261726SN/A
2622683Sktlim@umich.edu    virtual void serialize(std::ostream &os);
263726SN/A    virtual void unserialize(IniFile &db, const std::string &section);
264726SN/A
2653735Sstever@eecs.umich.edu    template <class T>
2663735Sstever@eecs.umich.edu    Fault read(Addr addr, T& data, unsigned flags);
267726SN/A
268726SN/A    template <class T>
2692683Sktlim@umich.edu    Fault write(T data, Addr addr, unsigned flags,
2702455SN/A                        uint64_t *res);
2712455SN/A
2723735Sstever@eecs.umich.edu    Fault prefetch(Addr addr, unsigned flags)
2733735Sstever@eecs.umich.edu    {
2742455SN/A        // need to do this...
2752455SN/A        return No_Fault;
2762683Sktlim@umich.edu    }
277726SN/A
278705SN/A    void writeHint(Addr addr, int size)
2792683Sktlim@umich.edu    {
2802683Sktlim@umich.edu        // need to do this...
2812683Sktlim@umich.edu    }
2822447SN/A};
2832683Sktlim@umich.edu
2842683Sktlim@umich.edu#endif // __SIMPLE_CPU_HH__
2852683Sktlim@umich.edu