]> git.proxmox.com Git - mirror_edk2.git/blame - Nt32Pkg/PlatformBdsDxe/BdsPlatform.c
Back the wrong check in for MdeModulePkg.dsc.
[mirror_edk2.git] / Nt32Pkg / PlatformBdsDxe / BdsPlatform.c
CommitLineData
bc11b829 1/*++\r
2\r
3Copyright (c) 2006 - 2007, 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 BdsPlatform.c\r
15\r
16Abstract:\r
17\r
18 This file include all platform action which can be customized\r
19 by IBV/OEM.\r
20\r
21--*/\r
22\r
bc11b829 23#include "Generic/Bds.h"\r
24#include "BdsPlatform.h"\r
06335580 25#include "Generic/BdsString.h"\r
bc11b829 26#include "Generic/Language.h"\r
27#include "Generic/FrontPage.h"\r
28\r
29CHAR16 mFirmwareVendor[] = L"TianoCore.org";\r
30\r
4bdccd28 31EFI_EVENT mReadyToBootEvent;\r
32\r
33EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
34 { EfiACPIReclaimMemory, 0 },\r
35 { EfiACPIMemoryNVS, 0 },\r
36 { EfiReservedMemoryType, 0 },\r
37 { EfiRuntimeServicesData, 0 },\r
38 { EfiRuntimeServicesCode, 0 },\r
39 { EfiBootServicesCode, 0 },\r
40 { EfiBootServicesData, 0 },\r
41 { EfiLoaderCode, 0 },\r
42 { EfiLoaderData, 0 },\r
43 { EfiMaxMemoryType, 0 }\r
44};\r
45\r
46VOID \r
47BdsSetMemoryTypeInformationVariable (\r
48 VOID\r
49 )\r
50{\r
51 EFI_STATUS Status;\r
52 EFI_MEMORY_TYPE_INFORMATION *PreviousMemoryTypeInformation;\r
53 EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation;\r
54 UINTN VariableSize;\r
55 BOOLEAN UpdateRequired;\r
56 UINTN Index;\r
57 UINTN Index1;\r
58 UINT32 Previous;\r
59 UINT32 Current;\r
60 UINT32 Next;\r
61 EFI_HOB_GUID_TYPE *Hob;\r
62\r
63 UpdateRequired = FALSE;\r
64\r
65 //\r
66 // Retrieve the current memory usage statistics. If they are not found, then\r
67 // no adjustments can be made to the Memory Type Information variable.\r
68 //\r
69 Status = EfiGetSystemConfigurationTable (&gEfiMemoryTypeInformationGuid, (VOID **)&CurrentMemoryTypeInformation);\r
70 if (EFI_ERROR (Status)) {\r
71 return;\r
72 }\r
73\r
74 //\r
75 // Get the Memory Type Information settings from a previous boot if they exist.\r
76 //\r
77 PreviousMemoryTypeInformation = BdsLibGetVariableAndSize (\r
78 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
79 &gEfiMemoryTypeInformationGuid,\r
80 &VariableSize\r
81 );\r
82\r
83 //\r
84 // If the previous Memory Type Information is not available, then set defaults\r
85 //\r
86 if (PreviousMemoryTypeInformation == NULL) {\r
87 Hob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid);\r
88\r
89 if (Hob != NULL) {\r
90 PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (Hob);\r
91 VariableSize = GET_GUID_HOB_DATA_SIZE (Hob);\r
92 ASSERT (VariableSize == sizeof (mDefaultMemoryTypeInformation));\r
93 CopyMem (mDefaultMemoryTypeInformation, PreviousMemoryTypeInformation, VariableSize);\r
94 } else {\r
95 PreviousMemoryTypeInformation = mDefaultMemoryTypeInformation;\r
96 VariableSize = sizeof (mDefaultMemoryTypeInformation);\r
97 }\r
98 UpdateRequired = TRUE;\r
99 }\r
100\r
101 //\r
102 // Use a hueristic to adjust the Memory Type Information for the next boot\r
103 //\r
104 for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {\r
105\r
106 Current = 0;\r
107 for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) {\r
108 if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) {\r
109 Current = CurrentMemoryTypeInformation[Index1].NumberOfPages;\r
110 break;\r
111 }\r
112 }\r
113\r
114 if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) {\r
115 continue;\r
116 }\r
117\r
118 Previous = PreviousMemoryTypeInformation[Index].NumberOfPages;\r
119\r
120 if (Current > Previous) {\r
121 Next = Current + (Current >> 2);\r
122 } else if (Current < (Previous >> 1)) {\r
123 Next = Previous - (Previous >> 2);\r
124 } else {\r
125 Next = Previous;\r
126 }\r
127 if (Next > 0 && Next <= 16) {\r
128 Next = 16;\r
129 }\r
130\r
131 if (Next != Previous) {\r
132 PreviousMemoryTypeInformation[Index].NumberOfPages = Next;\r
133 UpdateRequired = TRUE;\r
134 }\r
135 }\r
136\r
137 //\r
138 // If any changes were made to the Memory Type Information settings, then set the new variable value\r
139 //\r
140 if (UpdateRequired) {\r
141 Status = gRT->SetVariable (\r
142 EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,\r
143 &gEfiMemoryTypeInformationGuid,\r
144 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
145 VariableSize,\r
146 PreviousMemoryTypeInformation\r
147 );\r
148 }\r
149\r
150 return;\r
151}\r
152\r
153\r
154/*++\r
155\r
156Routine Description:\r
157\r
158 This routine is a notification function for legayc boot or exit boot\r
159 service event. It will adjust the memory information for different\r
160 memory type and save them into the variables for next boot\r
161\r
162Arguments:\r
163\r
164 Event - The event that triggered this notification function\r
165 Context - Pointer to the notification functions context\r
166\r
167Returns:\r
168\r
169 None.\r
170\r
171--*/\r
172VOID\r
173EFIAPI\r
174BdsReadyToBootEvent (\r
175 EFI_EVENT Event,\r
176 VOID *Context\r
177 )\r
178{\r
179 BdsSetMemoryTypeInformationVariable ();\r
180}\r
181\r
bc11b829 182//\r
183// BDS Platform Functions\r
184//\r
185VOID\r
186PlatformBdsInit (\r
187 IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData\r
188 )\r
189/*++\r
190\r
191Routine Description:\r
192\r
193 Platform Bds init. Incude the platform firmware vendor, revision\r
194 and so crc check.\r
195\r
196Arguments:\r
197\r
198 PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
199\r
200Returns:\r
201\r
202 None.\r
203\r
204--*/\r
205{\r
206 //\r
207 // set firmwarevendor, here can be IBV/OEM customize\r
208 //\r
209 gST->FirmwareVendor = AllocateRuntimeCopyPool (\r
210 sizeof (mFirmwareVendor),\r
211 &mFirmwareVendor\r
212 );\r
213 ASSERT (gST->FirmwareVendor != NULL);\r
214\r
851d410b 215 gST->FirmwareRevision = FIRMWARE_REVISION;\r
bc11b829 216\r
217 //\r
218 // Fixup Tasble CRC after we updated Firmware Vendor and Revision\r
219 //\r
220 gBS->CalculateCrc32 ((VOID *) gST, sizeof (EFI_SYSTEM_TABLE), &gST->Hdr.CRC32);\r
221\r
4bdccd28 222 //\r
223 // Create Ready To Boot event\r
224 // \r
225 EfiCreateEventReadyToBootEx (\r
226 TPL_CALLBACK,\r
227 BdsReadyToBootEvent,\r
228 NULL,\r
229 &mReadyToBootEvent\r
230 );\r
231\r
bc11b829 232 //\r
233 // Initialize the platform specific string and language\r
234 //\r
235 InitializeStringSupport ();\r
236 InitializeLanguage (TRUE);\r
237 InitializeFrontPage (FALSE);\r
238\r
239}\r
240\r
241EFI_STATUS\r
242PlatformBdsConnectConsole (\r
243 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
244 )\r
245/*++\r
246\r
247Routine Description:\r
248\r
249 Connect the predefined platform default console device. Always try to find\r
250 and enable the vga device if have.\r
251\r
252Arguments:\r
253\r
254 PlatformConsole - Predfined platform default console device array.\r
255 \r
256Returns:\r
257\r
258 EFI_SUCCESS - Success connect at least one ConIn and ConOut \r
259 device, there must have one ConOut device is \r
260 active vga device.\r
261 \r
262 EFI_STATUS - Return the status of \r
263 BdsLibConnectAllDefaultConsoles ()\r
264\r
265--*/\r
266{\r
267 EFI_STATUS Status;\r
268 UINTN Index;\r
269\r
270 Index = 0;\r
271 Status = EFI_SUCCESS;\r
272\r
273 //\r
274 // Have chance to connect the platform default console,\r
275 // the platform default console is the minimue device group\r
276 // the platform should support\r
277 //\r
278 while (PlatformConsole[Index].DevicePath != NULL) {\r
279 //\r
280 // Update the console variable with the connect type\r
281 //\r
282 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
283 BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);\r
284 }\r
285\r
286 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
287 BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);\r
288 }\r
289\r
290 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
291 BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);\r
292 }\r
293\r
294 Index++;\r
295 }\r
296 //\r
297 // Connect the all the default console with current cosole variable\r
298 //\r
299 Status = BdsLibConnectAllDefaultConsoles ();\r
300 if (EFI_ERROR (Status)) {\r
301 return Status;\r
302 }\r
303\r
304 return EFI_SUCCESS;\r
305}\r
306\r
307VOID\r
308PlatformBdsConnectSequence (\r
309 VOID\r
310 )\r
311/*++\r
312\r
313Routine Description:\r
314\r
315 Connect with predeined platform connect sequence, \r
316 the OEM/IBV can customize with their own connect sequence.\r
317 \r
318Arguments:\r
319\r
320 None.\r
321 \r
322Returns:\r
323\r
324 None.\r
325 \r
326--*/\r
327{\r
328 UINTN Index;\r
329\r
330 Index = 0;\r
331\r
332 //\r
333 // Here we can get the customized platform connect sequence\r
334 // Notes: we can connect with new variable which record the\r
335 // last time boots connect device path sequence\r
336 //\r
337 while (gPlatformConnectSequence[Index] != NULL) {\r
338 //\r
339 // Build the platform boot option\r
340 //\r
341 BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);\r
342 Index++;\r
343 }\r
344\r
345}\r
346\r
347VOID\r
348PlatformBdsGetDriverOption (\r
349 IN OUT LIST_ENTRY *BdsDriverLists\r
350 )\r
351/*++\r
352\r
353Routine Description:\r
354\r
355 Load the predefined driver option, OEM/IBV can customize this\r
356 to load their own drivers\r
357 \r
358Arguments:\r
359\r
360 BdsDriverLists - The header of the driver option link list.\r
361 \r
362Returns:\r
363\r
364 None.\r
365 \r
366--*/\r
367{\r
368 UINTN Index;\r
369\r
370 Index = 0;\r
371\r
372 //\r
373 // Here we can get the customized platform driver option\r
374 //\r
375 while (gPlatformDriverOption[Index] != NULL) {\r
376 //\r
377 // Build the platform boot option\r
378 //\r
379 BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");\r
380 Index++;\r
381 }\r
382\r
383}\r
384\r
385VOID\r
386PlatformBdsDiagnostics (\r
387 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,\r
388 IN BOOLEAN QuietBoot\r
389 )\r
390/*++\r
391\r
392Routine Description:\r
393\r
394 Perform the platform diagnostic, such like test memory. OEM/IBV also\r
395 can customize this fuction to support specific platform diagnostic.\r
396 \r
397Arguments:\r
398\r
399 MemoryTestLevel - The memory test intensive level\r
400 \r
401 QuietBoot - Indicate if need to enable the quiet boot\r
402 \r
403Returns:\r
404\r
405 None.\r
406 \r
407--*/\r
408{\r
409 EFI_STATUS Status;\r
410\r
411 //\r
412 // Here we can decide if we need to show\r
413 // the diagnostics screen\r
414 // Notes: this quiet boot code should be remove\r
415 // from the graphic lib\r
416 //\r
417 if (QuietBoot) {\r
418 EnableQuietBoot (&gEfiDefaultBmpLogoGuid);\r
419 //\r
420 // Perform system diagnostic\r
421 //\r
422 Status = BdsMemoryTest (MemoryTestLevel);\r
423 if (EFI_ERROR (Status)) {\r
424 DisableQuietBoot ();\r
425 }\r
426\r
427 return ;\r
428 }\r
429 //\r
430 // Perform system diagnostic\r
431 //\r
432 Status = BdsMemoryTest (MemoryTestLevel);\r
433}\r
434\r
435VOID\r
436PlatformBdsPolicyBehavior (\r
437 IN EFI_BDS_ARCH_PROTOCOL_INSTANCE *PrivateData,\r
438 IN OUT LIST_ENTRY *DriverOptionList,\r
439 IN OUT LIST_ENTRY *BootOptionList\r
440 )\r
441/*++\r
442\r
443Routine Description:\r
444\r
445 The function will excute with as the platform policy, current policy\r
446 is driven by boot mode. IBV/OEM can customize this code for their specific\r
447 policy action.\r
448 \r
449Arguments:\r
450\r
451 PrivateData - The EFI_BDS_ARCH_PROTOCOL_INSTANCE instance\r
452 \r
453 DriverOptionList - The header of the driver option link list\r
454 \r
455 BootOptionList - The header of the boot option link list\r
456 \r
457Returns:\r
458\r
459 None.\r
460 \r
461--*/\r
462{\r
463 EFI_STATUS Status;\r
464 UINT16 Timeout;\r
465\r
466 //\r
467 // Init the time out value\r
468 //\r
469 Timeout = BdsLibGetTimeout ();\r
470\r
471 //\r
472 // Load the driver option as the driver option list\r
473 //\r
474 PlatformBdsGetDriverOption (DriverOptionList);\r
475\r
476 //\r
477 // Get current Boot Mode\r
478 //\r
479 PrivateData->BootMode = GetBootModeHob();\r
480\r
481 //\r
482 // Go the different platform policy with different boot mode\r
483 // Notes: this part code can be change with the table policy\r
484 //\r
485 switch (PrivateData->BootMode) {\r
486\r
487 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:\r
488 case BOOT_WITH_MINIMAL_CONFIGURATION:\r
489 //\r
490 // In no-configuration boot mode, we can connect the\r
491 // console directly.\r
492 //\r
493 BdsLibConnectAllDefaultConsoles ();\r
494 PlatformBdsDiagnostics (IGNORE, TRUE);\r
495\r
496 //\r
497 // Perform some platform specific connect sequence\r
498 //\r
499 PlatformBdsConnectSequence ();\r
500\r
501 //\r
502 // Notes: current time out = 0 can not enter the\r
503 // front page\r
504 //\r
505 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
506\r
507 //\r
508 // Check the boot option with the boot option list\r
509 //\r
510 BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");\r
511 break;\r
512\r
513 case BOOT_ON_FLASH_UPDATE:\r
514 //\r
515 // Boot with the specific configuration\r
516 //\r
517 PlatformBdsConnectConsole (gPlatformConsole);\r
518 PlatformBdsDiagnostics (EXTENSIVE, FALSE);\r
519 BdsLibConnectAll ();\r
520 ProcessCapsules (BOOT_ON_FLASH_UPDATE);\r
521 break;\r
522\r
523 case BOOT_IN_RECOVERY_MODE:\r
524 //\r
525 // In recovery mode, just connect platform console\r
526 // and show up the front page\r
527 //\r
528 PlatformBdsConnectConsole (gPlatformConsole);\r
529 PlatformBdsDiagnostics (EXTENSIVE, FALSE);\r
530\r
531 //\r
532 // In recovery boot mode, we still enter to the\r
533 // frong page now\r
534 //\r
535 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
536 break;\r
537\r
538 case BOOT_WITH_FULL_CONFIGURATION:\r
539 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:\r
540 case BOOT_WITH_DEFAULT_SETTINGS:\r
541 default:\r
542 //\r
543 // Connect platform console\r
544 //\r
545 Status = PlatformBdsConnectConsole (gPlatformConsole);\r
546 if (EFI_ERROR (Status)) {\r
547 //\r
548 // Here OEM/IBV can customize with defined action\r
549 //\r
550 PlatformBdsNoConsoleAction ();\r
551 }\r
552\r
553 PlatformBdsDiagnostics (IGNORE, TRUE);\r
554\r
555 //\r
556 // Perform some platform specific connect sequence\r
557 //\r
558 PlatformBdsConnectSequence ();\r
559\r
560 //\r
561 // Give one chance to enter the setup if we\r
562 // have the time out\r
563 //\r
564 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
565\r
566 //\r
567 // Here we have enough time to do the enumeration of boot device\r
568 //\r
569 BdsLibEnumerateAllBootOption (BootOptionList);\r
570 break;\r
571 }\r
572\r
573 return ;\r
574\r
575}\r
576\r
577VOID\r
578PlatformBdsBootSuccess (\r
579 IN BDS_COMMON_OPTION *Option\r
580 )\r
581/*++\r
582\r
583Routine Description:\r
584 \r
585 Hook point after a boot attempt succeeds. We don't expect a boot option to\r
8a7d75b0 586 return, so the UEFI 2.0 specification defines that you will default to an\r
bc11b829 587 interactive mode and stop processing the BootOrder list in this case. This\r
588 is alos a platform implementation and can be customized by IBV/OEM.\r
589\r
590Arguments:\r
591\r
592 Option - Pointer to Boot Option that succeeded to boot.\r
593\r
594Returns:\r
595 \r
596 None.\r
597\r
598--*/\r
599{\r
600 CHAR16 *TmpStr;\r
601\r
602 //\r
603 // If Boot returned with EFI_SUCCESS and there is not in the boot device\r
604 // select loop then we need to pop up a UI and wait for user input.\r
605 //\r
606 TmpStr = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));\r
607 if (TmpStr != NULL) {\r
608 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
609 FreePool (TmpStr);\r
610 }\r
611}\r
612\r
613VOID\r
614PlatformBdsBootFail (\r
615 IN BDS_COMMON_OPTION *Option,\r
616 IN EFI_STATUS Status,\r
617 IN CHAR16 *ExitData,\r
618 IN UINTN ExitDataSize\r
619 )\r
620/*++\r
621\r
622Routine Description:\r
623 \r
624 Hook point after a boot attempt fails.\r
625\r
626Arguments:\r
627 \r
628 Option - Pointer to Boot Option that failed to boot.\r
629\r
630 Status - Status returned from failed boot.\r
631\r
632 ExitData - Exit data returned from failed boot.\r
633\r
634 ExitDataSize - Exit data size returned from failed boot.\r
635\r
636Returns:\r
637 \r
638 None.\r
639\r
640--*/\r
641{\r
642 CHAR16 *TmpStr;\r
643\r
644 //\r
645 // If Boot returned with failed status then we need to pop up a UI and wait\r
646 // for user input.\r
647 //\r
648 TmpStr = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));\r
649 if (TmpStr != NULL) {\r
650 BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);\r
651 FreePool (TmpStr);\r
652 }\r
653\r
654}\r
655\r
656EFI_STATUS\r
657PlatformBdsNoConsoleAction (\r
658 VOID\r
659 )\r
660/*++\r
661\r
662Routine Description:\r
663 \r
664 This function is remained for IBV/OEM to do some platform action,\r
665 if there no console device can be connected.\r
666\r
667Arguments:\r
668 \r
669 None.\r
670 \r
671Returns:\r
672 \r
673 EFI_SUCCESS - Direct return success now.\r
674\r
675--*/\r
676{\r
677 return EFI_SUCCESS;\r
678}\r