]>
Commit | Line | Data |
---|---|---|
94caa81c | 1 | /** @file\r |
2 | \r | |
04f1a709 | 3 | Copyright (c) 2013-2015, ARM Ltd. All rights reserved.<BR>\r |
94caa81c | 4 | \r |
5 | This program and the accompanying materials\r | |
6 | are licensed and made available under the terms and conditions of the BSD License\r | |
7 | which accompanies this distribution. The full text of the license may be found at\r | |
8 | http://opensource.org/licenses/bsd-license.php\r | |
9 | \r | |
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
12 | \r | |
13 | **/\r | |
14 | \r | |
dff72027 OM |
15 | #include "ArmVExpressInternal.h"\r |
16 | \r | |
35eabda7 AB |
17 | #include <PiDxe.h> |
18 | #include <Library/BaseMemoryLib.h> | |
94caa81c | 19 | #include <Library/VirtioMmioDeviceLib.h>\r |
ced216f8 | 20 | #include <Library/ArmShellCmdLib.h>\r |
04f1a709 | 21 | #include <Library/MemoryAllocationLib.h>\r |
35eabda7 AB |
22 | #include <Library/DevicePathLib.h> |
23 | ||
24 | #include <Protocol/FirmwareVolume2.h> | |
94caa81c | 25 | \r |
26 | #define ARM_FVP_BASE_VIRTIO_BLOCK_BASE 0x1c130000\r | |
27 | \r | |
28 | #pragma pack(1)\r | |
29 | typedef struct {\r | |
30 | VENDOR_DEVICE_PATH Vendor;\r | |
31 | EFI_DEVICE_PATH_PROTOCOL End;\r | |
32 | } VIRTIO_BLK_DEVICE_PATH;\r | |
33 | #pragma pack()\r | |
34 | \r | |
35 | VIRTIO_BLK_DEVICE_PATH mVirtioBlockDevicePath =\r | |
36 | {\r | |
37 | {\r | |
38 | {\r | |
39 | HARDWARE_DEVICE_PATH,\r | |
40 | HW_VENDOR_DP,\r | |
41 | {\r | |
42 | (UINT8)( sizeof(VENDOR_DEVICE_PATH) ),\r | |
43 | (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)\r | |
44 | }\r | |
45 | },\r | |
46 | EFI_CALLER_ID_GUID,\r | |
47 | },\r | |
48 | {\r | |
49 | END_DEVICE_PATH_TYPE,\r | |
50 | END_ENTIRE_DEVICE_PATH_SUBTYPE,\r | |
51 | {\r | |
52 | sizeof (EFI_DEVICE_PATH_PROTOCOL),\r | |
53 | 0\r | |
54 | }\r | |
55 | }\r | |
56 | };\r | |
57 | \r | |
35eabda7 AB |
58 | STATIC |
59 | EFI_STATUS | |
60 | InternalFindFdtByGuid ( | |
61 | IN OUT EFI_DEVICE_PATH **FdtDevicePath, | |
62 | IN CONST EFI_GUID *FdtGuid | |
63 | ) | |
64 | { | |
65 | MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath; | |
66 | EFI_HANDLE *HandleBuffer; | |
67 | UINTN HandleCount; | |
68 | UINTN Index; | |
69 | EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; | |
70 | EFI_GUID NameGuid; | |
71 | UINTN Size; | |
72 | VOID *Key; | |
73 | EFI_FV_FILETYPE FileType; | |
74 | EFI_FV_FILE_ATTRIBUTES Attributes; | |
75 | EFI_DEVICE_PATH *FvDevicePath; | |
76 | EFI_STATUS Status; | |
77 | ||
78 | if (FdtGuid == NULL) { | |
79 | return EFI_NOT_FOUND; | |
80 | } | |
81 | ||
82 | EfiInitializeFwVolDevicepathNode (&FileDevicePath, FdtGuid); | |
83 | ||
84 | HandleBuffer = NULL; | |
85 | Status = gBS->LocateHandleBuffer ( | |
86 | ByProtocol, | |
87 | &gEfiFirmwareVolume2ProtocolGuid, | |
88 | NULL, | |
89 | &HandleCount, | |
90 | &HandleBuffer | |
91 | ); | |
92 | if (EFI_ERROR (Status)) { | |
93 | return Status; | |
94 | } | |
95 | ||
96 | for (Index = 0; Index < HandleCount; Index++) { | |
97 | Status = gBS->HandleProtocol ( | |
98 | HandleBuffer[Index], | |
99 | &gEfiFirmwareVolume2ProtocolGuid, | |
100 | (VOID **) &FvProtocol | |
101 | ); | |
102 | if (EFI_ERROR (Status)) { | |
103 | return Status; | |
104 | } | |
105 | ||
106 | // Allocate Key | |
107 | Key = AllocatePool (FvProtocol->KeySize); | |
108 | ASSERT (Key != NULL); | |
109 | ZeroMem (Key, FvProtocol->KeySize); | |
110 | ||
111 | do { | |
112 | FileType = EFI_FV_FILETYPE_RAW; | |
113 | Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size); | |
114 | if (Status == EFI_NOT_FOUND) { | |
115 | break; | |
116 | } | |
117 | if (EFI_ERROR (Status)) { | |
118 | return Status; | |
119 | } | |
120 | ||
121 | // | |
122 | // Check whether this file is the one we are looking for. If so, | |
123 | // create a device path for it and return it to the caller. | |
124 | // | |
125 | if (CompareGuid (&NameGuid, FdtGuid)) { | |
126 | Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath); | |
127 | if (!EFI_ERROR (Status)) { | |
128 | *FdtDevicePath = AppendDevicePathNode (FvDevicePath, | |
129 | (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath); | |
130 | } | |
131 | goto Done; | |
132 | } | |
133 | } while (TRUE); | |
134 | FreePool (Key); | |
135 | } | |
136 | ||
137 | if (Index == HandleCount) { | |
138 | Status = EFI_NOT_FOUND; | |
139 | } | |
140 | return Status; | |
141 | ||
142 | Done: | |
143 | FreePool (Key); | |
144 | return Status; | |
145 | } | |
146 | ||
04f1a709 RC |
147 | /**\r |
148 | * Generic UEFI Entrypoint for 'ArmFvpDxe' driver\r | |
149 | * See UEFI specification for the details of the parameters\r | |
150 | */\r | |
94caa81c | 151 | EFI_STATUS\r |
152 | EFIAPI\r | |
153 | ArmFvpInitialise (\r | |
154 | IN EFI_HANDLE ImageHandle,\r | |
155 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
156 | )\r | |
157 | {\r | |
04f1a709 RC |
158 | CONST ARM_VEXPRESS_PLATFORM* Platform;\r |
159 | EFI_STATUS Status;\r | |
160 | CHAR16 *TextDevicePath;\r | |
161 | UINTN TextDevicePathSize;\r | |
162 | VOID *Buffer;\r | |
35eabda7 | 163 | EFI_DEVICE_PATH *FdtDevicePath; |
94caa81c | 164 | \r |
165 | Status = gBS->InstallProtocolInterface (&ImageHandle,\r | |
166 | &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE,\r | |
167 | &mVirtioBlockDevicePath);\r | |
168 | if (EFI_ERROR (Status)) {\r | |
169 | return Status;\r | |
170 | }\r | |
171 | \r | |
04f1a709 RC |
172 | Status = ArmVExpressGetPlatform (&Platform);\r |
173 | if (!EFI_ERROR (Status)) {\r | |
35eabda7 AB |
174 | FdtDevicePath = NULL; |
175 | Status = InternalFindFdtByGuid (&FdtDevicePath, Platform->FdtGuid); | |
176 | if (!EFI_ERROR (Status)) { | |
177 | TextDevicePath = ConvertDevicePathToText (FdtDevicePath, FALSE, FALSE); | |
178 | if (TextDevicePath != NULL) { | |
179 | TextDevicePathSize = StrSize (TextDevicePath); | |
180 | } | |
181 | FreePool (FdtDevicePath); | |
182 | } else { | |
183 | TextDevicePathSize = StrSize ((CHAR16*)PcdGetPtr (PcdFvpFdtDevicePathsBase)) - sizeof (CHAR16); | |
184 | TextDevicePathSize += StrSize (Platform->FdtName); | |
185 | ||
186 | TextDevicePath = AllocatePool (TextDevicePathSize); | |
187 | if (TextDevicePath != NULL) { | |
188 | StrCpy (TextDevicePath, ((CHAR16*)PcdGetPtr (PcdFvpFdtDevicePathsBase))); | |
189 | StrCat (TextDevicePath, Platform->FdtName); | |
190 | } | |
191 | } | |
04f1a709 | 192 | if (TextDevicePath != NULL) {\r |
04f1a709 RC |
193 | Buffer = PcdSetPtr (PcdFdtDevicePaths, &TextDevicePathSize, TextDevicePath);\r |
194 | if (Buffer == NULL) {\r | |
195 | DEBUG ((\r | |
196 | EFI_D_ERROR,\r | |
197 | "ArmFvpDxe: Setting of FDT device path in PcdFdtDevicePaths failed - %r\n", EFI_BUFFER_TOO_SMALL\r | |
198 | ));\r | |
199 | }\r | |
200 | FreePool (TextDevicePath);\r | |
201 | }\r | |
202 | }\r | |
203 | \r | |
94caa81c | 204 | // Declare the Virtio BlockIo device\r |
205 | Status = VirtioMmioInstallDevice (ARM_FVP_BASE_VIRTIO_BLOCK_BASE, ImageHandle);\r | |
206 | if (EFI_ERROR (Status)) {\r | |
207 | DEBUG ((EFI_D_ERROR, "ArmFvpDxe: Failed to install Virtio block device\n"));\r | |
208 | }\r | |
209 | \r | |
ced216f8 HL |
210 | // Install dynamic Shell command to run baremetal binaries.\r |
211 | Status = ShellDynCmdRunAxfInstall (ImageHandle);\r | |
212 | if (EFI_ERROR (Status)) {\r | |
213 | DEBUG ((EFI_D_ERROR, "ArmFvpDxe: Failed to install ShellDynCmdRunAxf\n"));\r | |
214 | }\r | |
215 | \r | |
94caa81c | 216 | return Status;\r |
217 | }\r |