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