Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * OpenSPARC T2 Processor File: pci_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 _PCI_BUS_NEW_IMPL_H | |
24 | #define _PCI_BUS_NEW_IMPL_H | |
25 | ||
26 | ||
27 | #include <list> | |
28 | #include <map> | |
29 | #include <stdio.h> | |
30 | ||
31 | #include "pci.h" | |
32 | #include "arg.h" | |
33 | using namespace std; | |
34 | ||
35 | class pciBus:public Module, pciBusIf{ | |
36 | ||
37 | ||
38 | public: | |
39 | struct pciDevInfo{ | |
40 | const char * name; | |
41 | mmi_instance_t instance; | |
42 | genericPciDevIf * devIf; | |
43 | uint8_t device; | |
44 | uint8_t function; | |
45 | ||
46 | pciDevInfo(){ | |
47 | name = 0; | |
48 | devIf = 0; | |
49 | device = function = -1; | |
50 | } | |
51 | ||
52 | pciDevInfo(const char * n, mmi_instance_t i, genericPciDevIf * dI, uint8_t d, uint8_t 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>\n",name, device, function); | |
62 | } | |
63 | ||
64 | }; | |
65 | ||
66 | struct pciRange{ | |
67 | uint64_t base; | |
68 | uint64_t end; // base + size - 1 | |
69 | pciDevInfo * devInfo; // pointer to the info struct for this device | |
70 | ||
71 | pciRange(){ | |
72 | base = end = -1; | |
73 | devInfo = 0; | |
74 | } | |
75 | pciRange(uint64_t b, uint64_t e, pciDevInfo * 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 , pciRange *,compare> pciDevMap; | |
98 | typedef map<uint64_t , pciRange *,compare>::iterator pciDevMapIterator; | |
99 | ||
100 | ||
101 | ||
102 | pciDevInfo *searchDevInfoListByName(const char * name){ | |
103 | list<pciDevInfo *>::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 | pciDevInfo *searchDevInfoListByDevFun(uint8_t dev, uint8_t fun){ | |
112 | list<pciDevInfo *>::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(pciRange * pI,pci_space_t space){ | |
123 | pciDevMapIterator dmIter; | |
124 | ||
125 | dmIter = pciAddrSpace[space].lower_bound(pI->base); | |
126 | for(dmIter = pciAddrSpace[space].begin(); dmIter != pciAddrSpace[space].end(); dmIter++){ | |
127 | if(pI->base >= dmIter->second->base && pI->base <= dmIter->second->end || \ | |
128 | pI->end >= dmIter->second->base && pI->end <= dmIter->second->end || \ | |
129 | pI->base <= dmIter->second->base && pI->end >= dmIter->second->end){ | |
130 | if(strcmp(pI->devInfo->name,dmIter->second->devInfo->name)){ | |
131 | printf("%s add Space error : Conflicting ranges\n",getName()); | |
132 | printf("Existing device -->"); dmIter->second->print(); | |
133 | printf("Conflicting device -->"); pI->print(); | |
134 | } | |
135 | return false; //range conflict | |
136 | } | |
137 | } | |
138 | ||
139 | pciAddrSpace[space][pI->base] = pI; | |
140 | return true; | |
141 | } | |
142 | ||
143 | ||
144 | bool removeMap(pciDevInfo * pI){ //remove all the mappings for device with info struct pI | |
145 | pciDevMapIterator dmIter; | |
146 | for(uint8_t i = 0; i < PCI_NSPACES; i++) | |
147 | for(dmIter = pciAddrSpace[i].begin(); dmIter != pciAddrSpace[i].end(); dmIter++) | |
148 | if(dmIter->second->devInfo == pI){ | |
149 | pciDevMapIterator dmIter1 = ++dmIter; | |
150 | pciAddrSpace[i].erase(--dmIter); | |
151 | dmIter = dmIter1; | |
152 | } | |
153 | return true; | |
154 | } | |
155 | ||
156 | bool removeSpace(uint64_t base, pci_space_t space){ | |
157 | return pciAddrSpace[space].erase(base); | |
158 | } | |
159 | ||
160 | ||
161 | static const char * pci_space_name(pci_space_t space){ | |
162 | switch(space){ | |
163 | case PCI_CFG: | |
164 | return "PCI config"; | |
165 | case PCI_IO: | |
166 | return "PCI IO"; | |
167 | case PCI_MEM32: | |
168 | return "PCI MEM32"; | |
169 | case PCI_MEM64: | |
170 | return "PCI MEM64"; | |
171 | default: | |
172 | return "Unknow!!"; | |
173 | } | |
174 | } | |
175 | ||
176 | list<pciDevInfo*> devInfoList; //list of devices present on the pci Bus | |
177 | ||
178 | pciDevMap pciAddrSpace[PCI_NSPACES]; | |
179 | ||
180 | const char * bridgeName; | |
181 | //mmi_instance_t bridgeMod; | |
182 | mmi_instance_t bridgeMod; | |
183 | pciBridgeIf * bridgeIf; | |
184 | ||
185 | ||
186 | public: | |
187 | pciBus(const char *_modname, const char *_instance_name); | |
188 | ~pciBus(); | |
189 | ||
190 | void modinfo(); | |
191 | bool parse_arg(const char *arg); | |
192 | void module_added(mmi_instance_t , const char *target_name); | |
193 | void module_deleted(mmi_instance_t, const char *target_name); | |
194 | void * get_interface(const char *name); | |
195 | bool check_args(); | |
196 | const char * get_help(); | |
197 | ||
198 | bool busif_add_device(const char *devname, uint8_t device, uint8_t function); | |
199 | bool busif_delete_device(const char *devname); | |
200 | bool busif_map(const char *devname, pci_space_t, uint64_t base, uint64_t size); | |
201 | bool busif_unmap(const char *devname, pci_space_t, uint64_t base); | |
202 | int busif_add_interrupt(int device, int dev_type, int slot_irl[], bool isMulti = false); | |
203 | int busif_free_interrupt(int device); | |
204 | bool busif_interrupt_in(bool set, int dev_number, int line, SAM_DeviceId *samId); | |
205 | uint64_t busif_get_lowest_base(pci_space_t, uint64_t sz); | |
206 | ||
207 | pciXactnStatus busif_dma(bool wr, uint64_t vaddr, void *data, long count, SAM_DeviceId *samId); | |
208 | pciXactnStatus busif_special_cycle(uint16_t mssg, uint16_t data); | |
209 | pciXactnStatus busif_intr_ack(uint64_t * data); | |
210 | pciXactnStatus busif_access_w_size(pci_space_t, uint64_t paddr, uint64_t offset, bool_t wr, uint64_t* buf, uint8_t size, SAM_DeviceId * samId); | |
211 | pciXactnStatus busif_access_w_byte_enables(pci_space_t, uint64_t paddr, uint64_t offset, bool_t wr, uint64_t* buf, uint8_t byte_enable, SAM_DeviceId * samId); | |
212 | int busif_get_busno(){return bridgeIf->busif_get_secondary_busno();} | |
213 | }; | |
214 | ||
215 | #endif | |
216 | ||
217 |