tsunami_pchip.cc (8229:78bf55f23338) tsunami_pchip.cc (8232:b28d06a175be)
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Ali Saidi
29 * Andrew Schultz
30 */
31
32/** @file
33 * Tsunami PChip (pci)
34 */
35
36#include <deque>
37#include <string>
38#include <vector>
39
40#include "base/trace.hh"
41#include "config/the_isa.hh"
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Ali Saidi
29 * Andrew Schultz
30 */
31
32/** @file
33 * Tsunami PChip (pci)
34 */
35
36#include <deque>
37#include <string>
38#include <vector>
39
40#include "base/trace.hh"
41#include "config/the_isa.hh"
42#include "debug/Tsunami.hh"
42#include "dev/alpha/tsunami.hh"
43#include "dev/alpha/tsunami_pchip.hh"
44#include "dev/alpha/tsunamireg.h"
45#include "mem/packet.hh"
46#include "mem/packet_access.hh"
47#include "sim/system.hh"
48
49using namespace std;
50//Should this be AlphaISA?
51using namespace TheISA;
52
53TsunamiPChip::TsunamiPChip(const Params *p)
54: BasicPioDevice(p)
55{
56 pioSize = 0x1000;
57
58 for (int i = 0; i < 4; i++) {
59 wsba[i] = 0;
60 wsm[i] = 0;
61 tba[i] = 0;
62 }
63
64 // initialize pchip control register
65 pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36);
66
67 //Set back pointer in tsunami
68 p->tsunami->pchip = this;
69}
70
71Tick
72TsunamiPChip::read(PacketPtr pkt)
73{
74 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
75
76 pkt->allocate();
77 Addr daddr = (pkt->getAddr() - pioAddr) >> 6;;
78 assert(pkt->getSize() == sizeof(uint64_t));
79
80
81 DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
82
83 switch(daddr) {
84 case TSDEV_PC_WSBA0:
85 pkt->set(wsba[0]);
86 break;
87 case TSDEV_PC_WSBA1:
88 pkt->set(wsba[1]);
89 break;
90 case TSDEV_PC_WSBA2:
91 pkt->set(wsba[2]);
92 break;
93 case TSDEV_PC_WSBA3:
94 pkt->set(wsba[3]);
95 break;
96 case TSDEV_PC_WSM0:
97 pkt->set(wsm[0]);
98 break;
99 case TSDEV_PC_WSM1:
100 pkt->set(wsm[1]);
101 break;
102 case TSDEV_PC_WSM2:
103 pkt->set(wsm[2]);
104 break;
105 case TSDEV_PC_WSM3:
106 pkt->set(wsm[3]);
107 break;
108 case TSDEV_PC_TBA0:
109 pkt->set(tba[0]);
110 break;
111 case TSDEV_PC_TBA1:
112 pkt->set(tba[1]);
113 break;
114 case TSDEV_PC_TBA2:
115 pkt->set(tba[2]);
116 break;
117 case TSDEV_PC_TBA3:
118 pkt->set(tba[3]);
119 break;
120 case TSDEV_PC_PCTL:
121 pkt->set(pctl);
122 break;
123 case TSDEV_PC_PLAT:
124 panic("PC_PLAT not implemented\n");
125 case TSDEV_PC_RES:
126 panic("PC_RES not implemented\n");
127 case TSDEV_PC_PERROR:
128 pkt->set((uint64_t)0x00);
129 break;
130 case TSDEV_PC_PERRMASK:
131 pkt->set((uint64_t)0x00);
132 break;
133 case TSDEV_PC_PERRSET:
134 panic("PC_PERRSET not implemented\n");
135 case TSDEV_PC_TLBIV:
136 panic("PC_TLBIV not implemented\n");
137 case TSDEV_PC_TLBIA:
138 pkt->set((uint64_t)0x00); // shouldn't be readable, but linux
139 break;
140 case TSDEV_PC_PMONCTL:
141 panic("PC_PMONCTL not implemented\n");
142 case TSDEV_PC_PMONCNT:
143 panic("PC_PMONCTN not implemented\n");
144 default:
145 panic("Default in PChip Read reached reading 0x%x\n", daddr);
146 }
147 pkt->makeAtomicResponse();
148 return pioDelay;
149
150}
151
152Tick
153TsunamiPChip::write(PacketPtr pkt)
154{
155 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
156 Addr daddr = (pkt->getAddr() - pioAddr) >> 6;
157
158 assert(pkt->getSize() == sizeof(uint64_t));
159
160 DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
161
162 switch(daddr) {
163 case TSDEV_PC_WSBA0:
164 wsba[0] = pkt->get<uint64_t>();
165 break;
166 case TSDEV_PC_WSBA1:
167 wsba[1] = pkt->get<uint64_t>();
168 break;
169 case TSDEV_PC_WSBA2:
170 wsba[2] = pkt->get<uint64_t>();
171 break;
172 case TSDEV_PC_WSBA3:
173 wsba[3] = pkt->get<uint64_t>();
174 break;
175 case TSDEV_PC_WSM0:
176 wsm[0] = pkt->get<uint64_t>();
177 break;
178 case TSDEV_PC_WSM1:
179 wsm[1] = pkt->get<uint64_t>();
180 break;
181 case TSDEV_PC_WSM2:
182 wsm[2] = pkt->get<uint64_t>();
183 break;
184 case TSDEV_PC_WSM3:
185 wsm[3] = pkt->get<uint64_t>();
186 break;
187 case TSDEV_PC_TBA0:
188 tba[0] = pkt->get<uint64_t>();
189 break;
190 case TSDEV_PC_TBA1:
191 tba[1] = pkt->get<uint64_t>();
192 break;
193 case TSDEV_PC_TBA2:
194 tba[2] = pkt->get<uint64_t>();
195 break;
196 case TSDEV_PC_TBA3:
197 tba[3] = pkt->get<uint64_t>();
198 break;
199 case TSDEV_PC_PCTL:
200 pctl = pkt->get<uint64_t>();
201 break;
202 case TSDEV_PC_PLAT:
203 panic("PC_PLAT not implemented\n");
204 case TSDEV_PC_RES:
205 panic("PC_RES not implemented\n");
206 case TSDEV_PC_PERROR:
207 break;
208 case TSDEV_PC_PERRMASK:
209 panic("PC_PERRMASK not implemented\n");
210 case TSDEV_PC_PERRSET:
211 panic("PC_PERRSET not implemented\n");
212 case TSDEV_PC_TLBIV:
213 panic("PC_TLBIV not implemented\n");
214 case TSDEV_PC_TLBIA:
215 break; // value ignored, supposted to invalidate SG TLB
216 case TSDEV_PC_PMONCTL:
217 panic("PC_PMONCTL not implemented\n");
218 case TSDEV_PC_PMONCNT:
219 panic("PC_PMONCTN not implemented\n");
220 default:
221 panic("Default in PChip write reached reading 0x%x\n", daddr);
222
223 } // uint64_t
224
225 pkt->makeAtomicResponse();
226 return pioDelay;
227}
228
229#define DMA_ADDR_MASK ULL(0x3ffffffff)
230
231Addr
232TsunamiPChip::translatePciToDma(Addr busAddr)
233{
234 // compare the address to the window base registers
235 uint64_t tbaMask = 0;
236 uint64_t baMask = 0;
237
238 uint64_t windowMask = 0;
239 uint64_t windowBase = 0;
240
241 uint64_t pteEntry = 0;
242
243 Addr pteAddr;
244 Addr dmaAddr;
245
246#if 0
247 DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr);
248 for (int i = 0; i < 4; i++) {
249 DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n",
250 i, wsba[i], wsm[i]);
251
252 windowBase = wsba[i];
253 windowMask = ~wsm[i] & (ULL(0xfff) << 20);
254
255 if ((busAddr & windowMask) == (windowBase & windowMask)) {
256 DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n",
257 i, windowBase, windowMask, (busAddr & windowMask),
258 (windowBase & windowMask));
259 }
260 }
261#endif
262
263 for (int i = 0; i < 4; i++) {
264
265 windowBase = wsba[i];
266 windowMask = ~wsm[i] & (ULL(0xfff) << 20);
267
268 if ((busAddr & windowMask) == (windowBase & windowMask)) {
269
270 if (wsba[i] & 0x1) { // see if enabled
271 if (wsba[i] & 0x2) { // see if SG bit is set
272 /** @todo
273 This currently is faked by just doing a direct
274 read from memory, however, to be realistic, this
275 needs to actually do a bus transaction. The process
276 is explained in the tsunami documentation on page
277 10-12 and basically munges the address to look up a
278 PTE from a table in memory and then uses that mapping
279 to create an address for the SG page
280 */
281
282 tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff));
283 baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13);
284 pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);
285
286 pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t));
287
288 dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff));
289
290 } else {
291 baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff);
292 tbaMask = ~baMask;
293 dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask);
294 }
295
296 return (dmaAddr & DMA_ADDR_MASK);
297 }
298 }
299 }
300
301 // if no match was found, then return the original address
302 return busAddr;
303}
304
305Addr
306TsunamiPChip::calcConfigAddr(int bus, int dev, int func)
307{
308 assert(func < 8);
309 assert(dev < 32);
310 assert(bus == 0);
311
312 return TsunamiPciBus0Config | (func << 8) | (dev << 11);
313}
314
315Addr
316TsunamiPChip::calcIOAddr(Addr addr)
317{
318 return TSUNAMI_PCI0_IO + addr;
319}
320
321Addr
322TsunamiPChip::calcMemAddr(Addr addr)
323{
324 return TSUNAMI_PCI0_MEMORY + addr;
325}
326
327void
328TsunamiPChip::serialize(std::ostream &os)
329{
330 SERIALIZE_SCALAR(pctl);
331 SERIALIZE_ARRAY(wsba, 4);
332 SERIALIZE_ARRAY(wsm, 4);
333 SERIALIZE_ARRAY(tba, 4);
334}
335
336void
337TsunamiPChip::unserialize(Checkpoint *cp, const std::string &section)
338{
339 UNSERIALIZE_SCALAR(pctl);
340 UNSERIALIZE_ARRAY(wsba, 4);
341 UNSERIALIZE_ARRAY(wsm, 4);
342 UNSERIALIZE_ARRAY(tba, 4);
343}
344
345
346TsunamiPChip *
347TsunamiPChipParams::create()
348{
349 return new TsunamiPChip(this);
350}
43#include "dev/alpha/tsunami.hh"
44#include "dev/alpha/tsunami_pchip.hh"
45#include "dev/alpha/tsunamireg.h"
46#include "mem/packet.hh"
47#include "mem/packet_access.hh"
48#include "sim/system.hh"
49
50using namespace std;
51//Should this be AlphaISA?
52using namespace TheISA;
53
54TsunamiPChip::TsunamiPChip(const Params *p)
55: BasicPioDevice(p)
56{
57 pioSize = 0x1000;
58
59 for (int i = 0; i < 4; i++) {
60 wsba[i] = 0;
61 wsm[i] = 0;
62 tba[i] = 0;
63 }
64
65 // initialize pchip control register
66 pctl = (ULL(0x1) << 20) | (ULL(0x1) << 32) | (ULL(0x2) << 36);
67
68 //Set back pointer in tsunami
69 p->tsunami->pchip = this;
70}
71
72Tick
73TsunamiPChip::read(PacketPtr pkt)
74{
75 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
76
77 pkt->allocate();
78 Addr daddr = (pkt->getAddr() - pioAddr) >> 6;;
79 assert(pkt->getSize() == sizeof(uint64_t));
80
81
82 DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
83
84 switch(daddr) {
85 case TSDEV_PC_WSBA0:
86 pkt->set(wsba[0]);
87 break;
88 case TSDEV_PC_WSBA1:
89 pkt->set(wsba[1]);
90 break;
91 case TSDEV_PC_WSBA2:
92 pkt->set(wsba[2]);
93 break;
94 case TSDEV_PC_WSBA3:
95 pkt->set(wsba[3]);
96 break;
97 case TSDEV_PC_WSM0:
98 pkt->set(wsm[0]);
99 break;
100 case TSDEV_PC_WSM1:
101 pkt->set(wsm[1]);
102 break;
103 case TSDEV_PC_WSM2:
104 pkt->set(wsm[2]);
105 break;
106 case TSDEV_PC_WSM3:
107 pkt->set(wsm[3]);
108 break;
109 case TSDEV_PC_TBA0:
110 pkt->set(tba[0]);
111 break;
112 case TSDEV_PC_TBA1:
113 pkt->set(tba[1]);
114 break;
115 case TSDEV_PC_TBA2:
116 pkt->set(tba[2]);
117 break;
118 case TSDEV_PC_TBA3:
119 pkt->set(tba[3]);
120 break;
121 case TSDEV_PC_PCTL:
122 pkt->set(pctl);
123 break;
124 case TSDEV_PC_PLAT:
125 panic("PC_PLAT not implemented\n");
126 case TSDEV_PC_RES:
127 panic("PC_RES not implemented\n");
128 case TSDEV_PC_PERROR:
129 pkt->set((uint64_t)0x00);
130 break;
131 case TSDEV_PC_PERRMASK:
132 pkt->set((uint64_t)0x00);
133 break;
134 case TSDEV_PC_PERRSET:
135 panic("PC_PERRSET not implemented\n");
136 case TSDEV_PC_TLBIV:
137 panic("PC_TLBIV not implemented\n");
138 case TSDEV_PC_TLBIA:
139 pkt->set((uint64_t)0x00); // shouldn't be readable, but linux
140 break;
141 case TSDEV_PC_PMONCTL:
142 panic("PC_PMONCTL not implemented\n");
143 case TSDEV_PC_PMONCNT:
144 panic("PC_PMONCTN not implemented\n");
145 default:
146 panic("Default in PChip Read reached reading 0x%x\n", daddr);
147 }
148 pkt->makeAtomicResponse();
149 return pioDelay;
150
151}
152
153Tick
154TsunamiPChip::write(PacketPtr pkt)
155{
156 assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
157 Addr daddr = (pkt->getAddr() - pioAddr) >> 6;
158
159 assert(pkt->getSize() == sizeof(uint64_t));
160
161 DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
162
163 switch(daddr) {
164 case TSDEV_PC_WSBA0:
165 wsba[0] = pkt->get<uint64_t>();
166 break;
167 case TSDEV_PC_WSBA1:
168 wsba[1] = pkt->get<uint64_t>();
169 break;
170 case TSDEV_PC_WSBA2:
171 wsba[2] = pkt->get<uint64_t>();
172 break;
173 case TSDEV_PC_WSBA3:
174 wsba[3] = pkt->get<uint64_t>();
175 break;
176 case TSDEV_PC_WSM0:
177 wsm[0] = pkt->get<uint64_t>();
178 break;
179 case TSDEV_PC_WSM1:
180 wsm[1] = pkt->get<uint64_t>();
181 break;
182 case TSDEV_PC_WSM2:
183 wsm[2] = pkt->get<uint64_t>();
184 break;
185 case TSDEV_PC_WSM3:
186 wsm[3] = pkt->get<uint64_t>();
187 break;
188 case TSDEV_PC_TBA0:
189 tba[0] = pkt->get<uint64_t>();
190 break;
191 case TSDEV_PC_TBA1:
192 tba[1] = pkt->get<uint64_t>();
193 break;
194 case TSDEV_PC_TBA2:
195 tba[2] = pkt->get<uint64_t>();
196 break;
197 case TSDEV_PC_TBA3:
198 tba[3] = pkt->get<uint64_t>();
199 break;
200 case TSDEV_PC_PCTL:
201 pctl = pkt->get<uint64_t>();
202 break;
203 case TSDEV_PC_PLAT:
204 panic("PC_PLAT not implemented\n");
205 case TSDEV_PC_RES:
206 panic("PC_RES not implemented\n");
207 case TSDEV_PC_PERROR:
208 break;
209 case TSDEV_PC_PERRMASK:
210 panic("PC_PERRMASK not implemented\n");
211 case TSDEV_PC_PERRSET:
212 panic("PC_PERRSET not implemented\n");
213 case TSDEV_PC_TLBIV:
214 panic("PC_TLBIV not implemented\n");
215 case TSDEV_PC_TLBIA:
216 break; // value ignored, supposted to invalidate SG TLB
217 case TSDEV_PC_PMONCTL:
218 panic("PC_PMONCTL not implemented\n");
219 case TSDEV_PC_PMONCNT:
220 panic("PC_PMONCTN not implemented\n");
221 default:
222 panic("Default in PChip write reached reading 0x%x\n", daddr);
223
224 } // uint64_t
225
226 pkt->makeAtomicResponse();
227 return pioDelay;
228}
229
230#define DMA_ADDR_MASK ULL(0x3ffffffff)
231
232Addr
233TsunamiPChip::translatePciToDma(Addr busAddr)
234{
235 // compare the address to the window base registers
236 uint64_t tbaMask = 0;
237 uint64_t baMask = 0;
238
239 uint64_t windowMask = 0;
240 uint64_t windowBase = 0;
241
242 uint64_t pteEntry = 0;
243
244 Addr pteAddr;
245 Addr dmaAddr;
246
247#if 0
248 DPRINTF(IdeDisk, "Translation for bus address: %#x\n", busAddr);
249 for (int i = 0; i < 4; i++) {
250 DPRINTF(IdeDisk, "(%d) base:%#x mask:%#x\n",
251 i, wsba[i], wsm[i]);
252
253 windowBase = wsba[i];
254 windowMask = ~wsm[i] & (ULL(0xfff) << 20);
255
256 if ((busAddr & windowMask) == (windowBase & windowMask)) {
257 DPRINTF(IdeDisk, "Would have matched %d (wb:%#x wm:%#x --> ba&wm:%#x wb&wm:%#x)\n",
258 i, windowBase, windowMask, (busAddr & windowMask),
259 (windowBase & windowMask));
260 }
261 }
262#endif
263
264 for (int i = 0; i < 4; i++) {
265
266 windowBase = wsba[i];
267 windowMask = ~wsm[i] & (ULL(0xfff) << 20);
268
269 if ((busAddr & windowMask) == (windowBase & windowMask)) {
270
271 if (wsba[i] & 0x1) { // see if enabled
272 if (wsba[i] & 0x2) { // see if SG bit is set
273 /** @todo
274 This currently is faked by just doing a direct
275 read from memory, however, to be realistic, this
276 needs to actually do a bus transaction. The process
277 is explained in the tsunami documentation on page
278 10-12 and basically munges the address to look up a
279 PTE from a table in memory and then uses that mapping
280 to create an address for the SG page
281 */
282
283 tbaMask = ~(((wsm[i] & (ULL(0xfff) << 20)) >> 10) | ULL(0x3ff));
284 baMask = (wsm[i] & (ULL(0xfff) << 20)) | (ULL(0x7f) << 13);
285 pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);
286
287 pioPort->readBlob(pteAddr, (uint8_t*)&pteEntry, sizeof(uint64_t));
288
289 dmaAddr = ((pteEntry & ~ULL(0x1)) << 12) | (busAddr & ULL(0x1fff));
290
291 } else {
292 baMask = (wsm[i] & (ULL(0xfff) << 20)) | ULL(0xfffff);
293 tbaMask = ~baMask;
294 dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask);
295 }
296
297 return (dmaAddr & DMA_ADDR_MASK);
298 }
299 }
300 }
301
302 // if no match was found, then return the original address
303 return busAddr;
304}
305
306Addr
307TsunamiPChip::calcConfigAddr(int bus, int dev, int func)
308{
309 assert(func < 8);
310 assert(dev < 32);
311 assert(bus == 0);
312
313 return TsunamiPciBus0Config | (func << 8) | (dev << 11);
314}
315
316Addr
317TsunamiPChip::calcIOAddr(Addr addr)
318{
319 return TSUNAMI_PCI0_IO + addr;
320}
321
322Addr
323TsunamiPChip::calcMemAddr(Addr addr)
324{
325 return TSUNAMI_PCI0_MEMORY + addr;
326}
327
328void
329TsunamiPChip::serialize(std::ostream &os)
330{
331 SERIALIZE_SCALAR(pctl);
332 SERIALIZE_ARRAY(wsba, 4);
333 SERIALIZE_ARRAY(wsm, 4);
334 SERIALIZE_ARRAY(tba, 4);
335}
336
337void
338TsunamiPChip::unserialize(Checkpoint *cp, const std::string &section)
339{
340 UNSERIALIZE_SCALAR(pctl);
341 UNSERIALIZE_ARRAY(wsba, 4);
342 UNSERIALIZE_ARRAY(wsm, 4);
343 UNSERIALIZE_ARRAY(tba, 4);
344}
345
346
347TsunamiPChip *
348TsunamiPChipParams::create()
349{
350 return new TsunamiPChip(this);
351}