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 §ion); 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