tsunami_pchip.cc revision 892
1360SN/A/*
21458SN/A * Copyright (c) 2004 The Regents of The University of Michigan
3360SN/A * All rights reserved.
4360SN/A *
5360SN/A * Redistribution and use in source and binary forms, with or without
6360SN/A * modification, are permitted provided that the following conditions are
7360SN/A * met: redistributions of source code must retain the above copyright
8360SN/A * notice, this list of conditions and the following disclaimer;
9360SN/A * redistributions in binary form must reproduce the above copyright
10360SN/A * notice, this list of conditions and the following disclaimer in the
11360SN/A * documentation and/or other materials provided with the distribution;
12360SN/A * neither the name of the copyright holders nor the names of its
13360SN/A * contributors may be used to endorse or promote products derived from
14360SN/A * this software without specific prior written permission.
15360SN/A *
16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu/* @file
30360SN/A * Tsunami PChip (pci)
31360SN/A */
3211793Sbrandon.potter@amd.com
3311793Sbrandon.potter@amd.com#include <deque>
342093SN/A#include <string>
35360SN/A#include <vector>
36360SN/A
376712Snate@binkert.org#include "base/trace.hh"
386712Snate@binkert.org#include "cpu/exec_context.hh"
39360SN/A#include "dev/console.hh"
40360SN/A#include "dev/etherdev.hh"
417680Sgblack@eecs.umich.edu#include "dev/scsi_ctrl.hh"
422474SN/A#include "dev/tlaser_clock.hh"
43360SN/A#include "dev/tsunami_pchip.hh"
446658Snate@binkert.org#include "dev/tsunamireg.h"
458229Snate@binkert.org#include "dev/tsunami.hh"
462680Sktlim@umich.edu#include "mem/functional_mem/memory_control.hh"
4711380Salexandru.dutu@amd.com#include "mem/functional_mem/physical_memory.hh"
488232Snate@binkert.org#include "sim/builder.hh"
492474SN/A#include "sim/system.hh"
50360SN/A
518229Snate@binkert.orgusing namespace std;
526029Ssteve.reinhardt@amd.com
53360SN/ATsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
54360SN/A                           MemoryController *mmu)
552107SN/A    : FunctionalMemory(name), addr(a), tsunami(t)
56360SN/A{
57360SN/A    mmu->add_child(this, Range<Addr>(addr, addr + size));
583114Sgblack@eecs.umich.edu
59360SN/A    for (int i = 0; i < 4; i++) {
6011380Salexandru.dutu@amd.com        wsba[i] = 0;
6110253Ssteve.reinhardt@amd.com        wsm[i] = 0;
6211380Salexandru.dutu@amd.com        tba[i] = 0;
6310253Ssteve.reinhardt@amd.com    }
6410253Ssteve.reinhardt@amd.com
6510253Ssteve.reinhardt@amd.com    //Set back pointer in tsunami
6611380Salexandru.dutu@amd.com    tsunami->pchip = this;
6710253Ssteve.reinhardt@amd.com}
6810253Ssteve.reinhardt@amd.com
6911380Salexandru.dutu@amd.comFault
7011380Salexandru.dutu@amd.comTsunamiPChip::read(MemReqPtr &req, uint8_t *data)
7111380Salexandru.dutu@amd.com{
7211380Salexandru.dutu@amd.com    DPRINTF(Tsunami, "read  va=%#x size=%d\n",
7311380Salexandru.dutu@amd.com            req->vaddr, req->size);
7411380Salexandru.dutu@amd.com
7511380Salexandru.dutu@amd.com    Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6;
7610253Ssteve.reinhardt@amd.com
77360SN/A    switch (req->size) {
782680Sktlim@umich.edu
79360SN/A      case sizeof(uint64_t):
8010500Ssteve.reinhardt@amd.com          switch(daddr) {
8111380Salexandru.dutu@amd.com              case TSDEV_PC_WSBA0:
8210500Ssteve.reinhardt@amd.com                    *(uint64_t*)data = wsba[0];
8311380Salexandru.dutu@amd.com                    return No_Fault;
8411380Salexandru.dutu@amd.com              case TSDEV_PC_WSBA1:
8510500Ssteve.reinhardt@amd.com                    *(uint64_t*)data = wsba[1];
86360SN/A                    return No_Fault;
8710500Ssteve.reinhardt@amd.com              case TSDEV_PC_WSBA2:
885958Sgblack@eecs.umich.edu                    *(uint64_t*)data = wsba[2];
89360SN/A                    return No_Fault;
90360SN/A              case TSDEV_PC_WSBA3:
91360SN/A                    *(uint64_t*)data = wsba[3];
921450SN/A                    return No_Fault;
933114Sgblack@eecs.umich.edu              case TSDEV_PC_WSM0:
942680Sktlim@umich.edu                    *(uint64_t*)data = wsm[0];
95360SN/A                    return No_Fault;
961969SN/A              case TSDEV_PC_WSM1:
972484SN/A                    *(uint64_t*)data = wsm[1];
982484SN/A                    return No_Fault;
99360SN/A              case TSDEV_PC_WSM2:
100360SN/A                    *(uint64_t*)data = wsm[2];
101360SN/A                    return No_Fault;
1021450SN/A              case TSDEV_PC_WSM3:
1033114Sgblack@eecs.umich.edu                    *(uint64_t*)data = wsm[3];
1042680Sktlim@umich.edu                    return No_Fault;
105360SN/A              case TSDEV_PC_TBA0:
1066701Sgblack@eecs.umich.edu                    *(uint64_t*)data = tba[0];
10710831Ssteve.reinhardt@amd.com                    return No_Fault;
108360SN/A              case TSDEV_PC_TBA1:
10910831Ssteve.reinhardt@amd.com                    *(uint64_t*)data = tba[1];
11010831Ssteve.reinhardt@amd.com                    return No_Fault;
11110831Ssteve.reinhardt@amd.com              case TSDEV_PC_TBA2:
112360SN/A                    *(uint64_t*)data = tba[2];
11310831Ssteve.reinhardt@amd.com                    return No_Fault;
11410831Ssteve.reinhardt@amd.com              case TSDEV_PC_TBA3:
11510831Ssteve.reinhardt@amd.com                    *(uint64_t*)data = tba[3];
116360SN/A                    return No_Fault;
11710831Ssteve.reinhardt@amd.com              case TSDEV_PC_PCTL:
11810831Ssteve.reinhardt@amd.com                    // might want to change the clock??
1198149SChris.Emmons@ARM.com                    *(uint64_t*)data = 0x00; // try this
1208149SChris.Emmons@ARM.com                    return No_Fault;
1218149SChris.Emmons@ARM.com              case TSDEV_PC_PLAT:
1228149SChris.Emmons@ARM.com                    panic("PC_PLAT not implemented\n");
1238149SChris.Emmons@ARM.com              case TSDEV_PC_RES:
1248149SChris.Emmons@ARM.com                    panic("PC_RES not implemented\n");
1253114Sgblack@eecs.umich.edu              case TSDEV_PC_PERROR:
1262680Sktlim@umich.edu                    *(uint64_t*)data = 0x00;
127360SN/A                    return No_Fault;
1286029Ssteve.reinhardt@amd.com              case TSDEV_PC_PERRMASK:
1296029Ssteve.reinhardt@amd.com                    *(uint64_t*)data = 0x00;
1306701Sgblack@eecs.umich.edu                    return No_Fault;
1315958Sgblack@eecs.umich.edu              case TSDEV_PC_PERRSET:
1326701Sgblack@eecs.umich.edu                    panic("PC_PERRSET not implemented\n");
1336029Ssteve.reinhardt@amd.com              case TSDEV_PC_TLBIV:
1346029Ssteve.reinhardt@amd.com                    panic("PC_TLBIV not implemented\n");
1356029Ssteve.reinhardt@amd.com              case TSDEV_PC_TLBIA:
1362834Sksewell@umich.edu                    *(uint64_t*)data = 0x00; // shouldn't be readable, but linux
137360SN/A                    return No_Fault;
1381458SN/A              case TSDEV_PC_PMONCTL:
139360SN/A                    panic("PC_PMONCTL not implemented\n");
140360SN/A              case TSDEV_PC_PMONCNT:
141360SN/A                    panic("PC_PMONCTN not implemented\n");
1421450SN/A              default:
1436109Ssanchezd@stanford.edu                  panic("Default in PChip Read reached reading 0x%x\n", daddr);
1446109Ssanchezd@stanford.edu
1456109Ssanchezd@stanford.edu           } // uint64_t
14610483Swiseveri@student.ethz.ch
14710483Swiseveri@student.ethz.ch      break;
14810483Swiseveri@student.ethz.ch      case sizeof(uint32_t):
14910483Swiseveri@student.ethz.ch      case sizeof(uint16_t):
15010483Swiseveri@student.ethz.ch      case sizeof(uint8_t):
15110483Swiseveri@student.ethz.ch      default:
15210483Swiseveri@student.ethz.ch        panic("invalid access size(?) for tsunami register!\n\n");
15310483Swiseveri@student.ethz.ch    }
15410483Swiseveri@student.ethz.ch    DPRINTFN("Tsunami PChip ERROR: read  daddr=%#x size=%d\n", daddr, req->size);
15510483Swiseveri@student.ethz.ch
15610483Swiseveri@student.ethz.ch    return No_Fault;
1576109Ssanchezd@stanford.edu}
1586109Ssanchezd@stanford.edu
1596109Ssanchezd@stanford.eduFault
1606109Ssanchezd@stanford.eduTsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
1616109Ssanchezd@stanford.edu{
1626109Ssanchezd@stanford.edu    DPRINTF(Tsunami, "write - va=%#x size=%d \n",
1633114Sgblack@eecs.umich.edu            req->vaddr, req->size);
164360SN/A
16510318Sandreas.hansson@arm.com    Addr daddr = (req->paddr - (addr & PA_IMPL_MASK)) >> 6;
166360SN/A
167360SN/A    switch (req->size) {
168360SN/A
1691450SN/A      case sizeof(uint64_t):
1705748SSteve.Reinhardt@amd.com          switch(daddr) {
171360SN/A              case TSDEV_PC_WSBA0:
172360SN/A                    wsba[0] = *(uint64_t*)data;
1736701Sgblack@eecs.umich.edu                    return No_Fault;
1746701Sgblack@eecs.umich.edu              case TSDEV_PC_WSBA1:
1755748SSteve.Reinhardt@amd.com                    wsba[1] = *(uint64_t*)data;
1765748SSteve.Reinhardt@amd.com                    return No_Fault;
1775748SSteve.Reinhardt@amd.com              case TSDEV_PC_WSBA2:
1785748SSteve.Reinhardt@amd.com                    wsba[2] = *(uint64_t*)data;
1795748SSteve.Reinhardt@amd.com                    return No_Fault;
1805748SSteve.Reinhardt@amd.com              case TSDEV_PC_WSBA3:
1815748SSteve.Reinhardt@amd.com                    wsba[3] = *(uint64_t*)data;
1825748SSteve.Reinhardt@amd.com                    return No_Fault;
1832474SN/A              case TSDEV_PC_WSM0:
18410318Sandreas.hansson@arm.com                    wsm[0] = *(uint64_t*)data;
1855748SSteve.Reinhardt@amd.com                    return No_Fault;
18610318Sandreas.hansson@arm.com              case TSDEV_PC_WSM1:
1876687Stjones1@inf.ed.ac.uk                    wsm[1] = *(uint64_t*)data;
1886687Stjones1@inf.ed.ac.uk                    return No_Fault;
1896687Stjones1@inf.ed.ac.uk              case TSDEV_PC_WSM2:
1906687Stjones1@inf.ed.ac.uk                    wsm[2] = *(uint64_t*)data;
1918852Sandreas.hansson@arm.com                    return No_Fault;
1926687Stjones1@inf.ed.ac.uk              case TSDEV_PC_WSM3:
1936687Stjones1@inf.ed.ac.uk                    wsm[3] = *(uint64_t*)data;
19410318Sandreas.hansson@arm.com                    return No_Fault;
1956687Stjones1@inf.ed.ac.uk              case TSDEV_PC_TBA0:
1968852Sandreas.hansson@arm.com                    tba[0] = *(uint64_t*)data;
19710318Sandreas.hansson@arm.com                    return No_Fault;
1986687Stjones1@inf.ed.ac.uk              case TSDEV_PC_TBA1:
1996687Stjones1@inf.ed.ac.uk                    tba[1] = *(uint64_t*)data;
2006687Stjones1@inf.ed.ac.uk                    return No_Fault;
20110318Sandreas.hansson@arm.com              case TSDEV_PC_TBA2:
2028852Sandreas.hansson@arm.com                    tba[2] = *(uint64_t*)data;
2036687Stjones1@inf.ed.ac.uk                    return No_Fault;
2046687Stjones1@inf.ed.ac.uk              case TSDEV_PC_TBA3:
2052474SN/A                    tba[3] = *(uint64_t*)data;
2061450SN/A                    return No_Fault;
2075748SSteve.Reinhardt@amd.com              case TSDEV_PC_PCTL:
2085748SSteve.Reinhardt@amd.com                    // might want to change the clock??
20911380Salexandru.dutu@amd.com                    return No_Fault;
21011380Salexandru.dutu@amd.com              case TSDEV_PC_PLAT:
2111458SN/A                    panic("PC_PLAT not implemented\n");
212360SN/A              case TSDEV_PC_RES:
213360SN/A                    panic("PC_RES not implemented\n");
214360SN/A              case TSDEV_PC_PERROR:
2151450SN/A                    return No_Fault;
2163114Sgblack@eecs.umich.edu              case TSDEV_PC_PERRMASK:
217360SN/A                    panic("PC_PERRMASK not implemented\n");
2186701Sgblack@eecs.umich.edu              case TSDEV_PC_PERRSET:
21910931Sbrandon.potter@amd.com                    panic("PC_PERRSET not implemented\n");
22010931Sbrandon.potter@amd.com              case TSDEV_PC_TLBIV:
22110932Sbrandon.potter@amd.com                    panic("PC_TLBIV not implemented\n");
22210931Sbrandon.potter@amd.com              case TSDEV_PC_TLBIA:
22310931Sbrandon.potter@amd.com                    return No_Fault; // value ignored, supposted to invalidate SG TLB
22410931Sbrandon.potter@amd.com              case TSDEV_PC_PMONCTL:
2257508Stjones1@inf.ed.ac.uk                    panic("PC_PMONCTL not implemented\n");
2267508Stjones1@inf.ed.ac.uk              case TSDEV_PC_PMONCNT:
2277508Stjones1@inf.ed.ac.uk                    panic("PC_PMONCTN not implemented\n");
2281970SN/A              default:
22910932Sbrandon.potter@amd.com                  panic("Default in PChip Read reached reading 0x%x\n", daddr);
2301970SN/A
231360SN/A           } // uint64_t
232360SN/A
233360SN/A      break;
2341450SN/A      case sizeof(uint32_t):
2353114Sgblack@eecs.umich.edu      case sizeof(uint16_t):
236360SN/A      case sizeof(uint8_t):
2376701Sgblack@eecs.umich.edu      default:
23810931Sbrandon.potter@amd.com        panic("invalid access size(?) for tsunami register!\n\n");
2396701Sgblack@eecs.umich.edu    }
2406701Sgblack@eecs.umich.edu
2416701Sgblack@eecs.umich.edu    DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size);
242360SN/A
24310932Sbrandon.potter@amd.com    return No_Fault;
24410931Sbrandon.potter@amd.com}
24510931Sbrandon.potter@amd.com
24610931Sbrandon.potter@amd.com#define DMA_ADDR_MASK ULL(0x3ffffffff)
24710931Sbrandon.potter@amd.com
248360SN/AAddr
24911684Snderumigny@gmail.comTsunamiPChip::translatePciToDma(Addr busAddr)
2508706Sandreas.hansson@arm.com{
251360SN/A    // compare the address to the window base registers
2521458SN/A    uint64_t tbaMask = 0;
253360SN/A    uint64_t baMask = 0;
254360SN/A
2551450SN/A    uint64_t windowMask = 0;
2563114Sgblack@eecs.umich.edu    uint64_t windowBase = 0;
257360SN/A
2586701Sgblack@eecs.umich.edu    uint64_t pteEntry = 0;
25910931Sbrandon.potter@amd.com
2606701Sgblack@eecs.umich.edu    Addr pteAddr;
2616701Sgblack@eecs.umich.edu    Addr dmaAddr;
2626701Sgblack@eecs.umich.edu
263360SN/A    for (int i = 0; i < 4; i++) {
26410932Sbrandon.potter@amd.com        windowBase = wsba[i];
26510931Sbrandon.potter@amd.com        windowMask = ~wsm[i] & (0x7ff << 20);
26610931Sbrandon.potter@amd.com
26710931Sbrandon.potter@amd.com        if ((busAddr & windowMask) == (windowBase & windowMask)) {
2688706Sandreas.hansson@arm.com
269360SN/A
27010931Sbrandon.potter@amd.com            if (wsba[i] & 0x1) {   // see if enabled
271360SN/A                if (wsba[i] & 0x2) { // see if SG bit is set
27210931Sbrandon.potter@amd.com                    /** @todo
273360SN/A                        This currently is faked by just doing a direct
2741458SN/A                        read from memory, however, to be realistic, this
275360SN/A                        needs to actually do a bus transaction.  The process
276360SN/A                        is explained in the tsunami documentation on page
277360SN/A                        10-12 and basically munges the address to look up a
2781450SN/A                        PTE from a table in memory and then uses that mapping
2793114Sgblack@eecs.umich.edu                        to create an address for the SG page
280360SN/A                    */
2816701Sgblack@eecs.umich.edu
28210931Sbrandon.potter@amd.com                    tbaMask = ~(((wsm[i] & (0x7ff << 20)) >> 10) | 0x3ff);
2836701Sgblack@eecs.umich.edu                    baMask = (wsm[i] & (0x7ff << 20)) | (0x7f << 13);
2846701Sgblack@eecs.umich.edu                    pteAddr = (tba[i] & tbaMask) | ((busAddr & baMask) >> 10);
285360SN/A
28610932Sbrandon.potter@amd.com                    memcpy((void *)&pteEntry,
28710931Sbrandon.potter@amd.com                           tsunami->system->
28810931Sbrandon.potter@amd.com                           physmem->dma_addr(pteAddr, sizeof(uint64_t)),
28910931Sbrandon.potter@amd.com                           sizeof(uint64_t));
29010931Sbrandon.potter@amd.com
291360SN/A                    dmaAddr = ((pteEntry & ~0x1) << 12) | (busAddr & 0x1fff);
2921458SN/A
293360SN/A                } else {
294360SN/A                    baMask = (wsm[i] & (0x7ff << 20)) | 0xfffff;
295360SN/A                    tbaMask = ~baMask;
2961450SN/A                    dmaAddr = (tba[i] & tbaMask) | (busAddr & baMask);
2974118Sgblack@eecs.umich.edu                }
2984118Sgblack@eecs.umich.edu
2996701Sgblack@eecs.umich.edu                return (dmaAddr & DMA_ADDR_MASK);
30010931Sbrandon.potter@amd.com            }
3016701Sgblack@eecs.umich.edu        }
3026701Sgblack@eecs.umich.edu    }
3036701Sgblack@eecs.umich.edu
3046701Sgblack@eecs.umich.edu    return 0;
3054118Sgblack@eecs.umich.edu}
30610932Sbrandon.potter@amd.com
30710931Sbrandon.potter@amd.comvoid
30810931Sbrandon.potter@amd.comTsunamiPChip::serialize(std::ostream &os)
30910931Sbrandon.potter@amd.com{
3104118Sgblack@eecs.umich.edu    SERIALIZE_ARRAY(wsba, 4);
3114118Sgblack@eecs.umich.edu    SERIALIZE_ARRAY(wsm, 4);
31210931Sbrandon.potter@amd.com    SERIALIZE_ARRAY(tba, 4);
3134118Sgblack@eecs.umich.edu}
3144118Sgblack@eecs.umich.edu
31511379Sbrandon.potter@amd.comvoid
3164118Sgblack@eecs.umich.eduTsunamiPChip::unserialize(Checkpoint *cp, const std::string &section)
31711379Sbrandon.potter@amd.com{
31811379Sbrandon.potter@amd.com    UNSERIALIZE_ARRAY(wsba, 4);
31911379Sbrandon.potter@amd.com    UNSERIALIZE_ARRAY(wsm, 4);
32011379Sbrandon.potter@amd.com    UNSERIALIZE_ARRAY(tba, 4);
32111379Sbrandon.potter@amd.com}
3224118Sgblack@eecs.umich.edu
3234118Sgblack@eecs.umich.eduBEGIN_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
3244118Sgblack@eecs.umich.edu
3254118Sgblack@eecs.umich.edu    SimObjectParam<Tsunami *> tsunami;
3263114Sgblack@eecs.umich.edu    SimObjectParam<MemoryController *> mmu;
327360SN/A    Param<Addr> addr;
32811383Sbrandon.potter@amd.com
32911383Sbrandon.potter@amd.comEND_DECLARE_SIM_OBJECT_PARAMS(TsunamiPChip)
33011383Sbrandon.potter@amd.com
3311458SN/ABEGIN_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
332360SN/A
333360SN/A    INIT_PARAM(tsunami, "Tsunami"),
334360SN/A    INIT_PARAM(mmu, "Memory Controller"),
335360SN/A    INIT_PARAM(addr, "Device Address")
336360SN/A
3371450SN/AEND_INIT_SIM_OBJECT_PARAMS(TsunamiPChip)
3383114Sgblack@eecs.umich.edu
339360SN/ACREATE_SIM_OBJECT(TsunamiPChip)
3406701Sgblack@eecs.umich.edu{
3416701Sgblack@eecs.umich.edu    return new TsunamiPChip(getInstanceName(), tsunami, addr, mmu);
3426701Sgblack@eecs.umich.edu}
3436701Sgblack@eecs.umich.edu
344360SN/AREGISTER_SIM_OBJECT("TsunamiPChip", TsunamiPChip)
345360SN/A