]> git.proxmox.com Git - mirror_edk2.git/blob - ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.c
ArmVirtPkg/VirtFdtDxe: remove Xenio handling and rename to VirtioFdtDxe
[mirror_edk2.git] / ArmVirtPkg / VirtioFdtDxe / VirtioFdtDxe.c
1 /** @file
2 * Virtio FDT client protocol driver for virtio,mmio DT node
3 *
4 * Copyright (c) 2014 - 2016, Linaro Ltd. All rights reserved.<BR>
5 *
6 * This program and the accompanying materials are
7 * licensed and made available under the terms and conditions of the BSD License
8 * which accompanies this distribution. The full text of the license may be found at
9 * http://opensource.org/licenses/bsd-license.php
10 *
11 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 *
14 **/
15
16 #include <Library/BaseLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/DevicePathLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiDriverEntryPoint.h>
23 #include <Library/VirtioMmioDeviceLib.h>
24
25 #include <Guid/VirtioMmioTransport.h>
26
27 #include <Protocol/FdtClient.h>
28
29 #pragma pack (1)
30 typedef struct {
31 VENDOR_DEVICE_PATH Vendor;
32 UINT64 PhysBase;
33 EFI_DEVICE_PATH_PROTOCOL End;
34 } VIRTIO_TRANSPORT_DEVICE_PATH;
35 #pragma pack ()
36
37 EFI_STATUS
38 EFIAPI
39 InitializeVirtioFdtDxe (
40 IN EFI_HANDLE ImageHandle,
41 IN EFI_SYSTEM_TABLE *SystemTable
42 )
43 {
44 EFI_STATUS Status, FindNodeStatus;
45 FDT_CLIENT_PROTOCOL *FdtClient;
46 INT32 Node;
47 CONST UINT64 *Reg;
48 UINT32 RegSize;
49 VIRTIO_TRANSPORT_DEVICE_PATH *DevicePath;
50 EFI_HANDLE Handle;
51 UINT64 RegBase;
52
53 Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
54 (VOID **)&FdtClient);
55 ASSERT_EFI_ERROR (Status);
56
57 for (FindNodeStatus = FdtClient->FindCompatibleNode (FdtClient,
58 "virtio,mmio", &Node);
59 !EFI_ERROR (FindNodeStatus);
60 FindNodeStatus = FdtClient->FindNextCompatibleNode (FdtClient,
61 "virtio,mmio", Node, &Node)) {
62
63 Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",
64 (CONST VOID **)&Reg, &RegSize);
65 if (EFI_ERROR (Status)) {
66 DEBUG ((EFI_D_ERROR, "%a: GetNodeProperty () failed (Status == %r)\n",
67 __FUNCTION__, Status));
68 continue;
69 }
70
71 ASSERT (RegSize == 16);
72
73 //
74 // Create a unique device path for this transport on the fly
75 //
76 RegBase = SwapBytes64 (*Reg);
77 DevicePath = (VIRTIO_TRANSPORT_DEVICE_PATH *)CreateDeviceNode (
78 HARDWARE_DEVICE_PATH,
79 HW_VENDOR_DP,
80 sizeof (VIRTIO_TRANSPORT_DEVICE_PATH));
81 if (DevicePath == NULL) {
82 DEBUG ((EFI_D_ERROR, "%a: Out of memory\n", __FUNCTION__));
83 continue;
84 }
85
86 CopyGuid (&DevicePath->Vendor.Guid, &gVirtioMmioTransportGuid);
87 DevicePath->PhysBase = RegBase;
88 SetDevicePathNodeLength (&DevicePath->Vendor,
89 sizeof (*DevicePath) - sizeof (DevicePath->End));
90 SetDevicePathEndNode (&DevicePath->End);
91
92 Handle = NULL;
93 Status = gBS->InstallProtocolInterface (&Handle,
94 &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,
95 DevicePath);
96 if (EFI_ERROR (Status)) {
97 DEBUG ((EFI_D_ERROR, "%a: Failed to install the EFI_DEVICE_PATH "
98 "protocol on a new handle (Status == %r)\n",
99 __FUNCTION__, Status));
100 FreePool (DevicePath);
101 continue;
102 }
103
104 Status = VirtioMmioInstallDevice (RegBase, Handle);
105 if (EFI_ERROR (Status)) {
106 DEBUG ((EFI_D_ERROR, "%a: Failed to install VirtIO transport @ 0x%Lx "
107 "on handle %p (Status == %r)\n", __FUNCTION__, RegBase,
108 Handle, Status));
109
110 Status = gBS->UninstallProtocolInterface (Handle,
111 &gEfiDevicePathProtocolGuid, DevicePath);
112 ASSERT_EFI_ERROR (Status);
113 FreePool (DevicePath);
114 continue;
115 }
116 }
117
118 if (EFI_ERROR (FindNodeStatus) && FindNodeStatus != EFI_NOT_FOUND) {
119 DEBUG ((EFI_D_ERROR, "%a: Error occurred while iterating DT nodes "
120 "(FindNodeStatus == %r)\n", __FUNCTION__, FindNodeStatus));
121 }
122
123 return EFI_SUCCESS;
124 }