dvfs_handler.hh revision 10360
15612Sgblack@eecs.umich.edu/*
25612Sgblack@eecs.umich.edu * Copyright (c) 2013-2014 ARM Limited
35612Sgblack@eecs.umich.edu * All rights reserved
45612Sgblack@eecs.umich.edu *
55612Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
65612Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
75612Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
85612Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
95612Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
105612Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
115612Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
125612Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
135612Sgblack@eecs.umich.edu *
145612Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
155612Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
165612Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
175612Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
185612Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
195612Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
205612Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
215612Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
225612Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
235612Sgblack@eecs.umich.edu * this software without specific prior written permission.
245612Sgblack@eecs.umich.edu *
255612Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
265612Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
275612Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
285612Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
295612Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
305612Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
315612Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
325612Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
335612Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
345612Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
355612Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
365612Sgblack@eecs.umich.edu *
375612Sgblack@eecs.umich.edu * Authors: Vasileios Spiliopoulos
385612Sgblack@eecs.umich.edu *          Akash Bagdia
395612Sgblack@eecs.umich.edu *          Stephan Diestelhorst
405612Sgblack@eecs.umich.edu */
415612Sgblack@eecs.umich.edu
425612Sgblack@eecs.umich.edu/**
435612Sgblack@eecs.umich.edu * @file
445612Sgblack@eecs.umich.edu * DVFSHandler and DomainConfig class declaration used for managing voltage
455612Sgblack@eecs.umich.edu * and frequency scaling of the various DVFS domains in the system (with each
465612Sgblack@eecs.umich.edu * domain having their independent domain configuration information)
475612Sgblack@eecs.umich.edu */
485612Sgblack@eecs.umich.edu
495612Sgblack@eecs.umich.edu
505612Sgblack@eecs.umich.edu#ifndef __SIM_DVFS_HANDLER_HH__
515612Sgblack@eecs.umich.edu#define __SIM_DVFS_HANDLER_HH__
525612Sgblack@eecs.umich.edu
535612Sgblack@eecs.umich.edu#include <vector>
545612Sgblack@eecs.umich.edu
555612Sgblack@eecs.umich.edu#include "params/ClockDomain.hh"
565612Sgblack@eecs.umich.edu#include "params/DVFSHandler.hh"
575612Sgblack@eecs.umich.edu#include "params/VoltageDomain.hh"
585612Sgblack@eecs.umich.edu#include "sim/clock_domain.hh"
595612Sgblack@eecs.umich.edu#include "sim/eventq.hh"
605612Sgblack@eecs.umich.edu#include "sim/sim_object.hh"
615612Sgblack@eecs.umich.edu
625614Sgblack@eecs.umich.edu
635614Sgblack@eecs.umich.edu/**
645612Sgblack@eecs.umich.edu * DVFS Handler class, maintains a list of all the domains it can handle.
655612Sgblack@eecs.umich.edu * Each entry of that list is an object of the DomainConfig class, and the
665612Sgblack@eecs.umich.edu * handler uses the methods provided by that class to get access to the
675614Sgblack@eecs.umich.edu * configuration of each domain. The handler is responsible for setting/getting
685615Sgblack@eecs.umich.edu * clock periods and voltages from clock/voltage domains.
695612Sgblack@eecs.umich.edu * The handler acts the bridge between software configurable information
705625Sgblack@eecs.umich.edu * for each domain as provided to the controller and the hardware
715625Sgblack@eecs.umich.edu * implementation details for those domains.
725625Sgblack@eecs.umich.edu */
735625Sgblack@eecs.umich.educlass DVFSHandler : public SimObject
74{
75  public:
76    typedef DVFSHandlerParams Params;
77    DVFSHandler(const Params *p);
78
79    typedef SrcClockDomain::DomainID DomainID;
80    typedef SrcClockDomain::PerfLevel PerfLevel;
81
82    /**
83     * Check whether a domain ID is known to the handler or not.
84     * @param domain_id Domain ID to check
85     * @return Domain ID known to handler?
86     */
87    bool validDomainID(DomainID domain_id) const;
88
89    /**
90     * Get transition latency to switch between performance levels.
91     * @return Transition latency
92     */
93    Tick transLatency() const { return _transLatency; }
94
95    /**
96     * Set a new performance level for the specified domain.  The actual update
97     * will be delayed by transLatency().
98     *
99     * @param domain_id Software visible ID of the domain to be configured
100     * @param perf_level Requested performance level (0 - fast, >0 slower)
101     * @return status whether the setting was successful
102     */
103    bool perfLevel(DomainID domain_id, PerfLevel perf_level);
104
105    /**
106     * Get the current performance level of a domain.  While a change request is
107     * in-flight, will return the current (i.e. old, unmodified) value.
108     *
109     * @param domain_id Domain ID to query
110     * @return Current performance level of the specified domain
111     */
112    PerfLevel perfLevel(DomainID domain_id) const {
113         assert(isEnabled());
114         return findDomain(domain_id)->perfLevel();
115    }
116
117    /**
118     * Read the clock period of the specified domain at the specified
119     * performance level.
120     * @param domain_id Domain ID to query
121     * @param perf_level Performance level of interest
122     * @return Clock period in ticks for the requested performance level of
123     * the respective domain
124     */
125    Tick clkPeriodAtPerfLevel(DomainID domain_id, PerfLevel perf_level) const
126    {
127        return findDomain(domain_id)->clkPeriodAtPerfLevel(perf_level);
128    }
129
130    /**
131     * Get the total number of available performance levels.
132     *
133     * @param domain_id Domain ID to query
134     * @return Number of performance levels that where configured for the
135     * respective domain
136     */
137    PerfLevel numPerfLevels(PerfLevel domain_id) const
138    {
139        return findDomain(domain_id)->numPerfLevels();
140    }
141
142    /**
143     * Check enable status of the DVFS handler, when the handler is disabled, no
144     * request should be sent to the handler.
145     * @return True, if the handler is enabled
146     */
147    bool isEnabled() const { return enableHandler; }
148
149    void serialize(std::ostream &os);
150    void unserialize(Checkpoint *cp, const std::string &section);
151
152  private:
153    typedef std::map<DomainID, SrcClockDomain*> Domains;
154    Domains domains;
155
156    /**
157      * Clock domain of the system the handler is instantiated.
158      */
159    SrcClockDomain* sysClkDomain;
160
161    /**
162     * Search for a domain based on the domain ID.
163     *
164     * @param domain_id Domain ID to search for
165     * @return Pointer to the source clock domain with matching ID.
166     */
167    SrcClockDomain *findDomain(DomainID domain_id) const {
168        auto it = domains.find(domain_id);
169        panic_if(it == domains.end(),
170                 "DVFS: Could not find a domain for ID %d.\n",domain_id );
171        return domains.find(domain_id)->second;
172    }
173
174    /**
175     * Disabling the DVFS handler ensures that all the DVFS migration requests
176     * are ignored. Domains remain at their default frequency and voltage.
177     */
178    bool enableHandler;
179
180
181    /**
182     * This corresponds to the maximum transition latency associated with the
183     * hardware transitioning from a particular performance level to the other
184     */
185    const Tick _transLatency;
186
187
188
189    /**
190     * Update performance level event, encapsulates all the required information
191     * for a future call to change a domain's performance level.
192     */
193    struct UpdateEvent : public Event {
194        UpdateEvent() : Event(DVFS_Update_Pri), domainIDToSet(0),
195                        perfLevelToSet(0) {}
196
197        /**
198         * Static pointer to the single DVFS hander for all the update events
199         */
200        static DVFSHandler *dvfsHandler;
201
202        /**
203         * ID of the domain that will be changed by the in-flight event
204         */
205        DomainID domainIDToSet;
206
207        /**
208         * Target performance level of the in-flight event
209         */
210        PerfLevel perfLevelToSet;
211
212        /**
213         * Updates the performance level by modifying the clock and the voltage
214         * of the associated clocked objects.  Gets information from
215         * domainIDToSet and perfLevelToSet for easier calling through an
216         * event.
217         */
218        void updatePerfLevel();
219
220        void process() { updatePerfLevel(); }
221    };
222
223    typedef std::map<DomainID, UpdateEvent> UpdatePerfLevelEvents;
224    /**
225     * Map from domain IDs -> perf level update events, records in-flight change
226     * requests per domain ID.
227     */
228    UpdatePerfLevelEvents updatePerfLevelEvents;
229};
230
231#endif // __SIM_DVFS_HANDLER_HH__
232