tsunami_pchip.cc revision 835
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
24using namespace std;
25
26TsunamiPChip::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
42Fault
43TsunamiPChip::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
132Fault
133TsunamiPChip::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
220Addr
221TsunamiPChip::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
249void
250TsunamiPChip::serialize(std::ostream &os)
251{
252    SERIALIZE_ARRAY(wsba, 4);
253    SERIALIZE_ARRAY(wsm, 4);
254    SERIALIZE_ARRAY(tba, 4);
255}
256
257void
258TsunamiPChip::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
265BEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
266
267    SimObjectParam<Tsunami *> tsunami;
268    SimObjectParam<MemoryController *> mmu;
269    Param<Addr> addr;
270
271END_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
272
273BEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
274
275    INIT_PARAM(tsunami, "Tsunami"),
276    INIT_PARAM(mmu, "Memory Controller"),
277    INIT_PARAM(addr, "Device Address")
278
279END_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
280
281CREATE_SIM_OBJECT(TsunamiPChip)
282{
283    return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu);
284}
285
286REGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip)
287