2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Nathan Binkert
35 * Mips Console Backdoor Definition
40 #include "arch/mips/system.hh"
41 #include "base/inifile.hh"
42 #include "base/str.hh"
43 #include "base/trace.hh"
44 #include "cpu/base.hh"
45 #include "cpu/thread_context.hh"
46 #include "dev/mips/backdoor.hh"
47 #include "dev/platform.hh"
48 #include "dev/simple_disk.hh"
49 #include "dev/terminal.hh"
50 #include "mem/packet.hh"
51 #include "mem/packet_access.hh"
52 #include "mem/physical.hh"
53 #include "params/MipsBackdoor.hh"
54 #include "sim/sim_object.hh"
58 using namespace MipsISA
;
60 MipsBackdoor::MipsBackdoor(const Params
*p
)
61 : BasicPioDevice(p
), disk(p
->disk
), terminal(p
->terminal
),
62 system(p
->system
), cpu(p
->cpu
)
65 pioSize
= sizeof(struct MipsAccess
);
67 mipsAccess
= new Access();
68 mipsAccess
->last_offset
= pioSize
- 1;
70 mipsAccess
->version
= MIPS_ACCESS_VERSION
;
71 mipsAccess
->diskUnit
= 1;
73 mipsAccess
->diskCount
= 0;
74 mipsAccess
->diskPAddr
= 0;
75 mipsAccess
->diskBlock
= 0;
76 mipsAccess
->diskOperation
= 0;
77 mipsAccess
->outputChar
= 0;
78 mipsAccess
->inputChar
= 0;
79 bzero(mipsAccess
->cpuStack
, sizeof(mipsAccess
->cpuStack
));
84 MipsBackdoor::startup()
86 system
->setMipsAccess(pioAddr
);
87 mipsAccess
->numCPUs
= system
->getNumCPUs();
88 mipsAccess
->kernStart
= MipsISA::Phys2K0Seg(system
->getKernelStart());
89 mipsAccess
->kernEnd
= MipsISA::Phys2K0Seg(system
->getKernelEnd());
90 mipsAccess
->entryPoint
= MipsISA::Phys2K0Seg(system
->getKernelEntry());
91 mipsAccess
->mem_size
= system
->physmem
->size();
92 mipsAccess
->cpuClock
= cpu
->frequency() / 1000000; // In MHz
93 mipsAccess
->intrClockFrequency
= params()->platform
->intrFrequency();
97 MipsBackdoor::read(PacketPtr pkt
)
100 /** XXX Do we want to push the addr munging to a bus brige or something? So
101 * the device has it's physical address and then the bridge adds on whatever
102 * machine dependent address swizzle is required?
104 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
106 Addr daddr
= pkt
->getAddr() - pioAddr
;
110 switch (pkt
->getSize())
112 case sizeof(uint32_t):
115 case offsetof(MipsAccess
, last_offset
):
116 pkt
->set(mipsAccess
->last_offset
);
118 case offsetof(MipsAccess
, version
):
119 pkt
->set(mipsAccess
->version
);
121 case offsetof(MipsAccess
, numCPUs
):
122 pkt
->set(mipsAccess
->numCPUs
);
124 case offsetof(MipsAccess
, intrClockFrequency
):
125 pkt
->set(mipsAccess
->intrClockFrequency
);
127 case offsetof(MipsAccess
, inputChar
):
128 pkt
->set(terminal
->console_in());
130 case offsetof(MipsAccess
, cpuClock
):
131 pkt
->set(mipsAccess
->cpuClock
);
133 case offsetof(MipsAccess
, mem_size
):
134 pkt
->set(mipsAccess
->mem_size
);
136 case offsetof(MipsAccess
, kernStart
):
137 pkt
->set(mipsAccess
->kernStart
);
139 case offsetof(MipsAccess
, kernEnd
):
140 pkt
->set(mipsAccess
->kernEnd
);
142 case offsetof(MipsAccess
, entryPoint
):
143 pkt
->set(mipsAccess
->entryPoint
);
145 case offsetof(MipsAccess
, diskUnit
):
146 pkt
->set(mipsAccess
->diskUnit
);
148 case offsetof(MipsAccess
, diskCount
):
149 pkt
->set(mipsAccess
->diskCount
);
151 case offsetof(MipsAccess
, diskPAddr
):
152 pkt
->set(mipsAccess
->diskPAddr
);
154 case offsetof(MipsAccess
, diskBlock
):
155 pkt
->set(mipsAccess
->diskBlock
);
157 case offsetof(MipsAccess
, diskOperation
):
158 pkt
->set(mipsAccess
->diskOperation
);
160 case offsetof(MipsAccess
, outputChar
):
161 pkt
->set(mipsAccess
->outputChar
);
164 int cpunum
= (daddr
- offsetof(MipsAccess
, cpuStack
)) /
165 sizeof(mipsAccess
->cpuStack
[0]);
167 if (cpunum
>= 0 && cpunum
< 64)
168 pkt
->set(mipsAccess
->cpuStack
[cpunum
]);
170 panic("Unknown 32bit access, %#x\n", daddr
);
172 //DPRINTF(MipsBackdoor, "read: offset=%#x val=%#x\n", daddr,
173 // pkt->get<uint64_t>());
176 pkt
->setBadAddress();
179 pkt
->makeAtomicResponse();
184 MipsBackdoor::write(PacketPtr pkt
)
186 assert(pkt
->getAddr() >= pioAddr
&& pkt
->getAddr() < pioAddr
+ pioSize
);
187 Addr daddr
= pkt
->getAddr() - pioAddr
;
189 uint32_t val
= pkt
->get
<uint32_t>();
190 assert(pkt
->getSize() == sizeof(uint32_t));
192 case offsetof(MipsAccess
, diskUnit
):
193 mipsAccess
->diskUnit
= val
;
196 case offsetof(MipsAccess
, diskCount
):
197 mipsAccess
->diskCount
= val
;
200 case offsetof(MipsAccess
, diskPAddr
):
201 mipsAccess
->diskPAddr
= val
;
204 case offsetof(MipsAccess
, diskBlock
):
205 mipsAccess
->diskBlock
= val
;
208 case offsetof(MipsAccess
, diskOperation
):
210 disk
->read(mipsAccess
->diskPAddr
, mipsAccess
->diskBlock
,
211 mipsAccess
->diskCount
);
213 panic("Invalid disk operation!");
217 case offsetof(MipsAccess
, outputChar
):
218 terminal
->out((char)(val
& 0xff));
222 int cpunum
= (daddr
- offsetof(MipsAccess
, cpuStack
)) /
223 sizeof(mipsAccess
->cpuStack
[0]);
224 warn("%d: Trying to launch CPU number %d!", curTick
, cpunum
);
225 assert(val
> 0 && "Must not access primary cpu");
226 if (cpunum
>= 0 && cpunum
< 64)
227 mipsAccess
->cpuStack
[cpunum
] = val
;
229 panic("Unknown 32bit access, %#x\n", daddr
);
232 pkt
->makeAtomicResponse();
238 MipsBackdoor::Access::serialize(ostream
&os
)
240 SERIALIZE_SCALAR(last_offset
);
241 SERIALIZE_SCALAR(version
);
242 SERIALIZE_SCALAR(numCPUs
);
243 SERIALIZE_SCALAR(mem_size
);
244 SERIALIZE_SCALAR(cpuClock
);
245 SERIALIZE_SCALAR(intrClockFrequency
);
246 SERIALIZE_SCALAR(kernStart
);
247 SERIALIZE_SCALAR(kernEnd
);
248 SERIALIZE_SCALAR(entryPoint
);
249 SERIALIZE_SCALAR(diskUnit
);
250 SERIALIZE_SCALAR(diskCount
);
251 SERIALIZE_SCALAR(diskPAddr
);
252 SERIALIZE_SCALAR(diskBlock
);
253 SERIALIZE_SCALAR(diskOperation
);
254 SERIALIZE_SCALAR(outputChar
);
255 SERIALIZE_SCALAR(inputChar
);
256 SERIALIZE_ARRAY(cpuStack
,64);
260 MipsBackdoor::Access::unserialize(Checkpoint
*cp
, const std::string
§ion
)
262 UNSERIALIZE_SCALAR(last_offset
);
263 UNSERIALIZE_SCALAR(version
);
264 UNSERIALIZE_SCALAR(numCPUs
);
265 UNSERIALIZE_SCALAR(mem_size
);
266 UNSERIALIZE_SCALAR(cpuClock
);
267 UNSERIALIZE_SCALAR(intrClockFrequency
);
268 UNSERIALIZE_SCALAR(kernStart
);
269 UNSERIALIZE_SCALAR(kernEnd
);
270 UNSERIALIZE_SCALAR(entryPoint
);
271 UNSERIALIZE_SCALAR(diskUnit
);
272 UNSERIALIZE_SCALAR(diskCount
);
273 UNSERIALIZE_SCALAR(diskPAddr
);
274 UNSERIALIZE_SCALAR(diskBlock
);
275 UNSERIALIZE_SCALAR(diskOperation
);
276 UNSERIALIZE_SCALAR(outputChar
);
277 UNSERIALIZE_SCALAR(inputChar
);
278 UNSERIALIZE_ARRAY(cpuStack
, 64);
282 MipsBackdoor::serialize(ostream
&os
)
284 mipsAccess
->serialize(os
);
288 MipsBackdoor::unserialize(Checkpoint
*cp
, const std::string
§ion
)
290 mipsAccess
->unserialize(cp
, section
);
294 MipsBackdoorParams::create()
296 return new MipsBackdoor(this);