system.hh revision 8922
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"
56603SN/A#include "cpu/pc_event.hh"
574762Snate@binkert.org#include "enums/MemoryMode.hh"
588769Sgblack@eecs.umich.edu#include "kern/system_events.hh"
598852Sandreas.hansson@arm.com#include "mem/fs_translating_port_proxy.hh"
608703Sandreas.hansson@arm.com#include "mem/mem_object.hh"
612520SN/A#include "mem/port.hh"
624762Snate@binkert.org#include "params/System.hh"
636658Snate@binkert.org
641634SN/Aclass BaseCPU;
658769Sgblack@eecs.umich.educlass BaseRemoteGDB;
668769Sgblack@eecs.umich.educlass GDBListener;
671634SN/Aclass ObjectFile;
682521SN/Aclass PhysicalMemory;
69803SN/Aclass Platform;
708769Sgblack@eecs.umich.educlass ThreadContext;
712SN/A
728703Sandreas.hansson@arm.comclass System : public MemObject
732SN/A{
748703Sandreas.hansson@arm.com  private:
758703Sandreas.hansson@arm.com
768703Sandreas.hansson@arm.com    /**
778703Sandreas.hansson@arm.com     * Private class for the system port which is only used as a
788703Sandreas.hansson@arm.com     * master for debug access and for non-structural entities that do
798703Sandreas.hansson@arm.com     * not have a port of their own.
808703Sandreas.hansson@arm.com     */
818922Swilliam.wang@arm.com    class SystemPort : public MasterPort
828703Sandreas.hansson@arm.com    {
838703Sandreas.hansson@arm.com      public:
848703Sandreas.hansson@arm.com
858703Sandreas.hansson@arm.com        /**
868703Sandreas.hansson@arm.com         * Create a system port with a name and an owner.
878703Sandreas.hansson@arm.com         */
888703Sandreas.hansson@arm.com        SystemPort(const std::string &_name, MemObject *_owner)
898922Swilliam.wang@arm.com            : MasterPort(_name, _owner)
908703Sandreas.hansson@arm.com        { }
918703Sandreas.hansson@arm.com        bool recvTiming(PacketPtr pkt)
928703Sandreas.hansson@arm.com        { panic("SystemPort does not receive timing!\n"); return false; }
938922Swilliam.wang@arm.com        void recvRetry()
948922Swilliam.wang@arm.com        { panic("SystemPort does not expect retry!\n"); }
958703Sandreas.hansson@arm.com        Tick recvAtomic(PacketPtr pkt)
968703Sandreas.hansson@arm.com        { panic("SystemPort does not receive atomic!\n"); return 0; }
978703Sandreas.hansson@arm.com        void recvFunctional(PacketPtr pkt)
988703Sandreas.hansson@arm.com        { panic("SystemPort does not receive functional!\n"); }
998703Sandreas.hansson@arm.com    };
1008703Sandreas.hansson@arm.com
1018703Sandreas.hansson@arm.com    SystemPort _systemPort;
1028703Sandreas.hansson@arm.com
103603SN/A  public:
1042901Ssaidi@eecs.umich.edu
1058703Sandreas.hansson@arm.com    /**
1068706Sandreas.hansson@arm.com     * After all objects have been created and all ports are
1078706Sandreas.hansson@arm.com     * connected, check that the system port is connected.
1088706Sandreas.hansson@arm.com     */
1098706Sandreas.hansson@arm.com    virtual void init();
1108706Sandreas.hansson@arm.com
1118706Sandreas.hansson@arm.com    /**
1128852Sandreas.hansson@arm.com     * Get a reference to the system port that can be used by
1138703Sandreas.hansson@arm.com     * non-structural simulation objects like processes or threads, or
1148703Sandreas.hansson@arm.com     * external entities like loaders and debuggers, etc, to access
1158703Sandreas.hansson@arm.com     * the memory system.
1168703Sandreas.hansson@arm.com     *
1178852Sandreas.hansson@arm.com     * @return a reference to the system port we own
1188703Sandreas.hansson@arm.com     */
1198922Swilliam.wang@arm.com    MasterPort& getSystemPort() { return _systemPort; }
1208703Sandreas.hansson@arm.com
1218703Sandreas.hansson@arm.com    /**
1228703Sandreas.hansson@arm.com     * Additional function to return the Port of a memory object.
1238703Sandreas.hansson@arm.com     */
1248922Swilliam.wang@arm.com    MasterPort& getMasterPort(const std::string &if_name, int idx = -1);
1258703Sandreas.hansson@arm.com
1262902Ssaidi@eecs.umich.edu    static const char *MemoryModeStrings[3];
1272902Ssaidi@eecs.umich.edu
1284762Snate@binkert.org    Enums::MemoryMode
1294762Snate@binkert.org    getMemoryMode()
1304762Snate@binkert.org    {
1314762Snate@binkert.org        assert(memoryMode);
1324762Snate@binkert.org        return memoryMode;
1334762Snate@binkert.org    }
1342901Ssaidi@eecs.umich.edu
1352901Ssaidi@eecs.umich.edu    /** Change the memory mode of the system. This should only be called by the
1362901Ssaidi@eecs.umich.edu     * python!!
1372901Ssaidi@eecs.umich.edu     * @param mode Mode to change to (atomic/timing)
1382901Ssaidi@eecs.umich.edu     */
1394762Snate@binkert.org    void setMemoryMode(Enums::MemoryMode mode);
1402901Ssaidi@eecs.umich.edu
1412521SN/A    PhysicalMemory *physmem;
1422SN/A    PCEventQueue pcEventQueue;
1432SN/A
1442680Sktlim@umich.edu    std::vector<ThreadContext *> threadContexts;
1455714Shsul@eecs.umich.edu    int _numContexts;
1461806SN/A
1476221Snate@binkert.org    ThreadContext *getThreadContext(ThreadID tid)
1485713Shsul@eecs.umich.edu    {
1495713Shsul@eecs.umich.edu        return threadContexts[tid];
1505713Shsul@eecs.umich.edu    }
1515713Shsul@eecs.umich.edu
1525714Shsul@eecs.umich.edu    int numContexts()
1531806SN/A    {
1546227Snate@binkert.org        assert(_numContexts == (int)threadContexts.size());
1555714Shsul@eecs.umich.edu        return _numContexts;
1561806SN/A    }
157180SN/A
1586029Ssteve.reinhardt@amd.com    /** Return number of running (non-halted) thread contexts in
1596029Ssteve.reinhardt@amd.com     * system.  These threads could be Active or Suspended. */
1606029Ssteve.reinhardt@amd.com    int numRunningContexts();
1616029Ssteve.reinhardt@amd.com
1628460SAli.Saidi@ARM.com    /** List to store ranges of memories in this system */
1638460SAli.Saidi@ARM.com    AddrRangeList memRanges;
1648460SAli.Saidi@ARM.com
1658460SAli.Saidi@ARM.com    /** check if an address points to valid system memory
1668460SAli.Saidi@ARM.com     * and thus we can fetch instructions out of it
1678460SAli.Saidi@ARM.com     */
1688460SAli.Saidi@ARM.com    bool isMemory(const Addr addr) const;
1698460SAli.Saidi@ARM.com
1708765Sgblack@eecs.umich.edu    Addr pagePtr;
1718765Sgblack@eecs.umich.edu
1722378SN/A    uint64_t init_param;
1732378SN/A
1742520SN/A    /** Port to physical memory used for writing object files into ram at
1752520SN/A     * boot.*/
1768852Sandreas.hansson@arm.com    PortProxy physProxy;
1778852Sandreas.hansson@arm.com    FSTranslatingPortProxy virtProxy;
1782520SN/A
1791885SN/A    /** kernel symbol table */
1801070SN/A    SymbolTable *kernelSymtab;
181954SN/A
1821070SN/A    /** Object pointer for the kernel code */
1831070SN/A    ObjectFile *kernel;
1841070SN/A
1851070SN/A    /** Begining of kernel code */
1861070SN/A    Addr kernelStart;
1871070SN/A
1881070SN/A    /** End of kernel code */
1891070SN/A    Addr kernelEnd;
1901070SN/A
1911070SN/A    /** Entry point in the kernel to start at */
1921070SN/A    Addr kernelEntry;
1931070SN/A
1947580SAli.Saidi@arm.com    /** Mask that should be anded for binary/symbol loading.
1957580SAli.Saidi@arm.com     * This allows one two different OS requirements for the same ISA to be
1967580SAli.Saidi@arm.com     * handled.  Some OSes are compiled for a virtual address and need to be
1977580SAli.Saidi@arm.com     * loaded into physical memory that starts at address 0, while other
1987580SAli.Saidi@arm.com     * bare metal tools generate images that start at address 0.
1997580SAli.Saidi@arm.com     */
2007580SAli.Saidi@arm.com    Addr loadAddrMask;
2017580SAli.Saidi@arm.com
2024997Sgblack@eecs.umich.edu  protected:
2037770SAli.Saidi@ARM.com    uint64_t nextPID;
2044997Sgblack@eecs.umich.edu
2054997Sgblack@eecs.umich.edu  public:
2064997Sgblack@eecs.umich.edu    uint64_t allocatePID()
2074997Sgblack@eecs.umich.edu    {
2087770SAli.Saidi@ARM.com        return nextPID++;
2094997Sgblack@eecs.umich.edu    }
2104997Sgblack@eecs.umich.edu
2115795Ssaidi@eecs.umich.edu    /** Amount of physical memory that is still free */
2125795Ssaidi@eecs.umich.edu    Addr freeMemSize();
2135795Ssaidi@eecs.umich.edu
2145795Ssaidi@eecs.umich.edu    /** Amount of physical memory that exists */
2155795Ssaidi@eecs.umich.edu    Addr memSize();
2165795Ssaidi@eecs.umich.edu
2171885SN/A  protected:
2184762Snate@binkert.org    Enums::MemoryMode memoryMode;
2197914SBrad.Beckmann@amd.com    uint64_t workItemsBegin;
2207914SBrad.Beckmann@amd.com    uint64_t workItemsEnd;
2218666SPrakash.Ramrakhyani@arm.com    uint32_t numWorkIds;
2227914SBrad.Beckmann@amd.com    std::vector<bool> activeCpus;
2237914SBrad.Beckmann@amd.com
2248832SAli.Saidi@ARM.com    /** This array is a per-sytem list of all devices capable of issuing a
2258832SAli.Saidi@ARM.com     * memory system request and an associated string for each master id.
2268832SAli.Saidi@ARM.com     * It's used to uniquely id any master in the system by name for things
2278832SAli.Saidi@ARM.com     * like cache statistics.
2288832SAli.Saidi@ARM.com     */
2298832SAli.Saidi@ARM.com    std::vector<std::string> masterIds;
2308832SAli.Saidi@ARM.com
2317914SBrad.Beckmann@amd.com  public:
2328832SAli.Saidi@ARM.com
2338832SAli.Saidi@ARM.com    /** Request an id used to create a request object in the system. All objects
2348832SAli.Saidi@ARM.com     * that intend to issues requests into the memory system must request an id
2358832SAli.Saidi@ARM.com     * in the init() phase of startup. All master ids must be fixed by the
2368832SAli.Saidi@ARM.com     * regStats() phase that immediately preceeds it. This allows objects in the
2378832SAli.Saidi@ARM.com     * memory system to understand how many masters may exist and
2388832SAli.Saidi@ARM.com     * appropriately name the bins of their per-master stats before the stats
2398832SAli.Saidi@ARM.com     * are finalized
2408832SAli.Saidi@ARM.com     */
2418832SAli.Saidi@ARM.com    MasterID getMasterId(std::string req_name);
2428832SAli.Saidi@ARM.com
2438832SAli.Saidi@ARM.com    /** Get the name of an object for a given request id.
2448832SAli.Saidi@ARM.com     */
2458832SAli.Saidi@ARM.com    std::string getMasterName(MasterID master_id);
2468832SAli.Saidi@ARM.com
2478832SAli.Saidi@ARM.com    /** Get the number of masters registered in the system */
2488832SAli.Saidi@ARM.com    MasterID maxMasters()
2498832SAli.Saidi@ARM.com    {
2508832SAli.Saidi@ARM.com        return masterIds.size();
2518832SAli.Saidi@ARM.com    }
2528832SAli.Saidi@ARM.com
2538666SPrakash.Ramrakhyani@arm.com    virtual void regStats();
2547914SBrad.Beckmann@amd.com    /**
2557914SBrad.Beckmann@amd.com     * Called by pseudo_inst to track the number of work items started by this
2567914SBrad.Beckmann@amd.com     * system.
2577914SBrad.Beckmann@amd.com     */
2588666SPrakash.Ramrakhyani@arm.com    uint64_t
2597914SBrad.Beckmann@amd.com    incWorkItemsBegin()
2607914SBrad.Beckmann@amd.com    {
2617914SBrad.Beckmann@amd.com        return ++workItemsBegin;
2627914SBrad.Beckmann@amd.com    }
2637914SBrad.Beckmann@amd.com
2647914SBrad.Beckmann@amd.com    /**
2657914SBrad.Beckmann@amd.com     * Called by pseudo_inst to track the number of work items completed by
2667914SBrad.Beckmann@amd.com     * this system.
2677914SBrad.Beckmann@amd.com     */
2687914SBrad.Beckmann@amd.com    uint64_t
2697914SBrad.Beckmann@amd.com    incWorkItemsEnd()
2707914SBrad.Beckmann@amd.com    {
2717914SBrad.Beckmann@amd.com        return ++workItemsEnd;
2727914SBrad.Beckmann@amd.com    }
2737914SBrad.Beckmann@amd.com
2747914SBrad.Beckmann@amd.com    /**
2757914SBrad.Beckmann@amd.com     * Called by pseudo_inst to mark the cpus actively executing work items.
2767914SBrad.Beckmann@amd.com     * Returns the total number of cpus that have executed work item begin or
2777914SBrad.Beckmann@amd.com     * ends.
2787914SBrad.Beckmann@amd.com     */
2797914SBrad.Beckmann@amd.com    int
2807914SBrad.Beckmann@amd.com    markWorkItem(int index)
2817914SBrad.Beckmann@amd.com    {
2827914SBrad.Beckmann@amd.com        int count = 0;
2837914SBrad.Beckmann@amd.com        assert(index < activeCpus.size());
2847914SBrad.Beckmann@amd.com        activeCpus[index] = true;
2857914SBrad.Beckmann@amd.com        for (std::vector<bool>::iterator i = activeCpus.begin();
2867914SBrad.Beckmann@amd.com             i < activeCpus.end(); i++) {
2877914SBrad.Beckmann@amd.com            if (*i) count++;
2887914SBrad.Beckmann@amd.com        }
2897914SBrad.Beckmann@amd.com        return count;
2907914SBrad.Beckmann@amd.com    }
2912901Ssaidi@eecs.umich.edu
2928666SPrakash.Ramrakhyani@arm.com    inline void workItemBegin(uint32_t tid, uint32_t workid)
2938666SPrakash.Ramrakhyani@arm.com    {
2948666SPrakash.Ramrakhyani@arm.com        std::pair<uint32_t,uint32_t> p(tid, workid);
2958666SPrakash.Ramrakhyani@arm.com        lastWorkItemStarted[p] = curTick();
2968666SPrakash.Ramrakhyani@arm.com    }
2978666SPrakash.Ramrakhyani@arm.com
2988666SPrakash.Ramrakhyani@arm.com    void workItemEnd(uint32_t tid, uint32_t workid);
2998666SPrakash.Ramrakhyani@arm.com
3001885SN/A    /**
3011885SN/A     * Fix up an address used to match PCs for hooking simulator
3021885SN/A     * events on to target function executions.  See comment in
3031885SN/A     * system.cc for details.
3041885SN/A     */
3058769Sgblack@eecs.umich.edu    virtual Addr fixFuncEventAddr(Addr addr)
3068769Sgblack@eecs.umich.edu    {
3078769Sgblack@eecs.umich.edu        panic("Base fixFuncEventAddr not implemented.\n");
3088769Sgblack@eecs.umich.edu    }
3091885SN/A
3101885SN/A    /**
3111885SN/A     * Add a function-based event to the given function, to be looked
3121885SN/A     * up in the specified symbol table.
3131885SN/A     */
3141885SN/A    template <class T>
3152989Ssaidi@eecs.umich.edu    T *addFuncEvent(SymbolTable *symtab, const char *lbl)
3161885SN/A    {
3171913SN/A        Addr addr = 0; // initialize only to avoid compiler warning
3181885SN/A
3191885SN/A        if (symtab->findAddress(lbl, addr)) {
3201885SN/A            T *ev = new T(&pcEventQueue, lbl, fixFuncEventAddr(addr));
3211885SN/A            return ev;
3221885SN/A        }
3231885SN/A
3241885SN/A        return NULL;
3251885SN/A    }
3261885SN/A
3271885SN/A    /** Add a function-based event to kernel code. */
3281885SN/A    template <class T>
3292989Ssaidi@eecs.umich.edu    T *addKernelFuncEvent(const char *lbl)
3301885SN/A    {
3311885SN/A        return addFuncEvent<T>(kernelSymtab, lbl);
3321885SN/A    }
3331885SN/A
33477SN/A  public:
3356658Snate@binkert.org    std::vector<BaseRemoteGDB *> remoteGDB;
3361070SN/A    std::vector<GDBListener *> gdbListen;
3373960Sgblack@eecs.umich.edu    bool breakpoint();
3381070SN/A
3391070SN/A  public:
3404762Snate@binkert.org    typedef SystemParams Params;
3411070SN/A
3422158SN/A  protected:
3432158SN/A    Params *_params;
3441070SN/A
3452158SN/A  public:
3461070SN/A    System(Params *p);
3472SN/A    ~System();
3482SN/A
3497733SAli.Saidi@ARM.com    void initState();
3501129SN/A
3512158SN/A    const Params *params() const { return (const Params *)_params; }
3522158SN/A
3531070SN/A  public:
3542378SN/A
3551070SN/A    /**
3561070SN/A     * Returns the addess the kernel starts at.
3571070SN/A     * @return address the kernel starts at
3581070SN/A     */
3591070SN/A    Addr getKernelStart() const { return kernelStart; }
3601070SN/A
3611070SN/A    /**
3621070SN/A     * Returns the addess the kernel ends at.
3631070SN/A     * @return address the kernel ends at
3641070SN/A     */
3651070SN/A    Addr getKernelEnd() const { return kernelEnd; }
3661070SN/A
3671070SN/A    /**
3681070SN/A     * Returns the addess the entry point to the kernel code.
3691070SN/A     * @return entry point of the kernel code
3701070SN/A     */
3711070SN/A    Addr getKernelEntry() const { return kernelEntry; }
3721070SN/A
3738601Ssteve.reinhardt@amd.com    /// Allocate npages contiguous unused physical pages
3748601Ssteve.reinhardt@amd.com    /// @return Starting address of first page
3758601Ssteve.reinhardt@amd.com    Addr allocPhysPages(int npages);
3762378SN/A
3775718Shsul@eecs.umich.edu    int registerThreadContext(ThreadContext *tc, int assigned=-1);
3785713Shsul@eecs.umich.edu    void replaceThreadContext(ThreadContext *tc, int context_id);
3791070SN/A
3801070SN/A    void serialize(std::ostream &os);
3811070SN/A    void unserialize(Checkpoint *cp, const std::string &section);
3827897Shestness@cs.utexas.edu    virtual void resume();
3832SN/A
38477SN/A  public:
3857897Shestness@cs.utexas.edu    Counter totalNumInsts;
3867897Shestness@cs.utexas.edu    EventQueue instEventQueue;
3878666SPrakash.Ramrakhyani@arm.com    std::map<std::pair<uint32_t,uint32_t>, Tick>  lastWorkItemStarted;
3888666SPrakash.Ramrakhyani@arm.com    std::map<uint32_t, Stats::Histogram*> workItemStats;
3897897Shestness@cs.utexas.edu
3902SN/A    ////////////////////////////////////////////
3912SN/A    //
3922SN/A    // STATIC GLOBAL SYSTEM LIST
3932SN/A    //
3942SN/A    ////////////////////////////////////////////
3952SN/A
3962SN/A    static std::vector<System *> systemList;
3972SN/A    static int numSystemsRunning;
3982SN/A
3992SN/A    static void printSystems();
4002158SN/A
4012158SN/A
4022SN/A};
4032SN/A
4042SN/A#endif // __SYSTEM_HH__
405