dvfs_handler.hh revision 10360
110249Sstephan.diestelhorst@arm.com/*
210249Sstephan.diestelhorst@arm.com * Copyright (c) 2013-2014 ARM Limited
310249Sstephan.diestelhorst@arm.com * All rights reserved
410249Sstephan.diestelhorst@arm.com *
510249Sstephan.diestelhorst@arm.com * The license below extends only to copyright in the software and shall
610249Sstephan.diestelhorst@arm.com * not be construed as granting a license to any other intellectual
710249Sstephan.diestelhorst@arm.com * property including but not limited to intellectual property relating
810249Sstephan.diestelhorst@arm.com * to a hardware implementation of the functionality of the software
910249Sstephan.diestelhorst@arm.com * licensed hereunder.  You may use the software subject to the license
1010249Sstephan.diestelhorst@arm.com * terms below provided that you ensure that this notice is replicated
1110249Sstephan.diestelhorst@arm.com * unmodified and in its entirety in all distributions of the software,
1210249Sstephan.diestelhorst@arm.com * modified or unmodified, in source code or in binary form.
1310249Sstephan.diestelhorst@arm.com *
1410249Sstephan.diestelhorst@arm.com * Redistribution and use in source and binary forms, with or without
1510249Sstephan.diestelhorst@arm.com * modification, are permitted provided that the following conditions are
1610249Sstephan.diestelhorst@arm.com * met: redistributions of source code must retain the above copyright
1710249Sstephan.diestelhorst@arm.com * notice, this list of conditions and the following disclaimer;
1810249Sstephan.diestelhorst@arm.com * redistributions in binary form must reproduce the above copyright
1910249Sstephan.diestelhorst@arm.com * notice, this list of conditions and the following disclaimer in the
2010249Sstephan.diestelhorst@arm.com * documentation and/or other materials provided with the distribution;
2110249Sstephan.diestelhorst@arm.com * neither the name of the copyright holders nor the names of its
2210249Sstephan.diestelhorst@arm.com * contributors may be used to endorse or promote products derived from
2310249Sstephan.diestelhorst@arm.com * this software without specific prior written permission.
2410249Sstephan.diestelhorst@arm.com *
2510249Sstephan.diestelhorst@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610249Sstephan.diestelhorst@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710249Sstephan.diestelhorst@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810249Sstephan.diestelhorst@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910249Sstephan.diestelhorst@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010249Sstephan.diestelhorst@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110249Sstephan.diestelhorst@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210249Sstephan.diestelhorst@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310249Sstephan.diestelhorst@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410249Sstephan.diestelhorst@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510249Sstephan.diestelhorst@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610249Sstephan.diestelhorst@arm.com *
3710249Sstephan.diestelhorst@arm.com * Authors: Vasileios Spiliopoulos
3810249Sstephan.diestelhorst@arm.com *          Akash Bagdia
3910249Sstephan.diestelhorst@arm.com *          Stephan Diestelhorst
4010249Sstephan.diestelhorst@arm.com */
4110249Sstephan.diestelhorst@arm.com
4210249Sstephan.diestelhorst@arm.com/**
4310249Sstephan.diestelhorst@arm.com * @file
4410249Sstephan.diestelhorst@arm.com * DVFSHandler and DomainConfig class declaration used for managing voltage
4510249Sstephan.diestelhorst@arm.com * and frequency scaling of the various DVFS domains in the system (with each
4610249Sstephan.diestelhorst@arm.com * domain having their independent domain configuration information)
4710249Sstephan.diestelhorst@arm.com */
4810249Sstephan.diestelhorst@arm.com
4910249Sstephan.diestelhorst@arm.com
5010249Sstephan.diestelhorst@arm.com#ifndef __SIM_DVFS_HANDLER_HH__
5110249Sstephan.diestelhorst@arm.com#define __SIM_DVFS_HANDLER_HH__
5210249Sstephan.diestelhorst@arm.com
5310249Sstephan.diestelhorst@arm.com#include <vector>
5410249Sstephan.diestelhorst@arm.com
5510249Sstephan.diestelhorst@arm.com#include "params/ClockDomain.hh"
5610249Sstephan.diestelhorst@arm.com#include "params/DVFSHandler.hh"
5710249Sstephan.diestelhorst@arm.com#include "params/VoltageDomain.hh"
5810249Sstephan.diestelhorst@arm.com#include "sim/clock_domain.hh"
5910249Sstephan.diestelhorst@arm.com#include "sim/eventq.hh"
6010249Sstephan.diestelhorst@arm.com#include "sim/sim_object.hh"
6110249Sstephan.diestelhorst@arm.com
6210249Sstephan.diestelhorst@arm.com
6310249Sstephan.diestelhorst@arm.com/**
6410249Sstephan.diestelhorst@arm.com * DVFS Handler class, maintains a list of all the domains it can handle.
6510249Sstephan.diestelhorst@arm.com * Each entry of that list is an object of the DomainConfig class, and the
6610249Sstephan.diestelhorst@arm.com * handler uses the methods provided by that class to get access to the
6710249Sstephan.diestelhorst@arm.com * configuration of each domain. The handler is responsible for setting/getting
6810249Sstephan.diestelhorst@arm.com * clock periods and voltages from clock/voltage domains.
6910249Sstephan.diestelhorst@arm.com * The handler acts the bridge between software configurable information
7010249Sstephan.diestelhorst@arm.com * for each domain as provided to the controller and the hardware
7110249Sstephan.diestelhorst@arm.com * implementation details for those domains.
7210249Sstephan.diestelhorst@arm.com */
7310249Sstephan.diestelhorst@arm.comclass DVFSHandler : public SimObject
7410249Sstephan.diestelhorst@arm.com{
7510249Sstephan.diestelhorst@arm.com  public:
7610249Sstephan.diestelhorst@arm.com    typedef DVFSHandlerParams Params;
7710249Sstephan.diestelhorst@arm.com    DVFSHandler(const Params *p);
7810249Sstephan.diestelhorst@arm.com
7910249Sstephan.diestelhorst@arm.com    typedef SrcClockDomain::DomainID DomainID;
8010249Sstephan.diestelhorst@arm.com    typedef SrcClockDomain::PerfLevel PerfLevel;
8110249Sstephan.diestelhorst@arm.com
8210249Sstephan.diestelhorst@arm.com    /**
8310249Sstephan.diestelhorst@arm.com     * Check whether a domain ID is known to the handler or not.
8410249Sstephan.diestelhorst@arm.com     * @param domain_id Domain ID to check
8510249Sstephan.diestelhorst@arm.com     * @return Domain ID known to handler?
8610249Sstephan.diestelhorst@arm.com     */
8710249Sstephan.diestelhorst@arm.com    bool validDomainID(DomainID domain_id) const;
8810249Sstephan.diestelhorst@arm.com
8910249Sstephan.diestelhorst@arm.com    /**
9010249Sstephan.diestelhorst@arm.com     * Get transition latency to switch between performance levels.
9110249Sstephan.diestelhorst@arm.com     * @return Transition latency
9210249Sstephan.diestelhorst@arm.com     */
9310249Sstephan.diestelhorst@arm.com    Tick transLatency() const { return _transLatency; }
9410249Sstephan.diestelhorst@arm.com
9510249Sstephan.diestelhorst@arm.com    /**
9610249Sstephan.diestelhorst@arm.com     * Set a new performance level for the specified domain.  The actual update
9710249Sstephan.diestelhorst@arm.com     * will be delayed by transLatency().
9810249Sstephan.diestelhorst@arm.com     *
9910249Sstephan.diestelhorst@arm.com     * @param domain_id Software visible ID of the domain to be configured
10010249Sstephan.diestelhorst@arm.com     * @param perf_level Requested performance level (0 - fast, >0 slower)
10110249Sstephan.diestelhorst@arm.com     * @return status whether the setting was successful
10210249Sstephan.diestelhorst@arm.com     */
10310249Sstephan.diestelhorst@arm.com    bool perfLevel(DomainID domain_id, PerfLevel perf_level);
10410249Sstephan.diestelhorst@arm.com
10510249Sstephan.diestelhorst@arm.com    /**
10610249Sstephan.diestelhorst@arm.com     * Get the current performance level of a domain.  While a change request is
10710249Sstephan.diestelhorst@arm.com     * in-flight, will return the current (i.e. old, unmodified) value.
10810249Sstephan.diestelhorst@arm.com     *
10910249Sstephan.diestelhorst@arm.com     * @param domain_id Domain ID to query
11010249Sstephan.diestelhorst@arm.com     * @return Current performance level of the specified domain
11110249Sstephan.diestelhorst@arm.com     */
11210249Sstephan.diestelhorst@arm.com    PerfLevel perfLevel(DomainID domain_id) const {
11310249Sstephan.diestelhorst@arm.com         assert(isEnabled());
11410249Sstephan.diestelhorst@arm.com         return findDomain(domain_id)->perfLevel();
11510249Sstephan.diestelhorst@arm.com    }
11610249Sstephan.diestelhorst@arm.com
11710249Sstephan.diestelhorst@arm.com    /**
11810249Sstephan.diestelhorst@arm.com     * Read the clock period of the specified domain at the specified
11910249Sstephan.diestelhorst@arm.com     * performance level.
12010249Sstephan.diestelhorst@arm.com     * @param domain_id Domain ID to query
12110249Sstephan.diestelhorst@arm.com     * @param perf_level Performance level of interest
12210249Sstephan.diestelhorst@arm.com     * @return Clock period in ticks for the requested performance level of
12310249Sstephan.diestelhorst@arm.com     * the respective domain
12410249Sstephan.diestelhorst@arm.com     */
12510249Sstephan.diestelhorst@arm.com    Tick clkPeriodAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const
12610249Sstephan.diestelhorst@arm.com    {
12710249Sstephan.diestelhorst@arm.com        return findDomain(domain_id)->clkPeriodAtPerfLevel(perf_level);
12810249Sstephan.diestelhorst@arm.com    }
12910249Sstephan.diestelhorst@arm.com
13010249Sstephan.diestelhorst@arm.com    /**
13110249Sstephan.diestelhorst@arm.com     * Get the total number of available performance levels.
13210249Sstephan.diestelhorst@arm.com     *
13310249Sstephan.diestelhorst@arm.com     * @param domain_id Domain ID to query
13410249Sstephan.diestelhorst@arm.com     * @return Number of performance levels that where configured for the
13510249Sstephan.diestelhorst@arm.com     * respective domain
13610249Sstephan.diestelhorst@arm.com     */
13710249Sstephan.diestelhorst@arm.com    PerfLevel numPerfLevels(PerfLevel domain_id) const
13810249Sstephan.diestelhorst@arm.com    {
13910249Sstephan.diestelhorst@arm.com        return findDomain(domain_id)->numPerfLevels();
14010249Sstephan.diestelhorst@arm.com    }
14110249Sstephan.diestelhorst@arm.com
14210249Sstephan.diestelhorst@arm.com    /**
14310249Sstephan.diestelhorst@arm.com     * Check enable status of the DVFS handler, when the handler is disabled, no
14410249Sstephan.diestelhorst@arm.com     * request should be sent to the handler.
14510249Sstephan.diestelhorst@arm.com     * @return True, if the handler is enabled
14610249Sstephan.diestelhorst@arm.com     */
14710249Sstephan.diestelhorst@arm.com    bool isEnabled() const { return enableHandler; }
14810249Sstephan.diestelhorst@arm.com
14910249Sstephan.diestelhorst@arm.com    void serialize(std::ostream &os);
15010249Sstephan.diestelhorst@arm.com    void unserialize(Checkpoint *cp, const std::string &section);
15110249Sstephan.diestelhorst@arm.com
15210249Sstephan.diestelhorst@arm.com  private:
15310249Sstephan.diestelhorst@arm.com    typedef std::map<DomainID, SrcClockDomain*> Domains;
15410249Sstephan.diestelhorst@arm.com    Domains domains;
15510249Sstephan.diestelhorst@arm.com
15610249Sstephan.diestelhorst@arm.com    /**
15710249Sstephan.diestelhorst@arm.com      * Clock domain of the system the handler is instantiated.
15810249Sstephan.diestelhorst@arm.com      */
15910249Sstephan.diestelhorst@arm.com    SrcClockDomain* sysClkDomain;
16010249Sstephan.diestelhorst@arm.com
16110249Sstephan.diestelhorst@arm.com    /**
16210249Sstephan.diestelhorst@arm.com     * Search for a domain based on the domain ID.
16310249Sstephan.diestelhorst@arm.com     *
16410249Sstephan.diestelhorst@arm.com     * @param domain_id Domain ID to search for
16510249Sstephan.diestelhorst@arm.com     * @return Pointer to the source clock domain with matching ID.
16610249Sstephan.diestelhorst@arm.com     */
16710249Sstephan.diestelhorst@arm.com    SrcClockDomain *findDomain(DomainID domain_id) const {
16810249Sstephan.diestelhorst@arm.com        auto it = domains.find(domain_id);
16910249Sstephan.diestelhorst@arm.com        panic_if(it == domains.end(),
17010249Sstephan.diestelhorst@arm.com                 "DVFS: Could not find a domain for ID %d.\n",domain_id );
17110249Sstephan.diestelhorst@arm.com        return domains.find(domain_id)->second;
17210249Sstephan.diestelhorst@arm.com    }
17310249Sstephan.diestelhorst@arm.com
17410249Sstephan.diestelhorst@arm.com    /**
17510249Sstephan.diestelhorst@arm.com     * Disabling the DVFS handler ensures that all the DVFS migration requests
17610249Sstephan.diestelhorst@arm.com     * are ignored. Domains remain at their default frequency and voltage.
17710249Sstephan.diestelhorst@arm.com     */
17810249Sstephan.diestelhorst@arm.com    bool enableHandler;
17910249Sstephan.diestelhorst@arm.com
18010249Sstephan.diestelhorst@arm.com
18110249Sstephan.diestelhorst@arm.com    /**
18210249Sstephan.diestelhorst@arm.com     * This corresponds to the maximum transition latency associated with the
18310249Sstephan.diestelhorst@arm.com     * hardware transitioning from a particular performance level to the other
18410249Sstephan.diestelhorst@arm.com     */
18510249Sstephan.diestelhorst@arm.com    const Tick _transLatency;
18610249Sstephan.diestelhorst@arm.com
18710249Sstephan.diestelhorst@arm.com
18810249Sstephan.diestelhorst@arm.com
18910249Sstephan.diestelhorst@arm.com    /**
19010249Sstephan.diestelhorst@arm.com     * Update performance level event, encapsulates all the required information
19110249Sstephan.diestelhorst@arm.com     * for a future call to change a domain's performance level.
19210249Sstephan.diestelhorst@arm.com     */
19310249Sstephan.diestelhorst@arm.com    struct UpdateEvent : public Event {
19410360Sandreas.hansson@arm.com        UpdateEvent() : Event(DVFS_Update_Pri), domainIDToSet(0),
19510360Sandreas.hansson@arm.com                        perfLevelToSet(0) {}
19610249Sstephan.diestelhorst@arm.com
19710249Sstephan.diestelhorst@arm.com        /**
19810249Sstephan.diestelhorst@arm.com         * Static pointer to the single DVFS hander for all the update events
19910249Sstephan.diestelhorst@arm.com         */
20010249Sstephan.diestelhorst@arm.com        static DVFSHandler *dvfsHandler;
20110249Sstephan.diestelhorst@arm.com
20210249Sstephan.diestelhorst@arm.com        /**
20310249Sstephan.diestelhorst@arm.com         * ID of the domain that will be changed by the in-flight event
20410249Sstephan.diestelhorst@arm.com         */
20510249Sstephan.diestelhorst@arm.com        DomainID domainIDToSet;
20610249Sstephan.diestelhorst@arm.com
20710249Sstephan.diestelhorst@arm.com        /**
20810249Sstephan.diestelhorst@arm.com         * Target performance level of the in-flight event
20910249Sstephan.diestelhorst@arm.com         */
21010249Sstephan.diestelhorst@arm.com        PerfLevel perfLevelToSet;
21110249Sstephan.diestelhorst@arm.com
21210249Sstephan.diestelhorst@arm.com        /**
21310249Sstephan.diestelhorst@arm.com         * Updates the performance level by modifying the clock and the voltage
21410249Sstephan.diestelhorst@arm.com         * of the associated clocked objects.  Gets information from
21510249Sstephan.diestelhorst@arm.com         * domainIDToSet and perfLevelToSet for easier calling through an
21610249Sstephan.diestelhorst@arm.com         * event.
21710249Sstephan.diestelhorst@arm.com         */
21810249Sstephan.diestelhorst@arm.com        void updatePerfLevel();
21910249Sstephan.diestelhorst@arm.com
22010249Sstephan.diestelhorst@arm.com        void process() { updatePerfLevel(); }
22110249Sstephan.diestelhorst@arm.com    };
22210249Sstephan.diestelhorst@arm.com
22310249Sstephan.diestelhorst@arm.com    typedef std::map<DomainID, UpdateEvent> UpdatePerfLevelEvents;
22410249Sstephan.diestelhorst@arm.com    /**
22510249Sstephan.diestelhorst@arm.com     * Map from domain IDs -> perf level update events, records in-flight change
22610249Sstephan.diestelhorst@arm.com     * requests per domain ID.
22710249Sstephan.diestelhorst@arm.com     */
22810249Sstephan.diestelhorst@arm.com    UpdatePerfLevelEvents updatePerfLevelEvents;
22910249Sstephan.diestelhorst@arm.com};
23010249Sstephan.diestelhorst@arm.com
23110249Sstephan.diestelhorst@arm.com#endif // __SIM_DVFS_HANDLER_HH__
232