]> git.proxmox.com Git - mirror_edk2.git/blame - EdkUnixPkg/Library/EdkGenericBdsLib/BdsBoot.c.orig
newline added at end
[mirror_edk2.git] / EdkUnixPkg / Library / EdkGenericBdsLib / BdsBoot.c.orig
CommitLineData
c9093a06 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 BdsBoot.c\r
15\r
16Abstract:\r
17\r
18 BDS Lib functions which relate with create or process the boot\r
19 option.\r
20\r
21--*/\r
22#include "Performance.h"\r
23\r
24BOOLEAN mEnumBootDevice = FALSE;\r
25\r
26EFI_STATUS\r
27BdsLibDoLegacyBoot (\r
28 IN BDS_COMMON_OPTION *Option\r
29 )\r
30/*++\r
31\r
32Routine Description:\r
33 \r
34 Boot the legacy system with the boot option\r
35\r
36Arguments:\r
37\r
38 Option - The legacy boot option which have BBS device path\r
39\r
40Returns:\r
41\r
42 EFI_UNSUPPORTED - There is no legacybios protocol, do not support\r
43 legacy boot.\r
44 \r
45 EFI_STATUS - Return the status of LegacyBios->LegacyBoot ().\r
46\r
47--*/\r
48{\r
49 EFI_STATUS Status;\r
50 EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;\r
51\r
52 Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL,
53 (void **)&LegacyBios);\r
54 if (EFI_ERROR (Status)) {\r
55 //\r
56 // If no LegacyBios protocol we do not support legacy boot\r
57 //\r
58 return EFI_UNSUPPORTED;\r
59 }\r
60 //\r
61 // Notes: if we seperate the int 19, then we don't need to refresh BBS\r
62 //\r
63 BdsRefreshBbsTableForBoot (Option);\r
64\r
65 //\r
66 // Write boot to OS performance data to a file\r
67 //\r
68 PERF_CODE (\r
69 WriteBootToOsPerformanceData ();\r
70 );\r
71\r
72\r
73 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Legacy Boot: %S\n", Option->Description));\r
74 return LegacyBios->LegacyBoot (\r
75 LegacyBios,\r
76 (BBS_BBS_DEVICE_PATH *) Option->DevicePath,\r
77 Option->LoadOptionsSize,\r
78 Option->LoadOptions\r
79 );\r
80}\r
81\r
82EFI_STATUS\r
83BdsLibBootViaBootOption (\r
84 IN BDS_COMMON_OPTION * Option,\r
85 IN EFI_DEVICE_PATH_PROTOCOL * DevicePath,\r
86 OUT UINTN *ExitDataSize,\r
87 OUT CHAR16 **ExitData OPTIONAL\r
88 )\r
89/*++\r
90\r
91Routine Description:\r
92\r
93 Process the boot option follow the EFI 1.1 specification and \r
94 special treat the legacy boot option with BBS_DEVICE_PATH.\r
95\r
96Arguments:\r
97\r
98 Option - The boot option need to be processed\r
99 \r
100 DevicePath - The device path which describe where to load \r
101 the boot image or the legcy BBS device path \r
102 to boot the legacy OS\r
103\r
104 ExitDataSize - Returned directly from gBS->StartImage ()\r
105\r
106 ExitData - Returned directly from gBS->StartImage ()\r
107\r
108Returns:\r
109\r
110 EFI_SUCCESS - Status from gBS->StartImage (),\r
111 or BdsBootByDiskSignatureAndPartition ()\r
112\r
113 EFI_NOT_FOUND - If the Device Path is not found in the system\r
114\r
115--*/\r
116{\r
117 EFI_STATUS Status;\r
118 EFI_HANDLE Handle;\r
119 EFI_HANDLE ImageHandle;\r
120 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
121 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
122 EFI_LOADED_IMAGE_PROTOCOL *ImageInfo;\r
123 EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;\r
124\r
125 *ExitDataSize = 0;\r
126 *ExitData = NULL;\r
127\r
128 //\r
129 // Notes: put EFI64 ROM Shadow Solution\r
130 //\r
131 EFI64_SHADOW_ALL_LEGACY_ROM ();\r
132\r
133 //\r
134 // Notes: this code can be remove after the s3 script table\r
135 // hook on the event EFI_EVENT_SIGNAL_READY_TO_BOOT or\r
136 // EFI_EVENT_SIGNAL_LEGACY_BOOT\r
137 //\r
138 Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL,
139 (VOID **)&AcpiS3Save);\r
140 if (!EFI_ERROR (Status)) {\r
141 AcpiS3Save->S3Save (AcpiS3Save, NULL);\r
142 }\r
143 //\r
144 // If it's Device Path that starts with a hard drive path,\r
145 // this routine will do the booting.\r
146 //\r
147 Status = BdsBootByDiskSignatureAndPartition (\r
148 Option,\r
149 (HARDDRIVE_DEVICE_PATH *) DevicePath,\r
150 Option->LoadOptionsSize,\r
151 Option->LoadOptions,\r
152 ExitDataSize,\r
153 ExitData\r
154 );\r
155 if (!EFI_ERROR (Status)) {\r
156 //\r
157 // If we found a disk signature and partition device path return success\r
158 //\r
159 return EFI_SUCCESS;\r
160 }\r
161\r
162 EfiSignalEventReadyToBoot ();\r
163\r
164 //\r
165 // Set Boot Current\r
166 //\r
167 gRT->SetVariable (\r
168 L"BootCurrent",\r
169 &gEfiGlobalVariableGuid,\r
170 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
171 sizeof (UINT16),\r
172 &Option->BootCurrent\r
173 );\r
174\r
175 if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) &&\r
176 (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP)\r
177 ) {\r
178 //\r
179 // Check to see if we should legacy BOOT. If yes then do the legacy boot\r
180 //\r
181 return BdsLibDoLegacyBoot (Option);\r
182 }\r
183\r
184 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Booting EFI 1.1 way %S\n", Option->Description));\r
185\r
186 Status = gBS->LoadImage (\r
187 TRUE,\r
188 mBdsImageHandle,\r
189 DevicePath,\r
190 NULL,\r
191 0,\r
192 &ImageHandle\r
193 );\r
194\r
195 //\r
196 // If we didn't find an image, we may need to load the default\r
197 // boot behavior for the device.\r
198 //\r
199 if (EFI_ERROR (Status)) {\r
200 //\r
201 // Find a Simple File System protocol on the device path. If the remaining\r
202 // device path is set to end then no Files are being specified, so try\r
203 // the removable media file name.\r
204 //\r
205 TempDevicePath = DevicePath;\r
206 Status = gBS->LocateDevicePath (\r
207 &gEfiSimpleFileSystemProtocolGuid,\r
208 &TempDevicePath,\r
209 &Handle\r
210 );\r
211 if (!EFI_ERROR (Status) && IsDevicePathEnd (TempDevicePath)) {\r
212 FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);\r
213 if (FilePath) {\r
214 Status = gBS->LoadImage (\r
215 TRUE,\r
216 mBdsImageHandle,\r
217 FilePath,\r
218 NULL,\r
219 0,\r
220 &ImageHandle\r
221 );\r
222 if (EFI_ERROR (Status)) {\r
223 //\r
224 // The DevicePath failed, and it's not a valid\r
225 // removable media device.\r
226 //\r
227 goto Done;\r
228 }\r
229 }\r
230 } else {\r
231 Status = EFI_NOT_FOUND;\r
232 }\r
233 }\r
234\r
235 if (EFI_ERROR (Status)) {\r
236 //\r
237 // It there is any error from the Boot attempt exit now.\r
238 //\r
239 goto Done;\r
240 }\r
241 //\r
242 // Provide the image with it's load options\r
243 //\r
244 Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid,
245 (VOID **) &ImageInfo);\r
246 ASSERT_EFI_ERROR (Status);\r
247\r
248 if (Option->LoadOptionsSize != 0) {\r
249 ImageInfo->LoadOptionsSize = Option->LoadOptionsSize;\r
250 ImageInfo->LoadOptions = Option->LoadOptions;\r
251 }\r
252 //\r
253 // Before calling the image, enable the Watchdog Timer for\r
254 // the 5 Minute period\r
255 //\r
256 gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL);\r
257\r
258 Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData);\r
259 DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Image Return Status = %r\n", Status));\r
260\r
261 //\r
262 // Clear the Watchdog Timer after the image returns\r
263 //\r
264 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);\r
265\r
266Done:\r
267 //\r
268 // Clear Boot Current\r
269 //\r
270 gRT->SetVariable (\r
271 L"BootCurrent",\r
272 &gEfiGlobalVariableGuid,\r
273 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
274 0,\r
275 &Option->BootCurrent\r
276 );\r
277\r
278 return Status;\r
279}\r
280\r
281EFI_STATUS\r
282BdsBootByDiskSignatureAndPartition (\r
283 IN BDS_COMMON_OPTION * Option,\r
284 IN HARDDRIVE_DEVICE_PATH * HardDriveDevicePath,\r
285 IN UINT32 LoadOptionsSize,\r
286 IN VOID *LoadOptions,\r
287 OUT UINTN *ExitDataSize,\r
288 OUT CHAR16 **ExitData OPTIONAL\r
289 )\r
290/*++\r
291\r
292Routine Description:\r
293\r
294 Check to see if a hard ware device path was passed in. If it was then search\r
295 all the block IO devices for the passed in hard drive device path. \r
296 \r
297Arguments:\r
298\r
299 Option - The current processing boot option.\r
300\r
301 HardDriveDevicePath - EFI Device Path to boot, if it starts with a hard\r
302 drive device path.\r
303\r
304 LoadOptionsSize - Passed into gBS->StartImage ()\r
305 via the loaded image protocol.\r
306\r
307 LoadOptions - Passed into gBS->StartImage ()\r
308 via the loaded image protocol.\r
309\r
310 ExitDataSize - returned directly from gBS->StartImage ()\r
311\r
312 ExitData - returned directly from gBS->StartImage ()\r
313\r
314Returns:\r
315\r
316 EFI_SUCCESS - Status from gBS->StartImage (),\r
317 or BootByDiskSignatureAndPartition ()\r
318 \r
319 EFI_NOT_FOUND - If the Device Path is not found in the system\r
320\r
321--*/\r
322{\r
323 EFI_STATUS Status;\r
324 UINTN BlockIoHandleCount;\r
325 EFI_HANDLE *BlockIoBuffer;\r
326 EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath;\r
327 EFI_DEVICE_PATH_PROTOCOL *BlockIoHdDevicePath;\r
328 HARDDRIVE_DEVICE_PATH *TmpHdPath;\r
329 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
330 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
331 UINTN Index;\r
332 BOOLEAN DevicePathMatch;\r
333 HARDDRIVE_DEVICE_PATH *TempPath;\r
334\r
335 *ExitDataSize = 0;\r
336 *ExitData = NULL;\r
337\r
338 if ( !((DevicePathType (&HardDriveDevicePath->Header) == MEDIA_DEVICE_PATH) &&\r
339 (DevicePathSubType (&HardDriveDevicePath->Header) == MEDIA_HARDDRIVE_DP))\r
340 ) {\r
341 //\r
342 // If the HardDriveDevicePath does not start with a Hard Drive Device Path\r
343 // exit.\r
344 //\r
345 return EFI_NOT_FOUND;\r
346 }\r
347 //\r
348 // The boot device have already been connected\r
349 //\r
350 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer);\r
351 if (EFI_ERROR (Status) || BlockIoHandleCount == 0) {\r
352 //\r
353 // If there was an error or there are no device handles that support\r
354 // the BLOCK_IO Protocol, then return.\r
355 //\r
356 return EFI_NOT_FOUND;\r
357 }\r
358 //\r
359 // Loop through all the device handles that support the BLOCK_IO Protocol\r
360 //\r
361 for (Index = 0; Index < BlockIoHandleCount; Index++) {\r
362\r
363 Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath);\r
364 if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) {\r
365 continue;\r
366 }\r
367 //\r
368 // Make PreviousDevicePath == the device path node before the end node\r
369 //\r
370 DevicePath = BlockIoDevicePath;\r
371 BlockIoHdDevicePath = NULL;\r
372\r
373 //\r
374 // find HardDriver device path node\r
375 //\r
376 while (!IsDevicePathEnd (DevicePath)) {\r
377 if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && \r
378 (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)\r
379 ) {\r
380 BlockIoHdDevicePath = DevicePath;\r
381 break;\r
382 }\r
383\r
384 DevicePath = NextDevicePathNode (DevicePath);\r
385 }\r
386\r
387 if (BlockIoHdDevicePath == NULL) {\r
388 continue;\r
389 }\r
390 //\r
391 // See if the harddrive device path in blockio matches the orig Hard Drive Node\r
392 //\r
393 DevicePathMatch = FALSE;\r
394\r
395 TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePath;\r
396 TempPath = (HARDDRIVE_DEVICE_PATH *) BdsLibUnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);\r
397\r
398 //\r
399 // Only several fields will be checked. NOT whole NODE\r
400 //\r
401 if ( TmpHdPath->PartitionNumber == TempPath->PartitionNumber &&\r
402 TmpHdPath->MBRType == TempPath->MBRType &&\r
403 TmpHdPath->SignatureType == TempPath->SignatureType &&\r
404 CompareGuid ((EFI_GUID *) TmpHdPath->Signature, (EFI_GUID *) TempPath->Signature)) {\r
405 //\r
406 // Get the matched device path\r
407 //\r
408 DevicePathMatch = TRUE;\r
409 }\r
410 //\r
411 // Only do the boot, when devicepath match\r
412 //\r
413 if (DevicePathMatch) {\r
414 //\r
415 // Combine the Block IO and Hard Drive Device path together and try\r
416 // to boot from it.\r
417 //\r
418 DevicePath = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath);\r
419 NewDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath);\r
420\r
421 //\r
422 // Recursive boot with new device path\r
423 //\r
424 Status = BdsLibBootViaBootOption (Option, NewDevicePath, ExitDataSize, ExitData);\r
425 if (!EFI_ERROR (Status)) {\r
426 break;\r
427 }\r
428 }\r
429 }\r
430\r
431 gBS->FreePool (BlockIoBuffer);\r
432 return Status;\r
433}\r
434\r
435EFI_STATUS\r
436BdsLibEnumerateAllBootOption (\r
437 IN OUT LIST_ENTRY *BdsBootOptionList\r
438 )\r
439/*++\r
440\r
441Routine Description:\r
442\r
443 This function will enumerate all possible boot device in the system,\r
444 it will only excute once of every boot.\r
445\r
446Arguments:\r
447\r
448 BdsBootOptionList - The header of the link list which indexed all\r
449 current boot options\r
450\r
451Returns:\r
452\r
453 EFI_SUCCESS - Finished all the boot device enumerate and create\r
454 the boot option base on that boot device\r
455\r
456--*/\r
457{\r
458 EFI_STATUS Status;\r
459 UINT16 BootOptionNumber;\r
460 UINTN NumberFileSystemHandles;\r
461 EFI_HANDLE *FileSystemHandles;\r
462 UINTN NumberBlkIoHandles;\r
463 EFI_HANDLE *BlkIoHandles;\r
464 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
465 UINTN Index;\r
466 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
467 UINTN NumberLoadFileHandles;\r
468 EFI_HANDLE *LoadFileHandles;\r
469 VOID *ProtocolInstance;\r
470 EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;\r
471 UINTN FvHandleCount;\r
472 EFI_HANDLE *FvHandleBuffer;\r
473 EFI_FV_FILETYPE Type;\r
474 UINTN Size;\r
475 EFI_FV_FILE_ATTRIBUTES Attributes;\r
476 UINT32 AuthenticationStatus;\r
477\r
478 BootOptionNumber = 0;\r
479\r
480 //\r
481 // If the boot device enumerate happened, just get the boot\r
482 // device from the boot order variable\r
483 //\r
484 if (mEnumBootDevice) {\r
485 BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
486 return EFI_SUCCESS;\r
487 }\r
488 //\r
489 // Notes: this dirty code is to get the legacy boot option from the\r
490 // BBS table and create to variable as the EFI boot option, it should\r
491 // be removed after the CSM can provide legacy boot option directly\r
492 //\r
493 REFRESH_LEGACY_BOOT_OPTIONS;\r
494\r
495 //\r
496 // Check all the block IO to create boot option\r
497 //\r
498 gBS->LocateHandleBuffer (\r
499 ByProtocol,\r
500 &gEfiBlockIoProtocolGuid,\r
501 NULL,\r
502 &NumberBlkIoHandles,\r
503 &BlkIoHandles\r
504 );\r
505 for (Index = 0; Index < NumberBlkIoHandles; Index++) {\r
506 Status = gBS->HandleProtocol (\r
507 BlkIoHandles[Index],\r
508 &gEfiBlockIoProtocolGuid,\r
509 (VOID **) &BlkIo\r
510 );\r
511 if (EFI_ERROR (Status)) {\r
512 continue;\r
513 }\r
514\r
515 if (!BlkIo->Media->RemovableMedia) {\r
516 //\r
517 // Skip fixed Media device on first loop interration\r
518 //\r
519 continue;\r
520 }\r
521\r
522 DevicePath = DevicePathFromHandle (BlkIoHandles[Index]);\r
523 if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && \r
524 (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)\r
525 ) {\r
526 //\r
527 // Build the boot option\r
528 //\r
529 BdsLibBuildOptionFromHandle (BlkIoHandles[Index], BdsBootOptionList);\r
530 BootOptionNumber++;\r
531 }\r
532 }\r
533\r
534 if (NumberBlkIoHandles) {\r
535 gBS->FreePool (BlkIoHandles);\r
536 }\r
537 //\r
538 // Parse Fixed Disk Devices.\r
539 //\r
540 gBS->LocateHandleBuffer (\r
541 ByProtocol,\r
542 &gEfiSimpleFileSystemProtocolGuid,\r
543 NULL,\r
544 &NumberFileSystemHandles,\r
545 &FileSystemHandles\r
546 );\r
547 for (Index = 0; Index < NumberFileSystemHandles; Index++) {\r
548 Status = gBS->HandleProtocol (\r
549 FileSystemHandles[Index],\r
550 &gEfiBlockIoProtocolGuid,\r
551 (VOID **) &BlkIo\r
552 );\r
553 if (!EFI_ERROR (Status)) {\r
554 if (BlkIo->Media->RemovableMedia) {\r
555 //\r
556 // If the file system handle supports a BlkIo protocol,\r
557 // skip the removable media devices\r
558 //\r
559 continue;\r
560 }\r
561 }\r
562\r
563 DevicePath = DevicePathFromHandle (FileSystemHandles[Index]);\r
564 if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && \r
565 (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)\r
566 ) {\r
567 //\r
568 // If the FileSystem protocol does not contain a BlkIo protocol,\r
569 // then build it\r
570 //\r
571 BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList);\r
572 BootOptionNumber++;\r
573 }\r
574 }\r
575\r
576 if (NumberFileSystemHandles) {\r
577 gBS->FreePool (FileSystemHandles);\r
578 }\r
579 //\r
580 // Parse Network Boot Device\r
581 //\r
582 gBS->LocateHandleBuffer (\r
583 ByProtocol,\r
584 &gEfiSimpleNetworkProtocolGuid,\r
585 NULL,\r
586 &NumberLoadFileHandles,\r
587 &LoadFileHandles\r
588 );\r
589 for (Index = 0; Index < NumberLoadFileHandles; Index++) {\r
590 Status = gBS->HandleProtocol (\r
591 LoadFileHandles[Index],\r
592 &gEfiLoadFileProtocolGuid,\r
593 (VOID **) &ProtocolInstance\r
594 );\r
595 if (EFI_ERROR (Status)) {\r
596 continue;\r
597 }\r
598\r
599 BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList);\r
600 BootOptionNumber++;\r
601 }\r
602\r
603 if (NumberLoadFileHandles) {\r
604 gBS->FreePool (LoadFileHandles);\r
605 }\r
606 //\r
607 // Check if we have on flash shell\r
608 //\r
609 gBS->LocateHandleBuffer (\r
610 ByProtocol,\r
611 &gEfiFirmwareVolumeProtocolGuid,\r
612 NULL,\r
613 &FvHandleCount,\r
614 &FvHandleBuffer\r
615 );\r
616 for (Index = 0; Index < FvHandleCount; Index++) {\r
617 gBS->HandleProtocol (\r
618 FvHandleBuffer[Index],\r
619 &gEfiFirmwareVolumeProtocolGuid,\r
620 (VOID **) &Fv\r
621 );\r
622\r
623 Status = Fv->ReadFile (\r
624 Fv,\r
625 &gEfiShellFileGuid,\r
626 NULL,\r
627 &Size,\r
628 &Type,\r
629 &Attributes,\r
630 &AuthenticationStatus\r
631 );\r
632 if (EFI_ERROR (Status)) {\r
633 //\r
634 // Skip if no shell file in the FV\r
635 //\r
636 continue;\r
637 }\r
638 //\r
639 // Build the shell boot option\r
640 //\r
641 BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList);\r
642 BootOptionNumber++;\r
643 }\r
644\r
645 if (FvHandleCount) {\r
646 gBS->FreePool (FvHandleBuffer);\r
647 }\r
648 //\r
649 // Make sure every boot only have one time\r
650 // boot device enumerate\r
651 //\r
652 BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder");\r
653 mEnumBootDevice = TRUE;\r
654\r
655 return EFI_SUCCESS;\r
656}\r
657\r
658VOID\r
659BdsLibBuildOptionFromHandle (\r
660 IN EFI_HANDLE Handle,\r
661 IN LIST_ENTRY *BdsBootOptionList\r
662 )\r
663/*++\r
664\r
665Routine Description:\r
666 \r
667 Build the boot option with the handle parsed in\r
668 \r
669Arguments:\r
670\r
671 Handle - The handle which present the device path to create boot option\r
672 \r
673 BdsBootOptionList - The header of the link list which indexed all current\r
674 boot options\r
675\r
676Returns:\r
677\r
678 VOID\r
679\r
680--*/\r
681{\r
682 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
683 CHAR16 *TempString;\r
684\r
685 DevicePath = DevicePathFromHandle (Handle);\r
686 TempString = DevicePathToStr (DevicePath);\r
687\r
688 //\r
689 // Create and register new boot option\r
690 //\r
691 BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, TempString, L"BootOrder");\r
692}\r
693\r
694VOID\r
695BdsLibBuildOptionFromShell (\r
696 IN EFI_HANDLE Handle,\r
697 IN OUT LIST_ENTRY *BdsBootOptionList\r
698 )\r
699/*++\r
700\r
701Routine Description:\r
702 \r
703 Build the on flash shell boot option with the handle parsed in\r
704 \r
705Arguments:\r
706\r
707 Handle - The handle which present the device path to create on flash shell\r
708 boot option\r
709 \r
710 BdsBootOptionList - The header of the link list which indexed all current\r
711 boot options\r
712\r
713Returns:\r
714\r
715 None\r
716\r
717--*/\r
718{\r
719 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
720 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode;\r
721\r
722 DevicePath = DevicePathFromHandle (Handle);\r
723\r
724 //\r
725 // Build the shell device path\r
726 //\r
727 EfiInitializeFwVolDevicepathNode (&ShellNode, &gEfiShellFileGuid);\r
728 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode);\r
729\r
730 //\r
731 // Create and register the shell boot option\r
732 //\r
733 BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"Internal EFI Shell", L"BootOrder");\r
734\r
735}\r
736\r
737VOID\r
738BdsLibBootNext (\r
739 VOID\r
740 )\r
741/*++\r
742\r
743Routine Description:\r
744 \r
745 Boot from the EFI1.1 spec defined "BootNext" variable\r
746 \r
747Arguments:\r
748\r
749 None\r
750 \r
751Returns:\r
752\r
753 None\r
754\r
755--*/\r
756{\r
757 UINT16 *BootNext;\r
758 UINTN BootNextSize;\r
759 CHAR16 Buffer[20];\r
760 BDS_COMMON_OPTION *BootOption;\r
761 LIST_ENTRY TempList;\r
762 UINTN ExitDataSize;\r
763 CHAR16 *ExitData;\r
764\r
765 //\r
766 // Init the boot option name buffer and temp link list\r
767 //\r
768 InitializeListHead (&TempList);\r
769 ZeroMem (Buffer, sizeof (Buffer));\r
770\r
771 BootNext = BdsLibGetVariableAndSize (\r
772 L"BootNext",\r
773 &gEfiGlobalVariableGuid,\r
774 &BootNextSize\r
775 );\r
776\r
777 //\r
778 // Clear the boot next variable first\r
779 //\r
780 if (BootNext != NULL) {\r
781 gRT->SetVariable (\r
782 L"BootNext",\r
783 &gEfiGlobalVariableGuid,\r
784 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
785 0,\r
786 BootNext\r
787 );\r
788\r
789 //\r
790 // Start to build the boot option and try to boot\r
791 //\r
792 UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext);\r
793 BootOption = BdsLibVariableToOption (&TempList, Buffer);\r
794 BdsLibConnectDevicePath (BootOption->DevicePath);\r
795 BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);\r
796 }\r
797\r
798}\r