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 */ 35struct 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 43union HvDsaMap { 44 u64 DsaAddr; 45 struct HvCallPci_DsaAddr Dsa; 46}; 47 48struct HvCallPci_LoadReturn { 49 u64 rc; 50 u64 value; 51}; 52 53enum 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 63struct HvCallPci_DeviceInfo { 64 u32 deviceType; /* See DeviceType enum for values */ 65}; 66 67struct HvCallPci_BusUnitInfo { 68 u32 sizeReturned; /* length of data returned */ 69 u32 deviceType; /* see DeviceType enum for values */ 70}; 71 72struct 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 */ 86enum {HvCallPci_MaxBusUnitInfoSize = 128}; 87 88struct 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 99enum 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 129static 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 148static 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 167static 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 181static 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 198static 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 213static 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 227static 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 241static 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 255static 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 269static 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 283static 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 298static 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