cpu.hh revision 1689
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29//Todo: Add in a lot of the functions that are ISA specific.  Also define
30//the functions that currently exist within the base cpu class.  Define
31//everything for the simobject stuff so it can be serialized and
32//instantiated, add in debugging statements everywhere.  Have CPU schedule
33//itself properly.  Threads!
34// Avoid running stages and advancing queues if idle/stalled.
35
36#ifndef __CPU_BETA_CPU_FULL_CPU_HH__
37#define __CPU_BETA_CPU_FULL_CPU_HH__
38
39#include <iostream>
40#include <list>
41#include <vector>
42
43#include "base/statistics.hh"
44#include "base/timebuf.hh"
45#include "cpu/base_cpu.hh"
46#include "cpu/beta_cpu/comm.hh"
47#include "cpu/beta_cpu/cpu_policy.hh"
48#include "cpu/exec_context.hh"
49#include "sim/process.hh"
50
51#ifdef FULL_SYSTEM
52#include "arch/alpha/ev5.hh"
53using namespace EV5;
54#endif
55
56class FunctionalMemory;
57class Process;
58
59class BaseFullCPU : public BaseCPU
60{
61    //Stuff that's pretty ISA independent will go here.
62  public:
63    typedef BaseCPU::Params Params;
64
65#ifdef FULL_SYSTEM
66    BaseFullCPU(Params &params);
67#else
68    BaseFullCPU(Params &params);
69#endif // FULL_SYSTEM
70
71  protected:
72    int cpu_id;
73};
74
75template <class Impl>
76class FullBetaCPU : public BaseFullCPU
77{
78  public:
79    //Put typedefs from the Impl here.
80    typedef typename Impl::ISA ISA;
81    typedef typename Impl::CPUPol CPUPolicy;
82    typedef typename Impl::Params Params;
83    typedef typename Impl::DynInstPtr DynInstPtr;
84
85  public:
86    enum Status {
87        Running,
88        Idle,
89        Halted,
90        Blocked // ?
91    };
92
93    Status _status;
94
95  private:
96    class TickEvent : public Event
97    {
98      private:
99        FullBetaCPU<Impl> *cpu;
100
101      public:
102        TickEvent(FullBetaCPU<Impl> *c);
103        void process();
104        const char *description();
105    };
106
107    TickEvent tickEvent;
108
109    /// Schedule tick event, regardless of its current state.
110    void scheduleTickEvent(int delay)
111    {
112        if (tickEvent.squashed())
113            tickEvent.reschedule(curTick + delay);
114        else if (!tickEvent.scheduled())
115            tickEvent.schedule(curTick + delay);
116    }
117
118    /// Unschedule tick event, regardless of its current state.
119    void unscheduleTickEvent()
120    {
121        if (tickEvent.scheduled())
122            tickEvent.squash();
123    }
124
125  public:
126    FullBetaCPU(Params &params);
127    ~FullBetaCPU();
128
129    void fullCPURegStats();
130
131    void tick();
132
133    void init();
134
135    void activateContext(int thread_num, int delay);
136    void suspendContext(int thread_num);
137    void deallocateContext(int thread_num);
138    void haltContext(int thread_num);
139
140    void switchOut();
141    void takeOverFrom(BaseCPU *oldCPU);
142
143    /** Get the current instruction sequence number, and increment it. */
144    InstSeqNum getAndIncrementInstSeq();
145
146#ifdef FULL_SYSTEM
147    /** Check if this address is a valid instruction address. */
148    bool validInstAddr(Addr addr) { return true; }
149
150    /** Check if this address is a valid data address. */
151    bool validDataAddr(Addr addr) { return true; }
152
153    /** Get instruction asid. */
154    int getInstAsid()
155    { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); }
156
157    /** Get data asid. */
158    int getDataAsid()
159    { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); }
160#else
161    bool validInstAddr(Addr addr)
162    { return thread[0]->validInstAddr(addr); }
163
164    bool validDataAddr(Addr addr)
165    { return thread[0]->validDataAddr(addr); }
166
167    int getInstAsid() { return thread[0]->asid; }
168    int getDataAsid() { return thread[0]->asid; }
169
170#endif
171
172    //
173    // New accessors for new decoder.
174    //
175    uint64_t readIntReg(int reg_idx);
176
177    float readFloatRegSingle(int reg_idx);
178
179    double readFloatRegDouble(int reg_idx);
180
181    uint64_t readFloatRegInt(int reg_idx);
182
183    void setIntReg(int reg_idx, uint64_t val);
184
185    void setFloatRegSingle(int reg_idx, float val);
186
187    void setFloatRegDouble(int reg_idx, double val);
188
189    void setFloatRegInt(int reg_idx, uint64_t val);
190
191    uint64_t readPC();
192
193    void setNextPC(uint64_t val);
194
195    void setPC(Addr new_PC);
196
197    /** Function to add instruction onto the head of the list of the
198     *  instructions.  Used when new instructions are fetched.
199     */
200    void addInst(DynInstPtr &inst);
201
202    /** Function to tell the CPU that an instruction has completed. */
203    void instDone();
204
205    /** Remove all instructions in back of the given instruction, but leave
206     *  that instruction in the list.  This is useful in a squash, when there
207     *  are instructions in this list that don't exist in structures such as
208     *  the ROB.  The instruction doesn't have to be the last instruction in
209     *  the list, but will be once this function completes.
210     *  @todo: Remove only up until that inst?  Squashed inst is most likely
211     *  valid.
212     */
213    void removeBackInst(DynInstPtr &inst);
214
215    /** Remove an instruction from the front of the list.  It is expected
216     *  that there are no instructions in front of it (that is, none are older
217     *  than the instruction being removed).  Used when retiring instructions.
218     *  @todo: Remove the argument to this function, and just have it remove
219     *  last instruction once it's verified that commit has the same ordering
220     *  as the instruction list.
221     */
222    void removeFrontInst(DynInstPtr &inst);
223
224    /** Remove all instructions that are not currently in the ROB. */
225    void removeInstsNotInROB();
226
227    /** Remove all instructions younger than the given sequence number. */
228    void removeInstsUntil(const InstSeqNum &seq_num);
229
230    /** Remove all instructions from the list. */
231    void removeAllInsts();
232
233    void dumpInsts();
234
235    /** Basically a wrapper function so that instructions executed at
236     *  commit can tell the instruction queue that they have completed.
237     *  Eventually this hack should be removed.
238     */
239    void wakeDependents(DynInstPtr &inst);
240
241  public:
242    /** List of all the instructions in flight. */
243    list<DynInstPtr> instList;
244
245    //not sure these should be private.
246  protected:
247    /** The fetch stage. */
248    typename CPUPolicy::Fetch fetch;
249
250    /** The fetch stage's status. */
251    typename CPUPolicy::Fetch::Status fetchStatus;
252
253    /** The decode stage. */
254    typename CPUPolicy::Decode decode;
255
256    /** The decode stage's status. */
257    typename CPUPolicy::Decode::Status decodeStatus;
258
259    /** The dispatch stage. */
260    typename CPUPolicy::Rename rename;
261
262    /** The dispatch stage's status. */
263    typename CPUPolicy::Rename::Status renameStatus;
264
265    /** The issue/execute/writeback stages. */
266    typename CPUPolicy::IEW iew;
267
268    /** The issue/execute/writeback stage's status. */
269    typename CPUPolicy::IEW::Status iewStatus;
270
271    /** The commit stage. */
272    typename CPUPolicy::Commit commit;
273
274    /** The fetch stage's status. */
275    typename CPUPolicy::Commit::Status commitStatus;
276
277    //Might want to just pass these objects in to the constructors of the
278    //appropriate stage.  regFile is in iew, freeList in dispatch, renameMap
279    //in dispatch, and the rob in commit.
280    /** The register file. */
281    typename CPUPolicy::RegFile regFile;
282
283    /** The free list. */
284    typename CPUPolicy::FreeList freeList;
285
286    /** The rename map. */
287    typename CPUPolicy::RenameMap renameMap;
288
289    /** The re-order buffer. */
290    typename CPUPolicy::ROB rob;
291
292  public:
293    /** Typedefs from the Impl to get the structs that each of the
294     *  time buffers should use.
295     */
296    typedef typename CPUPolicy::TimeStruct TimeStruct;
297
298    typedef typename CPUPolicy::FetchStruct FetchStruct;
299
300    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
301
302    typedef typename CPUPolicy::RenameStruct RenameStruct;
303
304    typedef typename CPUPolicy::IEWStruct IEWStruct;
305
306    /** The main time buffer to do backwards communication. */
307    TimeBuffer<TimeStruct> timeBuffer;
308
309    /** The fetch stage's instruction queue. */
310    TimeBuffer<FetchStruct> fetchQueue;
311
312    /** The decode stage's instruction queue. */
313    TimeBuffer<DecodeStruct> decodeQueue;
314
315    /** The rename stage's instruction queue. */
316    TimeBuffer<RenameStruct> renameQueue;
317
318    /** The IEW stage's instruction queue. */
319    TimeBuffer<IEWStruct> iewQueue;
320
321  public:
322    /** The temporary exec context to support older accessors. */
323    ExecContext *xc;
324
325    /** Temporary function to get pointer to exec context. */
326    ExecContext *xcBase()
327    {
328#ifdef FULL_SYSTEM
329        return system->execContexts[0];
330#else
331        return thread[0];
332#endif
333    }
334
335    InstSeqNum globalSeqNum;
336
337#ifdef FULL_SYSTEM
338    System *system;
339
340    MemoryController *memCtrl;
341    PhysicalMemory *physmem;
342
343    AlphaITB *itb;
344    AlphaDTB *dtb;
345
346//    SWContext *swCtx;
347#else
348    std::vector<ExecContext *> thread;
349#endif
350
351    FunctionalMemory *mem;
352
353    MemInterface *icacheInterface;
354    MemInterface *dcacheInterface;
355
356    bool deferRegistration;
357
358    Counter numInsts;
359
360    Counter funcExeInst;
361};
362
363#endif
364