1/* 2 * Copyright (c) 2012-2014 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions are 16 * met: redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer; 18 * redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution; 21 * neither the name of the copyright holders nor the names of its 22 * contributors may be used to endorse or promote products derived from 23 * this software without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Vasileios Spiliopoulos 38 * Akash Bagdia 39 * Stephan Diestelhorst 40 */ 41 42/** 43 * @file 44 * The energy controller is a device being used to manage power and energy 45 * related control operations within the system. It provides the necessary 46 * software interface to the kernel. The kernel will require gem5 specific 47 * drivers to access this device. 48 * 49 * Tasks handled by the controller are: 50 * a) Dynamic voltage and frequency scaling control operations 51 * 52 * Note that the registers defined do not resemble any specific controller 53 * device in real hardware. They are currently design to accomodate the gem5 54 * system requirements. 55 */ 56 57#ifndef __DEV_ARM_ENERGY_CTRL_HH__ 58#define __DEV_ARM_ENERGY_CTRL_HH__ 59 60#include "dev/io_device.hh" 61#include "params/EnergyCtrl.hh" 62 63class DVFSHandler; 64 65class EnergyCtrl : public BasicPioDevice 66{ 67 public: 68 /** 69 * Discovery flows: 70 * ---------------- 71 * * get basic DVFS handler information 72 * read(DVFS_HANDLER_STATUS) 73 * read(DVFS_HANDLER_TRANS_LATENCY) 74 * 75 * * get the number of domain IDs 76 * read(DVFS_NUM_DOMAINS) -> domains 77 * 78 * * query the driver to get the IDs for all i in domains 79 * write(DVFS_DOMAINID_AT_INDEX <- i) 80 * read(DOMAIN_ID) -> domainID_i 81 * 82 * * for each domainID i get voltage / frequency pairs 83 * write(DOMAIN_ID <- domainID_i) 84 * read(NUM_OF_PERF_LEVELS) -> levels_i 85 * * for each l in levels_i 86 * write(PERF_LEVEL_TO_READ <- l) 87 * read(FREQ_AT_PERF_LEVEL) -> freq_l_i 88 * read(VOLT_AT_PERF_LEVEL) -> volt_l_i 89 * 90 * 91 * Setting a specific performance level (V/F combination) 92 * ------------------------------------------------------ 93 * * get performance for domain_ID i 94 * write(DOMAIN_ID <- i) 95 * read(PERF_LEVEL) -> perf_level_i 96 * 97 * * set performance for domain_ID i 98 * write(DOMAIN_ID <- i) 99 * write(PERF_LEVEL <- perf_level_i) 100 * * wait for DVFS transition completion 101 * while (!read(PERF_LEVEL_ACK)); 102 */ 103 104 enum Registers { 105 DVFS_HANDLER_STATUS = 0, 106 DVFS_NUM_DOMAINS, 107 DVFS_DOMAINID_AT_INDEX, 108 DVFS_HANDLER_TRANS_LATENCY, 109 DOMAIN_ID, 110 PERF_LEVEL, 111 PERF_LEVEL_ACK, 112 NUM_OF_PERF_LEVELS, 113 PERF_LEVEL_TO_READ, 114 FREQ_AT_PERF_LEVEL, 115 VOLT_AT_PERF_LEVEL, 116 PIO_NUM_FIELDS 117 }; 118 119 typedef EnergyCtrlParams Params; 120 EnergyCtrl(const Params *p); 121 122 /** 123 * Read command sent to the device 124 * @param pkt Packet describing this request 125 * @return number of ticks it took to complete 126 */ 127 Tick read(PacketPtr pkt) override; 128 /** 129 * Write command sent to the device 130 * @param pkt Packet describing this request 131 * @return number of ticks it took to complete 132 */ 133 Tick write(PacketPtr pkt) override; 134 135 void serialize(CheckpointOut &cp) const override; 136 void unserialize(CheckpointIn &cp) override; 137 138 void startup() override; 139 void init() override; 140 141 private: 142 DVFSHandler *dvfsHandler; 143 144 /** 145 * Cluster ID (DOMAIN_ID) R/W register, programmed to ID of the domain for 146 * which the set/get performance level command can be issued 147 */ 148 uint32_t domainID; 149 150 /** 151 * Index for getting the domain ID from the domain ID list available with 152 * the DVFS handler 153 */ 154 uint32_t domainIDIndexToRead; 155 156 /** 157 * Acknowledgment (PERF_LEVEL_ACK) RO register, software polls this 158 * register to read back the status of the last programmed change in the 159 * domain ID and/or the performance level. Valid values are: 160 * '0' - Ack is not OK yet 161 * '1' - Ack is OK 162 * It is a read destructive register with a read of '1' resets the ack to 163 * '0'. 164 */ 165 uint32_t perfLevelAck; 166 167 uint32_t perfLevelToRead; 168 169 static uint32_t ticksTokHz(Tick period) { 170 return (uint32_t)(SimClock::Int::ms / period); 171 } 172 173 static uint32_t toMicroVolt(double voltage) { 174 return (uint32_t)(voltage * 1000000); 175 } 176 177 /** 178 * Update the acknowledgment that is read back by the software to confirm 179 * newly requested performance level has been set. 180 */ 181 void updatePLAck() { 182 perfLevelAck = 1; 183 } 184 185 EventFunctionWrapper updateAckEvent; 186}; 187#endif //__DEV_ARM_ENERGY_CTRL_HH__ 188