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