1 /*++ 2 3 Copyright (c) 2005 - 2006, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 PciCommand.c 15 16 Abstract: 17 18 PCI Bus Driver 19 20 Revision History 21 22 --*/ 23 24 #include "PciBus.h" 25 26 27 EFI_STATUS 28 PciReadCommandRegister ( 29 IN PCI_IO_DEVICE *PciIoDevice, 30 OUT UINT16 *Command 31 ) 32 /*++ 33 34 Routine Description: 35 36 Arguments: 37 38 Returns: 39 40 None 41 42 --*/ 43 { 44 45 EFI_PCI_IO_PROTOCOL *PciIo; 46 47 *Command = 0; 48 PciIo = &PciIoDevice->PciIo; 49 50 return PciIo->Pci.Read ( 51 PciIo, 52 EfiPciIoWidthUint16, 53 PCI_COMMAND_OFFSET, 54 1, 55 Command 56 ); 57 } 58 59 EFI_STATUS 60 PciSetCommandRegister ( 61 IN PCI_IO_DEVICE *PciIoDevice, 62 IN UINT16 Command 63 ) 64 /*++ 65 66 Routine Description: 67 68 Arguments: 69 70 Returns: 71 72 None 73 74 --*/ 75 { 76 UINT16 Temp; 77 EFI_PCI_IO_PROTOCOL *PciIo; 78 79 Temp = Command; 80 PciIo = &PciIoDevice->PciIo; 81 82 return PciIo->Pci.Write ( 83 PciIo, 84 EfiPciIoWidthUint16, 85 PCI_COMMAND_OFFSET, 86 1, 87 &Temp 88 ); 89 90 } 91 92 93 EFI_STATUS 94 PciEnableCommandRegister ( 95 IN PCI_IO_DEVICE *PciIoDevice, 96 IN UINT16 Command 97 ) 98 /*++ 99 100 Routine Description: 101 102 Arguments: 103 104 Returns: 105 106 None 107 108 --*/ 109 { 110 UINT16 OldCommand; 111 EFI_PCI_IO_PROTOCOL *PciIo; 112 113 OldCommand = 0; 114 PciIo = &PciIoDevice->PciIo; 115 116 PciIo->Pci.Read ( 117 PciIo, 118 EfiPciIoWidthUint16, 119 PCI_COMMAND_OFFSET, 120 1, 121 &OldCommand 122 ); 123 124 OldCommand = (UINT16) (OldCommand | Command); 125 126 return PciIo->Pci.Write ( 127 PciIo, 128 EfiPciIoWidthUint16, 129 PCI_COMMAND_OFFSET, 130 1, 131 &OldCommand 132 ); 133 134 } 135 136 137 EFI_STATUS 138 PciDisableCommandRegister ( 139 IN PCI_IO_DEVICE *PciIoDevice, 140 IN UINT16 Command 141 ) 142 /*++ 143 144 Routine Description: 145 146 Arguments: 147 148 Returns: 149 150 None 151 152 --*/ 153 { 154 UINT16 OldCommand; 155 EFI_PCI_IO_PROTOCOL *PciIo; 156 157 OldCommand = 0; 158 PciIo = &PciIoDevice->PciIo; 159 160 PciIo->Pci.Read ( 161 PciIo, 162 EfiPciIoWidthUint16, 163 PCI_COMMAND_OFFSET, 164 1, 165 &OldCommand 166 ); 167 168 OldCommand = (UINT16) (OldCommand & ~(Command)); 169 170 return PciIo->Pci.Write ( 171 PciIo, 172 EfiPciIoWidthUint16, 173 PCI_COMMAND_OFFSET, 174 1, 175 &OldCommand 176 ); 177 178 } 179 180 181 182 EFI_STATUS 183 PciSetBridgeControlRegister ( 184 IN PCI_IO_DEVICE *PciIoDevice, 185 IN UINT16 Command 186 ) 187 /*++ 188 189 Routine Description: 190 191 Arguments: 192 193 Returns: 194 195 None 196 197 --*/ 198 { 199 UINT16 Temp; 200 EFI_PCI_IO_PROTOCOL *PciIo; 201 202 Temp = Command; 203 PciIo = &PciIoDevice->PciIo; 204 205 return PciIo->Pci.Write ( 206 PciIo, 207 EfiPciIoWidthUint16, 208 PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 209 1, 210 &Temp 211 ); 212 213 } 214 215 216 EFI_STATUS 217 PciEnableBridgeControlRegister ( 218 IN PCI_IO_DEVICE *PciIoDevice, 219 IN UINT16 Command 220 ) 221 /*++ 222 223 Routine Description: 224 225 Arguments: 226 227 Returns: 228 229 None 230 231 --*/ 232 { 233 UINT16 OldCommand; 234 EFI_PCI_IO_PROTOCOL *PciIo; 235 236 OldCommand = 0; 237 PciIo = &PciIoDevice->PciIo; 238 239 PciIo->Pci.Read ( 240 PciIo, 241 EfiPciIoWidthUint16, 242 PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 243 1, 244 &OldCommand 245 ); 246 247 OldCommand = (UINT16) (OldCommand | Command); 248 249 return PciIo->Pci.Write ( 250 PciIo, 251 EfiPciIoWidthUint16, 252 PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 253 1, 254 &OldCommand 255 ); 256 257 } 258 259 EFI_STATUS 260 PciDisableBridgeControlRegister ( 261 IN PCI_IO_DEVICE *PciIoDevice, 262 IN UINT16 Command 263 ) 264 /*++ 265 266 Routine Description: 267 268 Arguments: 269 270 Returns: 271 272 None 273 274 --*/ 275 { 276 UINT16 OldCommand; 277 EFI_PCI_IO_PROTOCOL *PciIo; 278 279 OldCommand = 0; 280 PciIo = &PciIoDevice->PciIo; 281 282 PciIo->Pci.Read ( 283 PciIo, 284 EfiPciIoWidthUint16, 285 PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 286 1, 287 &OldCommand 288 ); 289 290 OldCommand = (UINT16) (OldCommand & ~(Command)); 291 292 return PciIo->Pci.Write ( 293 PciIo, 294 EfiPciIoWidthUint16, 295 PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 296 1, 297 &OldCommand 298 ); 299 300 } 301 302 303 304 EFI_STATUS 305 PciReadBridgeControlRegister ( 306 IN PCI_IO_DEVICE *PciIoDevice, 307 OUT UINT16 *Command 308 ) 309 /*++ 310 311 Routine Description: 312 313 Arguments: 314 315 Returns: 316 317 None 318 319 --*/ 320 { 321 322 EFI_PCI_IO_PROTOCOL *PciIo; 323 324 *Command = 0; 325 PciIo = &PciIoDevice->PciIo; 326 327 return PciIo->Pci.Read ( 328 PciIo, 329 EfiPciIoWidthUint16, 330 PCI_BRIDGE_CONTROL_REGISTER_OFFSET, 331 1, 332 Command 333 ); 334 335 } 336 337 BOOLEAN 338 PciCapabilitySupport ( 339 IN PCI_IO_DEVICE *PciIoDevice 340 ) 341 /*++ 342 343 Routine Description: 344 345 Arguments: 346 347 Returns: 348 349 None 350 351 --*/ 352 // TODO: PciIoDevice - add argument and description to function comment 353 { 354 355 if (PciIoDevice->Pci.Hdr.Status & EFI_PCI_STATUS_CAPABILITY) { 356 return TRUE; 357 } 358 359 return FALSE; 360 } 361 362 EFI_STATUS 363 LocateCapabilityRegBlock ( 364 IN PCI_IO_DEVICE *PciIoDevice, 365 IN UINT8 CapId, 366 IN OUT UINT8 *Offset, 367 OUT UINT8 *NextRegBlock OPTIONAL 368 ) 369 /*++ 370 371 Routine Description: 372 373 Locate Capability register. 374 375 Arguments: 376 377 PciIoDevice - A pointer to the PCI_IO_DEVICE. 378 CapId - The capability ID. 379 Offset - A pointer to the offset. 380 As input: the default offset; 381 As output: the offset of the found block. 382 NextRegBlock - An optional pointer to return the value of next block. 383 384 Returns: 385 386 EFI_UNSUPPORTED - The Pci Io device is not supported. 387 EFI_NOT_FOUND - The Pci Io device cannot be found. 388 EFI_SUCCESS - The Pci Io device is successfully located. 389 390 --*/ 391 { 392 UINT8 CapabilityPtr; 393 UINT16 CapabilityEntry; 394 UINT8 CapabilityID; 395 396 // 397 // To check the capability of this device supports 398 // 399 if (!PciCapabilitySupport (PciIoDevice)) { 400 return EFI_UNSUPPORTED; 401 } 402 403 if (*Offset != 0) { 404 CapabilityPtr = *Offset; 405 } else { 406 407 CapabilityPtr = 0; 408 if (IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) { 409 410 PciIoDevice->PciIo.Pci.Read ( 411 &PciIoDevice->PciIo, 412 EfiPciIoWidthUint8, 413 EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR, 414 1, 415 &CapabilityPtr 416 ); 417 } else { 418 419 PciIoDevice->PciIo.Pci.Read ( 420 &PciIoDevice->PciIo, 421 EfiPciIoWidthUint8, 422 PCI_CAPBILITY_POINTER_OFFSET, 423 1, 424 &CapabilityPtr 425 ); 426 } 427 } 428 429 while ((CapabilityPtr >= 0x40) && ((CapabilityPtr & 0x03) == 0x00)) { 430 PciIoDevice->PciIo.Pci.Read ( 431 &PciIoDevice->PciIo, 432 EfiPciIoWidthUint16, 433 CapabilityPtr, 434 1, 435 &CapabilityEntry 436 ); 437 438 CapabilityID = (UINT8) CapabilityEntry; 439 440 if (CapabilityID == CapId) { 441 *Offset = CapabilityPtr; 442 if (NextRegBlock != NULL) { 443 *NextRegBlock = (UINT8) (CapabilityEntry >> 8); 444 } 445 446 return EFI_SUCCESS; 447 } 448 449 CapabilityPtr = (UINT8) (CapabilityEntry >> 8); 450 } 451 452 return EFI_NOT_FOUND; 453 } 454