TianoCore EDK2 master
Loading...
Searching...
No Matches
UfsPciHcDxe.c
Go to the documentation of this file.
1
10#include "UfsPciHcDxe.h"
11
12//
13// NVM Express Driver Binding Protocol Instance
14//
15EFI_DRIVER_BINDING_PROTOCOL gUfsHcDriverBinding = {
19 0x10,
20 NULL,
21 NULL
22};
23
24//
25// Template for Ufs host controller private data.
26//
27UFS_HOST_CONTROLLER_PRIVATE_DATA gUfsHcTemplate = {
28 UFS_HC_PRIVATE_DATA_SIGNATURE, // Signature
29 { // UfsHcProtocol
38 },
39 NULL, // PciIo
40 0, // BarIndex
41 0 // PciAttributes
42};
43
54EFIAPI
57 OUT UINTN *MmioBar
58 )
59{
62 EFI_STATUS Status;
63 UINT8 BarIndex;
65
66 if ((This == NULL) || (MmioBar == NULL)) {
67 return EFI_INVALID_PARAMETER;
68 }
69
70 BarDesc = NULL;
71 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
72 PciIo = Private->PciIo;
73 BarIndex = Private->BarIndex;
74
75 Status = PciIo->GetBarAttributes (
76 PciIo,
77 BarIndex,
78 NULL,
79 (VOID **)&BarDesc
80 );
81 if (EFI_ERROR (Status)) {
82 return Status;
83 }
84
85 *MmioBar = (UINTN)BarDesc->AddrRangeMin;
86
87 FreePool (BarDesc);
88
89 return Status;
90}
91
112EFIAPI
116 IN VOID *HostAddress,
117 IN OUT UINTN *NumberOfBytes,
118 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
119 OUT VOID **Mapping
120 )
121{
123 EFI_PCI_IO_PROTOCOL *PciIo;
124 EFI_STATUS Status;
125
126 if ((This == NULL) || (HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) || (Mapping == NULL)) {
127 return EFI_INVALID_PARAMETER;
128 }
129
130 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
131 PciIo = Private->PciIo;
132
133 Status = PciIo->Map (PciIo, (EFI_PCI_IO_PROTOCOL_OPERATION)Operation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
134 return Status;
135}
136
148EFIAPI
151 IN VOID *Mapping
152 )
153{
155 EFI_PCI_IO_PROTOCOL *PciIo;
156 EFI_STATUS Status;
157
158 if ((This == NULL) || (Mapping == NULL)) {
159 return EFI_INVALID_PARAMETER;
160 }
161
162 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
163 PciIo = Private->PciIo;
164
165 Status = PciIo->Unmap (PciIo, Mapping);
166 return Status;
167}
168
190EFIAPI
194 IN EFI_MEMORY_TYPE MemoryType,
195 IN UINTN Pages,
196 OUT VOID **HostAddress,
197 IN UINT64 Attributes
198 )
199{
201 EFI_PCI_IO_PROTOCOL *PciIo;
202 EFI_STATUS Status;
203
204 if ((This == NULL) || (HostAddress == NULL)) {
205 return EFI_INVALID_PARAMETER;
206 }
207
208 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
209 PciIo = Private->PciIo;
210
211 Status = PciIo->AllocateBuffer (PciIo, Type, MemoryType, Pages, HostAddress, Attributes);
212 return Status;
213}
214
228EFIAPI
231 IN UINTN Pages,
232 IN VOID *HostAddress
233 )
234{
236 EFI_PCI_IO_PROTOCOL *PciIo;
237 EFI_STATUS Status;
238
239 if ((This == NULL) || (HostAddress == NULL)) {
240 return EFI_INVALID_PARAMETER;
241 }
242
243 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
244 PciIo = Private->PciIo;
245
246 Status = PciIo->FreeBuffer (PciIo, Pages, HostAddress);
247 return Status;
248}
249
262EFIAPI
265 )
266{
268 EFI_PCI_IO_PROTOCOL *PciIo;
269 EFI_STATUS Status;
270
271 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
272 PciIo = Private->PciIo;
273
274 Status = PciIo->Flush (PciIo);
275 return Status;
276}
277
297EFIAPI
300 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width,
301 IN UINT64 Offset,
302 IN UINTN Count,
303 IN OUT VOID *Buffer
304 )
305{
307 EFI_PCI_IO_PROTOCOL *PciIo;
308 EFI_STATUS Status;
309 UINT8 BarIndex;
310
311 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
312 PciIo = Private->PciIo;
313 BarIndex = Private->BarIndex;
314
315 Status = PciIo->Mem.Read (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer);
316
317 return Status;
318}
319
339EFIAPI
342 IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width,
343 IN UINT64 Offset,
344 IN UINTN Count,
345 IN OUT VOID *Buffer
346 )
347{
349 EFI_PCI_IO_PROTOCOL *PciIo;
350 EFI_STATUS Status;
351 UINT8 BarIndex;
352
353 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This);
354 PciIo = Private->PciIo;
355 BarIndex = Private->BarIndex;
356
357 Status = PciIo->Mem.Write (PciIo, (EFI_PCI_IO_PROTOCOL_WIDTH)Width, BarIndex, Offset, Count, Buffer);
358
359 return Status;
360}
361
405EFIAPI
408 IN EFI_HANDLE Controller,
409 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
410 )
411{
412 EFI_STATUS Status;
413 BOOLEAN UfsHcFound;
414 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
415 EFI_PCI_IO_PROTOCOL *PciIo;
416 PCI_TYPE00 PciData;
417
418 PciIo = NULL;
419 ParentDevicePath = NULL;
420 UfsHcFound = FALSE;
421
422 //
423 // UfsHcDxe is a device driver, and should ingore the
424 // "RemainingDevicePath" according to EFI spec
425 //
426 Status = gBS->OpenProtocol (
427 Controller,
428 &gEfiDevicePathProtocolGuid,
429 (VOID *)&ParentDevicePath,
430 This->DriverBindingHandle,
431 Controller,
432 EFI_OPEN_PROTOCOL_BY_DRIVER
433 );
434 if (EFI_ERROR (Status)) {
435 //
436 // EFI_ALREADY_STARTED is also an error
437 //
438 return Status;
439 }
440
441 //
442 // Close the protocol because we don't use it here
443 //
444 gBS->CloseProtocol (
445 Controller,
446 &gEfiDevicePathProtocolGuid,
447 This->DriverBindingHandle,
448 Controller
449 );
450
451 //
452 // Now test the EfiPciIoProtocol
453 //
454 Status = gBS->OpenProtocol (
455 Controller,
456 &gEfiPciIoProtocolGuid,
457 (VOID **)&PciIo,
458 This->DriverBindingHandle,
459 Controller,
460 EFI_OPEN_PROTOCOL_BY_DRIVER
461 );
462 if (EFI_ERROR (Status)) {
463 return Status;
464 }
465
466 //
467 // Now further check the PCI header: Base class (offset 0x0B) and
468 // Sub Class (offset 0x0A). This controller should be an UFS controller
469 //
470 Status = PciIo->Pci.Read (
471 PciIo,
472 EfiPciIoWidthUint8,
473 0,
474 sizeof (PciData),
475 &PciData
476 );
477 if (EFI_ERROR (Status)) {
478 gBS->CloseProtocol (
479 Controller,
480 &gEfiPciIoProtocolGuid,
481 This->DriverBindingHandle,
482 Controller
483 );
484 return EFI_UNSUPPORTED;
485 }
486
487 //
488 // Since we already got the PciData, we can close protocol to avoid to carry it on for multiple exit points.
489 //
490 gBS->CloseProtocol (
491 Controller,
492 &gEfiPciIoProtocolGuid,
493 This->DriverBindingHandle,
494 Controller
495 );
496
497 //
498 // Examine UFS Host Controller PCI Configuration table fields
499 //
500 if (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) {
501 if (PciData.Hdr.ClassCode[1] == 0x09 ) {
502 // UFS Controller Subclass
503 UfsHcFound = TRUE;
504 }
505 }
506
507 if (!UfsHcFound) {
508 return EFI_UNSUPPORTED;
509 }
510
511 return Status;
512}
513
550EFIAPI
553 IN EFI_HANDLE Controller,
554 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
555 )
556{
557 EFI_STATUS Status;
558 EFI_PCI_IO_PROTOCOL *PciIo;
560 UINT64 Supports;
561 UINT8 BarIndex;
563
564 PciIo = NULL;
565 Private = NULL;
566 Supports = 0;
567 BarDesc = NULL;
568
569 //
570 // Now test and open the EfiPciIoProtocol
571 //
572 Status = gBS->OpenProtocol (
573 Controller,
574 &gEfiPciIoProtocolGuid,
575 (VOID **)&PciIo,
576 This->DriverBindingHandle,
577 Controller,
578 EFI_OPEN_PROTOCOL_BY_DRIVER
579 );
580 //
581 // Status == 0 - A normal execution flow, SUCCESS and the program proceeds.
582 // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
583 // that the protocol has been opened and should be treated as a
584 // normal condition and the program proceeds. The Protocol will not
585 // opened 'again' by this call.
586 // Status != ALREADY_STARTED - Error status, terminate program execution
587 //
588 if (EFI_ERROR (Status)) {
589 //
590 // EFI_ALREADY_STARTED is also an error
591 //
592 return Status;
593 }
594
595 Private = AllocateCopyPool (sizeof (UFS_HOST_CONTROLLER_PRIVATE_DATA), &gUfsHcTemplate);
596 if (Private == NULL) {
597 Status = EFI_OUT_OF_RESOURCES;
598 goto Done;
599 }
600
601 Private->PciIo = PciIo;
602
603 for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {
604 Status = PciIo->GetBarAttributes (
605 PciIo,
606 BarIndex,
607 NULL,
608 (VOID **)&BarDesc
609 );
610 if (Status == EFI_UNSUPPORTED) {
611 continue;
612 } else if (EFI_ERROR (Status)) {
613 goto Done;
614 }
615
616 if (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
617 Private->BarIndex = BarIndex;
618 FreePool (BarDesc);
619 break;
620 }
621
622 FreePool (BarDesc);
623 }
624
625 Status = PciIo->Attributes (
626 PciIo,
628 0,
629 &Private->PciAttributes
630 );
631
632 if (EFI_ERROR (Status)) {
633 goto Done;
634 }
635
636 Status = PciIo->Attributes (
637 PciIo,
639 0,
640 &Supports
641 );
642
643 if (!EFI_ERROR (Status)) {
644 Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
645 Status = PciIo->Attributes (
646 PciIo,
648 Supports,
649 NULL
650 );
651 } else {
652 goto Done;
653 }
654
658 Status = gBS->InstallProtocolInterface (
659 &Controller,
662 (VOID *)&(Private->UfsHc)
663 );
664
665Done:
666 if (EFI_ERROR (Status)) {
667 if ((Private != NULL) && (Private->PciAttributes != 0)) {
668 //
669 // Restore original PCI attributes
670 //
671 PciIo->Attributes (
672 PciIo,
674 Private->PciAttributes,
675 NULL
676 );
677 }
678
679 gBS->CloseProtocol (
680 Controller,
681 &gEfiPciIoProtocolGuid,
682 This->DriverBindingHandle,
683 Controller
684 );
685 if (Private != NULL) {
686 FreePool (Private);
687 }
688 }
689
690 return Status;
691}
692
720EFIAPI
723 IN EFI_HANDLE Controller,
724 IN UINTN NumberOfChildren,
725 IN EFI_HANDLE *ChildHandleBuffer
726 )
727{
728 EFI_STATUS Status;
731
735 Status = gBS->OpenProtocol (
736 Controller,
738 (VOID **)&UfsHc,
739 This->DriverBindingHandle,
740 Controller,
741 EFI_OPEN_PROTOCOL_GET_PROTOCOL
742 );
743
744 if (EFI_ERROR (Status)) {
745 return EFI_DEVICE_ERROR;
746 }
747
748 Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (UfsHc);
749
750 Status = gBS->UninstallProtocolInterface (
751 Controller,
753 &(Private->UfsHc)
754 );
755 if (!EFI_ERROR (Status)) {
756 //
757 // Restore original PCI attributes
758 //
759 Status = Private->PciIo->Attributes (
760 Private->PciIo,
762 Private->PciAttributes,
763 NULL
764 );
765 ASSERT_EFI_ERROR (Status);
766
767 //
768 // Close protocols opened by UFS host controller driver
769 //
770 gBS->CloseProtocol (
771 Controller,
772 &gEfiPciIoProtocolGuid,
773 This->DriverBindingHandle,
774 Controller
775 );
776
777 FreePool (Private);
778 }
779
780 return Status;
781}
782
794EFIAPI
796 IN EFI_HANDLE ImageHandle,
797 IN EFI_SYSTEM_TABLE *SystemTable
798 )
799{
800 EFI_STATUS Status;
801
803 ImageHandle,
804 SystemTable,
805 &gUfsHcDriverBinding,
806 ImageHandle,
807 &gUfsHcComponentName,
808 &gUfsHcComponentName2
809 );
810 ASSERT_EFI_ERROR (Status);
811
812 return Status;
813}
UINT64 UINTN
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST 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 OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
EFI_PCI_IO_PROTOCOL_WIDTH
Definition: PciIo.h:28
@ EfiPciIoAttributeOperationGet
Definition: PciIo.h:103
@ EfiPciIoAttributeOperationEnable
Definition: PciIo.h:111
@ EfiPciIoAttributeOperationSet
Definition: PciIo.h:107
@ EfiPciIoAttributeOperationSupported
Definition: PciIo.h:119
EFI_PCI_IO_PROTOCOL_OPERATION
Definition: PciIo.h:77
EFI_GUID gEdkiiUfsHostControllerProtocolGuid
EDKII_UFS_HOST_CONTROLLER_OPERATION
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
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_MEMORY_TYPE
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_ALLOCATE_TYPE
Definition: UefiSpec.h:29
EFI_STATUS EFIAPI UfsHcFlush(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This)
Definition: UfsPciHcDxe.c:263
EFI_STATUS EFIAPI UfsHcMmioRead(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
Definition: UfsPciHcDxe.c:298
EFI_STATUS EFIAPI UfsHcMmioWrite(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL_WIDTH Width, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
Definition: UfsPciHcDxe.c:340
EFI_STATUS EFIAPI UfsHcDriverEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: UfsPciHcDxe.c:795
EFI_STATUS EFIAPI UfsHcGetMmioBar(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, OUT UINTN *MmioBar)
Definition: UfsPciHcDxe.c:55
EFI_STATUS EFIAPI UfsHcDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
Definition: UfsPciHcDxe.c:721
EFI_STATUS EFIAPI UfsHcDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: UfsPciHcDxe.c:551
EFI_STATUS EFIAPI UfsHcAllocateBuffer(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT VOID **HostAddress, IN UINT64 Attributes)
Definition: UfsPciHcDxe.c:191
EFI_STATUS EFIAPI UfsHcMap(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, IN EDKII_UFS_HOST_CONTROLLER_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
Definition: UfsPciHcDxe.c:113
EFI_STATUS EFIAPI UfsHcUnmap(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, IN VOID *Mapping)
Definition: UfsPciHcDxe.c:149
EFI_STATUS EFIAPI UfsHcDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: UfsPciHcDxe.c:406
EFI_STATUS EFIAPI UfsHcFreeBuffer(IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, IN UINTN Pages, IN VOID *HostAddress)
Definition: UfsPciHcDxe.c:229
EFI_PCI_IO_PROTOCOL_IO_MEM Write
Definition: PciIo.h:197
EFI_PCI_IO_PROTOCOL_IO_MEM Read
Definition: PciIo.h:193
EFI_PCI_IO_PROTOCOL_CONFIG Read
Definition: PciIo.h:232