]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/FileSystem/BootMonFs/BootMonFsEntryPoint.c
OvmfPkg: BDS: remove dead call to PlatformBdsEnterFrontPage()
[mirror_edk2.git] / ArmPlatformPkg / FileSystem / BootMonFs / BootMonFsEntryPoint.c
CommitLineData
94e0955d
OM
1/** @file\r
2*\r
3* Copyright (c) 2012-2014, ARM Limited. All rights reserved.\r
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
15#include <Library/BaseMemoryLib.h>\r
16#include <Library/DevicePathLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
18#include <Library/PrintLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
20\r
21#include <Protocol/DevicePathFromText.h>\r
22#include <Protocol/DriverBinding.h>\r
23\r
24#include "BootMonFsInternal.h"\r
25\r
26EFI_DEVICE_PATH* mBootMonFsSupportedDevicePaths;\r
94e0955d
OM
27LIST_ENTRY mInstances;\r
28\r
29EFI_FILE_PROTOCOL mBootMonFsRootTemplate = {\r
30 EFI_FILE_PROTOCOL_REVISION,\r
31 BootMonFsOpenFile,\r
32 BootMonFsCloseFile,\r
33 BootMonFsDeleteFail,\r
34 BootMonFsReadDirectory,\r
35 BootMonFsWriteFile,\r
36 BootMonFsGetPositionUnsupported, // UEFI Spec: GetPosition not valid on dirs\r
37 BootMonFsSetDirPosition,\r
38 BootMonFsGetInfo,\r
39 BootMonFsSetInfo,\r
40 BootMonFsFlushDirectory\r
41};\r
42\r
43EFI_FILE_PROTOCOL mBootMonFsFileTemplate = {\r
44 EFI_FILE_PROTOCOL_REVISION,\r
45 BootMonFsOpenFile,\r
46 BootMonFsCloseFile,\r
47 BootMonFsDelete,\r
48 BootMonFsReadFile,\r
49 BootMonFsWriteFile,\r
50 BootMonFsGetPosition,\r
51 BootMonFsSetPosition,\r
52 BootMonFsGetInfo,\r
53 BootMonFsSetInfo,\r
54 BootMonFsFlushFile\r
55};\r
56\r
57EFI_STATUS\r
58BootMonGetFileFromAsciiFileName (\r
59 IN BOOTMON_FS_INSTANCE *Instance,\r
60 IN CHAR8* AsciiFileName,\r
61 OUT BOOTMON_FS_FILE **File\r
62 )\r
63{\r
64 LIST_ENTRY *Entry;\r
65 BOOTMON_FS_FILE *FileEntry;\r
66\r
67 // Remove the leading '\\'\r
68 if (*AsciiFileName == '\\') {\r
69 AsciiFileName++;\r
70 }\r
71\r
72 // Go through all the files in the list and return the file handle\r
73 for (Entry = GetFirstNode (&Instance->RootFile->Link);\r
74 !IsNull (&Instance->RootFile->Link, Entry);\r
75 Entry = GetNextNode (&Instance->RootFile->Link, Entry)\r
76 )\r
77 {\r
78 FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);\r
79 if (AsciiStrCmp (FileEntry->HwDescription.Footer.Filename, AsciiFileName) == 0) {\r
80 *File = FileEntry;\r
81 return EFI_SUCCESS;\r
82 }\r
83 }\r
84 return EFI_NOT_FOUND;\r
85}\r
86\r
87EFI_STATUS\r
88BootMonGetFileFromPosition (\r
89 IN BOOTMON_FS_INSTANCE *Instance,\r
90 IN UINTN Position,\r
91 OUT BOOTMON_FS_FILE **File\r
92 )\r
93{\r
94 LIST_ENTRY *Entry;\r
95 BOOTMON_FS_FILE *FileEntry;\r
96\r
97 // Go through all the files in the list and return the file handle\r
98 for (Entry = GetFirstNode (&Instance->RootFile->Link);\r
99 !IsNull (&Instance->RootFile->Link, Entry) && (&Instance->RootFile->Link != Entry);\r
100 Entry = GetNextNode (&Instance->RootFile->Link, Entry)\r
101 )\r
102 {\r
103 if (Position == 0) {\r
104 FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);\r
105 *File = FileEntry;\r
106 return EFI_SUCCESS;\r
107 }\r
108 Position--;\r
109 }\r
110 return EFI_NOT_FOUND;\r
111}\r
112\r
113EFI_STATUS\r
114BootMonFsCreateFile (\r
115 IN BOOTMON_FS_INSTANCE *Instance,\r
116 OUT BOOTMON_FS_FILE **File\r
117 )\r
118{\r
119 BOOTMON_FS_FILE *NewFile;\r
120\r
121 NewFile = (BOOTMON_FS_FILE*)AllocateZeroPool (sizeof (BOOTMON_FS_FILE));\r
122 if (NewFile == NULL) {\r
123 return EFI_OUT_OF_RESOURCES;\r
124 }\r
125\r
126 NewFile->Signature = BOOTMON_FS_FILE_SIGNATURE;\r
127 InitializeListHead (&NewFile->Link);\r
128 InitializeListHead (&NewFile->RegionToFlushLink);\r
129 NewFile->Instance = Instance;\r
130\r
131 // If the created file is the root file then create a directory EFI_FILE_PROTOCOL\r
132 if (Instance->RootFile == *File) {\r
133 CopyMem (&NewFile->File, &mBootMonFsRootTemplate, sizeof (mBootMonFsRootTemplate));\r
134 } else {\r
135 CopyMem (&NewFile->File, &mBootMonFsFileTemplate, sizeof (mBootMonFsFileTemplate));\r
136 }\r
137 *File = NewFile;\r
138 return EFI_SUCCESS;\r
139}\r
140\r
141STATIC\r
142EFI_STATUS\r
143SupportedDevicePathsInit (\r
144 VOID\r
145 )\r
146{\r
147 EFI_STATUS Status;\r
148 CHAR16* DevicePathListStr;\r
149 CHAR16* DevicePathStr;\r
150 CHAR16* NextDevicePathStr;\r
151 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;\r
152 EFI_DEVICE_PATH_PROTOCOL *Instance;\r
153\r
154 Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);\r
155 ASSERT_EFI_ERROR (Status);\r
156\r
157 // Initialize Variable\r
158 DevicePathListStr = (CHAR16*)PcdGetPtr (PcdBootMonFsSupportedDevicePaths);\r
159 mBootMonFsSupportedDevicePaths = NULL;\r
160\r
161 // Extract the Device Path instances from the multi-device path string\r
162 while ((DevicePathListStr != NULL) && (DevicePathListStr[0] != L'\0')) {\r
163 NextDevicePathStr = StrStr (DevicePathListStr, L";");\r
164 if (NextDevicePathStr == NULL) {\r
165 DevicePathStr = DevicePathListStr;\r
166 DevicePathListStr = NULL;\r
167 } else {\r
168 DevicePathStr = (CHAR16*)AllocateCopyPool ((NextDevicePathStr - DevicePathListStr + 1) * sizeof (CHAR16), DevicePathListStr);\r
169 if (DevicePathStr == NULL) {\r
170 return EFI_OUT_OF_RESOURCES;\r
171 }\r
172 *(DevicePathStr + (NextDevicePathStr - DevicePathListStr)) = L'\0';\r
173 DevicePathListStr = NextDevicePathStr;\r
174 if (DevicePathListStr[0] == L';') {\r
175 DevicePathListStr++;\r
176 }\r
177 }\r
178\r
179 Instance = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (DevicePathStr);\r
180 ASSERT (Instance != NULL);\r
181 mBootMonFsSupportedDevicePaths = AppendDevicePathInstance (mBootMonFsSupportedDevicePaths, Instance);\r
182\r
183 if (NextDevicePathStr != NULL) {\r
184 FreePool (DevicePathStr);\r
185 }\r
186 FreePool (Instance);\r
187 }\r
188\r
189 if (mBootMonFsSupportedDevicePaths == NULL) {\r
190 return EFI_UNSUPPORTED;\r
191 } else {\r
192 return EFI_SUCCESS;\r
193 }\r
194}\r
195\r
196EFI_STATUS\r
197EFIAPI\r
198BootMonFsDriverSupported (\r
199 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,\r
200 IN EFI_HANDLE ControllerHandle,\r
201 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL\r
202 )\r
203{\r
204 EFI_DISK_IO_PROTOCOL *DiskIo;\r
205 EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol;\r
206 EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePath;\r
207 EFI_DEVICE_PATH_PROTOCOL *SupportedDevicePaths;\r
208 EFI_STATUS Status;\r
209 UINTN Size1;\r
210 UINTN Size2;\r
211\r
212 //\r
213 // Open the IO Abstraction(s) needed to perform the supported test\r
214 //\r
215 Status = gBS->OpenProtocol (\r
216 ControllerHandle,\r
217 &gEfiDiskIoProtocolGuid,\r
218 (VOID **) &DiskIo,\r
c3b6d975 219 gImageHandle,\r
94e0955d
OM
220 ControllerHandle,\r
221 EFI_OPEN_PROTOCOL_BY_DRIVER\r
222 );\r
223\r
224 if (EFI_ERROR (Status)) {\r
225 return Status;\r
226 }\r
227 //\r
228 // Close the I/O Abstraction(s) used to perform the supported test\r
229 //\r
230 gBS->CloseProtocol (\r
231 ControllerHandle,\r
232 &gEfiDiskIoProtocolGuid,\r
c3b6d975 233 gImageHandle,\r
94e0955d
OM
234 ControllerHandle\r
235 );\r
236\r
237 // Check that BlockIo protocol instance exists\r
238 Status = gBS->OpenProtocol (\r
239 ControllerHandle,\r
240 &gEfiBlockIoProtocolGuid,\r
241 NULL,\r
c3b6d975 242 gImageHandle,\r
94e0955d
OM
243 ControllerHandle,\r
244 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
245 );\r
246 if (EFI_ERROR (Status)) {\r
247 return Status;\r
248 }\r
249\r
250 // Check if a DevicePath is attached to the handle\r
251 Status = gBS->OpenProtocol (\r
252 ControllerHandle,\r
253 &gEfiDevicePathProtocolGuid,\r
254 (VOID **)&DevicePathProtocol,\r
c3b6d975 255 gImageHandle,\r
94e0955d
OM
256 ControllerHandle,\r
257 EFI_OPEN_PROTOCOL_BY_DRIVER\r
258 );\r
259 if (EFI_ERROR (Status)) {\r
260 return Status;\r
261 }\r
262\r
263 // Check if the Device Path is the one which contains the Boot Monitor File System\r
264 Size1 = GetDevicePathSize (DevicePathProtocol);\r
265\r
266 // Go through the list of Device Path Instances\r
267 Status = EFI_UNSUPPORTED;\r
268 SupportedDevicePaths = mBootMonFsSupportedDevicePaths;\r
269 while (SupportedDevicePaths != NULL) {\r
270 SupportedDevicePath = GetNextDevicePathInstance (&SupportedDevicePaths, &Size2);\r
271\r
272 if ((Size1 == Size2) && (CompareMem (DevicePathProtocol, SupportedDevicePath, Size1) == 0)) {\r
273 // The Device Path is supported\r
274 Status = EFI_SUCCESS;\r
275 break;\r
276 }\r
277 }\r
278\r
c3b6d975 279 gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, gImageHandle, ControllerHandle);\r
94e0955d
OM
280 return Status;\r
281}\r
282\r
283EFI_STATUS\r
284EFIAPI\r
285BootMonFsDriverStart (\r
286 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,\r
287 IN EFI_HANDLE ControllerHandle,\r
288 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL\r
289 )\r
290{\r
291 BOOTMON_FS_INSTANCE *Instance;\r
292 EFI_STATUS Status;\r
293 UINTN VolumeNameSize;\r
294\r
295 Instance = AllocateZeroPool (sizeof (BOOTMON_FS_INSTANCE));\r
296 if (Instance == NULL) {\r
297 return EFI_OUT_OF_RESOURCES;\r
298 }\r
299\r
300 // Initialize the BlockIo of the Instance\r
301 Status = gBS->OpenProtocol (\r
302 ControllerHandle,\r
303 &gEfiBlockIoProtocolGuid,\r
304 (VOID **)&(Instance->BlockIo),\r
c3b6d975 305 gImageHandle,\r
94e0955d
OM
306 ControllerHandle,\r
307 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
308 );\r
309 if (EFI_ERROR (Status)) {\r
310 FreePool (Instance);\r
311 return Status;\r
312 }\r
313\r
314 Status = gBS->OpenProtocol (\r
315 ControllerHandle,\r
316 &gEfiDiskIoProtocolGuid,\r
317 (VOID **)&(Instance->DiskIo),\r
c3b6d975 318 gImageHandle,\r
94e0955d
OM
319 ControllerHandle,\r
320 EFI_OPEN_PROTOCOL_BY_DRIVER\r
321 );\r
322 if (EFI_ERROR (Status)) {\r
323 FreePool (Instance);\r
324 return Status;\r
325 }\r
326\r
327 //\r
328 // Initialize the attributes of the Instance\r
329 //\r
330 Instance->Signature = BOOTMON_FS_SIGNATURE;\r
331 Instance->ControllerHandle = ControllerHandle;\r
332 Instance->Media = Instance->BlockIo->Media;\r
333 Instance->Binding = DriverBinding;\r
334\r
335 // Initialize the Simple File System Protocol\r
336 Instance->Fs.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;\r
337 Instance->Fs.OpenVolume = OpenBootMonFsOpenVolume;\r
338\r
339 // Volume name + L' ' + '2' digit number\r
340 VolumeNameSize = StrSize (BOOTMON_FS_VOLUME_LABEL) + (3 * sizeof (CHAR16));\r
341\r
342 // Initialize FileSystem Information\r
343 Instance->FsInfo.Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + VolumeNameSize;\r
344 Instance->FsInfo.BlockSize = Instance->Media->BlockSize;\r
345 Instance->FsInfo.ReadOnly = FALSE;\r
346 Instance->FsInfo.VolumeSize =\r
347 Instance->Media->BlockSize * (Instance->Media->LastBlock - Instance->Media->LowestAlignedLba);\r
348 CopyMem (Instance->FsInfo.VolumeLabel, BOOTMON_FS_VOLUME_LABEL, StrSize (BOOTMON_FS_VOLUME_LABEL));\r
349\r
350 // Initialize the root file\r
351 Status = BootMonFsCreateFile (Instance, &Instance->RootFile);\r
352 if (EFI_ERROR (Status)) {\r
353 FreePool (Instance);\r
354 return Status;\r
355 }\r
356\r
357 // Initialize the DevicePath of the Instance\r
358 Status = gBS->OpenProtocol (\r
359 ControllerHandle,\r
360 &gEfiDevicePathProtocolGuid,\r
361 (VOID **)&(Instance->DevicePath),\r
c3b6d975 362 gImageHandle,\r
94e0955d
OM
363 ControllerHandle,\r
364 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
365 );\r
366 if (EFI_ERROR (Status)) {\r
367 FreePool (Instance);\r
368 return Status;\r
369 }\r
370\r
371 //\r
372 // Install the Simple File System Protocol\r
373 //\r
374 Status = gBS->InstallMultipleProtocolInterfaces (\r
375 &ControllerHandle,\r
376 &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,\r
377 NULL\r
378 );\r
379\r
380 InsertTailList (&mInstances, &Instance->Link);\r
381\r
382 return Status;\r
383}\r
384\r
385\r
386EFI_STATUS\r
387EFIAPI\r
388BootMonFsDriverStop (\r
389 IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,\r
390 IN EFI_HANDLE ControllerHandle,\r
391 IN UINTN NumberOfChildren,\r
392 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL\r
393 )\r
394{\r
395 BOOTMON_FS_INSTANCE *Instance;\r
396 LIST_ENTRY *Link;\r
397 EFI_STATUS Status;\r
398 BOOLEAN InstanceFound;\r
399\r
400 // Find instance from ControllerHandle.\r
401 Instance = NULL;\r
402 InstanceFound = FALSE;\r
403 // For each instance in mInstances:\r
404 for (Link = GetFirstNode (&mInstances); !IsNull (&mInstances, Link); Link = GetNextNode (&mInstances, Link)) {\r
405 Instance = BOOTMON_FS_FROM_LINK (Link);\r
406\r
407 if (Instance->ControllerHandle == ControllerHandle) {\r
408 InstanceFound = TRUE;\r
409 break;\r
410 }\r
411 }\r
412 ASSERT (InstanceFound == TRUE);\r
413\r
414 gBS->CloseProtocol (\r
415 ControllerHandle,\r
416 &gEfiDevicePathProtocolGuid,\r
417 DriverBinding->ImageHandle,\r
418 ControllerHandle);\r
419\r
420 gBS->CloseProtocol (\r
421 ControllerHandle,\r
422 &gEfiDiskIoProtocolGuid,\r
423 DriverBinding->ImageHandle,\r
424 ControllerHandle);\r
425\r
426 gBS->CloseProtocol (\r
427 ControllerHandle,\r
428 &gEfiBlockIoProtocolGuid,\r
429 DriverBinding->ImageHandle,\r
430 ControllerHandle);\r
431\r
432 Status = gBS->UninstallMultipleProtocolInterfaces (\r
433 &ControllerHandle,\r
434 &gEfiSimpleFileSystemProtocolGuid, &Instance->Fs,\r
435 NULL);\r
436\r
437 return Status;\r
438}\r
439\r
440//\r
441// Simple Network Protocol Driver Global Variables\r
442//\r
443EFI_DRIVER_BINDING_PROTOCOL mBootMonFsDriverBinding = {\r
444 BootMonFsDriverSupported,\r
445 BootMonFsDriverStart,\r
446 BootMonFsDriverStop,\r
447 0xa,\r
448 NULL,\r
449 NULL\r
450};\r
451\r
452EFI_STATUS\r
453EFIAPI\r
454BootMonFsEntryPoint (\r
455 IN EFI_HANDLE ImageHandle,\r
456 IN EFI_SYSTEM_TABLE *SystemTable\r
457 )\r
458{\r
459 EFI_STATUS Status;\r
460\r
94e0955d
OM
461 InitializeListHead (&mInstances);\r
462\r
463 // Initialize the list of Device Paths that could support BootMonFs\r
464 Status = SupportedDevicePathsInit ();\r
465 if (!EFI_ERROR (Status)) {\r
466 Status = gBS->InstallMultipleProtocolInterfaces (\r
467 &ImageHandle,\r
468 &gEfiDriverBindingProtocolGuid, &mBootMonFsDriverBinding,\r
469 NULL\r
470 );\r
471 ASSERT_EFI_ERROR (Status);\r
472 } else {\r
473 DEBUG((EFI_D_ERROR,"Warning: No Device Paths supporting BootMonFs have been defined in the PCD.\n"));\r
474 }\r
475\r
476 return Status;\r
477}\r