cpu.hh revision 2632
12391SN/A/*
22391SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
32391SN/A * All rights reserved.
42391SN/A *
52391SN/A * Redistribution and use in source and binary forms, with or without
62391SN/A * modification, are permitted provided that the following conditions are
72391SN/A * met: redistributions of source code must retain the above copyright
82391SN/A * notice, this list of conditions and the following disclaimer;
92391SN/A * redistributions in binary form must reproduce the above copyright
102391SN/A * notice, this list of conditions and the following disclaimer in the
112391SN/A * documentation and/or other materials provided with the distribution;
122391SN/A * neither the name of the copyright holders nor the names of its
132391SN/A * contributors may be used to endorse or promote products derived from
142391SN/A * this software without specific prior written permission.
152391SN/A *
162391SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172391SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182391SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192391SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202391SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212391SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222391SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232391SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242391SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252391SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262391SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292391SN/A//Todo: Add in a lot of the functions that are ISA specific.  Also define
302391SN/A//the functions that currently exist within the base cpu class.  Define
312391SN/A//everything for the simobject stuff so it can be serialized and
322391SN/A//instantiated, add in debugging statements everywhere.  Have CPU schedule
332391SN/A//itself properly.  Threads!
342391SN/A// Avoid running stages and advancing queues if idle/stalled.
352391SN/A
362391SN/A#ifndef __CPU_O3_CPU_FULL_CPU_HH__
372391SN/A#define __CPU_O3_CPU_FULL_CPU_HH__
382462SN/A
392414SN/A#include <iostream>
402415SN/A#include <list>
412415SN/A#include <vector>
422416SN/A
432416SN/A#include "base/statistics.hh"
442462SN/A#include "base/timebuf.hh"
452391SN/A#include "config/full_system.hh"
462391SN/A#include "cpu/base.hh"
472391SN/A#include "cpu/cpu_exec_context.hh"
482462SN/A#include "cpu/o3/comm.hh"
492391SN/A#include "cpu/o3/cpu_policy.hh"
502413SN/A#include "sim/process.hh"
512413SN/A
522413SN/Aclass ExecContext;
532413SN/Aclass FunctionalMemory;
542413SN/Aclass Process;
552413SN/A
562640Sstever@eecs.umich.educlass BaseFullCPU : public BaseCPU
572413SN/A{
582413SN/A    //Stuff that's pretty ISA independent will go here.
592413SN/A  public:
602630SN/A    typedef BaseCPU::Params Params;
612413SN/A
622630SN/A#if FULL_SYSTEM
632413SN/A    BaseFullCPU(Params &params);
642630SN/A#else
652413SN/A    BaseFullCPU(Params &params);
662413SN/A#endif // FULL_SYSTEM
672413SN/A
682521SN/A  protected:
692521SN/A    int cpu_id;
702413SN/A};
712413SN/A
722413SN/Atemplate <class Impl>
732413SN/Aclass FullO3CPU : public BaseFullCPU
742416SN/A{
752416SN/A  public:
762413SN/A    //Put typedefs from the Impl here.
772415SN/A    typedef typename Impl::CPUPol CPUPolicy;
782415SN/A    typedef typename Impl::Params Params;
792630SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
802415SN/A
812415SN/A  public:
822630SN/A    enum Status {
832415SN/A        Running,
842415SN/A        Idle,
852415SN/A        Halted,
862413SN/A        Blocked // ?
872391SN/A    };
882391SN/A
892391SN/A    Status _status;
902391SN/A
912391SN/A  private:
922391SN/A    class TickEvent : public Event
932391SN/A    {
942391SN/A      private:
952391SN/A        FullO3CPU<Impl> *cpu;
962499SN/A
972391SN/A      public:
982565SN/A        TickEvent(FullO3CPU<Impl> *c);
992391SN/A        void process();
1002391SN/A        const char *description();
1012391SN/A    };
1022391SN/A
1032391SN/A    TickEvent tickEvent;
1042391SN/A
1052565SN/A    /// Schedule tick event, regardless of its current state.
1062391SN/A    void scheduleTickEvent(int delay)
1072391SN/A    {
1082391SN/A        if (tickEvent.squashed())
1092415SN/A            tickEvent.reschedule(curTick + delay);
1102521SN/A        else if (!tickEvent.scheduled())
1112521SN/A            tickEvent.schedule(curTick + delay);
1122541SN/A    }
1132391SN/A
1142391SN/A    /// Unschedule tick event, regardless of its current state.
1152414SN/A    void unscheduleTickEvent()
1162413SN/A    {
1172630SN/A        if (tickEvent.scheduled())
1182630SN/A            tickEvent.squash();
1192630SN/A    }
1202413SN/A
1212413SN/A  public:
1222391SN/A    FullO3CPU(Params &params);
1232391SN/A    ~FullO3CPU();
1242391SN/A
1252391SN/A    void fullCPURegStats();
1262497SN/A
1272391SN/A    void tick();
1282391SN/A
1292391SN/A    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