81 if (!Config->Exists ||
82 (FieldSize > Config->Length) ||
83 (FieldOffset > Config->Length - FieldSize))
85 return EFI_INVALID_PARAMETER;
91 Width = EfiPciIoWidthUint8;
95 Width = EfiPciIoWidthUint16;
105 Width = EfiPciIoWidthUint32;
109 return EFI_INVALID_PARAMETER;
112 BarType = (Config->BarType == Virtio10BarTypeMem) ? &PciIo->Mem : &PciIo->Io;
113 Access = Write ? BarType->
Write : BarType->
Read;
119 Config->Offset + FieldOffset,
150 OUT VIRTIO_1_0_BAR_TYPE *BarType
156 Status = PciIo->GetBarAttributes (PciIo, BarIndex,
NULL, &Resources);
157 if (EFI_ERROR (Status)) {
161 Status = EFI_UNSUPPORTED;
163 if (*(UINT8 *)Resources == ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR) {
166 Descriptor = Resources;
167 switch (Descriptor->ResType) {
168 case ACPI_ADDRESS_SPACE_TYPE_MEM:
169 *BarType = Virtio10BarTypeMem;
173 case ACPI_ADDRESS_SPACE_TYPE_IO:
174 *BarType = Virtio10BarTypeIo;
214 UINT16 VendorInstance;
218 if (EFI_ERROR (Status)) {
223 if (EFI_ERROR (Status)) {
224 goto UninitPciDevice;
227 for (VendorInstance = 0;
232 EFI_PCI_CAPABILITY_ID_VENDOR,
253 if (EFI_ERROR (Status)) {
257 if (CapLen <
sizeof VirtIoCap) {
267 Status =
PciCapRead (PciDevice, VendorCap, 0, &VirtIoCap,
sizeof VirtIoCap);
268 if (EFI_ERROR (Status)) {
272 switch (VirtIoCap.ConfigType) {
273 case VIRTIO_PCI_CAP_COMMON_CFG:
274 ParsedConfig = &Device->CommonConfig;
276 case VIRTIO_PCI_CAP_NOTIFY_CFG:
277 ParsedConfig = &Device->NotifyConfig;
279 case VIRTIO_PCI_CAP_DEVICE_CFG:
280 ParsedConfig = &Device->SpecificConfig;
292 Status =
GetBarType (Device->PciIo, VirtIoCap.Bar, &ParsedConfig->BarType);
293 if (EFI_ERROR (Status)) {
297 ParsedConfig->Bar = VirtIoCap.Bar;
298 ParsedConfig->Offset = VirtIoCap.Offset;
299 ParsedConfig->Length = VirtIoCap.Length;
301 if (VirtIoCap.ConfigType == VIRTIO_PCI_CAP_NOTIFY_CFG) {
306 if (CapLen < sizeof VirtIoCap + sizeof Device->NotifyOffsetMultiplier) {
317 &Device->NotifyOffsetMultiplier,
318 sizeof Device->NotifyOffsetMultiplier
320 if (EFI_ERROR (Status)) {
328 ParsedConfig->Exists =
TRUE;
360 IN OUT UINT64 *Attributes
363 if (Config->Exists) {
364 *Attributes |= (Config->BarType == Virtio10BarTypeMem) ?
377Virtio10GetDeviceFeatures (
379 OUT UINT64 *DeviceFeatures
384 UINT32 Features32[2];
386 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
388 for (Selector = 0; Selector < 2; ++Selector) {
402 if (EFI_ERROR (Status)) {
414 sizeof Features32[Selector],
415 &Features32[Selector]
417 if (EFI_ERROR (Status)) {
422 *DeviceFeatures =
LShiftU64 (Features32[1], 32) | Features32[0];
429Virtio10SetGuestFeatures (
436 UINT32 Features32[2];
438 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
440 Features32[0] = (UINT32)Features;
441 Features32[1] = (UINT32)
RShiftU64 (Features, 32);
443 for (Selector = 0; Selector < 2; ++Selector) {
457 if (EFI_ERROR (Status)) {
469 sizeof Features32[Selector],
470 &Features32[Selector]
472 if (EFI_ERROR (Status)) {
483Virtio10SetQueueAddress (
486 IN UINT64 RingBaseShift
494 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
496 Address = (
UINTN)Ring->Desc;
497 Address += RingBaseShift;
506 if (EFI_ERROR (Status)) {
510 Address = (
UINTN)Ring->Avail.Flags;
511 Address += RingBaseShift;
520 if (EFI_ERROR (Status)) {
524 Address = (
UINTN)Ring->Used.Flags;
525 Address += RingBaseShift;
534 if (EFI_ERROR (Status)) {
561 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
577Virtio10SetQueueNotify (
584 UINT16 SavedQueueSelect;
587 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
600 sizeof SavedQueueSelect,
603 if (EFI_ERROR (Status)) {
618 if (EFI_ERROR (Status)) {
633 if (EFI_ERROR (Status)) {
645 sizeof SavedQueueSelect,
648 if (EFI_ERROR (Status)) {
659 NotifyOffset * Dev->NotifyOffsetMultiplier,
669Virtio10SetQueueAlign (
674 return (Alignment == EFI_PAGE_SIZE) ?
EFI_SUCCESS : EFI_UNSUPPORTED;
685 return (PageSize == EFI_PAGE_SIZE) ?
EFI_SUCCESS : EFI_UNSUPPORTED;
691Virtio10GetQueueNumMax (
693 OUT UINT16 *QueueNumMax
699 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
729 Status = Virtio10GetQueueNumMax (This, &CurrentSize);
730 if (EFI_ERROR (Status)) {
734 return (CurrentSize == QueueSize) ?
EFI_SUCCESS : EFI_UNSUPPORTED;
740Virtio10GetDeviceStatus (
742 OUT UINT8 *DeviceStatus
748 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
755 sizeof *DeviceStatus,
764Virtio10SetDeviceStatus (
766 IN UINT8 DeviceStatus
772 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
798 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
802 &Dev->SpecificConfig,
825 if (FieldSize != BufferSize) {
826 return EFI_INVALID_PARAMETER;
829 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
833 &Dev->SpecificConfig,
845Virtio10AllocateSharedPages (
848 IN OUT VOID **HostAddress
854 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
856 Status = Dev->PciIo->AllocateBuffer (
862 EFI_PCI_ATTRIBUTE_MEMORY_CACHED
870Virtio10FreeSharedPages (
878 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
880 Dev->PciIo->FreeBuffer (
890Virtio10MapSharedBuffer (
892 IN VIRTIO_MAP_OPERATION Operation,
893 IN VOID *HostAddress,
903 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
909 case VirtioOperationBusMasterRead:
912 case VirtioOperationBusMasterWrite:
915 case VirtioOperationBusMasterCommonBuffer:
919 return EFI_INVALID_PARAMETER;
922 Status = Dev->PciIo->Map (
936Virtio10UnmapSharedBuffer (
944 Dev = VIRTIO_1_0_FROM_VIRTIO_DEVICE (This);
946 Status = Dev->PciIo->Unmap (
955 VIRTIO_SPEC_REVISION (1, 0, 0),
957 Virtio10GetDeviceFeatures,
958 Virtio10SetGuestFeatures,
959 Virtio10SetQueueAddress,
961 Virtio10SetQueueNotify,
962 Virtio10SetQueueAlign,
964 Virtio10GetQueueNumMax,
966 Virtio10GetDeviceStatus,
967 Virtio10SetDeviceStatus,
970 Virtio10AllocateSharedPages,
971 Virtio10FreeSharedPages,
972 Virtio10MapSharedBuffer,
973 Virtio10UnmapSharedBuffer
983Virtio10BindingSupported (
993 Status =
gBS->OpenProtocol (
995 &gEfiPciIoProtocolGuid,
997 This->DriverBindingHandle,
999 EFI_OPEN_PROTOCOL_BY_DRIVER
1001 if (EFI_ERROR (Status)) {
1005 Status = PciIo->Pci.Read (
1007 EfiPciIoWidthUint32,
1009 sizeof Pci /
sizeof (UINT32),
1012 if (EFI_ERROR (Status)) {
1016 Status = EFI_UNSUPPORTED;
1021 if ((Pci.Hdr.VendorId == VIRTIO_VENDOR_ID) &&
1022 (Pci.Hdr.DeviceId >= 0x1040) &&
1023 (Pci.Hdr.DeviceId <= 0x107F) &&
1024 (Pci.Hdr.RevisionID >= 0x01) &&
1025 (Pci.Device.SubsystemID >= 0x40) &&
1039 if ((Pci.Hdr.DeviceId != 0x1050) || !
IS_PCI_VGA (&Pci)) {
1045 gBS->CloseProtocol (
1047 &gEfiPciIoProtocolGuid,
1048 This->DriverBindingHandle,
1058Virtio10BindingStart (
1067 UINT64 SetAttributes;
1070 if (Device ==
NULL) {
1071 return EFI_OUT_OF_RESOURCES;
1074 Device->Signature = VIRTIO_1_0_SIGNATURE;
1075 CopyMem (&Device->VirtIo, &mVirtIoTemplate,
sizeof mVirtIoTemplate);
1077 Status =
gBS->OpenProtocol (
1079 &gEfiPciIoProtocolGuid,
1080 (VOID **)&Device->PciIo,
1081 This->DriverBindingHandle,
1083 EFI_OPEN_PROTOCOL_BY_DRIVER
1085 if (EFI_ERROR (Status)) {
1089 Status = Device->PciIo->Pci.
Read (
1091 EfiPciIoWidthUint32,
1093 sizeof Pci / sizeof (UINT32),
1096 if (EFI_ERROR (Status)) {
1100 Device->VirtIo.SubSystemDeviceId = Pci.Hdr.DeviceId - 0x1040;
1102 Status = ParseCapabilities (Device);
1103 if (EFI_ERROR (Status)) {
1107 Status = Device->PciIo->Attributes (
1111 &Device->OriginalPciAttributes
1113 if (EFI_ERROR (Status)) {
1122 Status = Device->PciIo->Attributes (
1128 if (EFI_ERROR (Status)) {
1132 Status =
gBS->InstallProtocolInterface (
1134 &gVirtioDeviceProtocolGuid,
1138 if (EFI_ERROR (Status)) {
1139 goto RestorePciAttributes;
1144RestorePciAttributes:
1145 Device->PciIo->Attributes (
1148 Device->OriginalPciAttributes,
1153 gBS->CloseProtocol (
1155 &gEfiPciIoProtocolGuid,
1156 This->DriverBindingHandle,
1169Virtio10BindingStop (
1180 Status =
gBS->OpenProtocol (
1182 &gVirtioDeviceProtocolGuid,
1184 This->DriverBindingHandle,
1186 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1188 if (EFI_ERROR (Status)) {
1192 Device = VIRTIO_1_0_FROM_VIRTIO_DEVICE (VirtIo);
1194 Status =
gBS->UninstallProtocolInterface (
1196 &gVirtioDeviceProtocolGuid,
1199 if (EFI_ERROR (Status)) {
1203 Device->PciIo->Attributes (
1206 Device->OriginalPciAttributes,
1209 gBS->CloseProtocol (
1211 &gEfiPciIoProtocolGuid,
1212 This->DriverBindingHandle,
1221 &Virtio10BindingSupported,
1222 &Virtio10BindingStart,
1223 &Virtio10BindingStop,
1236 {
"eng;en", L
"Virtio 1.0 PCI Driver" },
1246Virtio10GetDriverName (
1249 OUT CHAR16 **DriverName
1254 This->SupportedLanguages,
1257 (BOOLEAN)(This == &mComponentName)
1264Virtio10GetDeviceName (
1269 OUT CHAR16 **ControllerName
1272 return EFI_UNSUPPORTED;
1277 &Virtio10GetDriverName,
1278 &Virtio10GetDeviceName,
PACKED struct @100 EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_DRIVER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN CHAR8 *Language, OUT CHAR16 **DriverName)
EFI_STATUS(EFIAPI * EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)(IN EFI_COMPONENT_NAME2_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define OFFSET_OF(TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
EFI_PCI_IO_PROTOCOL_WIDTH
#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
Clear for PCI controllers that can not genrate a DAC.
@ EfiPciIoAttributeOperationGet
@ EfiPciIoAttributeOperationEnable
@ EfiPciIoAttributeOperationSet
#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
Enable the DMA bit in the PCI Config Header.
EFI_PCI_IO_PROTOCOL_OPERATION
@ EfiPciIoOperationBusMasterWrite
@ EfiPciIoOperationBusMasterRead
@ EfiPciIoOperationBusMasterCommonBuffer
#define EFI_PCI_IO_ATTRIBUTE_MEMORY
Enable the Memory decode bit in the PCI Config Header.
#define EFI_PCI_IO_ATTRIBUTE_IO
Enable the I/O decode bit in the PCI Config Header.
EFI_STATUS(EFIAPI * EFI_PCI_IO_PROTOCOL_IO_MEM)(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT8 BarIndex, IN UINT64 Offset, IN UINTN Count, IN OUT VOID *Buffer)
#define EFI_PCI_STATUS_CAPABILITY
0x0010
VOID EFIAPI PciCapListUninit(IN PCI_CAP_LIST *CapList)
RETURN_STATUS EFIAPI PciCapListInit(IN PCI_CAP_DEV *PciDevice, OUT PCI_CAP_LIST **CapList)
RETURN_STATUS EFIAPI PciCapRead(IN PCI_CAP_DEV *PciDevice, IN PCI_CAP *Cap, IN UINT16 SourceOffsetInCap, OUT VOID *DestinationBuffer, IN UINT16 Size)
RETURN_STATUS EFIAPI PciCapListFindCap(IN PCI_CAP_LIST *CapList, IN PCI_CAP_DOMAIN Domain, IN UINT16 CapId, IN UINT16 Instance, OUT PCI_CAP **Cap OPTIONAL)
VOID EFIAPI PciCapPciIoDeviceUninit(IN PCI_CAP_DEV *PciDevice)
EFI_STATUS EFIAPI PciCapPciIoDeviceInit(IN EFI_PCI_IO_PROTOCOL *PciIo, OUT PCI_CAP_DEV **PciDevice)
UINT64 EFI_PHYSICAL_ADDRESS
EFI_STATUS EFIAPI LookupUnicodeString2(IN CONST CHAR8 *Language, IN CONST CHAR8 *SupportedLanguages, IN CONST EFI_UNICODE_STRING_TABLE *UnicodeStringTable, OUT CHAR16 **UnicodeString, IN BOOLEAN Iso639Language)
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)
STATIC VOID UpdateAttributes(IN VIRTIO_1_0_CONFIG *Config, IN OUT UINT64 *Attributes)
STATIC EFI_STATUS Virtio10Transfer(IN EFI_PCI_IO_PROTOCOL *PciIo, IN VIRTIO_1_0_CONFIG *Config, IN BOOLEAN Write, IN UINTN FieldOffset, IN UINTN FieldSize, IN OUT VOID *Buffer)
STATIC EFI_STATUS GetBarType(IN EFI_PCI_IO_PROTOCOL *PciIo, IN UINT8 BarIndex, OUT VIRTIO_1_0_BAR_TYPE *BarType)
EFI_PCI_IO_PROTOCOL_IO_MEM Write
EFI_PCI_IO_PROTOCOL_IO_MEM Read
EFI_PCI_IO_PROTOCOL_CONFIG Read