OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
BdsPlatform.c
Go to the documentation of this file.
1/*++
2
3Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4This program and the accompanying materials
5are licensed and made available under the terms and conditions of the BSD License
6which accompanies this distribution. The full text of the license may be found at
7http://opensource.org/licenses/bsd-license.php
8
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12Module Name:
13
14 BdsPlatform.c
15
16Abstract:
17
18 This file include all platform action which can be customized
19 by IBV/OEM.
20--*/
21
22#include "BdsPlatform.h"
23
24#include <PiDxe.h>
25
26#include <Guid/Acpi.h>
28#include <Guid/SmBios.h>
29
30#include <IndustryStandard/Pci.h>
31#include <IndustryStandard/SmBios.h>
32
33#include <Library/BaseLib.h>
34#include <Library/BaseMemoryLib.h>
35#include <Library/DebugLib.h>
36#include <Library/DevicePathLib.h>
37#include <Library/DxeServicesTableLib.h>
38#include <Library/HobLib.h>
39#include <Library/UefiBootServicesTableLib.h>
40
41#include <Protocol/PciIo.h>
42
43EFI_GUID *gTableGuidArray[] = {
44 &gEfiAcpi10TableGuid,
45 &gEfiAcpiTableGuid,
48};
49
50//
51// BDS Platform Functions
52//
53
54STATIC
55EFI_STATUS
57 IN UINTN TableLen,
58 IN OUT VOID **Table
59 )
60
61/*++
62
63Routine Description:
64 Convert RSDP of ACPI Table if its location is lower than Address:0x100000
65 Assumption here:
66 As in legacy Bios, ACPI table is required to place in E/F Seg,
67 So here we just check if the range is E/F seg,
68 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
69
70Arguments:
71 TableLen - Acpi RSDP length
72 Table - pointer to the table
73
74Returns:
75 EFI_SUCEESS - Convert Table successfully
76 Other - Failed
77
78--*/
79{
80 VOID *AcpiTableOri;
81 VOID *AcpiTableNew;
82 EFI_STATUS Status;
83 EFI_PHYSICAL_ADDRESS BufferPtr;
84
85 AcpiTableOri = (VOID *)(UINTN)(*(UINT64 *)(*Table));
86 if (((UINTN)AcpiTableOri < 0x100000) && ((UINTN)AcpiTableOri > 0xE0000)) {
88 Status = gBS->AllocatePages (
89 AllocateMaxAddress,
90 EfiACPIMemoryNVS,
91 EFI_SIZE_TO_PAGES (TableLen),
92 &BufferPtr
93 );
94 ASSERT_EFI_ERROR (Status);
95
96 AcpiTableNew = (VOID *)(UINTN)BufferPtr;
97 CopyMem (AcpiTableNew, AcpiTableOri, TableLen);
98 } else {
99 AcpiTableNew = AcpiTableOri;
100 }
101
102 //
103 // Change configuration table Pointer
104 //
105 *Table = AcpiTableNew;
106
107 return EFI_SUCCESS;
108}
109
110STATIC
111EFI_STATUS
113 IN OUT VOID **Table
114 )
115
116/*++
117
118Routine Description:
119
120 Convert Smbios Table if the Location of the SMBios Table is lower than Addres 0x100000
121 Assumption here:
122 As in legacy Bios, Smbios table is required to place in E/F Seg,
123 So here we just check if the range is F seg,
124 and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
125Arguments:
126 Table - pointer to the table
127
128Returns:
129 EFI_SUCEESS - Convert Table successfully
130 Other - Failed
131
132--*/
133{
134 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableNew;
135 SMBIOS_TABLE_ENTRY_POINT *SmbiosTableOri;
136 EFI_STATUS Status;
137 UINT32 SmbiosEntryLen;
138 UINT32 BufferLen;
139 EFI_PHYSICAL_ADDRESS BufferPtr;
140
141 SmbiosTableNew = NULL;
142
143 //
144 // Get Smibos configuration Table
145 //
146 SmbiosTableOri = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)(*(UINT64 *)(*Table));
147
148 if ((SmbiosTableOri == NULL) ||
149 ((UINTN)SmbiosTableOri > 0x100000) ||
150 ((UINTN)SmbiosTableOri < 0xF0000))
151 {
152 return EFI_SUCCESS;
153 }
154
155 //
156 // Relocate the Smibos memory
157 //
159 if (SmbiosTableOri->SmbiosBcdRevision != 0x21) {
160 SmbiosEntryLen = SmbiosTableOri->EntryPointLength;
161 } else {
162 //
163 // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1
164 //
165 SmbiosEntryLen = 0x1F;
166 }
167
168 BufferLen = SmbiosEntryLen + SYS_TABLE_PAD (SmbiosEntryLen) + SmbiosTableOri->TableLength;
169 Status = gBS->AllocatePages (
170 AllocateMaxAddress,
171 EfiACPIMemoryNVS,
172 EFI_SIZE_TO_PAGES (BufferLen),
173 &BufferPtr
174 );
175 ASSERT_EFI_ERROR (Status);
176
177 SmbiosTableNew = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)BufferPtr;
178 CopyMem (
179 SmbiosTableNew,
180 SmbiosTableOri,
181 SmbiosEntryLen
182 );
183 //
184 // Get Smbios Structure table address, and make sure the start address is 32-bit align
185 //
186 BufferPtr += SmbiosEntryLen + SYS_TABLE_PAD (SmbiosEntryLen);
187 CopyMem (
188 (VOID *)(UINTN)BufferPtr,
189 (VOID *)(UINTN)(SmbiosTableOri->TableAddress),
190 SmbiosTableOri->TableLength
191 );
192 SmbiosTableNew->TableAddress = (UINT32)BufferPtr;
193 SmbiosTableNew->SmbiosBcdRevision = 0x26;
194 SmbiosTableNew->IntermediateChecksum = 0;
195 SmbiosTableNew->IntermediateChecksum = CalculateCheckSum8 (
196 (UINT8 *)SmbiosTableNew + 0x10,
197 SmbiosEntryLen - 0x10
198 );
199 //
200 // Change the SMBIOS pointer
201 //
202 *Table = SmbiosTableNew;
203
204 return EFI_SUCCESS;
205}
206
207STATIC
208EFI_STATUS
210 IN EFI_GUID *TableGuid,
211 IN OUT VOID **Table
212 )
213
214/*++
215
216Routine Description:
217 Convert ACPI Table /Smbios Table /MP Table if its location is lower than Address:0x100000
218 Assumption here:
219 As in legacy Bios, ACPI/Smbios/MP table is required to place in E/F Seg,
220 So here we just check if the range is E/F seg,
221 and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
222
223Arguments:
224 TableGuid - Guid of the table
225 Table - pointer to the table
226
227Returns:
228 EFI_SUCEESS - Convert Table successfully
229 Other - Failed
230
231--*/
232{
233 EFI_STATUS Status;
234 VOID *AcpiHeader;
235 UINTN AcpiTableLen;
236
237 //
238 // If match acpi guid (1.0, 2.0, or later), Convert ACPI table according to version.
239 //
240 AcpiHeader = (VOID *)(UINTN)(*(UINT64 *)(*Table));
241
242 if (CompareGuid (TableGuid, &gEfiAcpiTableGuid) || CompareGuid (TableGuid, &gEfiAcpi20TableGuid)) {
243 if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved == 0x00) {
244 //
245 // If Acpi 1.0 Table, then RSDP structure doesn't contain Length field, use structure size
246 //
247 AcpiTableLen = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
248 } else if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved >= 0x02) {
249 //
250 // If Acpi 2.0 or later, use RSDP Length fied.
251 //
252 AcpiTableLen = ((EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Length;
253 } else {
254 //
255 // Invalid Acpi Version, return
256 //
257 return EFI_UNSUPPORTED;
258 }
259
260 Status = ConvertAcpiTable (AcpiTableLen, Table);
261 return Status;
262 }
263
264 //
265 // If matches smbios guid, convert Smbios table.
266 //
267 if (CompareGuid (TableGuid, &gEfiSmbiosTableGuid) ||
268 CompareGuid (TableGuid, &gEfiSmbios3TableGuid))
269 {
270 Status = ConvertSmbiosTable (Table);
271 return Status;
272 }
273
274 return EFI_UNSUPPORTED;
275}
276
277STATIC
278VOID
280 VOID
281 )
282
283/*++
284
285Routine Description:
286 Find GUID'ed HOBs that contain EFI_PHYSICAL_ADDRESS of ACPI, SMBIOS, MPs tables
287
288Arguments:
289 None
290
291Returns:
292 None.
293
294--*/
295{
296 EFI_PEI_HOB_POINTERS GuidHob;
297 EFI_PEI_HOB_POINTERS HobStart;
298 EFI_PHYSICAL_ADDRESS *Table;
299 UINTN Index;
300
301 //
302 // Get Hob List
303 //
304 HobStart.Raw = GetHobList ();
305 //
306 // Iteratively add ACPI Table, SMBIOS Table, MPS Table to EFI System Table
307 //
308 for (Index = 0; Index < sizeof (gTableGuidArray) / sizeof (*gTableGuidArray); ++Index) {
309 GuidHob.Raw = GetNextGuidHob (gTableGuidArray[Index], HobStart.Raw);
310 if (GuidHob.Raw != NULL) {
311 Table = GET_GUID_HOB_DATA (GuidHob.Guid);
312 if (Table != NULL) {
313 //
314 // Check if Mps Table/Smbios Table/Acpi Table exists in E/F seg,
315 // According to UEFI Spec, we should make sure Smbios table,
316 // ACPI table and Mps tables kept in memory of specified type
317 //
318 ConvertSystemTable (gTableGuidArray[Index], (VOID **)&Table);
319 gBS->InstallConfigurationTable (gTableGuidArray[Index], (VOID *)Table);
320 }
321 }
322 }
323}
324
325STATIC
326VOID
328 VOID
329 )
330{
331 EFI_STATUS Status;
332 UINTN NumberOfDescriptors;
333 EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
334 UINT64 Capabilities;
335 EFI_PEI_HOB_POINTERS GuidHob;
336 VOID *Table;
337 MEMORY_DESC_HOB MemoryDescHob;
338 UINTN Index;
339 EFI_PHYSICAL_ADDRESS Memory;
340 EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
341 EFI_PHYSICAL_ADDRESS FirstNonConventionalAddr;
342
343 //
344 // Promote reserved memory to system memory.
345 //
346 Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
347 ASSERT_EFI_ERROR (Status);
348
349 for (Index = 0; Index < NumberOfDescriptors; ++Index) {
350 Capabilities = MemorySpaceMap[Index].Capabilities;
351
352 if ( (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved)
355 {
356 Status = gDS->RemoveMemorySpace (
357 MemorySpaceMap[Index].BaseAddress,
358 MemorySpaceMap[Index].Length
359 );
360 if (EFI_ERROR (Status)) {
361 //
362 // This loop's purpose is to free reserved memory above 4GB. DxeCore
363 // itself is also found (below 4GB) and gives Access Denied here
364 // because it is associated with an image handle.
365 // TODO: Is it is possible to work round issue in first REF (note: that
366 // line dates to original EDK II DuetPkg) while still allowing DxeCore
367 // memory to be mapped as System rather than Reserved in the first place
368 // (see second REF)? (If it's not mapped correctly in the first place
369 // and it's associated with an image handle, it can't be remapped later
370 // using gDS calls.)
371 // REF: https://github.com/acidanthera/OpenCorePkg/blob/2462e02d49b8b9f2562ca76850b73477cc573d47/Legacy/BootPlatform/DxeIpl/HobGeneration.c#L201
372 // REF: https://github.com/acidanthera/audk/blob/e26eb0f9c18e6672c9516dbfdebf2dd9f750207e/MdeModulePkg/Core/Dxe/Gcd/Gcd.c#L2577-L2587
373 //
374 DEBUG ((
375 EFI_D_INFO,
376 "UpdateMemoryMap: Remove %016lx %016lx - %r\n",
377 MemorySpaceMap[Index].BaseAddress,
378 MemorySpaceMap[Index].Length,
379 Status
380 ));
381 continue;
382 }
383
384 Status = gDS->AddMemorySpace (
385 (Capabilities & EFI_MEMORY_MORE_RELIABLE) == EFI_MEMORY_MORE_RELIABLE
386 ? EfiGcdMemoryTypeMoreReliable : EfiGcdMemoryTypeSystemMemory,
387 MemorySpaceMap[Index].BaseAddress,
388 MemorySpaceMap[Index].Length,
389 Capabilities &~(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME)
390 );
391 ASSERT_EFI_ERROR (Status);
392 DEBUG ((
393 EFI_D_INFO,
394 "UpdateMemoryMap: Remap %016lx %016lx - %r\n",
395 MemorySpaceMap[Index].BaseAddress,
396 MemorySpaceMap[Index].Length,
397 Status
398 ));
399 }
400 }
401
402 gBS->FreePool (MemorySpaceMap);
403
404 //
405 // Add ACPINVS, ACPIReclaim, and Reserved memory to MemoryMap.
406 //
408 if (GuidHob.Raw == NULL) {
409 return;
410 }
411
412 Table = GET_GUID_HOB_DATA (GuidHob.Guid);
413 if (Table == NULL) {
414 return;
415 }
416
417 MemoryDescHob.MemDescCount = *(UINTN *)Table;
418 MemoryDescHob.MemDesc = *(EFI_MEMORY_DESCRIPTOR **)((UINTN)Table + sizeof (UINTN));
419
420 FirstNonConventionalAddr = 0xFFFFFFFF;
421 for (Index = 0; Index < MemoryDescHob.MemDescCount; Index++) {
422 if (MemoryDescHob.MemDesc[Index].PhysicalStart < 0x100000) {
423 continue;
424 }
425
426 if (MemoryDescHob.MemDesc[Index].PhysicalStart >= 0x100000000ULL) {
427 continue;
428 }
429
430 if ( (MemoryDescHob.MemDesc[Index].Type == EfiReservedMemoryType)
431 || (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData)
432 || (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode)
433 || (MemoryDescHob.MemDesc[Index].Type == EfiACPIReclaimMemory)
434 || (MemoryDescHob.MemDesc[Index].Type == EfiACPIMemoryNVS))
435 {
436 if (MemoryDescHob.MemDesc[Index].PhysicalStart < FirstNonConventionalAddr) {
437 FirstNonConventionalAddr = MemoryDescHob.MemDesc[Index].PhysicalStart;
438 }
439
440 if ( (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData)
441 || (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode))
442 {
443 //
444 // For RuntimeSevicesData and RuntimeServicesCode, they are BFV or DxeCore.
445 // The memory type is assigned in EfiLdr
446 //
447 Status = gDS->GetMemorySpaceDescriptor (MemoryDescHob.MemDesc[Index].PhysicalStart, &Descriptor);
448 if (EFI_ERROR (Status)) {
449 continue;
450 }
451
452 if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) {
453 //
454 // BFV or tested DXE core
455 //
456 continue;
457 }
458
459 //
460 // Untested DXE Core region, free and remove
461 //
462 Status = gDS->FreeMemorySpace (
463 MemoryDescHob.MemDesc[Index].PhysicalStart,
464 LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT)
465 );
466
467 if (EFI_ERROR (Status)) {
468 continue;
469 }
470
471 Status = gDS->RemoveMemorySpace (
472 MemoryDescHob.MemDesc[Index].PhysicalStart,
473 LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT)
474 );
475 if (EFI_ERROR (Status)) {
476 continue;
477 }
478
479 //
480 // Convert Runtime type to BootTime type
481 //
482 if (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) {
483 MemoryDescHob.MemDesc[Index].Type = EfiBootServicesData;
484 } else {
485 MemoryDescHob.MemDesc[Index].Type = EfiBootServicesCode;
486 }
487
488 //
489 // PassThrough, let below code add and allocate.
490 //
491 }
492
493 //
494 // ACPI or reserved memory
495 //
496 Status = gDS->AddMemorySpace (
497 EfiGcdMemoryTypeSystemMemory,
498 MemoryDescHob.MemDesc[Index].PhysicalStart,
499 LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT),
500 MemoryDescHob.MemDesc[Index].Attribute
501 );
502 if (EFI_ERROR (Status)) {
503 continue;
504 }
505
506 Memory = MemoryDescHob.MemDesc[Index].PhysicalStart;
507 Status = gBS->AllocatePages (
508 AllocateAddress,
509 (EFI_MEMORY_TYPE)MemoryDescHob.MemDesc[Index].Type,
510 (UINTN)MemoryDescHob.MemDesc[Index].NumberOfPages,
511 &Memory
512 );
513 if (EFI_ERROR (Status)) {
514 continue;
515 }
516 }
517 }
518
519 //
520 // dmazar: Part of mem fix when "available" memory regions are marked as "reserved"
521 // if they were above first non-avaialable region in BIOS mem map.
522 // We have left those regions as EfiConventionalMemory in EfiLdr/Support.c GenMemoryMap()
523 // and now we will add them to GCD and UEFI mem map
524 //
525 for (Index = 0; Index < MemoryDescHob.MemDescCount; Index++) {
526 if (MemoryDescHob.MemDesc[Index].PhysicalStart < 0x100000) {
527 continue;
528 }
529
530 if (MemoryDescHob.MemDesc[Index].Type != EfiConventionalMemory) {
531 continue;
532 }
533
534 if (MemoryDescHob.MemDesc[Index].PhysicalStart < FirstNonConventionalAddr) {
535 continue;
536 }
537
538 //
539 // This is our candidate - add it.
540 //
541 gDS->AddMemorySpace (
542 EfiGcdMemoryTypeSystemMemory,
543 MemoryDescHob.MemDesc[Index].PhysicalStart,
544 LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT),
545 MemoryDescHob.MemDesc[Index].Attribute
546 );
547 }
548}
549
550STATIC
551EFI_STATUS
553 VOID
554 )
555
556/*++
557
558Routine Description:
559
560 Connect RootBridge
561
562Arguments:
563
564 None.
565
566Returns:
567
568 EFI_SUCCESS - Connect RootBridge successfully.
569 EFI_STATUS - Connect RootBridge fail.
570
571--*/
572{
573 EFI_STATUS Status;
574 EFI_HANDLE RootHandle;
575
576 //
577 // Make all the PCI_IO protocols on PCI Seg 0 show up
578 //
580
581 Status = gBS->LocateDevicePath (
584 &RootHandle
585 );
586
587 if (EFI_ERROR (Status)) {
588 return Status;
589 }
590
591 Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);
592 if (EFI_ERROR (Status)) {
593 return Status;
594 }
595
596 return EFI_SUCCESS;
597}
598
599STATIC
600EFI_STATUS
602 IN EFI_HANDLE DeviceHandle
603 )
604
605/*++
606
607Routine Description:
608
609 Add IsaKeyboard to ConIn,
610 add IsaSerial to ConOut, ConIn, ErrOut.
611 LPC Bridge: 06 01 00
612
613Arguments:
614
615 DeviceHandle - Handle of PCIIO protocol.
616
617Returns:
618
619 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
620 EFI_STATUS - No LPC bridge is added.
621
622--*/
623{
624 EFI_STATUS Status;
625 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
626
627 DevicePath = NULL;
628 Status = gBS->HandleProtocol (
629 DeviceHandle,
631 (VOID *)&DevicePath
632 );
633 if (EFI_ERROR (Status)) {
634 return Status;
635 }
636
637 //
638 // Register Keyboard
639 //
640 DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
641
642 BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
643
644 return EFI_SUCCESS;
645}
646
647STATIC
648EFI_STATUS
650 IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
651 OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
652 )
653{
654 UINTN Index;
655 EFI_STATUS Status;
656 EFI_HANDLE PciDeviceHandle;
657 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
658 EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
659 UINTN GopHandleCount;
660 EFI_HANDLE *GopHandleBuffer;
661
662 if ((PciDevicePath == NULL) || (GopDevicePath == NULL)) {
663 return EFI_INVALID_PARAMETER;
664 }
665
666 //
667 // Initialize the GopDevicePath to be PciDevicePath
668 //
669 *GopDevicePath = PciDevicePath;
670 TempPciDevicePath = PciDevicePath;
671
672 Status = gBS->LocateDevicePath (
674 &TempPciDevicePath,
675 &PciDeviceHandle
676 );
677 if (EFI_ERROR (Status)) {
678 return Status;
679 }
680
681 //
682 // Try to connect this handle, so that GOP driver could start on this
683 // device and create child handles with GraphicsOutput Protocol installed
684 // on them, then we get device paths of these child handles and select
685 // them as possible console device.
686 //
687 gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);
688
689 Status = gBS->LocateHandleBuffer (
690 ByProtocol,
692 NULL,
693 &GopHandleCount,
694 &GopHandleBuffer
695 );
696 if (!EFI_ERROR (Status)) {
697 //
698 // Add all the child handles as possible Console Device
699 //
700 for (Index = 0; Index < GopHandleCount; Index++) {
701 Status = gBS->HandleProtocol (
702 GopHandleBuffer[Index],
704 (VOID *)&TempDevicePath
705 );
706 if (EFI_ERROR (Status)) {
707 continue;
708 }
709
710 if (CompareMem (
711 PciDevicePath,
712 TempDevicePath,
713 GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
714 ) == 0)
715 {
716 //
717 // In current implementation, we only enable one of the child handles
718 // as console device, i.e. sotre one of the child handle's device
719 // path to variable "ConOut"
720 // In future, we could select all child handles to be console device
721 //
722
723 *GopDevicePath = TempDevicePath;
724
725 //
726 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
727 // Add the integrity GOP device path.
728 //
729 BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);
730 BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);
731 }
732 }
733
734 gBS->FreePool (GopHandleBuffer);
735 }
736
737 return EFI_SUCCESS;
738}
739
740STATIC
741EFI_STATUS
743 IN EFI_HANDLE DeviceHandle
744 )
745
746/*++
747
748Routine Description:
749
750 Add PCI VGA to ConOut.
751 PCI VGA: 03 00 00
752
753Arguments:
754
755 DeviceHandle - Handle of PCIIO protocol.
756
757Returns:
758
759 EFI_SUCCESS - PCI VGA is added to ConOut.
760 EFI_STATUS - No PCI VGA device is added.
761
762--*/
763{
764 EFI_STATUS Status;
765 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
766 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
767
768 DevicePath = NULL;
769 Status = gBS->HandleProtocol (
770 DeviceHandle,
772 (VOID *)&DevicePath
773 );
774 if (EFI_ERROR (Status)) {
775 return Status;
776 }
777
778 GetGopDevicePath (DevicePath, &GopDevicePath);
779 DevicePath = GopDevicePath;
780
781 BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
782
783 return EFI_SUCCESS;
784}
785
786STATIC
787EFI_STATUS
789 BOOLEAN DetectVgaOnly
790 )
791
792/*++
793
794Routine Description:
795
796 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
797
798Arguments:
799
800 DetectVgaOnly - Only detect VGA device if it's TRUE.
801
802Returns:
803
804 EFI_SUCCESS - PCI Device check and Console variable update successfully.
805 EFI_STATUS - PCI Device check or Console variable update fail.
806
807--*/
808{
809 EFI_STATUS Status;
810 UINTN HandleCount;
811 EFI_HANDLE *HandleBuffer;
812 UINTN Index;
813 EFI_PCI_IO_PROTOCOL *PciIo;
814 PCI_TYPE00 Pci;
815
816 //
817 // Start to check all the PciIo to find all possible device
818 //
819 HandleCount = 0;
820 HandleBuffer = NULL;
821 Status = gBS->LocateHandleBuffer (
822 ByProtocol,
823 &gEfiPciIoProtocolGuid,
824 NULL,
825 &HandleCount,
826 &HandleBuffer
827 );
828 if (EFI_ERROR (Status)) {
829 return Status;
830 }
831
832 for (Index = 0; Index < HandleCount; Index++) {
833 Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID *)&PciIo);
834 if (EFI_ERROR (Status)) {
835 continue;
836 }
837
838 //
839 // Check for all PCI device
840 //
841 Status = PciIo->Pci.Read (
842 PciIo,
843 EfiPciIoWidthUint32,
844 0,
845 sizeof (Pci) / sizeof (UINT32),
846 &Pci
847 );
848 if (EFI_ERROR (Status)) {
849 continue;
850 }
851
852 if (!DetectVgaOnly) {
853 //
854 // Here we decide whether it is LPC Bridge
855 //
856 if ( (IS_PCI_LPC (&Pci))
857 || ( (IS_PCI_ISA_PDECODE (&Pci))
858 && (Pci.Hdr.VendorId == 0x8086)
859 && (Pci.Hdr.DeviceId == 0x7110)))
860 {
861 //
862 // Add IsaKeyboard to ConIn,
863 // add IsaSerial to ConOut, ConIn, ErrOut
864 //
865 PrepareLpcBridgeDevicePath (HandleBuffer[Index]);
866 continue;
867 }
868 }
869
870 //
871 // Here we decide which VGA device to enable in PCI bus
872 //
873 if (IS_PCI_VGA (&Pci)) {
874 //
875 // Add them to ConOut.
876 //
877 PreparePciVgaDevicePath (HandleBuffer[Index]);
878 continue;
879 }
880 }
881
882 gBS->FreePool (HandleBuffer);
883
884 return EFI_SUCCESS;
885}
886
887VOID
888EFIAPI
890 VOID
891 )
892
893/*++
894
895Routine Description:
896
897 Platform Bds init. Include the platform firmware vendor, revision
898 and so crc check.
899
900Arguments:
901
902Returns:
903
904 None.
905
906--*/
907{
909
911
912 //
913 // Append Usb Keyboard short form DevicePath into "ConInDev"
914 //
917 (EFI_DEVICE_PATH_PROTOCOL *)&gUsbClassKeyboardDevicePath,
918 NULL
919 );
920}
921
922EFI_STATUS
924 IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
925 )
926
927/*++
928
929Routine Description:
930
931 Connect the predefined platform default console device. Always try to find
932 and enable the vga device if have.
933
934Arguments:
935
936 PlatformConsole - Predfined platform default console device array.
937
938Returns:
939
940 EFI_SUCCESS - Success connect at least one ConIn and ConOut
941 device, there must have one ConOut device is
942 active vga device.
943
944 EFI_STATUS - Return the status of
945 BdsLibConnectAllDefaultConsoles ()
946
947--*/
948{
949 EFI_STATUS Status;
950 UINTN Index;
951 EFI_DEVICE_PATH_PROTOCOL *VarConout;
952 EFI_DEVICE_PATH_PROTOCOL *VarConin;
953 UINTN DevicePathSize;
954
955 //
956 // Connect RootBridge
957 //
959
960 VarConout = BdsLibGetVariableAndSize (
963 &DevicePathSize
964 );
965 VarConin = BdsLibGetVariableAndSize (
968 &DevicePathSize
969 );
970
971 if ((VarConout == NULL) || (VarConin == NULL)) {
972 //
973 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
974 //
976
977 //
978 // Have chance to connect the platform default console,
979 // the platform default console is the minimue device group
980 // the platform should support
981 //
982 for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
983 //
984 // Update the console variable with the connect type
985 //
986 if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
987 BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);
988 }
989
990 if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
991 BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);
992 }
993
994 if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
995 BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);
996 }
997 }
998 } else {
999 //
1000 // Only detect VGA device and add them to ConOut
1001 //
1003 }
1004
1005 //
1006 // Connect the all the default console with current console variable
1007 //
1009
1010 return Status;
1011}
1012
1013VOID
1014EFIAPI
1016 VOID
1017 )
1018
1019/*++
1020
1021Routine Description:
1022
1023 The function will excute with as the platform policy, current policy
1024 is driven by boot mode. IBV/OEM can customize this code for their specific
1025 policy action.
1026
1027Arguments:
1028
1029 DriverOptionList - The header of the driver option link list
1030
1031 BootOptionList - The header of the boot option link list
1032
1033Returns:
1034
1035 None.
1036
1037--*/
1038{
1040
1042}
UINT8 Reserved[430]
Definition Apm.h:39
UINT64 Length
STATIC VOID GetSystemTablesFromHob(VOID)
STATIC EFI_STATUS GetGopDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath, OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath)
STATIC VOID UpdateMemoryMap(VOID)
STATIC EFI_STATUS ConvertSmbiosTable(IN OUT VOID **Table)
STATIC EFI_STATUS PreparePciVgaDevicePath(IN EFI_HANDLE DeviceHandle)
STATIC EFI_STATUS PrepareLpcBridgeDevicePath(IN EFI_HANDLE DeviceHandle)
VOID EFIAPI PlatformBdsPolicyBehavior(VOID)
VOID EFIAPI PlatformBdsInit(VOID)
STATIC EFI_STATUS ConvertSystemTable(IN EFI_GUID *TableGuid, IN OUT VOID **Table)
STATIC EFI_STATUS ConnectRootBridge(VOID)
EFI_GUID * gTableGuidArray[]
Definition BdsPlatform.c:43
STATIC EFI_STATUS DetectAndPreparePlatformPciDevicePath(BOOLEAN DetectVgaOnly)
STATIC EFI_STATUS ConvertAcpiTable(IN UINTN TableLen, IN OUT VOID **Table)
Definition BdsPlatform.c:56
EFI_STATUS BdsConnectConsole(IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole)
USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath
EFI_DEVICE_PATH_PROTOCOL * gPlatformRootBridges[]
#define VarConsoleOutDev
Definition BdsPlatform.h:43
#define VarConsoleInpDev
Definition BdsPlatform.h:41
#define EFI_MEMORY_PRESENT
Definition BdsPlatform.h:37
#define VarConsoleOut
Definition BdsPlatform.h:44
#define VarConsoleInp
Definition BdsPlatform.h:42
#define EFI_SYSTEM_TABLE_MAX_ADDRESS
Definition BdsPlatform.h:97
#define EFI_MEMORY_TESTED
Definition BdsPlatform.h:39
#define EFI_MEMORY_INITIALIZED
Definition BdsPlatform.h:38
#define SYS_TABLE_PAD(ptr)
Definition BdsPlatform.h:98
#define VarErrorOut
Definition BdsPlatform.h:46
ACPI_HID_DEVICE_PATH gPnpPs2KeyboardDeviceNode
BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[]
#define IS_PCI_ISA_PDECODE(_p)
Definition BdsPlatform.h:48
#define STD_ERROR
Definition DuetBdsLib.h:22
EFI_STATUS EFIAPI BdsLibConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect)
Definition BdsConnect.c:94
#define CONSOLE_OUT
Definition DuetBdsLib.h:21
EFI_STATUS EFIAPI BdsLibConnectAllDefaultConsoles(VOID)
Definition BdsConsole.c:506
EFI_STATUS EFIAPI BdsLibUpdateConsoleVariable(IN CHAR16 *ConVarName, IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath, IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath)
Definition BdsConsole.c:198
VOID EFIAPI BdsLibConnectAll(VOID)
Definition BdsConnect.c:36
#define CONSOLE_IN
Definition DuetBdsLib.h:23
VOID *EFIAPI BdsLibGetVariableAndSize(IN CHAR16 *Name, IN EFI_GUID *VendorGuid, OUT UINTN *VariableSize)
Definition BdsMisc.c:36
EFI_GUID gLdrMemoryDescriptorGuid
EFI_BOOT_SERVICES * gBS
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
EFI_GUID gEfiSmbios3TableGuid
EFI_GUID gEfiGlobalVariableGuid
EFI_GUID gEfiGraphicsOutputProtocolGuid
EFI_GUID gEfiDevicePathProtocolGuid
EFI_GUID gEfiSmbiosTableGuid
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition UserMath.c:76
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition UserMisc.c:671
EFI_MEMORY_DESCRIPTOR * MemDesc