/*
 * Copyright (c) 2010,2013,2015 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "dev/arm/rv_ctrl.hh"

#include "base/trace.hh"
#include "debug/RVCTRL.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/power/thermal_model.hh"
#include "sim/system.hh"
#include "sim/voltage_domain.hh"

RealViewCtrl::RealViewCtrl(Params *p)
    : BasicPioDevice(p, 0xD4), flags(0), scData(0)
{
}

Tick
RealViewCtrl::read(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);
    Addr daddr = pkt->getAddr() - pioAddr;

    switch(daddr) {
      case ProcId0:
        pkt->setLE(params()->proc_id0);
        break;
      case ProcId1:
        pkt->setLE(params()->proc_id1);
        break;
      case Clock24:
        Tick clk;
        clk = SimClock::Float::MHz * curTick() * 24;
        pkt->setLE((uint32_t)(clk));
        break;
      case Clock100:
        Tick clk100;
        clk100 = SimClock::Float::MHz * curTick() * 100;
        pkt->setLE((uint32_t)(clk100));
        break;
      case Flash:
        pkt->setLE<uint32_t>(0);
        break;
      case Clcd:
        pkt->setLE<uint32_t>(0x00001F00);
        break;
      case Osc0:
        pkt->setLE<uint32_t>(0x00012C5C);
        break;
      case Osc1:
        pkt->setLE<uint32_t>(0x00002CC0);
        break;
      case Osc2:
        pkt->setLE<uint32_t>(0x00002C75);
        break;
      case Osc3:
        pkt->setLE<uint32_t>(0x00020211);
        break;
      case Osc4:
        pkt->setLE<uint32_t>(0x00002C75);
        break;
      case Lock:
        pkt->setLE<uint32_t>(sysLock);
        break;
      case Flags:
        pkt->setLE<uint32_t>(flags);
        break;
      case IdReg:
        pkt->setLE<uint32_t>(params()->idreg);
        break;
      case CfgStat:
        pkt->setLE<uint32_t>(1);
        break;
      case CfgData:
        pkt->setLE<uint32_t>(scData);
        DPRINTF(RVCTRL, "Read %#x from SCReg\n", scData);
        break;
      case CfgCtrl:
        pkt->setLE<uint32_t>(0); // not busy
        DPRINTF(RVCTRL, "Read 0 from CfgCtrl\n");
        break;
      default:
        warn("Tried to read RealView I/O at offset %#x that doesn't exist\n",
             daddr);
        pkt->setLE<uint32_t>(0);
        break;
    }
    pkt->makeAtomicResponse();
    return pioDelay;

}

Tick
RealViewCtrl::write(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);

    Addr daddr = pkt->getAddr() - pioAddr;
    switch (daddr) {
      case Flash:
      case Clcd:
      case Osc0:
      case Osc1:
      case Osc2:
      case Osc3:
      case Osc4:
        break;
      case Lock:
        sysLock.lockVal = pkt->getLE<uint16_t>();
        break;
      case ResetCtl:
        // Ignore writes to reset control
        warn_once("Ignoring write to reset control\n");
        break;
      case Flags:
        flags = pkt->getLE<uint32_t>();
        break;
      case FlagsClr:
        flags = 0;
        break;
      case CfgData:
        scData = pkt->getLE<uint32_t>();
        break;
      case CfgCtrl: {
          // A request is being submitted to read/write the system control
          // registers.  See
          // http://infocenter.arm.com/help/topic/com.arm.doc.dui0447h/CACDEFGH.html
          CfgCtrlReg req = pkt->getLE<uint32_t>();
          if (!req.start) {
              DPRINTF(RVCTRL, "SCReg: write %#x to ctrl but not starting\n",
                      req);
              break;
          }

          auto it_dev(devices.find(req & CFG_CTRL_ADDR_MASK));
          if (it_dev == devices.end()) {
              warn_once("SCReg: Access to unknown device "
                        "dcc%d:site%d:pos%d:fn%d:dev%d\n",
                        req.dcc, req.site, req.pos, req.func, req.dev);
              break;
          }

          // Service the request as a read or write depending on the
          // wr bit in the control register.
          Device &dev(*it_dev->second);
          if (req.wr) {
              DPRINTF(RVCTRL, "SCReg: Writing %#x (ctrlWr %#x)\n",
                      scData, req);
              dev.write(scData);

          } else {
              scData = dev.read();
              DPRINTF(RVCTRL, "SCReg: Reading %#x (ctrlRd %#x)\n",
                      scData, req);
          }
      } break;
      case CfgStat:     // Weird to write this
      default:
        warn("Tried to write RVIO at offset %#x (data %#x) that doesn't exist\n",
             daddr, pkt->getLE<uint32_t>());
        break;
    }
    pkt->makeAtomicResponse();
    return pioDelay;
}

void
RealViewCtrl::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(flags);
}

void
RealViewCtrl::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(flags);
}

void
RealViewCtrl::registerDevice(DeviceFunc func, uint8_t site, uint8_t pos,
                             uint8_t dcc, uint16_t dev,
                             Device *handler)
{
    CfgCtrlReg addr = 0;
    addr.func = func;
    addr.site = site;
    addr.pos = pos;
    addr.dcc = dcc;
    addr.dev = dev;

    if (devices.find(addr) != devices.end()) {
        fatal("Platform device dcc%d:site%d:pos%d:fn%d:dev%d "
              "already registered.",
              addr.dcc, addr.site, addr.pos, addr.func, addr.dev);
    }

    devices[addr] = handler;
}


RealViewOsc::RealViewOsc(RealViewOscParams *p)
    : ClockDomain(p, p->voltage_domain),
      RealViewCtrl::Device(*p->parent, RealViewCtrl::FUNC_OSC,
                           p->site, p->position, p->dcc, p->device)
{
    if (SimClock::Float::s  / p->freq > UINT32_MAX) {
        fatal("Oscillator frequency out of range: %f\n",
            SimClock::Float::s  / p->freq / 1E6);
    }

    _clockPeriod = p->freq;
}

void
RealViewOsc::startup()
{
    // Tell dependent object to set their clock frequency
    for (auto m : members)
        m->updateClockPeriod();
}

void
RealViewOsc::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(_clockPeriod);
}

void
RealViewOsc::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(_clockPeriod);
}

void
RealViewOsc::clockPeriod(Tick clock_period)
{
    panic_if(clock_period == 0, "%s has a clock period of zero\n", name());

    // Align all members to the current tick
    for (auto m : members)
        m->updateClockPeriod();

    _clockPeriod = clock_period;

    // inform any derived clocks they need to updated their period
    for (auto m : children)
        m->updateClockPeriod();
}

uint32_t
RealViewOsc::read() const
{
    const uint32_t freq(SimClock::Float::s / _clockPeriod);
    DPRINTF(RVCTRL, "Reading OSC frequency: %f MHz\n", freq / 1E6);
    return freq;
}

void
RealViewOsc::write(uint32_t freq)
{
    DPRINTF(RVCTRL, "Setting new OSC frequency: %f MHz\n", freq / 1E6);
    clockPeriod(SimClock::Float::s / freq);
}

uint32_t
RealViewTemperatureSensor::read() const
{
    // Temperature reported in uC
    ThermalModel * tm = system->getThermalModel();
    if (tm) {
        double t = tm->getTemp();
        if (t < 0)
            warn("Temperature below zero!\n");
        return fmax(0, t) * 1000000;
    }

    // Report a dummy 25 degrees temperature
    return 25000000;
}

RealViewCtrl *
RealViewCtrlParams::create()
{
    return new RealViewCtrl(this);
}

RealViewOsc *
RealViewOscParams::create()
{
    return new RealViewOsc(this);
}

RealViewTemperatureSensor *
RealViewTemperatureSensorParams::create()
{
    return new RealViewTemperatureSensor(this);
}
