123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /** @file
- * Virtio FDT client protocol driver for virtio,mmio DT node
- *
- * Copyright (c) 2014 - 2016, Linaro Ltd. All rights reserved.<BR>
- *
- * SPDX-License-Identifier: BSD-2-Clause-Patent
- *
- **/
- #include <Library/BaseLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/DebugLib.h>
- #include <Library/DevicePathLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/UefiDriverEntryPoint.h>
- #include <Library/VirtioMmioDeviceLib.h>
- #include <Guid/VirtioMmioTransport.h>
- #include <Protocol/FdtClient.h>
- #pragma pack (1)
- typedef struct {
- VENDOR_DEVICE_PATH Vendor;
- UINT64 PhysBase;
- EFI_DEVICE_PATH_PROTOCOL End;
- } VIRTIO_TRANSPORT_DEVICE_PATH;
- #pragma pack ()
- EFI_STATUS
- EFIAPI
- InitializeVirtioFdtDxe (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status, FindNodeStatus;
- FDT_CLIENT_PROTOCOL *FdtClient;
- INT32 Node;
- CONST UINT64 *Reg;
- UINT32 RegSize;
- VIRTIO_TRANSPORT_DEVICE_PATH *DevicePath;
- EFI_HANDLE Handle;
- UINT64 RegBase;
- Status = gBS->LocateProtocol (
- &gFdtClientProtocolGuid,
- NULL,
- (VOID **)&FdtClient
- );
- ASSERT_EFI_ERROR (Status);
- for (FindNodeStatus = FdtClient->FindCompatibleNode (
- FdtClient,
- "virtio,mmio",
- &Node
- );
- !EFI_ERROR (FindNodeStatus);
- FindNodeStatus = FdtClient->FindNextCompatibleNode (
- FdtClient,
- "virtio,mmio",
- Node,
- &Node
- ))
- {
- Status = FdtClient->GetNodeProperty (
- FdtClient,
- Node,
- "reg",
- (CONST VOID **)&Reg,
- &RegSize
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: GetNodeProperty () failed (Status == %r)\n",
- __FUNCTION__,
- Status
- ));
- continue;
- }
- ASSERT (RegSize == 16);
- //
- // Create a unique device path for this transport on the fly
- //
- RegBase = SwapBytes64 (*Reg);
- DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
- HARDWARE_DEVICE_PATH,
- HW_VENDOR_DP,
- sizeof (VIRTIO_TRANSPORT_DEVICE_PATH)
- );
- if (DevicePath == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Out of memory\n", __FUNCTION__));
- continue;
- }
- CopyGuid (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid);
- DevicePath->PhysBase = RegBase;
- SetDevicePathNodeLength (
- &DevicePath->Vendor,
- sizeof (*DevicePath) - sizeof (DevicePath->End)
- );
- SetDevicePathEndNode (&DevicePath->End);
- Handle = NULL;
- Status = gBS->InstallProtocolInterface (
- &Handle,
- &gEfiDevicePathProtocolGuid,
- EFI_NATIVE_INTERFACE,
- DevicePath
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Failed to install the EFI_DEVICE_PATH "
- "protocol on a new handle (Status == %r)\n",
- __FUNCTION__,
- Status
- ));
- FreePool (DevicePath);
- continue;
- }
- Status = VirtioMmioInstallDevice (RegBase, Handle);
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Failed to install VirtIO transport @ 0x%Lx "
- "on handle %p (Status == %r)\n",
- __FUNCTION__,
- RegBase,
- Handle,
- Status
- ));
- Status = gBS->UninstallProtocolInterface (
- Handle,
- &gEfiDevicePathProtocolGuid,
- DevicePath
- );
- ASSERT_EFI_ERROR (Status);
- FreePool (DevicePath);
- continue;
- }
- }
- if (EFI_ERROR (FindNodeStatus) && (FindNodeStatus != EFI_NOT_FOUND)) {
- DEBUG ((
- DEBUG_ERROR,
- "%a: Error occurred while iterating DT nodes "
- "(FindNodeStatus == %r)\n",
- __FUNCTION__,
- FindNodeStatus
- ));
- }
- return EFI_SUCCESS;
- }
|