system.hh revision 8703
1/*
2 * Copyright (c) 2012 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2002-2005 The Regents of The University of Michigan
15 * Copyright (c) 2011 Regents of the University of California
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Steve Reinhardt
42 *          Lisa Hsu
43 *          Nathan Binkert
44 *          Rick Strong
45 */
46
47#ifndef __SYSTEM_HH__
48#define __SYSTEM_HH__
49
50#include <string>
51#include <vector>
52
53#include "base/loader/symtab.hh"
54#include "base/misc.hh"
55#include "base/statistics.hh"
56#include "config/full_system.hh"
57#include "cpu/pc_event.hh"
58#include "enums/MemoryMode.hh"
59#include "mem/mem_object.hh"
60#include "mem/port.hh"
61#include "params/System.hh"
62
63#if FULL_SYSTEM
64#include "kern/system_events.hh"
65#endif
66
67class BaseCPU;
68class ThreadContext;
69class ObjectFile;
70class PhysicalMemory;
71
72#if FULL_SYSTEM
73class Platform;
74class FunctionalPort;
75class VirtualPort;
76#endif
77class GDBListener;
78class BaseRemoteGDB;
79
80class System : public MemObject
81{
82  private:
83
84    /**
85     * Private class for the system port which is only used as a
86     * master for debug access and for non-structural entities that do
87     * not have a port of their own.
88     */
89    class SystemPort : public Port
90    {
91      public:
92
93        /**
94         * Create a system port with a name and an owner.
95         */
96        SystemPort(const std::string &_name, MemObject *_owner)
97            : Port(_name, _owner)
98        { }
99        bool recvTiming(PacketPtr pkt)
100        { panic("SystemPort does not receive timing!\n"); return false; }
101        Tick recvAtomic(PacketPtr pkt)
102        { panic("SystemPort does not receive atomic!\n"); return 0; }
103        void recvFunctional(PacketPtr pkt)
104        { panic("SystemPort does not receive functional!\n"); }
105        void recvStatusChange(Status status) { }
106
107    };
108
109    SystemPort _systemPort;
110
111  public:
112
113    /**
114     * Get a pointer to the system port that can be used by
115     * non-structural simulation objects like processes or threads, or
116     * external entities like loaders and debuggers, etc, to access
117     * the memory system.
118     *
119     * @return a pointer to the system port we own
120     */
121    Port* getSystemPort() { return &_systemPort; }
122
123    /**
124     * Additional function to return the Port of a memory object.
125     */
126    Port *getPort(const std::string &if_name, int idx = -1);
127
128    static const char *MemoryModeStrings[3];
129
130    Enums::MemoryMode
131    getMemoryMode()
132    {
133        assert(memoryMode);
134        return memoryMode;
135    }
136
137    /** Change the memory mode of the system. This should only be called by the
138     * python!!
139     * @param mode Mode to change to (atomic/timing)
140     */
141    void setMemoryMode(Enums::MemoryMode mode);
142
143    PhysicalMemory *physmem;
144    PCEventQueue pcEventQueue;
145
146    std::vector<ThreadContext *> threadContexts;
147    int _numContexts;
148
149    ThreadContext *getThreadContext(ThreadID tid)
150    {
151        return threadContexts[tid];
152    }
153
154    int numContexts()
155    {
156        assert(_numContexts == (int)threadContexts.size());
157        return _numContexts;
158    }
159
160    /** Return number of running (non-halted) thread contexts in
161     * system.  These threads could be Active or Suspended. */
162    int numRunningContexts();
163
164    /** List to store ranges of memories in this system */
165    AddrRangeList memRanges;
166
167    /** check if an address points to valid system memory
168     * and thus we can fetch instructions out of it
169     */
170    bool isMemory(const Addr addr) const;
171
172#if FULL_SYSTEM
173    Platform *platform;
174    uint64_t init_param;
175
176    /** Port to physical memory used for writing object files into ram at
177     * boot.*/
178    FunctionalPort *functionalPort;
179    VirtualPort *virtPort;
180
181    /** kernel symbol table */
182    SymbolTable *kernelSymtab;
183
184    /** Object pointer for the kernel code */
185    ObjectFile *kernel;
186
187    /** Begining of kernel code */
188    Addr kernelStart;
189
190    /** End of kernel code */
191    Addr kernelEnd;
192
193    /** Entry point in the kernel to start at */
194    Addr kernelEntry;
195
196    /** Mask that should be anded for binary/symbol loading.
197     * This allows one two different OS requirements for the same ISA to be
198     * handled.  Some OSes are compiled for a virtual address and need to be
199     * loaded into physical memory that starts at address 0, while other
200     * bare metal tools generate images that start at address 0.
201     */
202    Addr loadAddrMask;
203
204#else
205
206    Addr pagePtr;
207
208  protected:
209    uint64_t nextPID;
210
211  public:
212    uint64_t allocatePID()
213    {
214        return nextPID++;
215    }
216
217    /** Amount of physical memory that is still free */
218    Addr freeMemSize();
219
220    /** Amount of physical memory that exists */
221    Addr memSize();
222
223
224#endif // FULL_SYSTEM
225
226  protected:
227    Enums::MemoryMode memoryMode;
228    uint64_t workItemsBegin;
229    uint64_t workItemsEnd;
230    uint32_t numWorkIds;
231    std::vector<bool> activeCpus;
232
233  public:
234    virtual void regStats();
235    /**
236     * Called by pseudo_inst to track the number of work items started by this
237     * system.
238     */
239    uint64_t
240    incWorkItemsBegin()
241    {
242        return ++workItemsBegin;
243    }
244
245    /**
246     * Called by pseudo_inst to track the number of work items completed by
247     * this system.
248     */
249    uint64_t
250    incWorkItemsEnd()
251    {
252        return ++workItemsEnd;
253    }
254
255    /**
256     * Called by pseudo_inst to mark the cpus actively executing work items.
257     * Returns the total number of cpus that have executed work item begin or
258     * ends.
259     */
260    int
261    markWorkItem(int index)
262    {
263        int count = 0;
264        assert(index < activeCpus.size());
265        activeCpus[index] = true;
266        for (std::vector<bool>::iterator i = activeCpus.begin();
267             i < activeCpus.end(); i++) {
268            if (*i) count++;
269        }
270        return count;
271    }
272
273    inline void workItemBegin(uint32_t tid, uint32_t workid)
274    {
275        std::pair<uint32_t,uint32_t> p(tid, workid);
276        lastWorkItemStarted[p] = curTick();
277    }
278
279    void workItemEnd(uint32_t tid, uint32_t workid);
280
281#if FULL_SYSTEM
282    /**
283     * Fix up an address used to match PCs for hooking simulator
284     * events on to target function executions.  See comment in
285     * system.cc for details.
286     */
287    virtual Addr fixFuncEventAddr(Addr addr) = 0;
288
289    /**
290     * Add a function-based event to the given function, to be looked
291     * up in the specified symbol table.
292     */
293    template <class T>
294    T *addFuncEvent(SymbolTable *symtab, const char *lbl)
295    {
296        Addr addr = 0; // initialize only to avoid compiler warning
297
298        if (symtab->findAddress(lbl, addr)) {
299            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
300            return ev;
301        }
302
303        return NULL;
304    }
305
306    /** Add a function-based event to kernel code. */
307    template <class T>
308    T *addKernelFuncEvent(const char *lbl)
309    {
310        return addFuncEvent<T>(kernelSymtab, lbl);
311    }
312
313#endif
314  public:
315    std::vector<BaseRemoteGDB *> remoteGDB;
316    std::vector<GDBListener *> gdbListen;
317    bool breakpoint();
318
319  public:
320    typedef SystemParams Params;
321
322  protected:
323    Params *_params;
324
325  public:
326    System(Params *p);
327    ~System();
328
329    void initState();
330
331    const Params *params() const { return (const Params *)_params; }
332
333  public:
334
335#if FULL_SYSTEM
336    /**
337     * Returns the addess the kernel starts at.
338     * @return address the kernel starts at
339     */
340    Addr getKernelStart() const { return kernelStart; }
341
342    /**
343     * Returns the addess the kernel ends at.
344     * @return address the kernel ends at
345     */
346    Addr getKernelEnd() const { return kernelEnd; }
347
348    /**
349     * Returns the addess the entry point to the kernel code.
350     * @return entry point of the kernel code
351     */
352    Addr getKernelEntry() const { return kernelEntry; }
353
354#else
355
356    /// Allocate npages contiguous unused physical pages
357    /// @return Starting address of first page
358    Addr allocPhysPages(int npages);
359
360#endif // FULL_SYSTEM
361
362    int registerThreadContext(ThreadContext *tc, int assigned=-1);
363    void replaceThreadContext(ThreadContext *tc, int context_id);
364
365    void serialize(std::ostream &os);
366    void unserialize(Checkpoint *cp, const std::string &section);
367    virtual void resume();
368
369  public:
370    Counter totalNumInsts;
371    EventQueue instEventQueue;
372    std::map<std::pair<uint32_t,uint32_t>, Tick>  lastWorkItemStarted;
373    std::map<uint32_t, Stats::Histogram*> workItemStats;
374
375    ////////////////////////////////////////////
376    //
377    // STATIC GLOBAL SYSTEM LIST
378    //
379    ////////////////////////////////////////////
380
381    static std::vector<System *> systemList;
382    static int numSystemsRunning;
383
384    static void printSystems();
385
386
387};
388
389#endif // __SYSTEM_HH__
390