rv_ctrl.cc revision 9958:48eb085bc9ab
1/*
2 * Copyright (c) 2010,2013 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 */
39
40#include "base/trace.hh"
41#include "debug/RVCTRL.hh"
42#include "dev/arm/rv_ctrl.hh"
43#include "mem/packet.hh"
44#include "mem/packet_access.hh"
45
46RealViewCtrl::RealViewCtrl(Params *p)
47    : BasicPioDevice(p, 0xD4), flags(0), scData(0)
48{
49}
50
51Tick
52RealViewCtrl::read(PacketPtr pkt)
53{
54    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
55    assert(pkt->getSize() == 4);
56    Addr daddr = pkt->getAddr() - pioAddr;
57    pkt->allocate();
58
59    switch(daddr) {
60      case ProcId0:
61        pkt->set(params()->proc_id0);
62        break;
63      case ProcId1:
64        pkt->set(params()->proc_id1);
65        break;
66      case Clock24:
67        Tick clk;
68        clk = SimClock::Float::MHz * curTick() * 24;
69        pkt->set((uint32_t)(clk));
70        break;
71      case Clock100:
72        Tick clk100;
73        clk100 = SimClock::Float::MHz * curTick() * 100;
74        pkt->set((uint32_t)(clk100));
75        break;
76      case Flash:
77        pkt->set<uint32_t>(0);
78        break;
79      case Clcd:
80        pkt->set<uint32_t>(0x00001F00);
81        break;
82      case Osc0:
83        pkt->set<uint32_t>(0x00012C5C);
84        break;
85      case Osc1:
86        pkt->set<uint32_t>(0x00002CC0);
87        break;
88      case Osc2:
89        pkt->set<uint32_t>(0x00002C75);
90        break;
91      case Osc3:
92        pkt->set<uint32_t>(0x00020211);
93        break;
94      case Osc4:
95        pkt->set<uint32_t>(0x00002C75);
96        break;
97      case Lock:
98        pkt->set<uint32_t>(sysLock);
99        break;
100      case Flags:
101        pkt->set<uint32_t>(flags);
102        break;
103      case IdReg:
104        pkt->set<uint32_t>(params()->idreg);
105        break;
106      case CfgStat:
107        pkt->set<uint32_t>(1);
108        break;
109      case CfgData:
110        pkt->set<uint32_t>(scData);
111        DPRINTF(RVCTRL, "Read %#x from SCReg\n", scData);
112        break;
113      case CfgCtrl:
114        pkt->set<uint32_t>(0); // not busy
115        DPRINTF(RVCTRL, "Read 0 from CfgCtrl\n");
116        break;
117      default:
118        warn("Tried to read RealView I/O at offset %#x that doesn't exist\n",
119             daddr);
120        pkt->set<uint32_t>(0);
121        break;
122    }
123    pkt->makeAtomicResponse();
124    return pioDelay;
125
126}
127
128Tick
129RealViewCtrl::write(PacketPtr pkt)
130{
131    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
132
133    Addr daddr = pkt->getAddr() - pioAddr;
134    switch (daddr) {
135      case Flash:
136      case Clcd:
137      case Osc0:
138      case Osc1:
139      case Osc2:
140      case Osc3:
141      case Osc4:
142        break;
143      case Lock:
144        sysLock.lockVal = pkt->get<uint16_t>();
145        break;
146      case Flags:
147        flags = pkt->get<uint32_t>();
148        break;
149      case FlagsClr:
150        flags = 0;
151        break;
152      case CfgData:
153        scData = pkt->get<uint32_t>();
154        break;
155      case CfgCtrl: {
156          // A request is being submitted to read/write the system control
157          // registers.  See
158          // http://infocenter.arm.com/help/topic/com.arm.doc.dui0447h/CACDEFGH.html
159          // For now, model as much of the OSC regs (can't find docs) as Linux
160          // seems to require (can't find docs); some clocks are deemed to be 0,
161          // giving all kinds of /0 problems booting Linux 3.9.  Return a
162          // vaguely plausible number within the range the device trees state:
163          uint32_t data = pkt->get<uint32_t>();
164          uint16_t dev = bits(data, 11, 0);
165          uint8_t pos = bits(data, 15, 12);
166          uint8_t site = bits(data, 17, 16);
167          uint8_t func = bits(data, 25, 20);
168          uint8_t dcc = bits(data, 29, 26);
169          bool wr = bits(data, 30);
170          bool start = bits(data, 31);
171
172          if (start) {
173              if (wr) {
174                  warn_once("SCReg: Writing %#x to dcc%d:site%d:pos%d:fn%d:dev%d\n",
175                          scData, dcc, site, pos, func, dev);
176                  // Only really support reading, for now!
177              } else {
178                  // Only deal with function 1 (oscillators) so far!
179                  if (dcc != 0 || pos != 0 || func != 1) {
180                      warn("SCReg: read from unknown area "
181                           "(dcc %d:site%d:pos%d:fn%d:dev%d)\n",
182                           dcc, site, pos, func, dev);
183                  } else {
184                      switch (site) {
185                        case 0: { // Motherboard regs
186                            switch(dev) {
187                              case 0: // MCC clk
188                                scData = 25000000;
189                                break;
190                              case 1: // CLCD clk
191                                scData = 25000000;
192                                break;
193                              case 2: // PeriphClk 24MHz
194                                scData = 24000000;
195                                break;
196                              default:
197                                scData = 0;
198                                warn("SCReg: read from unknown dev %d "
199                                     "(site%d:pos%d:fn%d)\n",
200                                     dev, site, pos, func);
201                            }
202                        } break;
203                        case 1: { // Coretile 1 regs
204                            switch(dev) {
205                              case 0: // CPU PLL ref
206                                scData = 50000000;
207                                break;
208                              case 4: // Muxed AXI master clock
209                                scData = 40000000;
210                                break;
211                              case 5: // HDLCD clk
212                                scData = 50000000;
213                                break;
214                              case 6: // SMB clock
215                                scData = 35000000;
216                                break;
217                              case 7: // SYS PLL (also used for pl011 UART!)
218                                scData = 40000000;
219                                break;
220                              case 8: // DDR PLL 40MHz fixed
221                                scData = 40000000;
222                                break;
223                              default:
224                                scData = 0;
225                                warn("SCReg: read from unknown dev %d "
226                                     "(site%d:pos%d:fn%d)\n",
227                                     dev, site, pos, func);
228                            }
229                        } break;
230                        default:
231                          warn("SCReg: Read from unknown site %d (pos%d:fn%d:dev%d)\n",
232                               site, pos, func, dev);
233                      }
234                      DPRINTF(RVCTRL, "SCReg: Will read %#x (ctrlWr %#x)\n", scData, data);
235                  }
236              }
237          } else {
238              DPRINTF(RVCTRL, "SCReg: write %#x to ctrl but not starting\n", data);
239          }
240      } break;
241      case CfgStat:     // Weird to write this
242      default:
243        warn("Tried to write RVIO at offset %#x (data %#x) that doesn't exist\n",
244             daddr, pkt->get<uint32_t>());
245        break;
246    }
247    pkt->makeAtomicResponse();
248    return pioDelay;
249}
250
251void
252RealViewCtrl::serialize(std::ostream &os)
253{
254    SERIALIZE_SCALAR(flags);
255}
256
257void
258RealViewCtrl::unserialize(Checkpoint *cp, const std::string &section)
259{
260    UNSERIALIZE_SCALAR(flags);
261}
262
263RealViewCtrl *
264RealViewCtrlParams::create()
265{
266    return new RealViewCtrl(this);
267}
268