system.hh revision 8769:f95b2a679eb0
1/*
2 * Copyright (c) 2002-2005 The Regents of The University of Michigan
3 * Copyright (c) 2011 Regents of the University of California
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Authors: Steve Reinhardt
30 *          Lisa Hsu
31 *          Nathan Binkert
32 *          Rick Strong
33 */
34
35#ifndef __SYSTEM_HH__
36#define __SYSTEM_HH__
37
38#include <string>
39#include <vector>
40
41#include "base/loader/symtab.hh"
42#include "base/misc.hh"
43#include "base/statistics.hh"
44#include "config/full_system.hh"
45#include "cpu/pc_event.hh"
46#include "enums/MemoryMode.hh"
47#include "kern/system_events.hh"
48#include "mem/port.hh"
49#include "params/System.hh"
50#include "sim/sim_object.hh"
51
52class BaseCPU;
53class BaseRemoteGDB;
54class FunctionalPort;
55class GDBListener;
56class ObjectFile;
57class PhysicalMemory;
58class Platform;
59class ThreadContext;
60class VirtualPort;
61
62class System : public SimObject
63{
64  public:
65
66    static const char *MemoryModeStrings[3];
67
68    Enums::MemoryMode
69    getMemoryMode()
70    {
71        assert(memoryMode);
72        return memoryMode;
73    }
74
75    /** Change the memory mode of the system. This should only be called by the
76     * python!!
77     * @param mode Mode to change to (atomic/timing)
78     */
79    void setMemoryMode(Enums::MemoryMode mode);
80
81    PhysicalMemory *physmem;
82    PCEventQueue pcEventQueue;
83
84    std::vector<ThreadContext *> threadContexts;
85    int _numContexts;
86
87    ThreadContext *getThreadContext(ThreadID tid)
88    {
89        return threadContexts[tid];
90    }
91
92    int numContexts()
93    {
94        assert(_numContexts == (int)threadContexts.size());
95        return _numContexts;
96    }
97
98    /** Return number of running (non-halted) thread contexts in
99     * system.  These threads could be Active or Suspended. */
100    int numRunningContexts();
101
102    /** List to store ranges of memories in this system */
103    AddrRangeList memRanges;
104
105    /** check if an address points to valid system memory
106     * and thus we can fetch instructions out of it
107     */
108    bool isMemory(const Addr addr) const;
109
110    Addr pagePtr;
111
112    uint64_t init_param;
113
114    /** Port to physical memory used for writing object files into ram at
115     * boot.*/
116    FunctionalPort *functionalPort;
117    VirtualPort *virtPort;
118
119    /** kernel symbol table */
120    SymbolTable *kernelSymtab;
121
122    /** Object pointer for the kernel code */
123    ObjectFile *kernel;
124
125    /** Begining of kernel code */
126    Addr kernelStart;
127
128    /** End of kernel code */
129    Addr kernelEnd;
130
131    /** Entry point in the kernel to start at */
132    Addr kernelEntry;
133
134    /** Mask that should be anded for binary/symbol loading.
135     * This allows one two different OS requirements for the same ISA to be
136     * handled.  Some OSes are compiled for a virtual address and need to be
137     * loaded into physical memory that starts at address 0, while other
138     * bare metal tools generate images that start at address 0.
139     */
140    Addr loadAddrMask;
141
142  protected:
143    uint64_t nextPID;
144
145  public:
146    uint64_t allocatePID()
147    {
148        return nextPID++;
149    }
150
151    /** Amount of physical memory that is still free */
152    Addr freeMemSize();
153
154    /** Amount of physical memory that exists */
155    Addr memSize();
156
157  protected:
158    Enums::MemoryMode memoryMode;
159    uint64_t workItemsBegin;
160    uint64_t workItemsEnd;
161    std::vector<bool> activeCpus;
162
163  public:
164    /**
165     * Called by pseudo_inst to track the number of work items started by this
166     * system.
167     */
168    uint64_t
169    incWorkItemsBegin()
170    {
171        return ++workItemsBegin;
172    }
173
174    /**
175     * Called by pseudo_inst to track the number of work items completed by
176     * this system.
177     */
178    uint64_t
179    incWorkItemsEnd()
180    {
181        return ++workItemsEnd;
182    }
183
184    /**
185     * Called by pseudo_inst to mark the cpus actively executing work items.
186     * Returns the total number of cpus that have executed work item begin or
187     * ends.
188     */
189    int
190    markWorkItem(int index)
191    {
192        int count = 0;
193        assert(index < activeCpus.size());
194        activeCpus[index] = true;
195        for (std::vector<bool>::iterator i = activeCpus.begin();
196             i < activeCpus.end(); i++) {
197            if (*i) count++;
198        }
199        return count;
200    }
201
202    /**
203     * Fix up an address used to match PCs for hooking simulator
204     * events on to target function executions.  See comment in
205     * system.cc for details.
206     */
207    virtual Addr fixFuncEventAddr(Addr addr)
208    {
209        panic("Base fixFuncEventAddr not implemented.\n");
210    }
211
212    /**
213     * Add a function-based event to the given function, to be looked
214     * up in the specified symbol table.
215     */
216    template <class T>
217    T *addFuncEvent(SymbolTable *symtab, const char *lbl)
218    {
219        Addr addr = 0; // initialize only to avoid compiler warning
220
221        if (symtab->findAddress(lbl, addr)) {
222            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
223            return ev;
224        }
225
226        return NULL;
227    }
228
229    /** Add a function-based event to kernel code. */
230    template <class T>
231    T *addKernelFuncEvent(const char *lbl)
232    {
233        return addFuncEvent<T>(kernelSymtab, lbl);
234    }
235
236  public:
237    std::vector<BaseRemoteGDB *> remoteGDB;
238    std::vector<GDBListener *> gdbListen;
239    bool breakpoint();
240
241  public:
242    typedef SystemParams Params;
243
244  protected:
245    Params *_params;
246
247  public:
248    System(Params *p);
249    ~System();
250
251    void initState();
252
253    const Params *params() const { return (const Params *)_params; }
254
255  public:
256
257    /**
258     * Returns the addess the kernel starts at.
259     * @return address the kernel starts at
260     */
261    Addr getKernelStart() const { return kernelStart; }
262
263    /**
264     * Returns the addess the kernel ends at.
265     * @return address the kernel ends at
266     */
267    Addr getKernelEnd() const { return kernelEnd; }
268
269    /**
270     * Returns the addess the entry point to the kernel code.
271     * @return entry point of the kernel code
272     */
273    Addr getKernelEntry() const { return kernelEntry; }
274
275    Addr new_page();
276
277    int registerThreadContext(ThreadContext *tc, int assigned=-1);
278    void replaceThreadContext(ThreadContext *tc, int context_id);
279
280    void serialize(std::ostream &os);
281    void unserialize(Checkpoint *cp, const std::string &section);
282    virtual void resume();
283
284  public:
285    Counter totalNumInsts;
286    EventQueue instEventQueue;
287
288    ////////////////////////////////////////////
289    //
290    // STATIC GLOBAL SYSTEM LIST
291    //
292    ////////////////////////////////////////////
293
294    static std::vector<System *> systemList;
295    static int numSystemsRunning;
296
297    static void printSystems();
298
299
300};
301
302#endif // __SYSTEM_HH__
303