X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Farm%2Frv_ctrl.cc;h=954be6597e0d8091c237b745f28a4f926fd1095c;hb=381aa8498997f5ce93480511f7514be85356687a;hp=eceba81f127ca31129781a15d735f75955e2c5d9;hpb=91b737ed48008ed295db22c857183f040a63234c;p=gem5.git diff --git a/src/dev/arm/rv_ctrl.cc b/src/dev/arm/rv_ctrl.cc index eceba81f1..954be6597 100644 --- a/src/dev/arm/rv_ctrl.cc +++ b/src/dev/arm/rv_ctrl.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 ARM Limited + * Copyright (c) 2010,2013,2015 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -37,15 +37,19 @@ * Authors: Ali Saidi */ -#include "base/trace.hh" #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), flags(0) + : BasicPioDevice(p, 0xD4), flags(0), scData(0) { - pioSize = 0xD4; } Tick @@ -54,7 +58,6 @@ RealViewCtrl::read(PacketPtr pkt) assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize); assert(pkt->getSize() == 4); Addr daddr = pkt->getAddr() - pioAddr; - pkt->allocate(); switch(daddr) { case ProcId0: @@ -65,12 +68,12 @@ RealViewCtrl::read(PacketPtr pkt) break; case Clock24: Tick clk; - clk = (Tick)(curTick() / (24 * SimClock::Int::us)); + clk = SimClock::Float::MHz * curTick() * 24; pkt->set((uint32_t)(clk)); break; case Clock100: Tick clk100; - clk100 = (Tick)(curTick() / (100 * SimClock::Int::us)); + clk100 = SimClock::Float::MHz * curTick() * 100; pkt->set((uint32_t)(clk100)); break; case Flash: @@ -105,9 +108,19 @@ RealViewCtrl::read(PacketPtr pkt) break; case CfgStat: pkt->set(1); + break; + case CfgData: + pkt->set(scData); + DPRINTF(RVCTRL, "Read %#x from SCReg\n", scData); + break; + case CfgCtrl: + pkt->set(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->set(0); break; } pkt->makeAtomicResponse(); @@ -133,15 +146,56 @@ RealViewCtrl::write(PacketPtr pkt) case Lock: sysLock.lockVal = pkt->get(); break; + case ResetCtl: + // Ignore writes to reset control + warn_once("Ignoring write to reset control\n"); + break; case Flags: flags = pkt->get(); break; case FlagsClr: flags = 0; break; + case CfgData: + scData = pkt->get(); + 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->get(); + 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 that doesn't exist\n", - daddr); + warn("Tried to write RVIO at offset %#x (data %#x) that doesn't exist\n", + daddr, pkt->get()); break; } pkt->makeAtomicResponse(); @@ -149,19 +203,133 @@ RealViewCtrl::write(PacketPtr pkt) } void -RealViewCtrl::serialize(std::ostream &os) +RealViewCtrl::serialize(CheckpointOut &cp) const { SERIALIZE_SCALAR(flags); } void -RealViewCtrl::unserialize(Checkpoint *cp, const std::string §ion) +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); +}