cpu.hh revision 2632:1bb2f91485ea
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/cpu_exec_context.hh"
48#include "cpu/o3/comm.hh"
49#include "cpu/o3/cpu_policy.hh"
50#include "sim/process.hh"
51
52class ExecContext;
53class FunctionalMemory;
54class Process;
55
56class BaseFullCPU : public BaseCPU
57{
58    //Stuff that's pretty ISA independent will go here.
59  public:
60    typedef BaseCPU::Params Params;
61
62#if FULL_SYSTEM
63    BaseFullCPU(Params &params);
64#else
65    BaseFullCPU(Params &params);
66#endif // FULL_SYSTEM
67
68  protected:
69    int cpu_id;
70};
71
72template <class Impl>
73class FullO3CPU : public BaseFullCPU
74{
75  public:
76    //Put typedefs from the Impl here.
77    typedef typename Impl::CPUPol CPUPolicy;
78    typedef typename Impl::Params Params;
79    typedef typename Impl::DynInstPtr DynInstPtr;
80
81  public:
82    enum Status {
83        Running,
84        Idle,
85        Halted,
86        Blocked // ?
87    };
88
89    Status _status;
90
91  private:
92    class TickEvent : public Event
93    {
94      private:
95        FullO3CPU<Impl> *cpu;
96
97      public:
98        TickEvent(FullO3CPU<Impl> *c);
99        void process();
100        const char *description();
101    };
102
103    TickEvent tickEvent;
104
105    /// Schedule tick event, regardless of its current state.
106    void scheduleTickEvent(int delay)
107    {
108        if (tickEvent.squashed())
109            tickEvent.reschedule(curTick + delay);
110        else if (!tickEvent.scheduled())
111            tickEvent.schedule(curTick + delay);
112    }
113
114    /// Unschedule tick event, regardless of its current state.
115    void unscheduleTickEvent()
116    {
117        if (tickEvent.scheduled())
118            tickEvent.squash();
119    }
120
121  public:
122    FullO3CPU(Params &params);
123    ~FullO3CPU();
124
125    void fullCPURegStats();
126
127    void tick();
128
129    void init();
130
131    void activateContext(int thread_num, int delay);
132    void suspendContext(int thread_num);
133    void deallocateContext(int thread_num);
134    void haltContext(int thread_num);
135
136    void switchOut();
137    void takeOverFrom(BaseCPU *oldCPU);
138
139    /** Get the current instruction sequence number, and increment it. */
140    InstSeqNum getAndIncrementInstSeq();
141
142#if FULL_SYSTEM
143    /** Check if this address is a valid instruction address. */
144    bool validInstAddr(Addr addr) { return true; }
145
146    /** Check if this address is a valid data address. */
147    bool validDataAddr(Addr addr) { return true; }
148
149    /** Get instruction asid. */
150    int getInstAsid()
151    { return regFile.miscRegs.getInstAsid(); }
152
153    /** Get data asid. */
154    int getDataAsid()
155    { return regFile.miscRegs.getDataAsid(); }
156#else
157    bool validInstAddr(Addr addr)
158    { return thread[0]->validInstAddr(addr); }
159
160    bool validDataAddr(Addr addr)
161    { return thread[0]->validDataAddr(addr); }
162
163    int getInstAsid() { return thread[0]->getInstAsid(); }
164    int getDataAsid() { return thread[0]->getDataAsid(); }
165
166#endif
167
168    //
169    // New accessors for new decoder.
170    //
171    uint64_t readIntReg(int reg_idx);
172
173    FloatReg readFloatReg(int reg_idx);
174
175    FloatReg readFloatReg(int reg_idx, int width);
176
177    FloatRegBits readFloatRegBits(int reg_idx);
178
179    FloatRegBits readFloatRegBits(int reg_idx, int width);
180
181    void setIntReg(int reg_idx, uint64_t val);
182
183    void setFloatReg(int reg_idx, FloatReg val, int width);
184
185    void setFloatReg(int reg_idx, FloatReg val, int width);
186
187    void setFloatRegBits(int reg_idx, FloatRegBits val);
188
189    void setFloatRegBits(int reg_idx, FloatRegBits 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    CPUExecContext *cpuXC;
324
325    /** Temporary function to get pointer to exec context. */
326    ExecContext *xcBase()
327    {
328        return thread[0]->getProxy();
329    }
330
331    CPUExecContext *cpuXCBase()
332    {
333        return thread[0];
334    }
335
336    InstSeqNum globalSeqNum;
337
338#if FULL_SYSTEM
339    System *system;
340
341    MemoryController *memCtrl;
342    PhysicalMemory *physmem;
343
344    AlphaITB *itb;
345    AlphaDTB *dtb;
346
347//    SWContext *swCtx;
348#endif
349    std::vector<CPUExecContext *> thread;
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