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