rv_ctrl.cc revision 12078
16019Shines@cs.fsu.edu/* 27093Sgblack@eecs.umich.edu * Copyright (c) 2010,2013,2015 ARM Limited 37093Sgblack@eecs.umich.edu * All rights reserved 47093Sgblack@eecs.umich.edu * 57093Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67093Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77093Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87093Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97093Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107093Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117093Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127093Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137093Sgblack@eecs.umich.edu * 146019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without 156019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are 166019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright 176019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer; 186019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright 196019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the 206019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution; 216019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its 226019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 236019Shines@cs.fsu.edu * this software without specific prior written permission. 246019Shines@cs.fsu.edu * 256019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 266019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 276019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 286019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 296019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 306019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 316019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 336019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 346019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 356019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 366019Shines@cs.fsu.edu * 376019Shines@cs.fsu.edu * Authors: Ali Saidi 386019Shines@cs.fsu.edu */ 396019Shines@cs.fsu.edu 407399SAli.Saidi@ARM.com#include "dev/arm/rv_ctrl.hh" 417399SAli.Saidi@ARM.com 426019Shines@cs.fsu.edu#include "base/trace.hh" 436019Shines@cs.fsu.edu#include "debug/RVCTRL.hh" 446019Shines@cs.fsu.edu#include "mem/packet.hh" 456019Shines@cs.fsu.edu#include "mem/packet_access.hh" 466019Shines@cs.fsu.edu#include "sim/power/thermal_model.hh" 476019Shines@cs.fsu.edu#include "sim/system.hh" 486116Snate@binkert.org#include "sim/voltage_domain.hh" 496019Shines@cs.fsu.edu 506019Shines@cs.fsu.eduRealViewCtrl::RealViewCtrl(Params *p) 516019Shines@cs.fsu.edu : BasicPioDevice(p, 0xD4), flags(0), scData(0) 526019Shines@cs.fsu.edu{ 536019Shines@cs.fsu.edu} 546019Shines@cs.fsu.edu 556019Shines@cs.fsu.eduTick 566116Snate@binkert.orgRealViewCtrl::read(PacketPtr pkt) 576116Snate@binkert.org{ 586019Shines@cs.fsu.edu assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 596019Shines@cs.fsu.edu assert(pkt->getSize() == 4); 607406SAli.Saidi@ARM.com Addr daddr = pkt->getAddr() - pioAddr; 617406SAli.Saidi@ARM.com 627406SAli.Saidi@ARM.com switch(daddr) { 637406SAli.Saidi@ARM.com case ProcId0: 646019Shines@cs.fsu.edu pkt->set(params()->proc_id0); 656019Shines@cs.fsu.edu break; 666019Shines@cs.fsu.edu case ProcId1: 676019Shines@cs.fsu.edu pkt->set(params()->proc_id1); 686019Shines@cs.fsu.edu break; 697404SAli.Saidi@ARM.com case Clock24: 707404SAli.Saidi@ARM.com Tick clk; 717404SAli.Saidi@ARM.com clk = SimClock::Float::MHz * curTick() * 24; 726019Shines@cs.fsu.edu pkt->set((uint32_t)(clk)); 737404SAli.Saidi@ARM.com break; 747404SAli.Saidi@ARM.com case Clock100: 757399SAli.Saidi@ARM.com Tick clk100; 767406SAli.Saidi@ARM.com clk100 = SimClock::Float::MHz * curTick() * 100; 777404SAli.Saidi@ARM.com pkt->set((uint32_t)(clk100)); 787406SAli.Saidi@ARM.com break; 796019Shines@cs.fsu.edu case Flash: 806019Shines@cs.fsu.edu pkt->set<uint32_t>(0); 816019Shines@cs.fsu.edu break; 826019Shines@cs.fsu.edu case Clcd: 836019Shines@cs.fsu.edu pkt->set<uint32_t>(0x00001F00); 846019Shines@cs.fsu.edu break; 856019Shines@cs.fsu.edu case Osc0: 866019Shines@cs.fsu.edu pkt->set<uint32_t>(0x00012C5C); 877404SAli.Saidi@ARM.com break; 887404SAli.Saidi@ARM.com case Osc1: 896019Shines@cs.fsu.edu pkt->set<uint32_t>(0x00002CC0); 907404SAli.Saidi@ARM.com break; 917404SAli.Saidi@ARM.com case Osc2: 927404SAli.Saidi@ARM.com pkt->set<uint32_t>(0x00002C75); 937404SAli.Saidi@ARM.com break; 947404SAli.Saidi@ARM.com case Osc3: 957404SAli.Saidi@ARM.com pkt->set<uint32_t>(0x00020211); 967404SAli.Saidi@ARM.com break; 977404SAli.Saidi@ARM.com case Osc4: 987404SAli.Saidi@ARM.com pkt->set<uint32_t>(0x00002C75); 997404SAli.Saidi@ARM.com break; 1007404SAli.Saidi@ARM.com case Lock: 1017404SAli.Saidi@ARM.com pkt->set<uint32_t>(sysLock); 1027404SAli.Saidi@ARM.com break; 1037404SAli.Saidi@ARM.com case Flags: 1047404SAli.Saidi@ARM.com pkt->set<uint32_t>(flags); 1057404SAli.Saidi@ARM.com break; 1067404SAli.Saidi@ARM.com case IdReg: 1077404SAli.Saidi@ARM.com pkt->set<uint32_t>(params()->idreg); 1087404SAli.Saidi@ARM.com break; 1097404SAli.Saidi@ARM.com case CfgStat: 1107404SAli.Saidi@ARM.com pkt->set<uint32_t>(1); 1117404SAli.Saidi@ARM.com break; 1127404SAli.Saidi@ARM.com case CfgData: 1137404SAli.Saidi@ARM.com pkt->set<uint32_t>(scData); 1146019Shines@cs.fsu.edu DPRINTF(RVCTRL, "Read %#x from SCReg\n", scData); 1156019Shines@cs.fsu.edu break; 1166019Shines@cs.fsu.edu case CfgCtrl: 1176019Shines@cs.fsu.edu pkt->set<uint32_t>(0); // not busy 1187404SAli.Saidi@ARM.com DPRINTF(RVCTRL, "Read 0 from CfgCtrl\n"); 1196019Shines@cs.fsu.edu break; 1207404SAli.Saidi@ARM.com default: 1217404SAli.Saidi@ARM.com warn("Tried to read RealView I/O at offset %#x that doesn't exist\n", 1227404SAli.Saidi@ARM.com daddr); 1237404SAli.Saidi@ARM.com pkt->set<uint32_t>(0); 1247404SAli.Saidi@ARM.com break; 1257404SAli.Saidi@ARM.com } 1267404SAli.Saidi@ARM.com pkt->makeAtomicResponse(); 1277404SAli.Saidi@ARM.com return pioDelay; 1287404SAli.Saidi@ARM.com 1297404SAli.Saidi@ARM.com} 1307404SAli.Saidi@ARM.com 1317404SAli.Saidi@ARM.comTick 1327404SAli.Saidi@ARM.comRealViewCtrl::write(PacketPtr pkt) 1337404SAli.Saidi@ARM.com{ 1347404SAli.Saidi@ARM.com assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); 1357404SAli.Saidi@ARM.com 1366019Shines@cs.fsu.edu Addr daddr = pkt->getAddr() - pioAddr; 1376019Shines@cs.fsu.edu switch (daddr) { 1386019Shines@cs.fsu.edu case Flash: 1397404SAli.Saidi@ARM.com case Clcd: 1407404SAli.Saidi@ARM.com case Osc0: 1417404SAli.Saidi@ARM.com case Osc1: 1427404SAli.Saidi@ARM.com case Osc2: 1437404SAli.Saidi@ARM.com case Osc3: 1447404SAli.Saidi@ARM.com case Osc4: 1457404SAli.Saidi@ARM.com break; 1467404SAli.Saidi@ARM.com case Lock: 1477404SAli.Saidi@ARM.com sysLock.lockVal = pkt->get<uint16_t>(); 1487404SAli.Saidi@ARM.com break; 1497404SAli.Saidi@ARM.com case ResetCtl: 1507404SAli.Saidi@ARM.com // Ignore writes to reset control 1517404SAli.Saidi@ARM.com warn_once("Ignoring write to reset control\n"); 1527404SAli.Saidi@ARM.com break; 1537404SAli.Saidi@ARM.com case Flags: 1547404SAli.Saidi@ARM.com flags = pkt->get<uint32_t>(); 1556019Shines@cs.fsu.edu break; 1566019Shines@cs.fsu.edu case FlagsClr: 1577404SAli.Saidi@ARM.com flags = 0; 1587404SAli.Saidi@ARM.com break; 1597404SAli.Saidi@ARM.com case CfgData: 1607404SAli.Saidi@ARM.com scData = pkt->get<uint32_t>(); 1617404SAli.Saidi@ARM.com break; 1627404SAli.Saidi@ARM.com case CfgCtrl: { 1637404SAli.Saidi@ARM.com // A request is being submitted to read/write the system control 1647404SAli.Saidi@ARM.com // registers. See 1657404SAli.Saidi@ARM.com // http://infocenter.arm.com/help/topic/com.arm.doc.dui0447h/CACDEFGH.html 1667404SAli.Saidi@ARM.com CfgCtrlReg req = pkt->get<uint32_t>(); 1677404SAli.Saidi@ARM.com if (!req.start) { 1687404SAli.Saidi@ARM.com DPRINTF(RVCTRL, "SCReg: write %#x to ctrl but not starting\n", 1696019Shines@cs.fsu.edu req); 1706019Shines@cs.fsu.edu break; 1716019Shines@cs.fsu.edu } 1727404SAli.Saidi@ARM.com 1737404SAli.Saidi@ARM.com auto it_dev(devices.find(req & CFG_CTRL_ADDR_MASK)); 1747404SAli.Saidi@ARM.com if (it_dev == devices.end()) { 1757404SAli.Saidi@ARM.com warn_once("SCReg: Access to unknown device " 1767404SAli.Saidi@ARM.com "dcc%d:site%d:pos%d:fn%d:dev%d\n", 1777404SAli.Saidi@ARM.com req.dcc, req.site, req.pos, req.func, req.dev); 1787404SAli.Saidi@ARM.com break; 1797404SAli.Saidi@ARM.com } 1807404SAli.Saidi@ARM.com 1817404SAli.Saidi@ARM.com // Service the request as a read or write depending on the 1827404SAli.Saidi@ARM.com // wr bit in the control register. 1837404SAli.Saidi@ARM.com Device &dev(*it_dev->second); 1847404SAli.Saidi@ARM.com if (req.wr) { 1857404SAli.Saidi@ARM.com DPRINTF(RVCTRL, "SCReg: Writing %#x (ctrlWr %#x)\n", 1867404SAli.Saidi@ARM.com scData, req); 1877404SAli.Saidi@ARM.com dev.write(scData); 1887404SAli.Saidi@ARM.com 1897404SAli.Saidi@ARM.com } else { 1907404SAli.Saidi@ARM.com scData = dev.read(); 1917404SAli.Saidi@ARM.com DPRINTF(RVCTRL, "SCReg: Reading %#x (ctrlRd %#x)\n", 1927404SAli.Saidi@ARM.com scData, req); 1937404SAli.Saidi@ARM.com } 1947404SAli.Saidi@ARM.com } break; 1957404SAli.Saidi@ARM.com case CfgStat: // Weird to write this 1967404SAli.Saidi@ARM.com default: 1977404SAli.Saidi@ARM.com warn("Tried to write RVIO at offset %#x (data %#x) that doesn't exist\n", 1987404SAli.Saidi@ARM.com daddr, pkt->get<uint32_t>()); 1997404SAli.Saidi@ARM.com break; 2007404SAli.Saidi@ARM.com } 2017404SAli.Saidi@ARM.com pkt->makeAtomicResponse(); 2027404SAli.Saidi@ARM.com return pioDelay; 2037404SAli.Saidi@ARM.com} 2047404SAli.Saidi@ARM.com 2057404SAli.Saidi@ARM.comvoid 2067404SAli.Saidi@ARM.comRealViewCtrl::serialize(CheckpointOut &cp) const 2077404SAli.Saidi@ARM.com{ 2087404SAli.Saidi@ARM.com SERIALIZE_SCALAR(flags); 2097404SAli.Saidi@ARM.com} 2107404SAli.Saidi@ARM.com 2117404SAli.Saidi@ARM.comvoid 2127404SAli.Saidi@ARM.comRealViewCtrl::unserialize(CheckpointIn &cp) 2137404SAli.Saidi@ARM.com{ 2147404SAli.Saidi@ARM.com UNSERIALIZE_SCALAR(flags); 2157404SAli.Saidi@ARM.com} 2167404SAli.Saidi@ARM.com 2177404SAli.Saidi@ARM.comvoid 2187404SAli.Saidi@ARM.comRealViewCtrl::registerDevice(DeviceFunc func, uint8_t site, uint8_t pos, 2197404SAli.Saidi@ARM.com uint8_t dcc, uint16_t dev, 2207404SAli.Saidi@ARM.com Device *handler) 2217404SAli.Saidi@ARM.com{ 2227404SAli.Saidi@ARM.com CfgCtrlReg addr = 0; 2237404SAli.Saidi@ARM.com addr.func = func; 2247404SAli.Saidi@ARM.com addr.site = site; 2257404SAli.Saidi@ARM.com addr.pos = pos; 2267404SAli.Saidi@ARM.com addr.dcc = dcc; 2276019Shines@cs.fsu.edu addr.dev = dev; 2286019Shines@cs.fsu.edu 2296019Shines@cs.fsu.edu if (devices.find(addr) != devices.end()) { 2307404SAli.Saidi@ARM.com fatal("Platform device dcc%d:site%d:pos%d:fn%d:dev%d " 2316019Shines@cs.fsu.edu "already registered.", 2326019Shines@cs.fsu.edu addr.dcc, addr.site, addr.pos, addr.func, addr.dev); 2336019Shines@cs.fsu.edu } 2346019Shines@cs.fsu.edu 2356019Shines@cs.fsu.edu devices[addr] = handler; 2366019Shines@cs.fsu.edu} 2377399SAli.Saidi@ARM.com 2386019Shines@cs.fsu.edu 2396019Shines@cs.fsu.eduRealViewOsc::RealViewOsc(RealViewOscParams *p) 2406019Shines@cs.fsu.edu : ClockDomain(p, p->voltage_domain), 2416019Shines@cs.fsu.edu RealViewCtrl::Device(*p->parent, RealViewCtrl::FUNC_OSC, 2426019Shines@cs.fsu.edu p->site, p->position, p->dcc, p->device) 2436019Shines@cs.fsu.edu{ 2446019Shines@cs.fsu.edu if (SimClock::Float::s / p->freq > UINT32_MAX) { 2456019Shines@cs.fsu.edu fatal("Oscillator frequency out of range: %f\n", 2466019Shines@cs.fsu.edu SimClock::Float::s / p->freq / 1E6); 2476019Shines@cs.fsu.edu } 2486019Shines@cs.fsu.edu 2496019Shines@cs.fsu.edu _clockPeriod = p->freq; 2506019Shines@cs.fsu.edu} 2516019Shines@cs.fsu.edu 2526019Shines@cs.fsu.eduvoid 2536019Shines@cs.fsu.eduRealViewOsc::startup() 2546019Shines@cs.fsu.edu{ 2556019Shines@cs.fsu.edu // Tell dependent object to set their clock frequency 2566019Shines@cs.fsu.edu for (auto m : members) 2576019Shines@cs.fsu.edu m->updateClockPeriod(); 2586019Shines@cs.fsu.edu} 2596019Shines@cs.fsu.edu 2606019Shines@cs.fsu.eduvoid 2616019Shines@cs.fsu.eduRealViewOsc::serialize(CheckpointOut &cp) const 2626019Shines@cs.fsu.edu{ 2636019Shines@cs.fsu.edu SERIALIZE_SCALAR(_clockPeriod); 2646019Shines@cs.fsu.edu} 2656019Shines@cs.fsu.edu 2666019Shines@cs.fsu.eduvoid 2676019Shines@cs.fsu.eduRealViewOsc::unserialize(CheckpointIn &cp) 2686019Shines@cs.fsu.edu{ 2696019Shines@cs.fsu.edu UNSERIALIZE_SCALAR(_clockPeriod); 2706019Shines@cs.fsu.edu} 2716019Shines@cs.fsu.edu 2726019Shines@cs.fsu.eduvoid 2736019Shines@cs.fsu.eduRealViewOsc::clockPeriod(Tick clock_period) 2746019Shines@cs.fsu.edu{ 2756019Shines@cs.fsu.edu panic_if(clock_period == 0, "%s has a clock period of zero\n", name()); 2766019Shines@cs.fsu.edu 2776019Shines@cs.fsu.edu // Align all members to the current tick 2786019Shines@cs.fsu.edu for (auto m : members) 2796019Shines@cs.fsu.edu m->updateClockPeriod(); 2806019Shines@cs.fsu.edu 2816019Shines@cs.fsu.edu _clockPeriod = clock_period; 2826019Shines@cs.fsu.edu 2836019Shines@cs.fsu.edu // inform any derived clocks they need to updated their period 2846019Shines@cs.fsu.edu for (auto m : children) 2856019Shines@cs.fsu.edu m->updateClockPeriod(); 2866019Shines@cs.fsu.edu} 2876019Shines@cs.fsu.edu 2886019Shines@cs.fsu.eduuint32_t 2896019Shines@cs.fsu.eduRealViewOsc::read() const 2906019Shines@cs.fsu.edu{ 2916019Shines@cs.fsu.edu const uint32_t freq(SimClock::Float::s / _clockPeriod); 2926019Shines@cs.fsu.edu DPRINTF(RVCTRL, "Reading OSC frequency: %f MHz\n", freq / 1E6); 2936019Shines@cs.fsu.edu return freq; 2946019Shines@cs.fsu.edu} 2956019Shines@cs.fsu.edu 2966019Shines@cs.fsu.eduvoid 2976019Shines@cs.fsu.eduRealViewOsc::write(uint32_t freq) 2986019Shines@cs.fsu.edu{ 2996019Shines@cs.fsu.edu DPRINTF(RVCTRL, "Setting new OSC frequency: %f MHz\n", freq / 1E6); 3007404SAli.Saidi@ARM.com clockPeriod(SimClock::Float::s / freq); 3017404SAli.Saidi@ARM.com} 3027404SAli.Saidi@ARM.com 3037404SAli.Saidi@ARM.comuint32_t 3047404SAli.Saidi@ARM.comRealViewTemperatureSensor::read() const 3057404SAli.Saidi@ARM.com{ 3067093Sgblack@eecs.umich.edu // Temperature reported in uC 3077294Sgblack@eecs.umich.edu ThermalModel * tm = system->getThermalModel(); 3087294Sgblack@eecs.umich.edu if (tm) { 3097294Sgblack@eecs.umich.edu double t = tm->getTemp(); 3107404SAli.Saidi@ARM.com if (t < 0) 3117404SAli.Saidi@ARM.com warn("Temperature below zero!\n"); 3127404SAli.Saidi@ARM.com return fmax(0, t) * 1000000; 3137404SAli.Saidi@ARM.com } 3147294Sgblack@eecs.umich.edu 3157404SAli.Saidi@ARM.com // Report a dummy 25 degrees temperature 3167404SAli.Saidi@ARM.com return 25000000; 3177404SAli.Saidi@ARM.com} 3187294Sgblack@eecs.umich.edu 3197294Sgblack@eecs.umich.eduRealViewCtrl * 3207294Sgblack@eecs.umich.eduRealViewCtrlParams::create() 3216019Shines@cs.fsu.edu{ 3227093Sgblack@eecs.umich.edu return new RealViewCtrl(this); 3237404SAli.Saidi@ARM.com} 3247404SAli.Saidi@ARM.com 3257093Sgblack@eecs.umich.eduRealViewOsc * 3267093Sgblack@eecs.umich.eduRealViewOscParams::create() 3277093Sgblack@eecs.umich.edu{ 3286019Shines@cs.fsu.edu return new RealViewOsc(this); 3296019Shines@cs.fsu.edu} 3307404SAli.Saidi@ARM.com 3317404SAli.Saidi@ARM.comRealViewTemperatureSensor * 3327404SAli.Saidi@ARM.comRealViewTemperatureSensorParams::create() 3337404SAli.Saidi@ARM.com{ 3347404SAli.Saidi@ARM.com return new RealViewTemperatureSensor(this); 3357406SAli.Saidi@ARM.com} 3367406SAli.Saidi@ARM.com