1 /*
2  * Provides the Hypervisor PCI calls for iSeries Linux Parition.
3  * Copyright (C) 2001  <Wayne G Holm> <IBM Corporation>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the:
17  * Free Software Foundation, Inc.,
18  * 59 Temple Place, Suite 330,
19  * Boston, MA  02111-1307  USA
20  *
21  * Change Activity:
22  *   Created, Jan 9, 2001
23  */
24 
25 #ifndef _PLATFORMS_ISERIES_CALL_PCI_H
26 #define _PLATFORMS_ISERIES_CALL_PCI_H
27 
28 #include <asm/iseries/hv_call_sc.h>
29 #include <asm/iseries/hv_types.h>
30 
31 /*
32  * DSA == Direct Select Address
33  * this struct must be 64 bits in total
34  */
35 struct HvCallPci_DsaAddr {
36 	u16		busNumber;		/* PHB index? */
37 	u8		subBusNumber;		/* PCI bus number? */
38 	u8		deviceId;		/* device and function? */
39 	u8		barNumber;
40 	u8		reserved[3];
41 };
42 
43 union HvDsaMap {
44 	u64	DsaAddr;
45 	struct HvCallPci_DsaAddr Dsa;
46 };
47 
48 struct HvCallPci_LoadReturn {
49 	u64		rc;
50 	u64		value;
51 };
52 
53 enum HvCallPci_DeviceType {
54 	HvCallPci_NodeDevice	= 1,
55 	HvCallPci_SpDevice	= 2,
56 	HvCallPci_IopDevice     = 3,
57 	HvCallPci_BridgeDevice	= 4,
58 	HvCallPci_MultiFunctionDevice = 5,
59 	HvCallPci_IoaDevice	= 6
60 };
61 
62 
63 struct HvCallPci_DeviceInfo {
64 	u32	deviceType;		/* See DeviceType enum for values */
65 };
66 
67 struct HvCallPci_BusUnitInfo {
68 	u32	sizeReturned;		/* length of data returned */
69 	u32	deviceType;		/* see DeviceType enum for values */
70 };
71 
72 struct HvCallPci_BridgeInfo {
73 	struct HvCallPci_BusUnitInfo busUnitInfo;  /* Generic bus unit info */
74 	u8		subBusNumber;	/* Bus number of secondary bus */
75 	u8		maxAgents;	/* Max idsels on secondary bus */
76         u8              maxSubBusNumber; /* Max Sub Bus */
77 	u8		logicalSlotNumber; /* Logical Slot Number for IOA */
78 };
79 
80 
81 /*
82  * Maximum BusUnitInfo buffer size.  Provided for clients so
83  * they can allocate a buffer big enough for any type of bus
84  * unit.  Increase as needed.
85  */
86 enum {HvCallPci_MaxBusUnitInfoSize = 128};
87 
88 struct HvCallPci_BarParms {
89 	u64		vaddr;
90 	u64		raddr;
91 	u64		size;
92 	u64		protectStart;
93 	u64		protectEnd;
94 	u64		relocationOffset;
95 	u64		pciAddress;
96 	u64		reserved[3];
97 };
98 
99 enum HvCallPci_VpdType {
100 	HvCallPci_BusVpd	= 1,
101 	HvCallPci_BusAdapterVpd	= 2
102 };
103 
104 #define HvCallPciConfigLoad8		HvCallPci + 0
105 #define HvCallPciConfigLoad16		HvCallPci + 1
106 #define HvCallPciConfigLoad32		HvCallPci + 2
107 #define HvCallPciConfigStore8		HvCallPci + 3
108 #define HvCallPciConfigStore16		HvCallPci + 4
109 #define HvCallPciConfigStore32		HvCallPci + 5
110 #define HvCallPciEoi			HvCallPci + 16
111 #define HvCallPciGetBarParms		HvCallPci + 18
112 #define HvCallPciMaskFisr		HvCallPci + 20
113 #define HvCallPciUnmaskFisr		HvCallPci + 21
114 #define HvCallPciSetSlotReset		HvCallPci + 25
115 #define HvCallPciGetDeviceInfo		HvCallPci + 27
116 #define HvCallPciGetCardVpd		HvCallPci + 28
117 #define HvCallPciBarLoad8		HvCallPci + 40
118 #define HvCallPciBarLoad16		HvCallPci + 41
119 #define HvCallPciBarLoad32		HvCallPci + 42
120 #define HvCallPciBarLoad64		HvCallPci + 43
121 #define HvCallPciBarStore8		HvCallPci + 44
122 #define HvCallPciBarStore16		HvCallPci + 45
123 #define HvCallPciBarStore32		HvCallPci + 46
124 #define HvCallPciBarStore64		HvCallPci + 47
125 #define HvCallPciMaskInterrupts		HvCallPci + 48
126 #define HvCallPciUnmaskInterrupts	HvCallPci + 49
127 #define HvCallPciGetBusUnitInfo		HvCallPci + 50
128 
HvCallPci_configLoad16(u16 busNumber,u8 subBusNumber,u8 deviceId,u32 offset,u16 * value)129 static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
130 		u8 deviceId, u32 offset, u16 *value)
131 {
132 	struct HvCallPci_DsaAddr dsa;
133 	struct HvCallPci_LoadReturn retVal;
134 
135 	*((u64*)&dsa) = 0;
136 
137 	dsa.busNumber = busNumber;
138 	dsa.subBusNumber = subBusNumber;
139 	dsa.deviceId = deviceId;
140 
141 	HvCall3Ret16(HvCallPciConfigLoad16, &retVal, *(u64 *)&dsa, offset, 0);
142 
143 	*value = retVal.value;
144 
145 	return retVal.rc;
146 }
147 
HvCallPci_configLoad32(u16 busNumber,u8 subBusNumber,u8 deviceId,u32 offset,u32 * value)148 static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
149 		u8 deviceId, u32 offset, u32 *value)
150 {
151 	struct HvCallPci_DsaAddr dsa;
152 	struct HvCallPci_LoadReturn retVal;
153 
154 	*((u64*)&dsa) = 0;
155 
156 	dsa.busNumber = busNumber;
157 	dsa.subBusNumber = subBusNumber;
158 	dsa.deviceId = deviceId;
159 
160 	HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0);
161 
162 	*value = retVal.value;
163 
164 	return retVal.rc;
165 }
166 
HvCallPci_configStore8(u16 busNumber,u8 subBusNumber,u8 deviceId,u32 offset,u8 value)167 static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
168 		u8 deviceId, u32 offset, u8 value)
169 {
170 	struct HvCallPci_DsaAddr dsa;
171 
172 	*((u64*)&dsa) = 0;
173 
174 	dsa.busNumber = busNumber;
175 	dsa.subBusNumber = subBusNumber;
176 	dsa.deviceId = deviceId;
177 
178 	return HvCall4(HvCallPciConfigStore8, *(u64 *)&dsa, offset, value, 0);
179 }
180 
HvCallPci_eoi(u16 busNumberParm,u8 subBusParm,u8 deviceIdParm)181 static inline u64 HvCallPci_eoi(u16 busNumberParm, u8 subBusParm,
182 		u8 deviceIdParm)
183 {
184 	struct HvCallPci_DsaAddr dsa;
185 	struct HvCallPci_LoadReturn retVal;
186 
187 	*((u64*)&dsa) = 0;
188 
189 	dsa.busNumber = busNumberParm;
190 	dsa.subBusNumber = subBusParm;
191 	dsa.deviceId = deviceIdParm;
192 
193 	HvCall1Ret16(HvCallPciEoi, &retVal, *(u64*)&dsa);
194 
195 	return retVal.rc;
196 }
197 
HvCallPci_getBarParms(u16 busNumberParm,u8 subBusParm,u8 deviceIdParm,u8 barNumberParm,u64 parms,u32 sizeofParms)198 static inline u64 HvCallPci_getBarParms(u16 busNumberParm, u8 subBusParm,
199 		u8 deviceIdParm, u8 barNumberParm, u64 parms, u32 sizeofParms)
200 {
201 	struct HvCallPci_DsaAddr dsa;
202 
203 	*((u64*)&dsa) = 0;
204 
205 	dsa.busNumber = busNumberParm;
206 	dsa.subBusNumber = subBusParm;
207 	dsa.deviceId = deviceIdParm;
208 	dsa.barNumber = barNumberParm;
209 
210 	return HvCall3(HvCallPciGetBarParms, *(u64*)&dsa, parms, sizeofParms);
211 }
212 
HvCallPci_maskFisr(u16 busNumberParm,u8 subBusParm,u8 deviceIdParm,u64 fisrMask)213 static inline u64 HvCallPci_maskFisr(u16 busNumberParm, u8 subBusParm,
214 		u8 deviceIdParm, u64 fisrMask)
215 {
216 	struct HvCallPci_DsaAddr dsa;
217 
218 	*((u64*)&dsa) = 0;
219 
220 	dsa.busNumber = busNumberParm;
221 	dsa.subBusNumber = subBusParm;
222 	dsa.deviceId = deviceIdParm;
223 
224 	return HvCall2(HvCallPciMaskFisr, *(u64*)&dsa, fisrMask);
225 }
226 
HvCallPci_unmaskFisr(u16 busNumberParm,u8 subBusParm,u8 deviceIdParm,u64 fisrMask)227 static inline u64 HvCallPci_unmaskFisr(u16 busNumberParm, u8 subBusParm,
228 		u8 deviceIdParm, u64 fisrMask)
229 {
230 	struct HvCallPci_DsaAddr dsa;
231 
232 	*((u64*)&dsa) = 0;
233 
234 	dsa.busNumber = busNumberParm;
235 	dsa.subBusNumber = subBusParm;
236 	dsa.deviceId = deviceIdParm;
237 
238 	return HvCall2(HvCallPciUnmaskFisr, *(u64*)&dsa, fisrMask);
239 }
240 
HvCallPci_getDeviceInfo(u16 busNumberParm,u8 subBusParm,u8 deviceNumberParm,u64 parms,u32 sizeofParms)241 static inline u64 HvCallPci_getDeviceInfo(u16 busNumberParm, u8 subBusParm,
242 		u8 deviceNumberParm, u64 parms, u32 sizeofParms)
243 {
244 	struct HvCallPci_DsaAddr dsa;
245 
246 	*((u64*)&dsa) = 0;
247 
248 	dsa.busNumber = busNumberParm;
249 	dsa.subBusNumber = subBusParm;
250 	dsa.deviceId = deviceNumberParm << 4;
251 
252 	return HvCall3(HvCallPciGetDeviceInfo, *(u64*)&dsa, parms, sizeofParms);
253 }
254 
HvCallPci_maskInterrupts(u16 busNumberParm,u8 subBusParm,u8 deviceIdParm,u64 interruptMask)255 static inline u64 HvCallPci_maskInterrupts(u16 busNumberParm, u8 subBusParm,
256 		u8 deviceIdParm, u64 interruptMask)
257 {
258 	struct HvCallPci_DsaAddr dsa;
259 
260 	*((u64*)&dsa) = 0;
261 
262 	dsa.busNumber = busNumberParm;
263 	dsa.subBusNumber = subBusParm;
264 	dsa.deviceId = deviceIdParm;
265 
266 	return HvCall2(HvCallPciMaskInterrupts, *(u64*)&dsa, interruptMask);
267 }
268 
HvCallPci_unmaskInterrupts(u16 busNumberParm,u8 subBusParm,u8 deviceIdParm,u64 interruptMask)269 static inline u64 HvCallPci_unmaskInterrupts(u16 busNumberParm, u8 subBusParm,
270 		u8 deviceIdParm, u64 interruptMask)
271 {
272 	struct HvCallPci_DsaAddr dsa;
273 
274 	*((u64*)&dsa) = 0;
275 
276 	dsa.busNumber = busNumberParm;
277 	dsa.subBusNumber = subBusParm;
278 	dsa.deviceId = deviceIdParm;
279 
280 	return HvCall2(HvCallPciUnmaskInterrupts, *(u64*)&dsa, interruptMask);
281 }
282 
HvCallPci_getBusUnitInfo(u16 busNumberParm,u8 subBusParm,u8 deviceIdParm,u64 parms,u32 sizeofParms)283 static inline u64 HvCallPci_getBusUnitInfo(u16 busNumberParm, u8 subBusParm,
284 		u8 deviceIdParm, u64 parms, u32 sizeofParms)
285 {
286 	struct HvCallPci_DsaAddr dsa;
287 
288 	*((u64*)&dsa) = 0;
289 
290 	dsa.busNumber = busNumberParm;
291 	dsa.subBusNumber = subBusParm;
292 	dsa.deviceId = deviceIdParm;
293 
294 	return HvCall3(HvCallPciGetBusUnitInfo, *(u64*)&dsa, parms,
295 			sizeofParms);
296 }
297 
HvCallPci_getBusVpd(u16 busNumParm,u64 destParm,u16 sizeParm)298 static inline int HvCallPci_getBusVpd(u16 busNumParm, u64 destParm,
299 		u16 sizeParm)
300 {
301 	u64 xRc = HvCall4(HvCallPciGetCardVpd, busNumParm, destParm,
302 			sizeParm, HvCallPci_BusVpd);
303 	if (xRc == -1)
304 		return -1;
305 	else
306 		return xRc & 0xFFFF;
307 }
308 
309 #endif /* _PLATFORMS_ISERIES_CALL_PCI_H */
310