summaryrefslogtreecommitdiff
path: root/src/dev/arm/rv_ctrl.cc
diff options
context:
space:
mode:
authorMatt Evans <matt.evans@arm.com>2013-10-31 13:41:13 -0500
committerMatt Evans <matt.evans@arm.com>2013-10-31 13:41:13 -0500
commitd17529b046d832f889a0fdb506c3b8d1aed5cccb (patch)
tree94a10f280d748bd4e16de9a2476924d6a71508f9 /src/dev/arm/rv_ctrl.cc
parentc32fbb7c008d86abc59f56c93b1ff5876fff0ab3 (diff)
downloadgem5-d17529b046d832f889a0fdb506c3b8d1aed5cccb.tar.xz
dev: Add 'OSC' oscillator sys control reg support to VersatileExpress
The VE motherboard provides a set of system control registers through which various motherboard and coretile registers are accessed. Voltage regulators and oscillator (DLL/PLL) config are examples. These registers must be impleted to boot Linux 3.9+ kernels.
Diffstat (limited to 'src/dev/arm/rv_ctrl.cc')
-rw-r--r--src/dev/arm/rv_ctrl.cc108
1 files changed, 104 insertions, 4 deletions
diff --git a/src/dev/arm/rv_ctrl.cc b/src/dev/arm/rv_ctrl.cc
index 61111d22e..af121861c 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 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -38,12 +38,13 @@
*/
#include "base/trace.hh"
+#include "debug/RVCTRL.hh"
#include "dev/arm/rv_ctrl.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
RealViewCtrl::RealViewCtrl(Params *p)
- : BasicPioDevice(p, 0xD4), flags(0)
+ : BasicPioDevice(p, 0xD4), flags(0), scData(0)
{
}
@@ -105,9 +106,18 @@ RealViewCtrl::read(PacketPtr pkt)
case CfgStat:
pkt->set<uint32_t>(1);
break;
+ case CfgData:
+ pkt->set<uint32_t>(scData);
+ DPRINTF(RVCTRL, "Read %#x from SCReg\n", scData);
+ break;
+ case CfgCtrl:
+ pkt->set<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->set<uint32_t>(0);
break;
}
pkt->makeAtomicResponse();
@@ -139,9 +149,99 @@ RealViewCtrl::write(PacketPtr pkt)
case FlagsClr:
flags = 0;
break;
+ case CfgData:
+ scData = pkt->get<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
+ // For now, model as much of the OSC regs (can't find docs) as Linux
+ // seems to require (can't find docs); some clocks are deemed to be 0,
+ // giving all kinds of /0 problems booting Linux 3.9. Return a
+ // vaguely plausible number within the range the device trees state:
+ uint32_t data = pkt->get<uint32_t>();
+ uint16_t dev = bits(data, 11, 0);
+ uint8_t pos = bits(data, 15, 12);
+ uint8_t site = bits(data, 17, 16);
+ uint8_t func = bits(data, 25, 20);
+ uint8_t dcc = bits(data, 29, 26);
+ bool wr = bits(data, 30);
+ bool start = bits(data, 31);
+
+ if (start) {
+ if (wr) {
+ warn_once("SCReg: Writing %#x to dcc%d:site%d:pos%d:fn%d:dev%d\n",
+ scData, dcc, site, pos, func, dev);
+ // Only really support reading, for now!
+ } else {
+ // Only deal with function 1 (oscillators) so far!
+ if (dcc != 0 || pos != 0 || func != 1) {
+ warn("SCReg: read from unknown area "
+ "(dcc %d:site%d:pos%d:fn%d:dev%d)\n",
+ dcc, site, pos, func, dev);
+ } else {
+ switch (site) {
+ case 0: { // Motherboard regs
+ switch(dev) {
+ case 0: // MCC clk
+ scData = 25000000;
+ break;
+ case 1: // CLCD clk
+ scData = 25000000;
+ break;
+ case 2: // PeriphClk 24MHz
+ scData = 24000000;
+ break;
+ default:
+ scData = 0;
+ warn("SCReg: read from unknown dev %d "
+ "(site%d:pos%d:fn%d)\n",
+ dev, site, pos, func);
+ }
+ } break;
+ case 1: { // Coretile 1 regs
+ switch(dev) {
+ case 0: // CPU PLL ref
+ scData = 50000000;
+ break;
+ case 4: // Muxed AXI master clock
+ scData = 40000000;
+ break;
+ case 5: // HDLCD clk
+ scData = 50000000;
+ break;
+ case 6: // SMB clock
+ scData = 35000000;
+ break;
+ case 7: // SYS PLL (also used for pl011 UART!)
+ scData = 40000000;
+ break;
+ case 8: // DDR PLL 40MHz fixed
+ scData = 40000000;
+ break;
+ default:
+ scData = 0;
+ warn("SCReg: read from unknown dev %d "
+ "(site%d:pos%d:fn%d)\n",
+ dev, site, pos, func);
+ }
+ } break;
+ default:
+ warn("SCReg: Read from unknown site %d (pos%d:fn%d:dev%d)\n",
+ site, pos, func, dev);
+ }
+ DPRINTF(RVCTRL, "SCReg: Will read %#x (ctrlWr %#x)\n", scData, data);
+ }
+ }
+ } else {
+ DPRINTF(RVCTRL, "SCReg: write %#x to ctrl but not starting\n", data);
+ }
+ } 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<uint32_t>());
break;
}
pkt->makeAtomicResponse();