system.hh revision 8706
12SN/A/*
28703Sandreas.hansson@arm.com * Copyright (c) 2012 ARM Limited
38703Sandreas.hansson@arm.com * All rights reserved
48703Sandreas.hansson@arm.com *
58703Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
68703Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78703Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88703Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98703Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108703Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118703Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128703Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138703Sandreas.hansson@arm.com *
141762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
157897Shestness@cs.utexas.edu * Copyright (c) 2011 Regents of the University of California
162SN/A * All rights reserved.
172SN/A *
182SN/A * Redistribution and use in source and binary forms, with or without
192SN/A * modification, are permitted provided that the following conditions are
202SN/A * met: redistributions of source code must retain the above copyright
212SN/A * notice, this list of conditions and the following disclaimer;
222SN/A * redistributions in binary form must reproduce the above copyright
232SN/A * notice, this list of conditions and the following disclaimer in the
242SN/A * documentation and/or other materials provided with the distribution;
252SN/A * neither the name of the copyright holders nor the names of its
262SN/A * contributors may be used to endorse or promote products derived from
272SN/A * this software without specific prior written permission.
282SN/A *
292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
302SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
312SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
322SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
332SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
342SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
352SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
362SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
382SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
392SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
402665Ssaidi@eecs.umich.edu *
412665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt
422665Ssaidi@eecs.umich.edu *          Lisa Hsu
432665Ssaidi@eecs.umich.edu *          Nathan Binkert
447897Shestness@cs.utexas.edu *          Rick Strong
452SN/A */
462SN/A
472SN/A#ifndef __SYSTEM_HH__
482SN/A#define __SYSTEM_HH__
492SN/A
502SN/A#include <string>
5175SN/A#include <vector>
522SN/A
532439SN/A#include "base/loader/symtab.hh"
542439SN/A#include "base/misc.hh"
55603SN/A#include "base/statistics.hh"
562986Sgblack@eecs.umich.edu#include "config/full_system.hh"
57603SN/A#include "cpu/pc_event.hh"
584762Snate@binkert.org#include "enums/MemoryMode.hh"
598703Sandreas.hansson@arm.com#include "mem/mem_object.hh"
602520SN/A#include "mem/port.hh"
614762Snate@binkert.org#include "params/System.hh"
626658Snate@binkert.org
632378SN/A#if FULL_SYSTEM
64722SN/A#include "kern/system_events.hh"
652378SN/A#endif
66312SN/A
671634SN/Aclass BaseCPU;
682680Sktlim@umich.educlass ThreadContext;
691634SN/Aclass ObjectFile;
702521SN/Aclass PhysicalMemory;
712378SN/A
722378SN/A#if FULL_SYSTEM
73803SN/Aclass Platform;
748706Sandreas.hansson@arm.comclass PortProxy;
758706Sandreas.hansson@arm.comclass FSTranslatingPortProxy;
763960Sgblack@eecs.umich.edu#endif
772378SN/Aclass GDBListener;
786658Snate@binkert.orgclass BaseRemoteGDB;
792SN/A
808703Sandreas.hansson@arm.comclass System : public MemObject
812SN/A{
828703Sandreas.hansson@arm.com  private:
838703Sandreas.hansson@arm.com
848703Sandreas.hansson@arm.com    /**
858703Sandreas.hansson@arm.com     * Private class for the system port which is only used as a
868703Sandreas.hansson@arm.com     * master for debug access and for non-structural entities that do
878703Sandreas.hansson@arm.com     * not have a port of their own.
888703Sandreas.hansson@arm.com     */
898703Sandreas.hansson@arm.com    class SystemPort : public Port
908703Sandreas.hansson@arm.com    {
918703Sandreas.hansson@arm.com      public:
928703Sandreas.hansson@arm.com
938703Sandreas.hansson@arm.com        /**
948703Sandreas.hansson@arm.com         * Create a system port with a name and an owner.
958703Sandreas.hansson@arm.com         */
968703Sandreas.hansson@arm.com        SystemPort(const std::string &_name, MemObject *_owner)
978703Sandreas.hansson@arm.com            : Port(_name, _owner)
988703Sandreas.hansson@arm.com        { }
998703Sandreas.hansson@arm.com        bool recvTiming(PacketPtr pkt)
1008703Sandreas.hansson@arm.com        { panic("SystemPort does not receive timing!\n"); return false; }
1018703Sandreas.hansson@arm.com        Tick recvAtomic(PacketPtr pkt)
1028703Sandreas.hansson@arm.com        { panic("SystemPort does not receive atomic!\n"); return 0; }
1038703Sandreas.hansson@arm.com        void recvFunctional(PacketPtr pkt)
1048703Sandreas.hansson@arm.com        { panic("SystemPort does not receive functional!\n"); }
1058703Sandreas.hansson@arm.com        void recvStatusChange(Status status) { }
1068703Sandreas.hansson@arm.com
1078703Sandreas.hansson@arm.com    };
1088703Sandreas.hansson@arm.com
1098703Sandreas.hansson@arm.com    SystemPort _systemPort;
1108703Sandreas.hansson@arm.com
111603SN/A  public:
1122901Ssaidi@eecs.umich.edu
1138703Sandreas.hansson@arm.com    /**
1148706Sandreas.hansson@arm.com     * After all objects have been created and all ports are
1158706Sandreas.hansson@arm.com     * connected, check that the system port is connected.
1168706Sandreas.hansson@arm.com     */
1178706Sandreas.hansson@arm.com    virtual void init();
1188706Sandreas.hansson@arm.com
1198706Sandreas.hansson@arm.com    /**
1208703Sandreas.hansson@arm.com     * Get a pointer to the system port that can be used by
1218703Sandreas.hansson@arm.com     * non-structural simulation objects like processes or threads, or
1228703Sandreas.hansson@arm.com     * external entities like loaders and debuggers, etc, to access
1238703Sandreas.hansson@arm.com     * the memory system.
1248703Sandreas.hansson@arm.com     *
1258703Sandreas.hansson@arm.com     * @return a pointer to the system port we own
1268703Sandreas.hansson@arm.com     */
1278703Sandreas.hansson@arm.com    Port* getSystemPort() { return &_systemPort; }
1288703Sandreas.hansson@arm.com
1298703Sandreas.hansson@arm.com    /**
1308703Sandreas.hansson@arm.com     * Additional function to return the Port of a memory object.
1318703Sandreas.hansson@arm.com     */
1328703Sandreas.hansson@arm.com    Port *getPort(const std::string &if_name, int idx = -1);
1338703Sandreas.hansson@arm.com
1342902Ssaidi@eecs.umich.edu    static const char *MemoryModeStrings[3];
1352902Ssaidi@eecs.umich.edu
1364762Snate@binkert.org    Enums::MemoryMode
1374762Snate@binkert.org    getMemoryMode()
1384762Snate@binkert.org    {
1394762Snate@binkert.org        assert(memoryMode);
1404762Snate@binkert.org        return memoryMode;
1414762Snate@binkert.org    }
1422901Ssaidi@eecs.umich.edu
1432901Ssaidi@eecs.umich.edu    /** Change the memory mode of the system. This should only be called by the
1442901Ssaidi@eecs.umich.edu     * python!!
1452901Ssaidi@eecs.umich.edu     * @param mode Mode to change to (atomic/timing)
1462901Ssaidi@eecs.umich.edu     */
1474762Snate@binkert.org    void setMemoryMode(Enums::MemoryMode mode);
1482901Ssaidi@eecs.umich.edu
1492521SN/A    PhysicalMemory *physmem;
1502SN/A    PCEventQueue pcEventQueue;
1512SN/A
1522680Sktlim@umich.edu    std::vector<ThreadContext *> threadContexts;
1535714Shsul@eecs.umich.edu    int _numContexts;
1541806SN/A
1556221Snate@binkert.org    ThreadContext *getThreadContext(ThreadID tid)
1565713Shsul@eecs.umich.edu    {
1575713Shsul@eecs.umich.edu        return threadContexts[tid];
1585713Shsul@eecs.umich.edu    }
1595713Shsul@eecs.umich.edu
1605714Shsul@eecs.umich.edu    int numContexts()
1611806SN/A    {
1626227Snate@binkert.org        assert(_numContexts == (int)threadContexts.size());
1635714Shsul@eecs.umich.edu        return _numContexts;
1641806SN/A    }
165180SN/A
1666029Ssteve.reinhardt@amd.com    /** Return number of running (non-halted) thread contexts in
1676029Ssteve.reinhardt@amd.com     * system.  These threads could be Active or Suspended. */
1686029Ssteve.reinhardt@amd.com    int numRunningContexts();
1696029Ssteve.reinhardt@amd.com
1708460SAli.Saidi@ARM.com    /** List to store ranges of memories in this system */
1718460SAli.Saidi@ARM.com    AddrRangeList memRanges;
1728460SAli.Saidi@ARM.com
1738460SAli.Saidi@ARM.com    /** check if an address points to valid system memory
1748460SAli.Saidi@ARM.com     * and thus we can fetch instructions out of it
1758460SAli.Saidi@ARM.com     */
1768460SAli.Saidi@ARM.com    bool isMemory(const Addr addr) const;
1778460SAli.Saidi@ARM.com
1782378SN/A#if FULL_SYSTEM
1792378SN/A    Platform *platform;
1802378SN/A    uint64_t init_param;
1812378SN/A
1822520SN/A    /** Port to physical memory used for writing object files into ram at
1832520SN/A     * boot.*/
1848706Sandreas.hansson@arm.com    PortProxy* physProxy;
1858706Sandreas.hansson@arm.com    FSTranslatingPortProxy* virtProxy;
1862520SN/A
1871885SN/A    /** kernel symbol table */
1881070SN/A    SymbolTable *kernelSymtab;
189954SN/A
1901070SN/A    /** Object pointer for the kernel code */
1911070SN/A    ObjectFile *kernel;
1921070SN/A
1931070SN/A    /** Begining of kernel code */
1941070SN/A    Addr kernelStart;
1951070SN/A
1961070SN/A    /** End of kernel code */
1971070SN/A    Addr kernelEnd;
1981070SN/A
1991070SN/A    /** Entry point in the kernel to start at */
2001070SN/A    Addr kernelEntry;
2011070SN/A
2027580SAli.Saidi@arm.com    /** Mask that should be anded for binary/symbol loading.
2037580SAli.Saidi@arm.com     * This allows one two different OS requirements for the same ISA to be
2047580SAli.Saidi@arm.com     * handled.  Some OSes are compiled for a virtual address and need to be
2057580SAli.Saidi@arm.com     * loaded into physical memory that starts at address 0, while other
2067580SAli.Saidi@arm.com     * bare metal tools generate images that start at address 0.
2077580SAli.Saidi@arm.com     */
2087580SAli.Saidi@arm.com    Addr loadAddrMask;
2097580SAli.Saidi@arm.com
2102378SN/A#else
2112378SN/A
2127770SAli.Saidi@ARM.com    Addr pagePtr;
2132378SN/A
2144997Sgblack@eecs.umich.edu  protected:
2157770SAli.Saidi@ARM.com    uint64_t nextPID;
2164997Sgblack@eecs.umich.edu
2174997Sgblack@eecs.umich.edu  public:
2184997Sgblack@eecs.umich.edu    uint64_t allocatePID()
2194997Sgblack@eecs.umich.edu    {
2207770SAli.Saidi@ARM.com        return nextPID++;
2214997Sgblack@eecs.umich.edu    }
2224997Sgblack@eecs.umich.edu
2235795Ssaidi@eecs.umich.edu    /** Amount of physical memory that is still free */
2245795Ssaidi@eecs.umich.edu    Addr freeMemSize();
2255795Ssaidi@eecs.umich.edu
2265795Ssaidi@eecs.umich.edu    /** Amount of physical memory that exists */
2275795Ssaidi@eecs.umich.edu    Addr memSize();
2285795Ssaidi@eecs.umich.edu
2292378SN/A
2302378SN/A#endif // FULL_SYSTEM
2312378SN/A
2321885SN/A  protected:
2334762Snate@binkert.org    Enums::MemoryMode memoryMode;
2347914SBrad.Beckmann@amd.com    uint64_t workItemsBegin;
2357914SBrad.Beckmann@amd.com    uint64_t workItemsEnd;
2368666SPrakash.Ramrakhyani@arm.com    uint32_t numWorkIds;
2377914SBrad.Beckmann@amd.com    std::vector<bool> activeCpus;
2387914SBrad.Beckmann@amd.com
2397914SBrad.Beckmann@amd.com  public:
2408666SPrakash.Ramrakhyani@arm.com    virtual void regStats();
2417914SBrad.Beckmann@amd.com    /**
2427914SBrad.Beckmann@amd.com     * Called by pseudo_inst to track the number of work items started by this
2437914SBrad.Beckmann@amd.com     * system.
2447914SBrad.Beckmann@amd.com     */
2458666SPrakash.Ramrakhyani@arm.com    uint64_t
2467914SBrad.Beckmann@amd.com    incWorkItemsBegin()
2477914SBrad.Beckmann@amd.com    {
2487914SBrad.Beckmann@amd.com        return ++workItemsBegin;
2497914SBrad.Beckmann@amd.com    }
2507914SBrad.Beckmann@amd.com
2517914SBrad.Beckmann@amd.com    /**
2527914SBrad.Beckmann@amd.com     * Called by pseudo_inst to track the number of work items completed by
2537914SBrad.Beckmann@amd.com     * this system.
2547914SBrad.Beckmann@amd.com     */
2557914SBrad.Beckmann@amd.com    uint64_t
2567914SBrad.Beckmann@amd.com    incWorkItemsEnd()
2577914SBrad.Beckmann@amd.com    {
2587914SBrad.Beckmann@amd.com        return ++workItemsEnd;
2597914SBrad.Beckmann@amd.com    }
2607914SBrad.Beckmann@amd.com
2617914SBrad.Beckmann@amd.com    /**
2627914SBrad.Beckmann@amd.com     * Called by pseudo_inst to mark the cpus actively executing work items.
2637914SBrad.Beckmann@amd.com     * Returns the total number of cpus that have executed work item begin or
2647914SBrad.Beckmann@amd.com     * ends.
2657914SBrad.Beckmann@amd.com     */
2667914SBrad.Beckmann@amd.com    int
2677914SBrad.Beckmann@amd.com    markWorkItem(int index)
2687914SBrad.Beckmann@amd.com    {
2697914SBrad.Beckmann@amd.com        int count = 0;
2707914SBrad.Beckmann@amd.com        assert(index < activeCpus.size());
2717914SBrad.Beckmann@amd.com        activeCpus[index] = true;
2727914SBrad.Beckmann@amd.com        for (std::vector<bool>::iterator i = activeCpus.begin();
2737914SBrad.Beckmann@amd.com             i < activeCpus.end(); i++) {
2747914SBrad.Beckmann@amd.com            if (*i) count++;
2757914SBrad.Beckmann@amd.com        }
2767914SBrad.Beckmann@amd.com        return count;
2777914SBrad.Beckmann@amd.com    }
2782901Ssaidi@eecs.umich.edu
2798666SPrakash.Ramrakhyani@arm.com    inline void workItemBegin(uint32_t tid, uint32_t workid)
2808666SPrakash.Ramrakhyani@arm.com    {
2818666SPrakash.Ramrakhyani@arm.com        std::pair<uint32_t,uint32_t> p(tid, workid);
2828666SPrakash.Ramrakhyani@arm.com        lastWorkItemStarted[p] = curTick();
2838666SPrakash.Ramrakhyani@arm.com    }
2848666SPrakash.Ramrakhyani@arm.com
2858666SPrakash.Ramrakhyani@arm.com    void workItemEnd(uint32_t tid, uint32_t workid);
2868666SPrakash.Ramrakhyani@arm.com
2872424SN/A#if FULL_SYSTEM
2881885SN/A    /**
2891885SN/A     * Fix up an address used to match PCs for hooking simulator
2901885SN/A     * events on to target function executions.  See comment in
2911885SN/A     * system.cc for details.
2921885SN/A     */
2932158SN/A    virtual Addr fixFuncEventAddr(Addr addr) = 0;
2941885SN/A
2951885SN/A    /**
2961885SN/A     * Add a function-based event to the given function, to be looked
2971885SN/A     * up in the specified symbol table.
2981885SN/A     */
2991885SN/A    template <class T>
3002989Ssaidi@eecs.umich.edu    T *addFuncEvent(SymbolTable *symtab, const char *lbl)
3011885SN/A    {
3021913SN/A        Addr addr = 0; // initialize only to avoid compiler warning
3031885SN/A
3041885SN/A        if (symtab->findAddress(lbl, addr)) {
3051885SN/A            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
3061885SN/A            return ev;
3071885SN/A        }
3081885SN/A
3091885SN/A        return NULL;
3101885SN/A    }
3111885SN/A
3121885SN/A    /** Add a function-based event to kernel code. */
3131885SN/A    template <class T>
3142989Ssaidi@eecs.umich.edu    T *addKernelFuncEvent(const char *lbl)
3151885SN/A    {
3161885SN/A        return addFuncEvent<T>(kernelSymtab, lbl);
3171885SN/A    }
3181885SN/A
3192378SN/A#endif
32077SN/A  public:
3216658Snate@binkert.org    std::vector<BaseRemoteGDB *> remoteGDB;
3221070SN/A    std::vector<GDBListener *> gdbListen;
3233960Sgblack@eecs.umich.edu    bool breakpoint();
3241070SN/A
3251070SN/A  public:
3264762Snate@binkert.org    typedef SystemParams Params;
3271070SN/A
3282158SN/A  protected:
3292158SN/A    Params *_params;
3301070SN/A
3312158SN/A  public:
3321070SN/A    System(Params *p);
3332SN/A    ~System();
3342SN/A
3357733SAli.Saidi@ARM.com    void initState();
3361129SN/A
3372158SN/A    const Params *params() const { return (const Params *)_params; }
3382158SN/A
3391070SN/A  public:
3402378SN/A
3412378SN/A#if FULL_SYSTEM
3421070SN/A    /**
3431070SN/A     * Returns the addess the kernel starts at.
3441070SN/A     * @return address the kernel starts at
3451070SN/A     */
3461070SN/A    Addr getKernelStart() const { return kernelStart; }
3471070SN/A
3481070SN/A    /**
3491070SN/A     * Returns the addess the kernel ends at.
3501070SN/A     * @return address the kernel ends at
3511070SN/A     */
3521070SN/A    Addr getKernelEnd() const { return kernelEnd; }
3531070SN/A
3541070SN/A    /**
3551070SN/A     * Returns the addess the entry point to the kernel code.
3561070SN/A     * @return entry point of the kernel code
3571070SN/A     */
3581070SN/A    Addr getKernelEntry() const { return kernelEntry; }
3591070SN/A
3602378SN/A#else
3612378SN/A
3628601Ssteve.reinhardt@amd.com    /// Allocate npages contiguous unused physical pages
3638601Ssteve.reinhardt@amd.com    /// @return Starting address of first page
3648601Ssteve.reinhardt@amd.com    Addr allocPhysPages(int npages);
3652378SN/A
3662378SN/A#endif // FULL_SYSTEM
3672378SN/A
3685718Shsul@eecs.umich.edu    int registerThreadContext(ThreadContext *tc, int assigned=-1);
3695713Shsul@eecs.umich.edu    void replaceThreadContext(ThreadContext *tc, int context_id);
3701070SN/A
3711070SN/A    void serialize(std::ostream &os);
3721070SN/A    void unserialize(Checkpoint *cp, const std::string &section);
3737897Shestness@cs.utexas.edu    virtual void resume();
3742SN/A
37577SN/A  public:
3767897Shestness@cs.utexas.edu    Counter totalNumInsts;
3777897Shestness@cs.utexas.edu    EventQueue instEventQueue;
3788666SPrakash.Ramrakhyani@arm.com    std::map<std::pair<uint32_t,uint32_t>, Tick>  lastWorkItemStarted;
3798666SPrakash.Ramrakhyani@arm.com    std::map<uint32_t, Stats::Histogram*> workItemStats;
3807897Shestness@cs.utexas.edu
3812SN/A    ////////////////////////////////////////////
3822SN/A    //
3832SN/A    // STATIC GLOBAL SYSTEM LIST
3842SN/A    //
3852SN/A    ////////////////////////////////////////////
3862SN/A
3872SN/A    static std::vector<System *> systemList;
3882SN/A    static int numSystemsRunning;
3892SN/A
3902SN/A    static void printSystems();
3912158SN/A
3922158SN/A
3932SN/A};
3942SN/A
3952SN/A#endif // __SYSTEM_HH__
396