cpu.hh revision 2245
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_O3_CPU_FULL_CPU_HH__
37#define __CPU_O3_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 "config/full_system.hh"
46#include "cpu/base.hh"
47#include "cpu/o3/comm.hh"
48#include "cpu/o3/cpu_policy.hh"
49#include "cpu/exec_context.hh"
50#include "sim/process.hh"
51
52class FunctionalMemory;
53class Process;
54
55class BaseFullCPU : public BaseCPU
56{
57    //Stuff that's pretty ISA independent will go here.
58  public:
59    typedef BaseCPU::Params Params;
60
61#if FULL_SYSTEM
62    BaseFullCPU(Params &params);
63#else
64    BaseFullCPU(Params &params);
65#endif // FULL_SYSTEM
66
67  protected:
68    int cpu_id;
69};
70
71template <class Impl>
72class FullO3CPU : public BaseFullCPU
73{
74  public:
75    //Put typedefs from the Impl here.
76    typedef typename Impl::CPUPol CPUPolicy;
77    typedef typename Impl::Params Params;
78    typedef typename Impl::DynInstPtr DynInstPtr;
79
80  public:
81    enum Status {
82        Running,
83        Idle,
84        Halted,
85        Blocked // ?
86    };
87
88    Status _status;
89
90  private:
91    class TickEvent : public Event
92    {
93      private:
94        FullO3CPU<Impl> *cpu;
95
96      public:
97        TickEvent(FullO3CPU<Impl> *c);
98        void process();
99        const char *description();
100    };
101
102    TickEvent tickEvent;
103
104    /// Schedule tick event, regardless of its current state.
105    void scheduleTickEvent(int delay)
106    {
107        if (tickEvent.squashed())
108            tickEvent.reschedule(curTick + delay);
109        else if (!tickEvent.scheduled())
110            tickEvent.schedule(curTick + delay);
111    }
112
113    /// Unschedule tick event, regardless of its current state.
114    void unscheduleTickEvent()
115    {
116        if (tickEvent.scheduled())
117            tickEvent.squash();
118    }
119
120  public:
121    FullO3CPU(Params &params);
122    ~FullO3CPU();
123
124    void fullCPURegStats();
125
126    void tick();
127
128    void init();
129
130    void activateContext(int thread_num, int delay);
131    void suspendContext(int thread_num);
132    void deallocateContext(int thread_num);
133    void haltContext(int thread_num);
134
135    void switchOut();
136    void takeOverFrom(BaseCPU *oldCPU);
137
138    /** Get the current instruction sequence number, and increment it. */
139    InstSeqNum getAndIncrementInstSeq();
140
141#if FULL_SYSTEM
142    /** Check if this address is a valid instruction address. */
143    bool validInstAddr(Addr addr) { return true; }
144
145    /** Check if this address is a valid data address. */
146    bool validDataAddr(Addr addr) { return true; }
147
148    /** Get instruction asid. */
149    int getInstAsid()
150    { return regFile.miscRegs.getInstAsid(); }
151
152    /** Get data asid. */
153    int getDataAsid()
154    { return regFile.miscRegs.getDataAsid(); }
155#else
156    bool validInstAddr(Addr addr)
157    { return thread[0]->validInstAddr(addr); }
158
159    bool validDataAddr(Addr addr)
160    { return thread[0]->validDataAddr(addr); }
161
162    int getInstAsid() { return thread[0]->asid; }
163    int getDataAsid() { return thread[0]->asid; }
164
165#endif
166
167    //
168    // New accessors for new decoder.
169    //
170    uint64_t readIntReg(int reg_idx);
171
172    float readFloatRegSingle(int reg_idx);
173
174    double readFloatRegDouble(int reg_idx);
175
176    uint64_t readFloatRegInt(int reg_idx);
177
178    void setIntReg(int reg_idx, uint64_t val);
179
180    void setFloatRegSingle(int reg_idx, float val);
181
182    void setFloatRegDouble(int reg_idx, double val);
183
184    void setFloatRegInt(int reg_idx, uint64_t val);
185
186    uint64_t readPC();
187
188    void setNextPC(uint64_t val);
189
190    void setPC(Addr new_PC);
191
192    /** Function to add instruction onto the head of the list of the
193     *  instructions.  Used when new instructions are fetched.
194     */
195    void addInst(DynInstPtr &inst);
196
197    /** Function to tell the CPU that an instruction has completed. */
198    void instDone();
199
200    /** Remove all instructions in back of the given instruction, but leave
201     *  that instruction in the list.  This is useful in a squash, when there
202     *  are instructions in this list that don't exist in structures such as
203     *  the ROB.  The instruction doesn't have to be the last instruction in
204     *  the list, but will be once this function completes.
205     *  @todo: Remove only up until that inst?  Squashed inst is most likely
206     *  valid.
207     */
208    void removeBackInst(DynInstPtr &inst);
209
210    /** Remove an instruction from the front of the list.  It is expected
211     *  that there are no instructions in front of it (that is, none are older
212     *  than the instruction being removed).  Used when retiring instructions.
213     *  @todo: Remove the argument to this function, and just have it remove
214     *  last instruction once it's verified that commit has the same ordering
215     *  as the instruction list.
216     */
217    void removeFrontInst(DynInstPtr &inst);
218
219    /** Remove all instructions that are not currently in the ROB. */
220    void removeInstsNotInROB();
221
222    /** Remove all instructions younger than the given sequence number. */
223    void removeInstsUntil(const InstSeqNum &seq_num);
224
225    /** Remove all instructions from the list. */
226    void removeAllInsts();
227
228    void dumpInsts();
229
230    /** Basically a wrapper function so that instructions executed at
231     *  commit can tell the instruction queue that they have completed.
232     *  Eventually this hack should be removed.
233     */
234    void wakeDependents(DynInstPtr &inst);
235
236  public:
237    /** List of all the instructions in flight. */
238    list<DynInstPtr> instList;
239
240    //not sure these should be private.
241  protected:
242    /** The fetch stage. */
243    typename CPUPolicy::Fetch fetch;
244
245    /** The fetch stage's status. */
246    typename CPUPolicy::Fetch::Status fetchStatus;
247
248    /** The decode stage. */
249    typename CPUPolicy::Decode decode;
250
251    /** The decode stage's status. */
252    typename CPUPolicy::Decode::Status decodeStatus;
253
254    /** The dispatch stage. */
255    typename CPUPolicy::Rename rename;
256
257    /** The dispatch stage's status. */
258    typename CPUPolicy::Rename::Status renameStatus;
259
260    /** The issue/execute/writeback stages. */
261    typename CPUPolicy::IEW iew;
262
263    /** The issue/execute/writeback stage's status. */
264    typename CPUPolicy::IEW::Status iewStatus;
265
266    /** The commit stage. */
267    typename CPUPolicy::Commit commit;
268
269    /** The fetch stage's status. */
270    typename CPUPolicy::Commit::Status commitStatus;
271
272    //Might want to just pass these objects in to the constructors of the
273    //appropriate stage.  regFile is in iew, freeList in dispatch, renameMap
274    //in dispatch, and the rob in commit.
275    /** The register file. */
276    typename CPUPolicy::RegFile regFile;
277
278    /** The free list. */
279    typename CPUPolicy::FreeList freeList;
280
281    /** The rename map. */
282    typename CPUPolicy::RenameMap renameMap;
283
284    /** The re-order buffer. */
285    typename CPUPolicy::ROB rob;
286
287  public:
288    /** Typedefs from the Impl to get the structs that each of the
289     *  time buffers should use.
290     */
291    typedef typename CPUPolicy::TimeStruct TimeStruct;
292
293    typedef typename CPUPolicy::FetchStruct FetchStruct;
294
295    typedef typename CPUPolicy::DecodeStruct DecodeStruct;
296
297    typedef typename CPUPolicy::RenameStruct RenameStruct;
298
299    typedef typename CPUPolicy::IEWStruct IEWStruct;
300
301    /** The main time buffer to do backwards communication. */
302    TimeBuffer<TimeStruct> timeBuffer;
303
304    /** The fetch stage's instruction queue. */
305    TimeBuffer<FetchStruct> fetchQueue;
306
307    /** The decode stage's instruction queue. */
308    TimeBuffer<DecodeStruct> decodeQueue;
309
310    /** The rename stage's instruction queue. */
311    TimeBuffer<RenameStruct> renameQueue;
312
313    /** The IEW stage's instruction queue. */
314    TimeBuffer<IEWStruct> iewQueue;
315
316  public:
317    /** The temporary exec context to support older accessors. */
318    ExecContext *xc;
319
320    /** Temporary function to get pointer to exec context. */
321    ExecContext *xcBase()
322    {
323#if FULL_SYSTEM
324        return system->execContexts[0];
325#else
326        return thread[0];
327#endif
328    }
329
330    InstSeqNum globalSeqNum;
331
332#if FULL_SYSTEM
333    System *system;
334
335    MemoryController *memCtrl;
336    PhysicalMemory *physmem;
337
338    AlphaITB *itb;
339    AlphaDTB *dtb;
340
341//    SWContext *swCtx;
342#else
343    std::vector<ExecContext *> thread;
344#endif
345
346    FunctionalMemory *mem;
347
348    MemInterface *icacheInterface;
349    MemInterface *dcacheInterface;
350
351    bool deferRegistration;
352
353    Counter numInsts;
354
355    Counter funcExeInst;
356};
357
358#endif
359