Commit | Line | Data |
---|---|---|
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" | |
33 | using namespace std; | |
34 | ||
35 | class pcieBus:public Module, public pcieBusIf{ | |
36 | ||
37 | ||
38 | public: | |
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 | ||
95 | private: | |
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 | ||
184 | public: | |
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 |