Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / pcie_bus / include / pcie_bus.h
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: pcie_bus.h
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23#ifndef _PCIE_BUS_NEW_IMPL_H
24#define _PCIE_BUS_NEW_IMPL_H
25
26
27#include <list>
28#include <map>
29#include <stdio.h>
30
31#include "pcie.h"
32#include "arg.h"
33using namespace std;
34
35class pcieBus:public Module, public pcieBusIf{
36
37
38public:
39 struct pcieDevInfo{
40 const char * name;
41 mmi_instance_t instance;
42 genericPcieDevIf * devIf;
43 int device;
44 int function;
45
46 pcieDevInfo(){
47 name = 0;
48 devIf = 0;
49 device = function = -1;
50 }
51
52 pcieDevInfo(const char * n, mmi_instance_t i, genericPcieDevIf * dI, int d, int f = 0){
53 name = n;
54 device = d;
55 function = f;
56 instance = i;
57 devIf = dI;
58 }
59
60 void print(){
61 printf("name <%s>, dev <%d>, fun <%d>",name, device, function);
62 }
63
64 };
65
66 struct pcieRange{
67 uint64_t base;
68 uint64_t end; // base + size - 1
69 pcieDevInfo * devInfo; // pointer to the info struct for this device
70
71 pcieRange(){
72 base = end = -1;
73 devInfo = 0;
74 }
75 pcieRange(uint64_t b, uint64_t e, pcieDevInfo * di){
76 base = b; end = e; devInfo = di;
77 }
78
79 void print(){
80 devInfo->print();
81 printf(" base <%llx> end <%llx>\n", base, end);
82 }
83
84 };
85
86 //comparison function (reverse than normal default case)
87 class compare{
88 public:
89 bool operator()(uint64_t key1, uint64_t key2)const{
90 return key1 > key2;
91 }
92 };
93
94
95private:
96
97 typedef map<uint64_t , pcieRange *,compare> pcieDevMap;
98 typedef map<uint64_t , pcieRange *,compare>::iterator pcieDevMapIterator;
99
100
101
102 pcieDevInfo *searchDevInfoListByName(const char * name){
103 list<pcieDevInfo *>::iterator i;
104
105 for(i = devInfoList.begin(); i != devInfoList.end(); i++)
106 if(!strcmp(name, (*i)->name))
107 return *i;
108 return 0;
109 }
110
111 pcieDevInfo *searchDevInfoListByDevFun(int dev, int fun){
112 list<pcieDevInfo *>::iterator i;
113
114 for(i = devInfoList.begin(); i != devInfoList.end(); i++)
115 if(((*i)->device == dev) && ((*i)->function == fun))
116 return *i;
117
118 return 0;
119 }
120
121
122 bool addSpace(pcieRange * pI,pcie_space space){
123 pcieDevMapIterator dmIter;
124
125 for(dmIter = pcieAddrSpace[space].begin(); dmIter != pcieAddrSpace[space].end(); dmIter++){
126 if(pI->base >= dmIter->second->base && pI->base <= dmIter->second->end || // pI base within dmIter
127 pI->end >= dmIter->second->base && pI->end <= dmIter->second->end || // pI end within dmIter
128 pI->base <= dmIter->second->base && pI->end >= dmIter->second->end){ // pI encloses dmIter
129 if(strcmp(pI->devInfo->name,dmIter->second->devInfo->name)){
130 printf("%s add Space error : Conflicting ranges\n",getName());
131 printf("Existing device -->"); dmIter->second->print();
132 printf("Conflicting device -->"); pI->print();
133 }
134 return false; //range conflict
135 }
136 }
137
138 pcieAddrSpace[space][pI->base] = pI;
139 return true;
140 }
141
142
143 bool removeMap(pcieDevInfo * pI){ //remove all the mappings for device with info struct pI
144 pcieDevMapIterator dmIter;
145 for(uint8_t i = 0; i < PCI_NSPACES; i++)
146 for(dmIter = pcieAddrSpace[i].begin(); dmIter != pcieAddrSpace[i].end(); dmIter++)
147 if(dmIter->second->devInfo == pI){
148 pcieDevMapIterator dmIter1 = ++dmIter;
149 pcieAddrSpace[i].erase(--dmIter);
150 dmIter = dmIter1;
151 }
152 return true;
153 }
154
155 bool removeSpace(uint64_t base, pcie_space space){
156 return pcieAddrSpace[space].erase(base);
157 }
158
159
160 static const char * pcie_space_name(pcie_space space){
161 switch(space){
162 case PCIE_CFG:
163 return "PCIE config";
164 case PCIE_IO:
165 return "PCIE IO";
166 case PCIE_MEM:
167 return "PCIE MEM";
168 default:
169 return "Unknow Pcie Space!!";
170 }
171 }
172
173 list<pcieDevInfo*> devInfoList; //list of devices present on the pci Bus
174
175 pcieDevMap pcieAddrSpace[3]; // map in only PCIE_CFG, PCIE_IO, PCIE_MEM
176
177 const char * bridgeName;
178 mmi_instance_t bridgeMod;
179 genericPcieDevIf * bridgeIf;
180
181 uint16_t getBridgeId(){ return PCIE_REQUESTER_ID(bridgeIf->devif_getPriBusNo(),\
182 bridgeIf->devif_getDevice(),bridgeIf->devif_getFunction());}
183
184public:
185 pcieBus(const char *_modname, const char *_instance_name);
186 ~pcieBus();
187
188 void modinfo();
189 bool parse_arg(const char *arg);
190 void module_added(mmi_instance_t , const char *target_name);
191 void module_deleted(mmi_instance_t, const char *target_name);
192 void * get_interface(const char *name);
193 bool check_args();
194 const char * get_help();
195
196 void setBridgeIf(genericPcieDevIf * i){bridgeIf = i;}
197 bool busif_addDevice(const char *devname, int device, int function);
198 bool busif_deleteDevice(const char *devname);
199 bool busif_map(const char *devname, pcie_space, uint64_t base, uint64_t size);
200 bool busif_unmap(const char *devname, pcie_space, uint64_t base);
201 int busif_getBusno();
202 bool dump(const char * dir, const char* file){return true;}
203 bool restore(const char * dir, const char* file){return true;}
204 // get the mmi instance based upon device and function
205 mmi_instance_t getDevInstance(int dev,int fun);
206 int devif_getBusNo();
207 // access the mem, io, conf space addresses under this bus hierarchy.
208 pcieCompleter busif_access(pcie_space, bool wr, uint64_t addr, void * data, \
209 uint16_t length, uint8_t be, uint16_t reqId, addrMd_xactnType , SAM_DeviceId *samId, tlp_X args);
210 // addr is a 64 bit flat address into one of the mem/io/conf spaces.
211 // the bus would call one of the devif functions based upon the space.
212
213
214 pcieCompleter busif_msgAccess(uint8_t messageCode, msgRouting route,uint16_t reqId, SAM_DeviceId *samId,\
215 uint64_t tarIdOrAddr, /*msg tlp*/ \
216 void * data, uint16_t length, /* msgd tlp*/ \
217 uint16_t vendor, uint32_t vendor_data, tlp_X args = dont_care_attrs); /* vendor defined msg*/
218
219};
220
221#endif
222
223
224