Checkin of latest IDE and some separation between platforms (Tsunami and
[gem5.git] / dev / tsunami_pchip.cc
1 /* $Id$ */
2
3 /* @file
4 * Tsunami PChip (pci)
5 */
6
7 #include <deque>
8 #include <string>
9 #include <vector>
10
11 #include "base/trace.hh"
12 #include "cpu/exec_context.hh"
13 #include "dev/console.hh"
14 #include "dev/etherdev.hh"
15 #include "dev/scsi_ctrl.hh"
16 #include "dev/tlaser_clock.hh"
17 #include "dev/tsunami_pchip.hh"
18 #include "dev/tsunamireg.h"
19 #include "dev/tsunami.hh"
20 #include "mem/functional_mem/memory_control.hh"
21 #include "sim/builder.hh"
22 #include "sim/system.hh"
23
24 using namespace std;
25
26 TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
27 MemoryController *mmu)
28 : FunctionalMemory(name), addr(a), tsunami(t)
29 {
30 mmu->add_child(this, Range<Addr>(addr, addr + size));
31
32 for (int i = 0; i < 4; i++) {
33 wsba[i] = 0;
34 wsm[i] = 0;
35 tba[i] = 0;
36 }
37
38 //Set back pointer in tsunami
39 tsunami->pchip = this;
40 }
41
42 Fault
43 TsunamiPChip::read(MemReqPtr &req, uint8_t *data)
44 {
45 DPRINTF(Tsunami, "read va=%#x size=%d\n",
46 req->vaddr, req->size);
47
48 Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6;
49 // ExecContext *xc = req->xc;
50 // int cpuid = xc->cpu_id;
51
52 switch (req->size) {
53
54 case sizeof(uint64_t):
55 switch(daddr) {
56 case TSDEV_PC_WSBA0:
57 *(uint64_t*)data = wsba[0];
58 return No_Fault;
59 case TSDEV_PC_WSBA1:
60 *(uint64_t*)data = wsba[1];
61 return No_Fault;
62 case TSDEV_PC_WSBA2:
63 *(uint64_t*)data = wsba[2];
64 return No_Fault;
65 case TSDEV_PC_WSBA3:
66 *(uint64_t*)data = wsba[3];
67 return No_Fault;
68 case TSDEV_PC_WSM0:
69 *(uint64_t*)data = wsm[0];
70 return No_Fault;
71 case TSDEV_PC_WSM1:
72 *(uint64_t*)data = wsm[1];
73 return No_Fault;
74 case TSDEV_PC_WSM2:
75 *(uint64_t*)data = wsm[2];
76 return No_Fault;
77 case TSDEV_PC_WSM3:
78 *(uint64_t*)data = wsm[3];
79 return No_Fault;
80 case TSDEV_PC_TBA0:
81 *(uint64_t*)data = tba[0];
82 return No_Fault;
83 case TSDEV_PC_TBA1:
84 *(uint64_t*)data = tba[1];
85 return No_Fault;
86 case TSDEV_PC_TBA2:
87 *(uint64_t*)data = tba[2];
88 return No_Fault;
89 case TSDEV_PC_TBA3:
90 *(uint64_t*)data = tba[3];
91 return No_Fault;
92 case TSDEV_PC_PCTL:
93 // might want to change the clock??
94 *(uint64_t*)data = 0x00; // try this
95 return No_Fault;
96 case TSDEV_PC_PLAT:
97 panic("PC_PLAT not implemented\n");
98 case TSDEV_PC_RES:
99 panic("PC_RES not implemented\n");
100 case TSDEV_PC_PERROR:
101 panic("PC_PERROR not implemented\n");
102 case TSDEV_PC_PERRMASK:
103 panic("PC_PERRMASK not implemented\n");
104 case TSDEV_PC_PERRSET:
105 panic("PC_PERRSET not implemented\n");
106 case TSDEV_PC_TLBIV:
107 panic("PC_TLBIV not implemented\n");
108 case TSDEV_PC_TLBIA:
109 *(uint64_t*)data = 0x00; // shouldn't be readable, but linux
110 return No_Fault;
111 case TSDEV_PC_PMONCTL:
112 panic("PC_PMONCTL not implemented\n");
113 case TSDEV_PC_PMONCNT:
114 panic("PC_PMONCTN not implemented\n");
115 default:
116 panic("Default in PChip Read reached reading 0x%x\n", daddr);
117
118 } // uint64_t
119
120 break;
121 case sizeof(uint32_t):
122 case sizeof(uint16_t):
123 case sizeof(uint8_t):
124 default:
125 panic("invalid access size(?) for tsunami register!\n\n");
126 }
127 DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size);
128
129 return No_Fault;
130 }
131
132 Fault
133 TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
134 {
135 DPRINTF(Tsunami, "write - va=%#x size=%d \n",
136 req->vaddr, req->size);
137
138 Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6;
139
140 switch (req->size) {
141
142 case sizeof(uint64_t):
143 switch(daddr) {
144 case TSDEV_PC_WSBA0:
145 wsba[0] = *(uint64_t*)data;
146 return No_Fault;
147 case TSDEV_PC_WSBA1:
148 wsba[1] = *(uint64_t*)data;
149 return No_Fault;
150 case TSDEV_PC_WSBA2:
151 wsba[2] = *(uint64_t*)data;
152 return No_Fault;
153 case TSDEV_PC_WSBA3:
154 wsba[3] = *(uint64_t*)data;
155 return No_Fault;
156 case TSDEV_PC_WSM0:
157 wsm[0] = *(uint64_t*)data;
158 return No_Fault;
159 case TSDEV_PC_WSM1:
160 wsm[1] = *(uint64_t*)data;
161 return No_Fault;
162 case TSDEV_PC_WSM2:
163 wsm[2] = *(uint64_t*)data;
164 return No_Fault;
165 case TSDEV_PC_WSM3:
166 wsm[3] = *(uint64_t*)data;
167 return No_Fault;
168 case TSDEV_PC_TBA0:
169 tba[0] = *(uint64_t*)data;
170 return No_Fault;
171 case TSDEV_PC_TBA1:
172 tba[1] = *(uint64_t*)data;
173 return No_Fault;
174 case TSDEV_PC_TBA2:
175 tba[2] = *(uint64_t*)data;
176 return No_Fault;
177 case TSDEV_PC_TBA3:
178 tba[3] = *(uint64_t*)data;
179 return No_Fault;
180 case TSDEV_PC_PCTL:
181 // might want to change the clock??
182 //*(uint64_t*)data; // try this
183 return No_Fault;
184 case TSDEV_PC_PLAT:
185 panic("PC_PLAT not implemented\n");
186 case TSDEV_PC_RES:
187 panic("PC_RES not implemented\n");
188 case TSDEV_PC_PERROR:
189 panic("PC_PERROR not implemented\n");
190 case TSDEV_PC_PERRMASK:
191 panic("PC_PERRMASK not implemented\n");
192 case TSDEV_PC_PERRSET:
193 panic("PC_PERRSET not implemented\n");
194 case TSDEV_PC_TLBIV:
195 panic("PC_TLBIV not implemented\n");
196 case TSDEV_PC_TLBIA:
197 return No_Fault; // value ignored, supposted to invalidate SG TLB
198 case TSDEV_PC_PMONCTL:
199 panic("PC_PMONCTL not implemented\n");
200 case TSDEV_PC_PMONCNT:
201 panic("PC_PMONCTN not implemented\n");
202 default:
203 panic("Default in PChip Read reached reading 0x%x\n", daddr);
204
205 } // uint64_t
206
207 break;
208 case sizeof(uint32_t):
209 case sizeof(uint16_t):
210 case sizeof(uint8_t):
211 default:
212 panic("invalid access size(?) for tsunami register!\n\n");
213 }
214
215 DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size);
216
217 return No_Fault;
218 }
219
220 Addr
221 TsunamiPChip::translatePciToDma(Addr busAddr)
222 {
223 // compare the address to the window base registers
224 uint64_t windowMask = 0;
225 uint64_t windowBase = 0;
226 Addr dmaAddr;
227
228 for (int i = 0; i < 4; i++) {
229 windowBase = wsba[i];
230 windowMask = ~wsm[i] & (0x7ff << 20);
231
232 if ((busAddr & windowMask) == (windowBase & windowMask)) {
233 windowMask = (wsm[i] & (0x7ff << 20)) | 0xfffff;
234
235 if (wsba[i] & 0x1) { // see if enabled
236 if (wsba[i] & 0x2) // see if SG bit is set
237 panic("PCI to system SG mapping not currently implemented!\n");
238 else
239 dmaAddr = (tba[i] & ~windowMask) | (busAddr & windowMask);
240
241 return dmaAddr;
242 }
243 }
244 }
245
246 return 0;
247 }
248
249 void
250 TsunamiPChip::serialize(std::ostream &os)
251 {
252 SERIALIZE_ARRAY(wsba, 4);
253 SERIALIZE_ARRAY(wsm, 4);
254 SERIALIZE_ARRAY(tba, 4);
255 }
256
257 void
258 TsunamiPChip::unserialize(Checkpoint *cp, const std::string &section)
259 {
260 UNSERIALIZE_ARRAY(wsba, 4);
261 UNSERIALIZE_ARRAY(wsm, 4);
262 UNSERIALIZE_ARRAY(tba, 4);
263 }
264
265 BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
266
267 SimObjectParam<Tsunami *> tsunami;
268 SimObjectParam<MemoryController *> mmu;
269 Param<Addr> addr;
270
271 END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
272
273 BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
274
275 INIT_PARAM(tsunami, "Tsunami"),
276 INIT_PARAM(mmu, "Memory Controller"),
277 INIT_PARAM(addr, "Device Address")
278
279 END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
280
281 CREATE_SIM_OBJECT(TsunamiPChip)
282 {
283 return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu);
284 }
285
286 REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip)