TianoCore EDK2 master
Loading...
Searching...
No Matches
SioBusDxe.c
Go to the documentation of this file.
1
11#include "SioBusDxe.h"
12
13//
14// SioBus Driver Binding Protocol
15//
16EFI_DRIVER_BINDING_PROTOCOL gSioBusDriverBinding = {
20 0x10,
21 NULL,
22 NULL
23};
24
79EFIAPI
82 IN EFI_HANDLE Controller,
83 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
84 )
85{
86 EFI_STATUS Status;
88 PCI_TYPE00 Pci;
89 UINTN SegmentNumber;
90 UINTN BusNumber;
91 UINTN DeviceNumber;
92 UINTN FunctionNumber;
93
94 //
95 // Get PciIo protocol instance
96 //
97 Status = gBS->OpenProtocol (
98 Controller,
99 &gEfiPciIoProtocolGuid,
100 (VOID **)&PciIo,
101 This->DriverBindingHandle,
102 Controller,
103 EFI_OPEN_PROTOCOL_BY_DRIVER
104 );
105 if (EFI_ERROR (Status)) {
106 return Status;
107 }
108
109 Status = PciIo->Pci.Read (
110 PciIo,
111 EfiPciIoWidthUint32,
112 0,
113 sizeof (Pci) / sizeof (UINT32),
114 &Pci
115 );
116
117 if (!EFI_ERROR (Status)) {
118 Status = EFI_UNSUPPORTED;
119 if ((Pci.Hdr.Command & 0x03) == 0x03) {
120 if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
121 //
122 // See if this is a standard PCI to ISA Bridge from the Base Code and
123 // Class Code
124 //
125 if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA) {
126 Status = EFI_SUCCESS;
127 }
128
129 //
130 // See if this is an Intel PCI to ISA bridge in Positive Decode Mode
131 //
132 if ((Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) &&
133 (Pci.Hdr.VendorId == 0x8086))
134 {
135 //
136 // See if this is on Function #0 to avoid false positives on
137 // PCI_CLASS_BRIDGE_OTHER that has the same value as
138 // PCI_CLASS_BRIDGE_ISA_PDECODE
139 //
140 Status = PciIo->GetLocation (
141 PciIo,
142 &SegmentNumber,
143 &BusNumber,
144 &DeviceNumber,
145 &FunctionNumber
146 );
147 if (!EFI_ERROR (Status) && (FunctionNumber == 0)) {
148 Status = EFI_SUCCESS;
149 } else {
150 Status = EFI_UNSUPPORTED;
151 }
152 }
153 }
154 }
155 }
156
157 gBS->CloseProtocol (
158 Controller,
159 &gEfiPciIoProtocolGuid,
160 This->DriverBindingHandle,
161 Controller
162 );
163
164 return Status;
165}
166
214EFIAPI
217 IN EFI_HANDLE Controller,
218 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
219 )
220{
221 EFI_STATUS Status;
222 EFI_PCI_IO_PROTOCOL *PciIo;
223 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
224 UINT64 Supports;
225 UINT64 OriginalAttributes;
226 UINT64 Attributes;
227 BOOLEAN Enabled;
229 UINT32 ChildDeviceNumber;
230
231 Enabled = FALSE;
232 Supports = 0;
233 OriginalAttributes = 0;
234 Private = NULL;
235
236 //
237 // Open the PCI I/O Protocol Interface
238 //
239 PciIo = NULL;
240 Status = gBS->OpenProtocol (
241 Controller,
242 &gEfiPciIoProtocolGuid,
243 (VOID **)&PciIo,
244 This->DriverBindingHandle,
245 Controller,
246 EFI_OPEN_PROTOCOL_BY_DRIVER
247 );
248 if (EFI_ERROR (Status)) {
249 return Status;
250 }
251
252 //
253 // Open Device Path Protocol
254 //
255 Status = gBS->OpenProtocol (
256 Controller,
257 &gEfiDevicePathProtocolGuid,
258 (VOID **)&ParentDevicePath,
259 This->DriverBindingHandle,
260 Controller,
261 EFI_OPEN_PROTOCOL_BY_DRIVER
262 );
263 if (EFI_ERROR (Status)) {
264 gBS->CloseProtocol (
265 Controller,
266 &gEfiPciIoProtocolGuid,
267 This->DriverBindingHandle,
268 Controller
269 );
270 return Status;
271 }
272
273 //
274 // Get supported PCI attributes
275 //
276 Status = PciIo->Attributes (
277 PciIo,
279 0,
280 &Supports
281 );
282 if (EFI_ERROR (Status)) {
283 goto Done;
284 }
285
286 Supports &= (UINT64)(EFI_PCI_IO_ATTRIBUTE_ISA_IO |
288 if ((Supports == 0) ||
289 (Supports == (EFI_PCI_IO_ATTRIBUTE_ISA_IO |
291 {
292 Status = EFI_UNSUPPORTED;
293 goto Done;
294 }
295
296 Status = PciIo->Attributes (
297 PciIo,
299 0,
300 &OriginalAttributes
301 );
302 if (EFI_ERROR (Status)) {
303 goto Done;
304 }
305
306 Attributes = EFI_PCI_DEVICE_ENABLE |
307 Supports |
309 Status = PciIo->Attributes (
310 PciIo,
312 Attributes,
313 NULL
314 );
315 if (EFI_ERROR (Status)) {
316 goto Done;
317 }
318
319 Enabled = TRUE;
320
321 //
322 // Store the OriginalAttributes for the restore in BindingStop()
323 //
325 if (Private == NULL) {
326 Status = EFI_OUT_OF_RESOURCES;
327 goto Done;
328 }
329
330 Private->PciIo = PciIo;
331 Private->OriginalAttributes = OriginalAttributes;
332
333 Status = gBS->InstallProtocolInterface (
334 &Controller,
335 &gEfiCallerIdGuid,
337 Private
338 );
339 if (EFI_ERROR (Status)) {
340 goto Done;
341 }
342
343 //
344 // Report status code for the start of general controller initialization
345 //
348 (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),
349 ParentDevicePath
350 );
351
352 //
353 // Report status code for the start of enabling devices on the bus
354 //
357 (EFI_IO_BUS_LPC | EFI_IOB_PC_ENABLE),
358 ParentDevicePath
359 );
360
361 //
362 // Create all the children upon the first entrance
363 //
364 ChildDeviceNumber = SioCreateAllChildDevices (
365 This,
366 Controller,
367 PciIo,
368 ParentDevicePath
369 );
370 if (ChildDeviceNumber == 0) {
371 Status = EFI_DEVICE_ERROR;
372 }
373
374Done:
375 if (EFI_ERROR (Status)) {
376 if ((PciIo != NULL) && Enabled) {
377 PciIo->Attributes (
378 PciIo,
380 OriginalAttributes,
381 NULL
382 );
383 }
384
385 gBS->CloseProtocol (
386 Controller,
387 &gEfiDevicePathProtocolGuid,
388 This->DriverBindingHandle,
389 Controller
390 );
391
392 gBS->CloseProtocol (
393 Controller,
394 &gEfiPciIoProtocolGuid,
395 This->DriverBindingHandle,
396 Controller
397 );
398
399 if (Private != NULL) {
400 gBS->UninstallMultipleProtocolInterfaces (
401 Controller,
402 &gEfiCallerIdGuid,
403 Private,
404 NULL
405 );
406 FreePool (Private);
407 }
408
409 return Status;
410 }
411
412 return EFI_SUCCESS;
413}
414
449EFIAPI
452 IN EFI_HANDLE Controller,
453 IN UINTN NumberOfChildren,
454 IN EFI_HANDLE *ChildHandleBuffer
455 )
456{
457 EFI_STATUS Status;
459 UINTN Index;
460 BOOLEAN AllChildrenStopped;
461 EFI_SIO_PROTOCOL *Sio;
462 SIO_DEV *SioDevice;
463 EFI_PCI_IO_PROTOCOL *PciIo;
464
465 if (NumberOfChildren == 0) {
466 //
467 // Restore PCI attributes
468 //
469 Status = gBS->OpenProtocol (
470 Controller,
471 &gEfiCallerIdGuid,
472 (VOID **)&Private,
473 This->DriverBindingHandle,
474 Controller,
475 EFI_OPEN_PROTOCOL_GET_PROTOCOL
476 );
477 if (EFI_ERROR (Status)) {
478 return Status;
479 }
480
481 Status = Private->PciIo->Attributes (
482 Private->PciIo,
484 Private->OriginalAttributes,
485 NULL
486 );
487 if (EFI_ERROR (Status)) {
488 return Status;
489 }
490
491 gBS->UninstallProtocolInterface (
492 Controller,
493 &gEfiCallerIdGuid,
494 Private
495 );
496 FreePool (Private);
497
498 //
499 // Close the bus driver
500 //
501 Status = gBS->CloseProtocol (
502 Controller,
503 &gEfiDevicePathProtocolGuid,
504 This->DriverBindingHandle,
505 Controller
506 );
507 if (EFI_ERROR (Status)) {
508 return Status;
509 }
510
511 Status = gBS->CloseProtocol (
512 Controller,
513 &gEfiPciIoProtocolGuid,
514 This->DriverBindingHandle,
515 Controller
516 );
517 if (EFI_ERROR (Status)) {
518 return Status;
519 }
520
521 return EFI_SUCCESS;
522 }
523
524 //
525 // Stop all the children
526 //
527 AllChildrenStopped = TRUE;
528
529 for (Index = 0; Index < NumberOfChildren; Index++) {
530 Status = gBS->OpenProtocol (
531 ChildHandleBuffer[Index],
532 &gEfiSioProtocolGuid,
533 (VOID **)&Sio,
534 This->DriverBindingHandle,
535 Controller,
536 EFI_OPEN_PROTOCOL_GET_PROTOCOL
537 );
538 if (!EFI_ERROR (Status)) {
539 SioDevice = SIO_DEV_FROM_SIO (Sio);
540
541 //
542 // Close the child handle
543 //
544 Status = gBS->CloseProtocol (
545 Controller,
546 &gEfiPciIoProtocolGuid,
547 This->DriverBindingHandle,
548 ChildHandleBuffer[Index]
549 );
550 Status = gBS->UninstallMultipleProtocolInterfaces (
551 ChildHandleBuffer[Index],
552 &gEfiDevicePathProtocolGuid,
553 SioDevice->DevicePath,
554 &gEfiSioProtocolGuid,
555 &SioDevice->Sio,
556 NULL
557 );
558
559 if (!EFI_ERROR (Status)) {
560 FreePool (SioDevice->DevicePath);
561 FreePool (SioDevice);
562 } else {
563 //
564 // Re-open PCI IO Protocol on behalf of the child device
565 // because of failure of destroying the child device handle
566 //
567 gBS->OpenProtocol (
568 Controller,
569 &gEfiPciIoProtocolGuid,
570 (VOID **)&PciIo,
571 This->DriverBindingHandle,
572 ChildHandleBuffer[Index],
573 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
574 );
575 }
576 }
577
578 if (EFI_ERROR (Status)) {
579 AllChildrenStopped = FALSE;
580 }
581 }
582
583 if (!AllChildrenStopped) {
584 return EFI_DEVICE_ERROR;
585 }
586
587 return EFI_SUCCESS;
588}
589
601EFIAPI
603 IN EFI_HANDLE ImageHandle,
604 IN EFI_SYSTEM_TABLE *SystemTable
605 )
606{
607 //
608 // Install driver model protocol(s).
609 //
611 ImageHandle,
612 SystemTable,
613 &gSioBusDriverBinding,
614 ImageHandle,
615 &gSioBusComponentName,
616 &gSioBusComponentName2
617 );
618}
UINT64 UINTN
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
#define EFI_PCI_IO_ATTRIBUTE_ISA_IO
I/O cycles 0x0100-0x03FF or greater (10 bit decode)
Definition: PciIo.h:50
#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16
I/O cycles 0x0100-0x03FF or greater (16 bit decode)
Definition: PciIo.h:65
@ EfiPciIoAttributeOperationGet
Definition: PciIo.h:103
@ EfiPciIoAttributeOperationEnable
Definition: PciIo.h:111
@ EfiPciIoAttributeOperationSet
Definition: PciIo.h:107
@ EfiPciIoAttributeOperationSupported
Definition: PciIo.h:119
#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
I/O cycles 0x0000-0x00FF (10 bit decode)
Definition: PciIo.h:49
#define EFI_IOB_PC_INIT
Definition: PiStatusCode.h:549
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:43
EFI_STATUS EFIAPI SioBusDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: SioBusDxe.c:450
EFI_STATUS EFIAPI SioBusDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: SioBusDxe.c:80
EFI_STATUS EFIAPI SioBusDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: SioBusDxe.c:215
EFI_STATUS EFIAPI SioBusDxeDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: SioBusDxe.c:602
UINT32 SioCreateAllChildDevices(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_PCI_IO_PROTOCOL *PciIo, IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath)
Definition: SioService.c:376
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232