tsunami_pchip.cc revision 835
12SN/A/* $Id$ */
21762SN/A
32SN/A/* @file
42SN/A * Tsunami PChip (pci)
52SN/A */
62SN/A
72SN/A#include <deque>
82SN/A#include <string>
92SN/A#include <vector>
102SN/A
112SN/A#include "base/trace.hh"
122SN/A#include "cpu/exec_context.hh"
132SN/A#include "dev/console.hh"
142SN/A#include "dev/etherdev.hh"
152SN/A#include "dev/scsi_ctrl.hh"
162SN/A#include "dev/tlaser_clock.hh"
172SN/A#include "dev/tsunami_pchip.hh"
182SN/A#include "dev/tsunamireg.h"
192SN/A#include "dev/tsunami.hh"
202SN/A#include "mem/functional_mem/memory_control.hh"
212SN/A#include "sim/builder.hh"
222SN/A#include "sim/system.hh"
232SN/A
242SN/Ausing namespace std;
252SN/A
262SN/ATsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
272665Ssaidi@eecs.umich.edu                           MemoryController *mmu)
282665Ssaidi@eecs.umich.edu    : FunctionalMemory(name), addr(a), tsunami(t)
292665Ssaidi@eecs.umich.edu{
302SN/A    mmu->add_child(this, Range<Addr>(addr, addr + size));
312SN/A
322SN/A    for (int i = 0; i < 4; i++) {
332SN/A        wsba[i] = 0;
342SN/A        wsm[i] = 0;
352147SN/A        tba[i] = 0;
362147SN/A    }
372174SN/A
382147SN/A    //Set back pointer in tsunami
392680Sktlim@umich.edu    tsunami->pchip = this;
402132SN/A}
412147SN/A
422132SN/AFault
432147SN/ATsunamiPChip::read(MemReqPtr &req, uint8_t *data)
442147SN/A{
452147SN/A    DPRINTF(Tsunami, "read  va=%#x size=%d\n",
462147SN/A            req->vaddr, req->size);
472147SN/A
482147SN/A    Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6;
492147SN/A//    ExecContext *xc = req->xc;
502147SN/A//    int cpuid = xc->cpu_id;
512147SN/A
522147SN/A    switch (req->size) {
532147SN/A
542090SN/A      case sizeof(uint64_t):
552147SN/A          switch(daddr) {
564695Sgblack@eecs.umich.edu              case TSDEV_PC_WSBA0:
572680Sktlim@umich.edu                    *(uint64_t*)data = wsba[0];
582201SN/A                    return No_Fault;
592201SN/A              case TSDEV_PC_WSBA1:
604695Sgblack@eecs.umich.edu                    *(uint64_t*)data = wsba[1];
614695Sgblack@eecs.umich.edu                    return No_Fault;
622SN/A              case TSDEV_PC_WSBA2:
632SN/A                    *(uint64_t*)data = wsba[2];
642168SN/A                    return No_Fault;
652168SN/A              case TSDEV_PC_WSBA3:
662612SN/A                    *(uint64_t*)data = wsba[3];
672612SN/A                    return No_Fault;
682612SN/A              case TSDEV_PC_WSM0:
692612SN/A                    *(uint64_t*)data = wsm[0];
702612SN/A                    return No_Fault;
712612SN/A              case TSDEV_PC_WSM1:
722612SN/A                    *(uint64_t*)data = wsm[1];
732612SN/A                    return No_Fault;
742612SN/A              case TSDEV_PC_WSM2:
754695Sgblack@eecs.umich.edu                    *(uint64_t*)data = wsm[2];
762680Sktlim@umich.edu                    return No_Fault;
772612SN/A              case TSDEV_PC_WSM3:
782612SN/A                    *(uint64_t*)data = wsm[3];
794183Sgblack@eecs.umich.edu                    return No_Fault;
804183Sgblack@eecs.umich.edu              case TSDEV_PC_TBA0:
814183Sgblack@eecs.umich.edu                    *(uint64_t*)data = tba[0];
824183Sgblack@eecs.umich.edu                    return No_Fault;
834183Sgblack@eecs.umich.edu              case TSDEV_PC_TBA1:
844183Sgblack@eecs.umich.edu                    *(uint64_t*)data = tba[1];
854695Sgblack@eecs.umich.edu                    return No_Fault;
864183Sgblack@eecs.umich.edu              case TSDEV_PC_TBA2:
874183Sgblack@eecs.umich.edu                    *(uint64_t*)data = tba[2];
884183Sgblack@eecs.umich.edu                    return No_Fault;
894183Sgblack@eecs.umich.edu              case TSDEV_PC_TBA3:
904183Sgblack@eecs.umich.edu                    *(uint64_t*)data = tba[3];
912SN/A                    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