EFI_STATUS VirtioMmioSetQueueAddress ( VIRTIO_DEVICE_PROTOCOL *This, UINT32 Address ) { VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN, Address); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioSetGuestFeatures ( VIRTIO_DEVICE_PROTOCOL *This, UINT32 Features ) { VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_FEATURES, Features); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioSetQueueSel ( VIRTIO_DEVICE_PROTOCOL *This, UINT16 Sel ) { VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_SEL, Sel); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioSetQueueAlignment ( VIRTIO_DEVICE_PROTOCOL *This, UINT32 Alignment ) { VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_ALIGN, Alignment); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioSetQueueNotify ( VIRTIO_DEVICE_PROTOCOL *This, UINT16 QueueNotify ) { VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_QUEUE_NOTIFY, QueueNotify); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioSetDeviceStatus ( VIRTIO_DEVICE_PROTOCOL *This, UINT8 DeviceStatus ) { VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_STATUS, DeviceStatus); return EFI_SUCCESS; }
EFI_STATUS VirtioMmioUninstallDevice ( IN EFI_HANDLE DeviceHandle ) { VIRTIO_DEVICE_PROTOCOL *VirtioDevice; VIRTIO_MMIO_DEVICE *MmioDevice; EFI_STATUS Status; Status = gBS->OpenProtocol ( DeviceHandle, // candidate device &gVirtioDeviceProtocolGuid, // retrieve the VirtIo iface (VOID **)&VirtioDevice, // target pointer DeviceHandle, // requestor driver identity DeviceHandle, // requesting lookup for dev. EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added ); if (EFI_ERROR (Status)) { return Status; } // // Get the MMIO device from the VirtIo Device instance // MmioDevice = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice); // // Uninstall the protocol interface // Status = gBS->UninstallProtocolInterface (DeviceHandle, &gVirtioDeviceProtocolGuid, &MmioDevice->VirtioDevice ); if (EFI_ERROR (Status)) { return Status; } // // Uninitialize the VirtIo Device // VirtioMmioUninit (MmioDevice); FreePool (MmioDevice); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioGetDeviceStatus ( IN VIRTIO_DEVICE_PROTOCOL *This, OUT UINT8 *DeviceStatus ) { VIRTIO_MMIO_DEVICE *Device; if (DeviceStatus == NULL) { return EFI_INVALID_PARAMETER; } Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); *DeviceStatus = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_STATUS) & 0xFF; return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioGetQueueSize ( IN VIRTIO_DEVICE_PROTOCOL *This, OUT UINT16 *QueueNumMax ) { VIRTIO_MMIO_DEVICE *Device; if (QueueNumMax == NULL) { return EFI_INVALID_PARAMETER; } Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); *QueueNumMax = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_NUM_MAX) & 0xFFFF; return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioGetQueueAddress ( IN VIRTIO_DEVICE_PROTOCOL *This, OUT UINT32 *QueueAddress ) { VIRTIO_MMIO_DEVICE *Device; if (QueueAddress == NULL) { return EFI_INVALID_PARAMETER; } Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); *QueueAddress = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_QUEUE_PFN); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioGetDeviceFeatures ( IN VIRTIO_DEVICE_PROTOCOL *This, OUT UINT32 *DeviceFeatures ) { VIRTIO_MMIO_DEVICE *Device; if (DeviceFeatures == NULL) { return EFI_INVALID_PARAMETER; } Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); *DeviceFeatures = VIRTIO_CFG_READ (Device, VIRTIO_MMIO_OFFSET_HOST_FEATURES); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioSetPageSize ( VIRTIO_DEVICE_PROTOCOL *This, UINT32 PageSize ) { VIRTIO_MMIO_DEVICE *Device; if (PageSize != EFI_PAGE_SIZE) { return EFI_UNSUPPORTED; } Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); VIRTIO_CFG_WRITE (Device, VIRTIO_MMIO_OFFSET_GUEST_PAGE_SIZE, PageSize); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioDeviceRead ( IN VIRTIO_DEVICE_PROTOCOL *This, IN UINTN FieldOffset, IN UINTN FieldSize, IN UINTN BufferSize, OUT VOID *Buffer ) { UINTN SrcBaseAddress; VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); // // Parameter validation // ASSERT (FieldSize == BufferSize); // // Double-check fieldsize // if ((FieldSize != 1) && (FieldSize != 2) && (FieldSize != 4) && (FieldSize != 8)) { return EFI_INVALID_PARAMETER; } // // Compute base address // SrcBaseAddress = Device->BaseAddress + VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset; // // The device-specific memory area of Virtio-MMIO can only be read in // byte reads. This is not currently in the Virtio spec. // MmioReadBuffer8 (SrcBaseAddress, BufferSize, Buffer); return EFI_SUCCESS; }
EFI_STATUS EFIAPI VirtioMmioDeviceWrite ( IN VIRTIO_DEVICE_PROTOCOL *This, IN UINTN FieldOffset, IN UINTN FieldSize, IN UINT64 Value ) { UINTN DstBaseAddress; VIRTIO_MMIO_DEVICE *Device; Device = VIRTIO_MMIO_DEVICE_FROM_VIRTIO_DEVICE (This); // // Double-check fieldsize // if ((FieldSize != 1) && (FieldSize != 2) && (FieldSize != 4) && (FieldSize != 8)) { return EFI_INVALID_PARAMETER; } // // Compute base address // DstBaseAddress = Device->BaseAddress + VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_MMIO + FieldOffset; // // The device-specific memory area of Virtio-MMIO can only be written in // byte accesses. This is not currently in the Virtio spec. // MmioWriteBuffer8 (DstBaseAddress, FieldSize, (UINT8*)&Value); return EFI_SUCCESS; }