rv_ctrl.cc revision 11421:74c1e6513bd0
16019Shines@cs.fsu.edu/*
212528Schuan.zhu@arm.com * 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"
4510873Sandreas.sandberg@arm.com#include "mem/packet_access.hh"
4610873Sandreas.sandberg@arm.com#include "sim/power/thermal_model.hh"
4710474Sandreas.hansson@arm.com#include "sim/system.hh"
486019Shines@cs.fsu.edu#include "sim/voltage_domain.hh"
496019Shines@cs.fsu.edu
506019Shines@cs.fsu.eduRealViewCtrl::RealViewCtrl(Params *p)
516116Snate@binkert.org    : BasicPioDevice(p, 0xD4), flags(0), scData(0)
526019Shines@cs.fsu.edu{
5311793Sbrandon.potter@amd.com}
5411793Sbrandon.potter@amd.com
558782Sgblack@eecs.umich.eduTick
568756Sgblack@eecs.umich.eduRealViewCtrl::read(PacketPtr pkt)
576019Shines@cs.fsu.edu{
5812005Sandreas.sandberg@arm.com    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
596019Shines@cs.fsu.edu    assert(pkt->getSize() == 4);
606019Shines@cs.fsu.edu    Addr daddr = pkt->getAddr() - pioAddr;
616019Shines@cs.fsu.edu
6210024Sdam.sunwoo@arm.com    switch(daddr) {
636019Shines@cs.fsu.edu      case ProcId0:
648232Snate@binkert.org        pkt->set(params()->proc_id0);
658232Snate@binkert.org        break;
668232Snate@binkert.org      case ProcId1:
676116Snate@binkert.org        pkt->set(params()->proc_id1);
6811608Snikos.nikoleris@arm.com        break;
696116Snate@binkert.org      case Clock24:
708756Sgblack@eecs.umich.edu        Tick clk;
716019Shines@cs.fsu.edu        clk = SimClock::Float::MHz * curTick() * 24;
726019Shines@cs.fsu.edu        pkt->set((uint32_t)(clk));
736019Shines@cs.fsu.edu        break;
746019Shines@cs.fsu.edu      case Clock100:
756019Shines@cs.fsu.edu        Tick clk100;
7610037SARM gem5 Developers        clk100 = SimClock::Float::MHz * curTick() * 100;
7710037SARM gem5 Developers        pkt->set((uint32_t)(clk100));
7813374Sanouk.vanlaer@arm.com        break;
7910418Sandreas.hansson@arm.com      case Flash:
8011395Sandreas.sandberg@arm.com        pkt->set<uint32_t>(0);
8110537Sandreas.hansson@arm.com        break;
8213453Srekai.gonzalezalberquilla@arm.com      case Clcd:
8311152Smitch.hayenga@arm.com        pkt->set<uint32_t>(0x00001F00);
846019Shines@cs.fsu.edu        break;
8512005Sandreas.sandberg@arm.com      case Osc0:
8612005Sandreas.sandberg@arm.com        pkt->set<uint32_t>(0x00012C5C);
8710037SARM gem5 Developers        break;
887399SAli.Saidi@ARM.com      case Osc1:
8910037SARM gem5 Developers        pkt->set<uint32_t>(0x00002CC0);
9010037SARM gem5 Developers        break;
9110037SARM gem5 Developers      case Osc2:
9210037SARM gem5 Developers        pkt->set<uint32_t>(0x00002C75);
9312005Sandreas.sandberg@arm.com        break;
9412005Sandreas.sandberg@arm.com      case Osc3:
9512005Sandreas.sandberg@arm.com        pkt->set<uint32_t>(0x00020211);
966019Shines@cs.fsu.edu        break;
976019Shines@cs.fsu.edu      case Osc4:
986019Shines@cs.fsu.edu        pkt->set<uint32_t>(0x00002C75);
996019Shines@cs.fsu.edu        break;
10010037SARM gem5 Developers      case Lock:
10110037SARM gem5 Developers        pkt->set<uint32_t>(sysLock);
10210037SARM gem5 Developers        break;
10310037SARM gem5 Developers      case Flags:
10410037SARM gem5 Developers        pkt->set<uint32_t>(flags);
10510037SARM gem5 Developers        break;
10610037SARM gem5 Developers      case IdReg:
10710037SARM gem5 Developers        pkt->set<uint32_t>(params()->idreg);
10810037SARM gem5 Developers        break;
10910037SARM gem5 Developers      case CfgStat:
11010037SARM gem5 Developers        pkt->set<uint32_t>(1);
11110717Sandreas.hansson@arm.com        break;
11210037SARM gem5 Developers      case CfgData:
11310037SARM gem5 Developers        pkt->set<uint32_t>(scData);
11410717Sandreas.hansson@arm.com        DPRINTF(RVCTRL, "Read %#x from SCReg\n", scData);
1156019Shines@cs.fsu.edu        break;
1166019Shines@cs.fsu.edu      case CfgCtrl:
1177694SAli.Saidi@ARM.com        pkt->set<uint32_t>(0); // not busy
1187694SAli.Saidi@ARM.com        DPRINTF(RVCTRL, "Read 0 from CfgCtrl\n");
1197694SAli.Saidi@ARM.com        break;
12010037SARM gem5 Developers      default:
12110037SARM gem5 Developers        warn("Tried to read RealView I/O at offset %#x that doesn't exist\n",
12210037SARM gem5 Developers             daddr);
12310037SARM gem5 Developers        pkt->set<uint32_t>(0);
12410037SARM gem5 Developers        break;
12510037SARM gem5 Developers    }
12610037SARM gem5 Developers    pkt->makeAtomicResponse();
12710037SARM gem5 Developers    return pioDelay;
12810037SARM gem5 Developers
1297694SAli.Saidi@ARM.com}
1307694SAli.Saidi@ARM.com
1317694SAli.Saidi@ARM.comTick
1327694SAli.Saidi@ARM.comRealViewCtrl::write(PacketPtr pkt)
1337694SAli.Saidi@ARM.com{
1347694SAli.Saidi@ARM.com    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
1359738Sandreas@sandberg.pp.se
13612749Sgiacomo.travaglini@arm.com    Addr daddr = pkt->getAddr() - pioAddr;
13712749Sgiacomo.travaglini@arm.com    switch (daddr) {
1389738Sandreas@sandberg.pp.se      case Flash:
13912005Sandreas.sandberg@arm.com      case Clcd:
14012005Sandreas.sandberg@arm.com      case Osc0:
14112005Sandreas.sandberg@arm.com      case Osc1:
14212005Sandreas.sandberg@arm.com      case Osc2:
14312005Sandreas.sandberg@arm.com      case Osc3:
14412005Sandreas.sandberg@arm.com      case Osc4:
14512005Sandreas.sandberg@arm.com        break;
14612005Sandreas.sandberg@arm.com      case Lock:
14712005Sandreas.sandberg@arm.com        sysLock.lockVal = pkt->get<uint16_t>();
1489738Sandreas@sandberg.pp.se        break;
1499738Sandreas@sandberg.pp.se      case Flags:
1509738Sandreas@sandberg.pp.se        flags = pkt->get<uint32_t>();
1517404SAli.Saidi@ARM.com        break;
15210037SARM gem5 Developers      case FlagsClr:
15310037SARM gem5 Developers        flags = 0;
1546019Shines@cs.fsu.edu        break;
1557404SAli.Saidi@ARM.com      case CfgData:
1567404SAli.Saidi@ARM.com        scData = pkt->get<uint32_t>();
1577404SAli.Saidi@ARM.com        break;
15810037SARM gem5 Developers      case CfgCtrl: {
1597404SAli.Saidi@ARM.com          // A request is being submitted to read/write the system control
1607404SAli.Saidi@ARM.com          // registers.  See
16110037SARM gem5 Developers          // http://infocenter.arm.com/help/topic/com.arm.doc.dui0447h/CACDEFGH.html
16210037SARM gem5 Developers          CfgCtrlReg req = pkt->get<uint32_t>();
16310037SARM gem5 Developers          if (!req.start) {
16410037SARM gem5 Developers              DPRINTF(RVCTRL, "SCReg: write %#x to ctrl but not starting\n",
16510037SARM gem5 Developers                      req);
1669535Smrinmoy.ghosh@arm.com              break;
1677697SAli.Saidi@ARM.com          }
16811321Ssteve.reinhardt@amd.com
16910037SARM gem5 Developers          auto it_dev(devices.find(req & CFG_CTRL_ADDR_MASK));
1707697SAli.Saidi@ARM.com          if (it_dev == devices.end()) {
1717697SAli.Saidi@ARM.com              warn_once("SCReg: Access to unknown device "
1727697SAli.Saidi@ARM.com                        "dcc%d:site%d:pos%d:fn%d:dev%d\n",
1737697SAli.Saidi@ARM.com                        req.dcc, req.site, req.pos, req.func, req.dev);
1747697SAli.Saidi@ARM.com              break;
1757404SAli.Saidi@ARM.com          }
1767404SAli.Saidi@ARM.com
17710037SARM gem5 Developers          // Service the request as a read or write depending on the
1787404SAli.Saidi@ARM.com          // wr bit in the control register.
1797404SAli.Saidi@ARM.com          Device &dev(*it_dev->second);
18010037SARM gem5 Developers          if (req.wr) {
18110037SARM gem5 Developers              DPRINTF(RVCTRL, "SCReg: Writing %#x (ctrlWr %#x)\n",
18210037SARM gem5 Developers                      scData, req);
18310037SARM gem5 Developers              dev.write(scData);
18410037SARM gem5 Developers
18510037SARM gem5 Developers          } else {
18610037SARM gem5 Developers              scData = dev.read();
18710037SARM gem5 Developers              DPRINTF(RVCTRL, "SCReg: Reading %#x (ctrlRd %#x)\n",
18810367SAndrew.Bardsley@arm.com                      scData, req);
18910037SARM gem5 Developers          }
1907404SAli.Saidi@ARM.com      } break;
1916019Shines@cs.fsu.edu      case CfgStat:     // Weird to write this
1926019Shines@cs.fsu.edu      default:
1936019Shines@cs.fsu.edu        warn("Tried to write RVIO at offset %#x (data %#x) that doesn't exist\n",
1946019Shines@cs.fsu.edu             daddr, pkt->get<uint32_t>());
1957404SAli.Saidi@ARM.com        break;
1966019Shines@cs.fsu.edu    }
1977404SAli.Saidi@ARM.com    pkt->makeAtomicResponse();
19810037SARM gem5 Developers    return pioDelay;
19910037SARM gem5 Developers}
20010037SARM gem5 Developers
20110037SARM gem5 Developersvoid
20210037SARM gem5 DevelopersRealViewCtrl::serialize(CheckpointOut &cp) const
20310037SARM gem5 Developers{
2047404SAli.Saidi@ARM.com    SERIALIZE_SCALAR(flags);
20510037SARM gem5 Developers}
20610037SARM gem5 Developers
20710037SARM gem5 Developersvoid
2087697SAli.Saidi@ARM.comRealViewCtrl::unserialize(CheckpointIn &cp)
20910037SARM gem5 Developers{
21010037SARM gem5 Developers    UNSERIALIZE_SCALAR(flags);
21110037SARM gem5 Developers}
21210037SARM gem5 Developers
2137404SAli.Saidi@ARM.comvoid
2147697SAli.Saidi@ARM.comRealViewCtrl::registerDevice(DeviceFunc func, uint8_t site, uint8_t pos,
2157404SAli.Saidi@ARM.com                             uint8_t dcc, uint16_t dev,
21610037SARM gem5 Developers                             Device *handler)
21710037SARM gem5 Developers{
2187697SAli.Saidi@ARM.com    CfgCtrlReg addr = 0;
2197734SAli.Saidi@ARM.com    addr.func = func;
2207734SAli.Saidi@ARM.com    addr.site = site;
22110463SAndreas.Sandberg@ARM.com    addr.pos = pos;
2226019Shines@cs.fsu.edu    addr.dcc = dcc;
2236019Shines@cs.fsu.edu    addr.dev = dev;
2246019Shines@cs.fsu.edu
22510037SARM gem5 Developers    if (devices.find(addr) != devices.end()) {
2267404SAli.Saidi@ARM.com        fatal("Platform device dcc%d:site%d:pos%d:fn%d:dev%d "
2277404SAli.Saidi@ARM.com              "already registered.",
2287404SAli.Saidi@ARM.com              addr.dcc, addr.site, addr.pos, addr.func, addr.dev);
2297404SAli.Saidi@ARM.com    }
2307404SAli.Saidi@ARM.com
23110037SARM gem5 Developers    devices[addr] = handler;
23210037SARM gem5 Developers}
23310037SARM gem5 Developers
23410037SARM gem5 Developers
2357404SAli.Saidi@ARM.comRealViewOsc::RealViewOsc(RealViewOscParams *p)
2367404SAli.Saidi@ARM.com    : ClockDomain(p, p->voltage_domain),
2377404SAli.Saidi@ARM.com      RealViewCtrl::Device(*p->parent, RealViewCtrl::FUNC_OSC,
2387404SAli.Saidi@ARM.com                           p->site, p->position, p->dcc, p->device)
23910037SARM gem5 Developers{
2406019Shines@cs.fsu.edu    if (SimClock::Float::s  / p->freq > UINT32_MAX) {
24110037SARM gem5 Developers        fatal("Oscillator frequency out of range: %f\n",
24210037SARM gem5 Developers            SimClock::Float::s  / p->freq / 1E6);
2437404SAli.Saidi@ARM.com    }
2447404SAli.Saidi@ARM.com
2457404SAli.Saidi@ARM.com    _clockPeriod = p->freq;
24610037SARM gem5 Developers}
24710037SARM gem5 Developers
24810037SARM gem5 Developersvoid
24910037SARM gem5 DevelopersRealViewOsc::startup()
25010037SARM gem5 Developers{
25110037SARM gem5 Developers    // Tell dependent object to set their clock frequency
25210037SARM gem5 Developers    for (auto m : members)
25310037SARM gem5 Developers        m->updateClockPeriod();
25410037SARM gem5 Developers}
25510037SARM gem5 Developers
2567404SAli.Saidi@ARM.comvoid
2577404SAli.Saidi@ARM.comRealViewOsc::serialize(CheckpointOut &cp) const
25810037SARM gem5 Developers{
25910037SARM gem5 Developers    SERIALIZE_SCALAR(_clockPeriod);
26010037SARM gem5 Developers}
26110037SARM gem5 Developers
26210037SARM gem5 Developersvoid
26310037SARM gem5 DevelopersRealViewOsc::unserialize(CheckpointIn &cp)
26410037SARM gem5 Developers{
26510037SARM gem5 Developers    UNSERIALIZE_SCALAR(_clockPeriod);
26610037SARM gem5 Developers}
26710037SARM gem5 Developers
26810037SARM gem5 Developersvoid
26910037SARM gem5 DevelopersRealViewOsc::clockPeriod(Tick clock_period)
27010037SARM gem5 Developers{
27110037SARM gem5 Developers    panic_if(clock_period == 0, "%s has a clock period of zero\n", name());
27210037SARM gem5 Developers
27310037SARM gem5 Developers    // Align all members to the current tick
27410037SARM gem5 Developers    for (auto m : members)
27510037SARM gem5 Developers        m->updateClockPeriod();
27610037SARM gem5 Developers
27710037SARM gem5 Developers    _clockPeriod = clock_period;
27810037SARM gem5 Developers
27910037SARM gem5 Developers    // inform any derived clocks they need to updated their period
28010037SARM gem5 Developers    for (auto m : children)
28110037SARM gem5 Developers        m->updateClockPeriod();
28210037SARM gem5 Developers}
28310037SARM gem5 Developers
28410037SARM gem5 Developersuint32_t
2857734SAli.Saidi@ARM.comRealViewOsc::read() const
2867734SAli.Saidi@ARM.com{
28710037SARM gem5 Developers    const uint32_t freq(SimClock::Float::s / _clockPeriod);
28810037SARM gem5 Developers    DPRINTF(RVCTRL, "Reading OSC frequency: %f MHz\n", freq / 1E6);
28910037SARM gem5 Developers    return freq;
29010037SARM gem5 Developers}
29110037SARM gem5 Developers
2926019Shines@cs.fsu.eduvoid
2936019Shines@cs.fsu.eduRealViewOsc::write(uint32_t freq)
2947404SAli.Saidi@ARM.com{
29510037SARM gem5 Developers    DPRINTF(RVCTRL, "Setting new OSC frequency: %f MHz\n", freq / 1E6);
2967404SAli.Saidi@ARM.com    clockPeriod(SimClock::Float::s / freq);
29710037SARM gem5 Developers}
29810037SARM gem5 Developers
29910037SARM gem5 Developersuint32_t
30010037SARM gem5 DevelopersRealViewTemperatureSensor::read() const
3017734SAli.Saidi@ARM.com{
3027404SAli.Saidi@ARM.com    // Temperature reported in uC
3037404SAli.Saidi@ARM.com    ThermalModel * tm = system->getThermalModel();
3047404SAli.Saidi@ARM.com    if (tm) {
30510037SARM gem5 Developers        double t = tm->getTemp();
3067404SAli.Saidi@ARM.com        if (t < 0)
30710037SARM gem5 Developers            warn("Temperature below zero!\n");
30810037SARM gem5 Developers        return fmax(0, t) * 1000000;
3097404SAli.Saidi@ARM.com    }
31010037SARM gem5 Developers
3117404SAli.Saidi@ARM.com    // Report a dummy 25 degrees temperature
3127404SAli.Saidi@ARM.com    return 25000000;
3137404SAli.Saidi@ARM.com}
3147404SAli.Saidi@ARM.com
31510037SARM gem5 DevelopersRealViewCtrl *
31610037SARM gem5 DevelopersRealViewCtrlParams::create()
31710037SARM gem5 Developers{
31810037SARM gem5 Developers    return new RealViewCtrl(this);
3197404SAli.Saidi@ARM.com}
32010037SARM gem5 Developers
3217734SAli.Saidi@ARM.comRealViewOsc *
3227404SAli.Saidi@ARM.comRealViewOscParams::create()
32310037SARM gem5 Developers{
3247404SAli.Saidi@ARM.com    return new RealViewOsc(this);
3257734SAli.Saidi@ARM.com}
3267404SAli.Saidi@ARM.com
3277404SAli.Saidi@ARM.comRealViewTemperatureSensor *
3287404SAli.Saidi@ARM.comRealViewTemperatureSensorParams::create()
32910037SARM gem5 Developers{
3307404SAli.Saidi@ARM.com    return new RealViewTemperatureSensor(this);
33110037SARM gem5 Developers}
33210037SARM gem5 Developers