PageRenderTime 65ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/Library/BdsDxe/DuetBds/BdsPlatform.c

https://github.com/SunnyKi/bareBoot
C | 1810 lines | 1090 code | 152 blank | 568 comment | 185 complexity | 4c5f67c1a69333fa5cc681d98a75ce89 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*++
  2. Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
  3. This program and the accompanying materials
  4. are licensed and made available under the terms and conditions of the BSD License
  5. which accompanies this distribution. The full text of the license may be found at
  6. http://opensource.org/licenses/bsd-license.php
  7. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  9. Module Name:
  10. BdsPlatform.c
  11. Abstract:
  12. This file include all platform action which can be customized
  13. by IBV/OEM.
  14. --*/
  15. #include <Protocol/GraphicsOutput.h>
  16. #include <Library/ShiftKeysLib.h>
  17. #include "BdsPlatform.h"
  18. #include "InternalBdsLib.h"
  19. #include "Graphics.h"
  20. #define EFI_MEMORY_PRESENT 0x0100000000000000ULL
  21. #define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL
  22. #define EFI_MEMORY_TESTED 0x0400000000000000ULL
  23. #define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)
  24. #define SCAN_ESC 0x0017
  25. #define SCAN_F1 0x000B
  26. extern BOOLEAN gConnectAllHappened;
  27. extern USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath;
  28. EFI_GUID *gTableGuidArray[] = {&gEfiAcpi20TableGuid,
  29. &gEfiAcpiTableGuid,
  30. &gEfiSmbiosTableGuid,
  31. &gEfiMpsTableGuid};
  32. GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mGcdMemoryTypeNames[] = {
  33. "NonExist ", // EfiGcdMemoryTypeNonExistent
  34. "Reserved ", // EfiGcdMemoryTypeReserved
  35. "SystemMem", // EfiGcdMemoryTypeSystemMemory
  36. "MMIO ", // EfiGcdMemoryTypeMemoryMappedIo
  37. "Unknown " // EfiGcdMemoryTypeMaximum
  38. };
  39. GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *EfiMemoryTypeDesc[14] = {
  40. "reserved ",
  41. "LoaderCode",
  42. "LoaderData",
  43. "BS_code ",
  44. "BS_data ",
  45. "RT_code ",
  46. "RT_data ",
  47. "available ",
  48. "Unusable ",
  49. "ACPI_recl ",
  50. "ACPI_NVS ",
  51. "MemMapIO ",
  52. "MemPortIO ",
  53. "PAL_code "
  54. };
  55. //
  56. // BDS Platform Functions
  57. //
  58. VOID
  59. GetSystemTablesFromHob (
  60. VOID
  61. )
  62. /*++
  63. Routine Description:
  64. Find GUID'ed HOBs that contain EFI_PHYSICAL_ADDRESS of ACPI, SMBIOS, MPs tables
  65. Arguments:
  66. None
  67. Returns:
  68. None.
  69. --*/
  70. {
  71. EFI_PEI_HOB_POINTERS GuidHob;
  72. EFI_PEI_HOB_POINTERS HobStart;
  73. EFI_PHYSICAL_ADDRESS *Table;
  74. UINTN Index;
  75. //
  76. // Get Hob List
  77. //
  78. HobStart.Raw = GetHobList ();
  79. //
  80. // Iteratively add ACPI Table, SMBIOS Table, MPS Table to EFI System Table
  81. //
  82. for (Index = 0; Index < sizeof (gTableGuidArray) / sizeof (*gTableGuidArray); ++Index) {
  83. GuidHob.Raw = GetNextGuidHob (gTableGuidArray[Index], HobStart.Raw);
  84. if (GuidHob.Raw != NULL) {
  85. Table = GET_GUID_HOB_DATA (GuidHob.Guid);
  86. if (Table != NULL) {
  87. //
  88. // Check if Mps Table/Smbios Table/Acpi Table exists in E/F seg,
  89. // According to UEFI Spec, we should make sure Smbios table,
  90. // ACPI table and Mps tables kept in memory of specified type
  91. //
  92. ConvertSystemTable(gTableGuidArray[Index], (VOID**)&Table);
  93. gBS->InstallConfigurationTable (gTableGuidArray[Index], (VOID *)Table);
  94. }
  95. }
  96. }
  97. return;
  98. }
  99. #ifdef MEMMAP_DEBUG
  100. VOID
  101. DumpGcdMemoryMap (
  102. VOID
  103. )
  104. {
  105. UINTN NumberOfDescriptors;
  106. EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
  107. UINTN Index;
  108. gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
  109. DBG ("GCDMemType Range Capabilities Attributes \n");
  110. DBG ("========== ================================= ================ ================\n");
  111. for (Index = 0; Index < NumberOfDescriptors; Index++) {
  112. DBG ("%a %016lx-%016lx %016lx %016lx%c\n",
  113. mGcdMemoryTypeNames[MIN (MemorySpaceMap[Index].GcdMemoryType, EfiGcdMemoryTypeMaximum)],
  114. MemorySpaceMap[Index].BaseAddress,
  115. MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - 1,
  116. MemorySpaceMap[Index].Capabilities,
  117. MemorySpaceMap[Index].Attributes,
  118. MemorySpaceMap[Index].ImageHandle == NULL ? ' ' : '*'
  119. );
  120. }
  121. DBG ("\n");
  122. FreePool (MemorySpaceMap);
  123. }
  124. #endif
  125. VOID
  126. UpdateMemoryMap (
  127. VOID
  128. )
  129. {
  130. EFI_STATUS Status;
  131. EFI_PEI_HOB_POINTERS GuidHob;
  132. VOID *Table;
  133. MEMORY_DESC_HOB MemoryDescHob;
  134. UINTN Index;
  135. EFI_PHYSICAL_ADDRESS Memory;
  136. EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
  137. EFI_PHYSICAL_ADDRESS FirstNonConventionalAddr;
  138. UINTN NumberOfDescriptors;
  139. EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
  140. EFI_GCD_MEMORY_TYPE GcdType;
  141. GuidHob.Raw = GetFirstGuidHob (&gLdrMemoryDescriptorGuid);
  142. if (GuidHob.Raw == NULL) {
  143. return;
  144. }
  145. Table = GET_GUID_HOB_DATA (GuidHob.Guid);
  146. if (Table == NULL) {
  147. return;
  148. }
  149. MemoryDescHob.MemDescCount = *(UINTN *)Table;
  150. MemoryDescHob.MemDesc = *(EFI_MEMORY_DESCRIPTOR **)((UINTN)Table + sizeof(UINTN));
  151. #ifdef MEMMAP_DEBUG
  152. DumpGcdMemoryMap ();
  153. #endif
  154. gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
  155. for (Index = 0; Index < NumberOfDescriptors; Index++) {
  156. if ((MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved &&
  157. (MemorySpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
  158. (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED))) {
  159. //
  160. // For those reserved memory that have not been tested, simply promote to system memory.
  161. //
  162. GcdType = EfiGcdMemoryTypeSystemMemory;
  163. if ((MemorySpaceMap[Index].ImageHandle != NULL)){
  164. gDS->FreeMemorySpace (
  165. MemorySpaceMap[Index].BaseAddress,
  166. MemorySpaceMap[Index].Length
  167. );
  168. GcdType = EfiGcdMemoryTypeReserved;
  169. }
  170. gDS->RemoveMemorySpace (
  171. MemorySpaceMap[Index].BaseAddress,
  172. MemorySpaceMap[Index].Length
  173. );
  174. gDS->AddMemorySpace (
  175. GcdType,
  176. MemorySpaceMap[Index].BaseAddress,
  177. MemorySpaceMap[Index].Length,
  178. MemorySpaceMap[Index].Capabilities &~
  179. (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME | EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT)
  180. );
  181. }
  182. }
  183. FreePool (MemorySpaceMap);
  184. #ifdef MEMMAP_DEBUG
  185. DBG ("%a: Gcd Memory Map after update.\n",__FUNCTION__);
  186. DumpGcdMemoryMap ();
  187. #endif
  188. //
  189. // Add ACPINVS, ACPIReclaim, and Reserved memory to MemoryMap
  190. //
  191. FirstNonConventionalAddr = 0xFFFFFFFF;
  192. #ifdef MEMMAP_DEBUG
  193. DBG (" Type Physical Start Physical End Number of Pages Virtual Start Attribute\n");
  194. #endif
  195. for (Index = 0; Index < MemoryDescHob.MemDescCount; Index++) {
  196. #ifdef MEMMAP_DEBUG
  197. DBG ("%02d %a %016lx %016lx %016lx %016lx %016x\n",
  198. Index,
  199. EfiMemoryTypeDesc[MemoryDescHob.MemDesc[Index].Type],
  200. MemoryDescHob.MemDesc[Index].PhysicalStart,
  201. MemoryDescHob.MemDesc[Index].PhysicalStart + MemoryDescHob.MemDesc[Index].NumberOfPages * 4096 -1,
  202. MemoryDescHob.MemDesc[Index].NumberOfPages,
  203. MemoryDescHob.MemDesc[Index].VirtualStart,
  204. MemoryDescHob.MemDesc[Index].Attribute);
  205. #endif
  206. if (MemoryDescHob.MemDesc[Index].PhysicalStart < 0x100000) {
  207. continue;
  208. }
  209. if (MemoryDescHob.MemDesc[Index].PhysicalStart >= 0x100000000ULL) {
  210. continue;
  211. }
  212. if ((MemoryDescHob.MemDesc[Index].Type == EfiReservedMemoryType) ||
  213. (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) ||
  214. (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode) ||
  215. (MemoryDescHob.MemDesc[Index].Type == EfiACPIReclaimMemory) ||
  216. (MemoryDescHob.MemDesc[Index].Type == EfiACPIMemoryNVS)) {
  217. if (MemoryDescHob.MemDesc[Index].PhysicalStart < FirstNonConventionalAddr) {
  218. FirstNonConventionalAddr = MemoryDescHob.MemDesc[Index].PhysicalStart;
  219. }
  220. if ((MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) ||
  221. (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesCode)) {
  222. //
  223. // For RuntimeSevicesData and RuntimeServicesCode, they are BFV or DxeCore.
  224. // The memory type is assigned in EfiLdr
  225. //
  226. Status = gDS->GetMemorySpaceDescriptor (MemoryDescHob.MemDesc[Index].PhysicalStart, &Descriptor);
  227. if (EFI_ERROR (Status)) {
  228. continue;
  229. }
  230. if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) {
  231. //
  232. // BFV or tested DXE core
  233. //
  234. continue;
  235. }
  236. //
  237. // Untested DXE Core region, free and remove
  238. //
  239. Status = gDS->FreeMemorySpace (
  240. MemoryDescHob.MemDesc[Index].PhysicalStart,
  241. LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT)
  242. );
  243. if (EFI_ERROR (Status)) {
  244. continue;
  245. }
  246. Status = gDS->RemoveMemorySpace (
  247. MemoryDescHob.MemDesc[Index].PhysicalStart,
  248. LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT)
  249. );
  250. if (EFI_ERROR (Status)) {
  251. continue;
  252. }
  253. //
  254. // Convert Runtime type to BootTime type
  255. //
  256. if (MemoryDescHob.MemDesc[Index].Type == EfiRuntimeServicesData) {
  257. MemoryDescHob.MemDesc[Index].Type = EfiBootServicesData;
  258. } else {
  259. MemoryDescHob.MemDesc[Index].Type = EfiBootServicesCode;
  260. }
  261. //
  262. // PassThrough, let below code add and alloate.
  263. //
  264. }
  265. //
  266. // ACPI or reserved memory
  267. //
  268. Status = gDS->AddMemorySpace (
  269. EfiGcdMemoryTypeSystemMemory,
  270. MemoryDescHob.MemDesc[Index].PhysicalStart,
  271. LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT),
  272. MemoryDescHob.MemDesc[Index].Attribute
  273. );
  274. if (!(MemoryDescHob.MemDesc[Index].Type == EfiACPIReclaimMemory) &&
  275. !(MemoryDescHob.MemDesc[Index].Type == EfiACPIMemoryNVS)) {
  276. if (EFI_ERROR (Status)) {
  277. continue;
  278. }
  279. }
  280. Memory = MemoryDescHob.MemDesc[Index].PhysicalStart;
  281. Status = gBS->AllocatePages (
  282. AllocateAddress,
  283. (EFI_MEMORY_TYPE)MemoryDescHob.MemDesc[Index].Type,
  284. (UINTN)MemoryDescHob.MemDesc[Index].NumberOfPages,
  285. &Memory
  286. );
  287. if (EFI_ERROR (Status)) {
  288. //
  289. // For the page added, it must be allocated.
  290. //
  291. continue;
  292. }
  293. }
  294. }
  295. /**
  296. *
  297. * thanks for this fix dmazar!
  298. *
  299. **/
  300. #ifdef MEMMAP_DEBUG
  301. DBG ("%a: Efi Memory Map updated descriptors.\n",__FUNCTION__);
  302. DBG (" Type Physical Start Physical End Number of Pages Virtual Start Attribute\n");
  303. #endif
  304. for (Index = 0; Index < MemoryDescHob.MemDescCount; Index++) {
  305. if (MemoryDescHob.MemDesc[Index].PhysicalStart < 0x100000) {
  306. continue;
  307. }
  308. if (MemoryDescHob.MemDesc[Index].PhysicalStart >= 0x100000000ULL) {
  309. continue;
  310. }
  311. if (MemoryDescHob.MemDesc[Index].Type != EfiConventionalMemory) {
  312. continue;
  313. }
  314. if (MemoryDescHob.MemDesc[Index].PhysicalStart < FirstNonConventionalAddr) {
  315. continue;
  316. }
  317. // this is our candidate - add it
  318. #if 0
  319. Status = gDS->GetMemorySpaceDescriptor (MemoryDescHob.MemDesc[Index].PhysicalStart, &Descriptor);
  320. if (EFI_ERROR (Status)) {
  321. continue;
  322. }
  323. if (Descriptor.GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
  324. MemoryDescHob.MemDesc[Index].Type = EfiReservedMemoryType;
  325. continue;
  326. }
  327. gDS->RemoveMemorySpace (
  328. MemoryDescHob.MemDesc[Index].PhysicalStart,
  329. LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT)
  330. );
  331. #endif
  332. gDS->AddMemorySpace (
  333. EfiGcdMemoryTypeSystemMemory,
  334. MemoryDescHob.MemDesc[Index].PhysicalStart,
  335. LShiftU64 (MemoryDescHob.MemDesc[Index].NumberOfPages, EFI_PAGE_SHIFT),
  336. MemoryDescHob.MemDesc[Index].Attribute
  337. );
  338. #if 0
  339. Memory = MemoryDescHob.MemDesc[Index].PhysicalStart;
  340. gBS->AllocatePages (
  341. AllocateAddress,
  342. (EFI_MEMORY_TYPE)MemoryDescHob.MemDesc[Index].Type,
  343. (UINTN)MemoryDescHob.MemDesc[Index].NumberOfPages,
  344. &Memory
  345. );
  346. #endif
  347. #ifdef MEMMAP_DEBUG
  348. DBG ("%02d %a %016lx %016lx %016lx %016lx %016x\n",
  349. Index,
  350. EfiMemoryTypeDesc[MemoryDescHob.MemDesc[Index].Type],
  351. MemoryDescHob.MemDesc[Index].PhysicalStart,
  352. MemoryDescHob.MemDesc[Index].PhysicalStart + MemoryDescHob.MemDesc[Index].NumberOfPages * 4096 -1,
  353. MemoryDescHob.MemDesc[Index].NumberOfPages,
  354. MemoryDescHob.MemDesc[Index].VirtualStart,
  355. MemoryDescHob.MemDesc[Index].Attribute);
  356. #endif
  357. }
  358. #ifdef MEMMAP_DEBUG
  359. DumpGcdMemoryMap ();
  360. #endif
  361. }
  362. VOID
  363. EFIAPI
  364. PlatformBdsInit (
  365. VOID
  366. )
  367. /*++
  368. Routine Description:
  369. Platform Bds init. Include the platform firmware vendor, revision
  370. and so crc check.
  371. Arguments:
  372. Returns:
  373. None.
  374. --*/
  375. {
  376. GetSystemTablesFromHob ();
  377. UpdateMemoryMap ();
  378. //
  379. // Append Usb Keyboard short form DevicePath into "ConInDev"
  380. //
  381. BdsLibUpdateConsoleVariable (
  382. VarConsoleInpDev,
  383. (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath,
  384. NULL
  385. );
  386. }
  387. UINT64
  388. GetPciExpressBaseAddressForRootBridge (
  389. IN UINTN HostBridgeNumber,
  390. IN UINTN RootBridgeNumber
  391. )
  392. /*++
  393. Routine Description:
  394. This routine is to get PciExpress Base Address for this RootBridge
  395. Arguments:
  396. HostBridgeNumber - The number of HostBridge
  397. RootBridgeNumber - The number of RootBridge
  398. Returns:
  399. UINT64 - PciExpressBaseAddress for this HostBridge and RootBridge
  400. --*/
  401. {
  402. EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION *PciExpressBaseAddressInfo;
  403. UINTN BufferSize;
  404. UINT32 Index;
  405. UINT32 Number;
  406. EFI_PEI_HOB_POINTERS GuidHob;
  407. //
  408. // Get PciExpressAddressInfo Hob
  409. //
  410. PciExpressBaseAddressInfo = NULL;
  411. BufferSize = 0;
  412. GuidHob.Raw = GetFirstGuidHob (&gEfiPciExpressBaseAddressGuid);
  413. if (GuidHob.Raw != NULL) {
  414. PciExpressBaseAddressInfo = GET_GUID_HOB_DATA (GuidHob.Guid);
  415. BufferSize = GET_GUID_HOB_DATA_SIZE (GuidHob.Guid);
  416. } else {
  417. return 0;
  418. }
  419. //
  420. // Search the PciExpress Base Address in the Hob for current RootBridge
  421. //
  422. Number = (UINT32)(BufferSize / sizeof(EFI_PCI_EXPRESS_BASE_ADDRESS_INFORMATION));
  423. for (Index = 0; Index < Number; Index++) {
  424. if ((PciExpressBaseAddressInfo[Index].HostBridgeNumber == HostBridgeNumber) &&
  425. (PciExpressBaseAddressInfo[Index].RootBridgeNumber == RootBridgeNumber)) {
  426. return PciExpressBaseAddressInfo[Index].PciExpressBaseAddress;
  427. }
  428. }
  429. //
  430. // Do not find the PciExpress Base Address in the Hob
  431. //
  432. return 0;
  433. }
  434. VOID
  435. PatchPciRootBridgeDevicePath (
  436. IN UINTN HostBridgeNumber,
  437. IN UINTN RootBridgeNumber,
  438. IN PLATFORM_ROOT_BRIDGE_DEVICE_PATH *RootBridge
  439. )
  440. {
  441. UINT64 PciExpressBase;
  442. PciExpressBase = GetPciExpressBaseAddressForRootBridge (HostBridgeNumber, RootBridgeNumber);
  443. DEBUG ((EFI_D_INFO, "Get PciExpress Address from Hob: 0x%X\n", PciExpressBase));
  444. if (PciExpressBase != 0) {
  445. RootBridge->PciRootBridge.HID = EISA_PNP_ID(0x0A08);
  446. }
  447. }
  448. EFI_STATUS
  449. ConnectRootBridge (
  450. VOID
  451. )
  452. /*++
  453. Routine Description:
  454. Connect RootBridge
  455. Arguments:
  456. None.
  457. Returns:
  458. EFI_SUCCESS - Connect RootBridge successfully.
  459. EFI_STATUS - Connect RootBridge fail.
  460. --*/
  461. {
  462. EFI_STATUS Status;
  463. EFI_HANDLE RootHandle;
  464. //
  465. // Patch Pci Root Bridge Device Path
  466. //
  467. PatchPciRootBridgeDevicePath (0, 0, &gPlatformRootBridge0);
  468. //
  469. // Make all the PCI_IO protocols on PCI Seg 0 show up
  470. //
  471. BdsLibConnectDevicePath (gPlatformRootBridges[0]);
  472. Status = gBS->LocateDevicePath (
  473. &gEfiDevicePathProtocolGuid,
  474. &gPlatformRootBridges[0],
  475. &RootHandle
  476. );
  477. DEBUG ((EFI_D_INFO, "Pci Root bridge handle is 0x%X\n", RootHandle));
  478. if (EFI_ERROR (Status)) {
  479. return Status;
  480. }
  481. Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE);
  482. if (EFI_ERROR (Status)) {
  483. return Status;
  484. }
  485. return EFI_SUCCESS;
  486. }
  487. EFI_STATUS
  488. PrepareLpcBridgeDevicePath (
  489. IN EFI_HANDLE DeviceHandle
  490. )
  491. /*++
  492. Routine Description:
  493. Add IsaKeyboard to ConIn,
  494. add IsaSerial to ConOut, ConIn, ErrOut.
  495. LPC Bridge: 06 01 00
  496. Arguments:
  497. DeviceHandle - Handle of PCIIO protocol.
  498. Returns:
  499. EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
  500. EFI_STATUS - No LPC bridge is added.
  501. --*/
  502. {
  503. EFI_STATUS Status;
  504. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  505. EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
  506. DevicePath = NULL;
  507. Status = gBS->HandleProtocol (
  508. DeviceHandle,
  509. &gEfiDevicePathProtocolGuid,
  510. (VOID*)&DevicePath
  511. );
  512. if (EFI_ERROR (Status)) {
  513. return Status;
  514. }
  515. TempDevicePath = DevicePath;
  516. //
  517. // Register Keyboard
  518. //
  519. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
  520. BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
  521. //
  522. // Register COM1
  523. //
  524. DevicePath = TempDevicePath;
  525. gPnp16550ComPortDeviceNode.UID = 0;
  526. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
  527. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
  528. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
  529. BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
  530. BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
  531. BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
  532. //
  533. // Register COM2
  534. //
  535. DevicePath = TempDevicePath;
  536. gPnp16550ComPortDeviceNode.UID = 1;
  537. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
  538. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
  539. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
  540. BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
  541. BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
  542. BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
  543. return EFI_SUCCESS;
  544. }
  545. EFI_STATUS
  546. GetGopDevicePath (
  547. IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
  548. OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath
  549. )
  550. {
  551. UINTN Index;
  552. EFI_STATUS Status;
  553. EFI_HANDLE PciDeviceHandle;
  554. EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
  555. EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath;
  556. UINTN GopHandleCount;
  557. EFI_HANDLE *GopHandleBuffer;
  558. if (PciDevicePath == NULL || GopDevicePath == NULL) {
  559. return EFI_INVALID_PARAMETER;
  560. }
  561. //
  562. // Initialize the GopDevicePath to be PciDevicePath
  563. //
  564. *GopDevicePath = PciDevicePath;
  565. TempPciDevicePath = PciDevicePath;
  566. Status = gBS->LocateDevicePath (
  567. &gEfiDevicePathProtocolGuid,
  568. &TempPciDevicePath,
  569. &PciDeviceHandle
  570. );
  571. if (EFI_ERROR (Status)) {
  572. return Status;
  573. }
  574. //
  575. // Try to connect this handle, so that GOP dirver could start on this
  576. // device and create child handles with GraphicsOutput Protocol installed
  577. // on them, then we get device paths of these child handles and select
  578. // them as possible console device.
  579. //
  580. gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE); // 2,6 sec !!!!!!
  581. DBG (" BdsPlatorm: GetGopDevicePath->ConnectController\n");
  582. Status = gBS->LocateHandleBuffer (
  583. ByProtocol,
  584. &gEfiGraphicsOutputProtocolGuid,
  585. NULL,
  586. &GopHandleCount,
  587. &GopHandleBuffer
  588. );
  589. if (!EFI_ERROR (Status)) {
  590. //
  591. // Add all the child handles as possible Console Device
  592. //
  593. for (Index = 0; Index < GopHandleCount; Index++) {
  594. Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
  595. if (EFI_ERROR (Status)) {
  596. continue;
  597. }
  598. if (CompareMem (
  599. PciDevicePath,
  600. TempDevicePath,
  601. GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH
  602. ) == 0) {
  603. //
  604. // In current implementation, we only enable one of the child handles
  605. // as console device, i.e. sotre one of the child handle's device
  606. // path to variable "ConOut"
  607. // In futhure, we could select all child handles to be console device
  608. //
  609. *GopDevicePath = TempDevicePath;
  610. //
  611. // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
  612. // Add the integrity GOP device path.
  613. //
  614. BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);
  615. BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);
  616. }
  617. }
  618. gBS->FreePool (GopHandleBuffer);
  619. }
  620. return EFI_SUCCESS;
  621. }
  622. EFI_STATUS
  623. PreparePciVgaDevicePath (
  624. IN EFI_HANDLE DeviceHandle
  625. )
  626. /*++
  627. Routine Description:
  628. Add PCI VGA to ConOut.
  629. PCI VGA: 03 00 00
  630. Arguments:
  631. DeviceHandle - Handle of PCIIO protocol.
  632. Returns:
  633. EFI_SUCCESS - PCI VGA is added to ConOut.
  634. EFI_STATUS - No PCI VGA device is added.
  635. --*/
  636. {
  637. EFI_STATUS Status;
  638. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  639. EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
  640. DevicePath = NULL;
  641. GopDevicePath = NULL;
  642. Status = gBS->HandleProtocol (
  643. DeviceHandle,
  644. &gEfiDevicePathProtocolGuid,
  645. (VOID*)&DevicePath
  646. );
  647. if (EFI_ERROR (Status)) {
  648. return Status;
  649. }
  650. GetGopDevicePath (DevicePath, &GopDevicePath);
  651. DevicePath = GopDevicePath;
  652. BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
  653. return EFI_SUCCESS;
  654. }
  655. EFI_STATUS
  656. PreparePciSerialDevicePath (
  657. IN EFI_HANDLE DeviceHandle
  658. )
  659. /*++
  660. Routine Description:
  661. Add PCI Serial to ConOut, ConIn, ErrOut.
  662. PCI Serial: 07 00 02
  663. Arguments:
  664. DeviceHandle - Handle of PCIIO protocol.
  665. Returns:
  666. EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
  667. EFI_STATUS - No PCI Serial device is added.
  668. --*/
  669. {
  670. EFI_STATUS Status;
  671. EFI_DEVICE_PATH_PROTOCOL *DevicePath;
  672. DevicePath = NULL;
  673. Status = gBS->HandleProtocol (
  674. DeviceHandle,
  675. &gEfiDevicePathProtocolGuid,
  676. (VOID*)&DevicePath
  677. );
  678. if (EFI_ERROR (Status)) {
  679. return Status;
  680. }
  681. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
  682. DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
  683. BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
  684. BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
  685. BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
  686. return EFI_SUCCESS;
  687. }
  688. EFI_STATUS
  689. DetectAndPreparePlatformPciDevicePath (
  690. BOOLEAN DetectVgaOnly
  691. )
  692. /*++
  693. Routine Description:
  694. Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
  695. Arguments:
  696. DetectVgaOnly - Only detect VGA device if it's TRUE.
  697. Returns:
  698. EFI_SUCCESS - PCI Device check and Console variable update successfully.
  699. EFI_STATUS - PCI Device check or Console variable update fail.
  700. --*/
  701. {
  702. EFI_STATUS Status;
  703. UINTN HandleCount;
  704. EFI_HANDLE *HandleBuffer;
  705. UINTN Index;
  706. EFI_PCI_IO_PROTOCOL *PciIo;
  707. PCI_TYPE00 Pci;
  708. //
  709. // Start to check all the PciIo to find all possible device
  710. //
  711. HandleCount = 0;
  712. HandleBuffer = NULL;
  713. Status = gBS->LocateHandleBuffer (
  714. ByProtocol,
  715. &gEfiPciIoProtocolGuid,
  716. NULL,
  717. &HandleCount,
  718. &HandleBuffer
  719. );
  720. if (EFI_ERROR (Status)) {
  721. return Status;
  722. }
  723. for (Index = 0; Index < HandleCount; Index++) {
  724. Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);
  725. if (EFI_ERROR (Status)) {
  726. continue;
  727. }
  728. //
  729. // Check for all PCI device
  730. //
  731. Status = PciIo->Pci.Read (
  732. PciIo,
  733. EfiPciIoWidthUint32,
  734. 0,
  735. sizeof (Pci) / sizeof (UINT32),
  736. &Pci
  737. );
  738. if (EFI_ERROR (Status)) {
  739. continue;
  740. }
  741. if (!DetectVgaOnly) {
  742. //
  743. // Here we decide whether it is LPC Bridge
  744. //
  745. if ((IS_PCI_LPC (&Pci)) ||
  746. ((IS_PCI_ISA_PDECODE (&Pci)) && (Pci.Hdr.VendorId == 0x8086) && (Pci.Hdr.DeviceId == 0x7110))) {
  747. //
  748. // Add IsaKeyboard to ConIn,
  749. // add IsaSerial to ConOut, ConIn, ErrOut
  750. //
  751. PrepareLpcBridgeDevicePath (HandleBuffer[Index]);
  752. continue;
  753. }
  754. //
  755. // Here we decide which Serial device to enable in PCI bus
  756. //
  757. if (IS_PCI_16550SERIAL (&Pci)) {
  758. //
  759. // Add them to ConOut, ConIn, ErrOut.
  760. //
  761. PreparePciSerialDevicePath (HandleBuffer[Index]);
  762. continue;
  763. }
  764. }
  765. //
  766. // Here we decide which VGA device to enable in PCI bus
  767. //
  768. if (IS_PCI_VGA (&Pci)) {
  769. //
  770. // Add them to ConOut.
  771. //
  772. PreparePciVgaDevicePath (HandleBuffer[Index]);
  773. continue;
  774. }
  775. }
  776. gBS->FreePool (HandleBuffer);
  777. return EFI_SUCCESS;
  778. }
  779. EFI_STATUS
  780. PlatformBdsConnectConsole (
  781. IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
  782. )
  783. /*++
  784. Routine Description:
  785. Connect the predefined platform default console device. Always try to find
  786. and enable the vga device if have.
  787. Arguments:
  788. PlatformConsole - Predfined platform default console device array.
  789. Returns:
  790. EFI_SUCCESS - Success connect at least one ConIn and ConOut
  791. device, there must have one ConOut device is
  792. active vga device.
  793. EFI_STATUS - Return the status of
  794. BdsLibConnectAllDefaultConsoles ()
  795. --*/
  796. {
  797. EFI_STATUS Status;
  798. UINTN Index;
  799. EFI_DEVICE_PATH_PROTOCOL *VarConout;
  800. EFI_DEVICE_PATH_PROTOCOL *VarConin;
  801. UINTN DevicePathSize;
  802. //
  803. // Connect RootBridge
  804. //
  805. ConnectRootBridge (); //
  806. VarConout = BdsLibGetVariableAndSize (
  807. VarConsoleOut,
  808. &gEfiGlobalVariableGuid,
  809. &DevicePathSize
  810. );
  811. VarConin = BdsLibGetVariableAndSize (
  812. VarConsoleInp,
  813. &gEfiGlobalVariableGuid,
  814. &DevicePathSize
  815. );
  816. if (VarConout == NULL || VarConin == NULL) {
  817. //
  818. // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
  819. //
  820. DetectAndPreparePlatformPciDevicePath (FALSE);
  821. //
  822. // Have chance to connect the platform default console,
  823. // the platform default console is the minimue device group
  824. // the platform should support
  825. //
  826. for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
  827. //
  828. // Update the console variable with the connect type
  829. //
  830. if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
  831. BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);
  832. }
  833. if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
  834. BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);
  835. }
  836. if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
  837. BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);
  838. }
  839. }
  840. } else {
  841. //
  842. // Only detect VGA device and add them to ConOut
  843. //
  844. DetectAndPreparePlatformPciDevicePath (TRUE);
  845. }
  846. //
  847. // The ConIn devices connection will start the USB bus, should disable all
  848. // Usb legacy support firstly.
  849. // Caution: Must ensure the PCI bus driver has been started. Since the
  850. // ConnectRootBridge() will create all the PciIo protocol, it's safe here now
  851. //
  852. #ifdef SPEEDUP
  853. #ifndef BLOCKIO // ata w/o usb drivers
  854. Status = DisableUsbLegacySupport ();
  855. #else // blockio w/o usb drivers
  856. if (ShiftKeyPressed () & EFI_LEFT_ALT_PRESSED) { // blockio w usb drivers
  857. Status = DisableUsbLegacySupport ();
  858. }
  859. #endif
  860. #else // any w usb drivers
  861. Status = DisableUsbLegacySupport ();
  862. #endif
  863. //
  864. // Connect the all the default console with current cosole variable
  865. //
  866. DBG (" BdsPlatorm: Starting BdsLibConnectAllDefaultConsoles\n"); // 2.6 sec
  867. Status = BdsLibConnectAllDefaultConsoles ();
  868. if (EFI_ERROR (Status)) {
  869. return Status;
  870. }
  871. return EFI_SUCCESS;
  872. }
  873. VOID
  874. PlatformBdsConnectSequence (
  875. VOID
  876. )
  877. /*++
  878. Routine Description:
  879. Connect with predeined platform connect sequence,
  880. the OEM/IBV can customize with their own connect sequence.
  881. Arguments:
  882. None.
  883. Returns:
  884. None.
  885. --*/
  886. {
  887. UINTN Index;
  888. Index = 0;
  889. //
  890. // Here we can get the customized platform connect sequence
  891. // Notes: we can connect with new variable which record the
  892. // last time boots connect device path sequence
  893. //
  894. while (gPlatformConnectSequence[Index] != NULL) {
  895. //
  896. // Build the platform boot option
  897. //
  898. BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
  899. Index++;
  900. }
  901. }
  902. VOID
  903. PlatformBdsGetDriverOption (
  904. IN OUT LIST_ENTRY *BdsDriverLists
  905. )
  906. /*++
  907. Routine Description:
  908. Load the predefined driver option, OEM/IBV can customize this
  909. to load their own drivers
  910. Arguments:
  911. BdsDriverLists - The header of the driver option link list.
  912. Returns:
  913. None.
  914. --*/
  915. {
  916. UINTN Index;
  917. Index = 0;
  918. //
  919. // Here we can get the customized platform driver option
  920. //
  921. while (gPlatformDriverOption[Index] != NULL) {
  922. //
  923. // Build the platform boot option
  924. //
  925. BdsLibRegisterNewOption (BdsDriverLists, NULL, gPlatformDriverOption[Index], NULL, L"DriverOrder", FALSE);
  926. Index++;
  927. }
  928. }
  929. #if 0
  930. VOID
  931. EnableSmbus (
  932. VOID
  933. )
  934. {
  935. EFI_STATUS Status;
  936. EFI_HANDLE *HandleBuffer;
  937. EFI_GUID **ProtocolGuidArray;
  938. EFI_PCI_IO_PROTOCOL *PciIo;
  939. UINTN HandleCount;
  940. UINTN ArrayCount;
  941. UINTN HandleIndex;
  942. UINTN ProtocolIndex;
  943. UINTN Segment;
  944. UINTN Bus;
  945. UINTN Device;
  946. UINTN Function;
  947. UINT32 rcba;
  948. UINT32 *fdr;
  949. Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
  950. if (!EFI_ERROR (Status)) {
  951. for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
  952. Status = gBS->ProtocolsPerHandle (HandleBuffer[HandleIndex], &ProtocolGuidArray, &ArrayCount);
  953. if (!EFI_ERROR (Status)) {
  954. for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
  955. if (CompareGuid (&gEfiPciIoProtocolGuid, ProtocolGuidArray[ProtocolIndex])) {
  956. Status = gBS->OpenProtocol (HandleBuffer[HandleIndex],
  957. &gEfiPciIoProtocolGuid,
  958. (VOID **) &PciIo,
  959. gImageHandle,
  960. NULL,
  961. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  962. );
  963. if (!EFI_ERROR (Status)) {
  964. /* Read PCI BUS */
  965. Status = PciIo->Pci.Read (
  966. PciIo,
  967. EfiPciIoWidthUint32,
  968. 0,
  969. sizeof (gPci) / sizeof (UINT32),
  970. &gPci
  971. );
  972. if (gPci.Hdr.VendorId == 0x8086) {
  973. Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
  974. /**
  975. *
  976. * if found LPC - write 0 in SMbus Disabled (3 bit Function Disable register 0x3418)
  977. *
  978. **/
  979. if ((Bus == 0) && (Device == 0x1F) && (Function == 0)) {
  980. Status = PciIo->Pci.Read (
  981. PciIo,
  982. EfiPciIoWidthUint32,
  983. (UINT64) (0xF0 & ~3),
  984. 1,
  985. &rcba
  986. );
  987. rcba &= ~1;
  988. Print (L"RCBA = 0x%x\n", rcba);
  989. fdr = ((UINT32 *) (UINTN) (rcba + 0x3418));
  990. Print (L"fdr = 0x%x\n", *((UINT32 *) (UINTN) (rcba + 0x3418)));
  991. *fdr &= ~0x8;
  992. Print (L"fdr = 0x%x\n", *((UINT32 *) (UINTN) (rcba + 0x3418)));
  993. Pause (NULL);
  994. }
  995. }
  996. }
  997. }
  998. }
  999. }
  1000. }
  1001. }
  1002. }
  1003. #endif
  1004. CHAR16*
  1005. MakeProductNameDir (
  1006. IN CHAR16 *ProductName
  1007. )
  1008. {
  1009. CHAR16 *tp;
  1010. if (ProductName == NULL) {
  1011. return NULL;
  1012. }
  1013. tp = ProductName + StrLen (ProductName);
  1014. /* Trim trailing nonprintables */
  1015. while (tp >= ProductName && (*tp <= L' ' || *tp == 0x00FF)) {
  1016. *tp = 0x0000;
  1017. tp--;
  1018. }
  1019. if (StrLen (ProductName) < 1) {
  1020. FreePool (ProductName);
  1021. return NULL;
  1022. }
  1023. tp = AllocateZeroPool (StrSize (L"\\EFI\\bareboot\\") + StrSize (ProductName) + StrSize (L"\\"));
  1024. StrCpy (tp, L"\\EFI\\bareboot\\");
  1025. StrCat (tp, ProductName);
  1026. StrCat (tp, L"\\");
  1027. FreePool (ProductName);
  1028. return tp;
  1029. }
  1030. VOID
  1031. EFIAPI
  1032. PlatformBdsPolicyBehavior (
  1033. VOID
  1034. )
  1035. /*++
  1036. Routine Description:
  1037. The function will excute with as the platform policy, current policy
  1038. is driven by boot mode. IBV/OEM can customize this code for their specific
  1039. policy action.
  1040. Arguments:
  1041. DriverOptionList - The header of the driver option link list
  1042. BootOptionList - The header of the boot option link list
  1043. Returns:
  1044. None.
  1045. --*/
  1046. {
  1047. EFI_STATUS Status;
  1048. EFI_BOOT_MODE BootMode;
  1049. #if 0
  1050. CHAR16 *TmpUStr;
  1051. EFI_INPUT_KEY mKey;
  1052. #else
  1053. EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleTextInEx;
  1054. EFI_KEY_DATA mKeyData;
  1055. #endif
  1056. EFI_SMBIOS_HANDLE SmbiosHandle;
  1057. EFI_SMBIOS_PROTOCOL *Smbios;
  1058. EFI_SMBIOS_TABLE_HEADER *Record;
  1059. SMBIOS_TABLE_TYPE1 *Type1Record;
  1060. SMBIOS_TABLE_TYPE2 *Type2Record;
  1061. BOOLEAN GotIt[2];
  1062. CHAR16 *TmpString1;
  1063. CHAR16 *TmpString2;
  1064. UINT8 StrIndex;
  1065. gPNDirExists = FALSE;
  1066. gPNConfigPlist = NULL;
  1067. gPNAcpiDir = NULL;
  1068. TmpString1 = NULL;
  1069. TmpString2 = NULL;
  1070. GotIt[0] = FALSE;
  1071. GotIt[1] = FALSE;
  1072. DBG ("BdsPlatorm: Starting BdsLibGetBootMode\n");
  1073. Status = BdsLibGetBootMode (&BootMode);
  1074. ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
  1075. // very long function:
  1076. DBG ("BdsPlatorm: Starting PlatformBdsConnectConsole\n"); // 5.2 sec
  1077. PlatformBdsConnectConsole (gPlatformConsole);
  1078. ClearScreen (0x030000, NULL);
  1079. #if 0
  1080. EnableSmbus ();
  1081. #endif
  1082. DBG ("BdsPlatorm: Starting BdsLibConnectAllDriversToAllControllers\n"); // 2.3 sec
  1083. BdsLibConnectAllDriversToAllControllers ();
  1084. Status = gBS->LocateProtocol (
  1085. &gEfiSmbiosProtocolGuid,
  1086. NULL,
  1087. (VOID **) &Smbios
  1088. );
  1089. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  1090. do {
  1091. Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  1092. if (EFI_ERROR(Status)) {
  1093. break;
  1094. }
  1095. if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) {
  1096. Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;
  1097. StrIndex = Type1Record->ProductName;
  1098. GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &TmpString1);
  1099. GotIt[0] = TRUE;
  1100. }
  1101. if (Record->Type == EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION) {
  1102. Type2Record = (SMBIOS_TABLE_TYPE2 *) Record;
  1103. StrIndex = Type2Record->ProductName;
  1104. GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type2Record + Type2Record->Hdr.Length), StrIndex, &TmpString2);
  1105. GotIt[1] = TRUE;
  1106. }
  1107. } while (!(GotIt[0] && GotIt[1]));
  1108. DBG ("BdsPlatorm: DMI TableType1->ProductName = '%s'\n", TmpString1);
  1109. DBG ("BdsPlatorm: DMI TableType2->ProductName = '%s'\n", TmpString2);
  1110. gProductNameDir = MakeProductNameDir (TmpString1);
  1111. DBG ("BdsPlatorm: ProductNameDir = '%s'\n", gProductNameDir);
  1112. gProductNameDir2 = MakeProductNameDir (TmpString2);
  1113. DBG ("BdsPlatorm: ProductNameDir2 = '%s'\n", gProductNameDir2);
  1114. DBG ("BdsPlatorm: Starting BdsLibEnumerateAllBootOption\n");
  1115. BdsLibEnumerateAllBootOption (&gBootOptionList);
  1116. if (gSettings.SaveVideoRom) {
  1117. UINT8 *vrom;
  1118. UINT32 vrom_size;
  1119. vrom = (UINT8*) (UINTN) 0xc0000;
  1120. vrom_size = vrom[2] * 512;
  1121. if (vrom_size == 0) {
  1122. vrom_size = 0x20000;
  1123. }
  1124. DBG ("BdsPlatorm: vrom_size = 0x%x\n", vrom_size);
  1125. egSaveFile (gRootFHandle, L"EFI\\bareboot\\rom.rom", vrom, vrom_size);
  1126. }
  1127. if (gSettings.ScreenMode != 0xffff) {
  1128. SetModeScreen (gSettings.ScreenMode);
  1129. }
  1130. if (gSettings.YoBlack) {
  1131. ClearScreen (0x030000, NULL);
  1132. } else {
  1133. ClearScreen (0xBFBFBF, NULL);
  1134. }
  1135. AddBootArgs = "\0 23456789012345678901234567890123456789";
  1136. if (ShiftKeyPressed () & EFI_LEFT_SHIFT_PRESSED) {
  1137. AsciiStrCat (AddBootArgs, " -v");
  1138. }
  1139. if (ShiftKeyPressed () & EFI_LEFT_CONTROL_PRESSED) {
  1140. AsciiStrCat (AddBootArgs, " -s");
  1141. }
  1142. if ((ShiftKeyPressed () & EFI_RIGHT_ALT_PRESSED) ||
  1143. (ShiftKeyPressed () & EFI_RIGHT_CONTROL_PRESSED)) {
  1144. AsciiStrCat (AddBootArgs, " -x");
  1145. }
  1146. if (ShiftKeyPressed () & EFI_LEFT_ALT_PRESSED) {
  1147. #if 0
  1148. Status = gST->ConIn->Reset (gST->ConIn, TRUE);
  1149. #endif
  1150. PlatformBdsEnterFrontPage (0xffff);
  1151. }
  1152. #if 0
  1153. Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &mKey);
  1154. if (!EFI_ERROR (Status)) {
  1155. if (mKey.ScanCode == SCAN_F1) {
  1156. Status = gST->ConIn->Reset (gST->ConIn, TRUE);
  1157. PlatformBdsEnterFrontPage (0xffff);
  1158. }
  1159. }
  1160. #else
  1161. Status = gBS->LocateProtocol (
  1162. &gEfiSimpleTextInputExProtocolGuid,
  1163. NULL,
  1164. (VOID **) &SimpleTextInEx
  1165. );
  1166. if (!EFI_ERROR (Status)) {
  1167. Status = SimpleTextInEx->ReadKeyStrokeEx (
  1168. SimpleTextInEx,
  1169. &mKeyData
  1170. );
  1171. if (mKeyData.Key.ScanCode == SCAN_F1) {
  1172. #if 0
  1173. (mKeyData.KeyState.KeyShiftState & EFI_LEFT_ALT_PRESSED) {
  1174. #endif
  1175. Status = SimpleTextInEx->Reset (
  1176. SimpleTextInEx,
  1177. TRUE
  1178. );
  1179. PlatformBdsEnterFrontPage (0xffff);
  1180. }
  1181. }
  1182. #endif
  1183. DBG ("BdsPlatorm: Starting PlatformBdsEnterFrontPage\n");
  1184. PlatformBdsEnterFrontPage (gSettings.BootTimeout);
  1185. return ;
  1186. }
  1187. VOID
  1188. EFIAPI
  1189. PlatformBdsBootSuccess (
  1190. IN BDS_COMMON_OPTION *Option
  1191. )
  1192. /*++
  1193. Routine Description:
  1194. Hook point after a boot attempt succeeds. We don't expect a boot option to
  1195. return, so the EFI 1.0 specification defines that you will default to an
  1196. interactive mode and stop processing the BootOrder list in this case. This
  1197. is alos a platform implementation and can be customized by IBV/OEM.
  1198. Arguments:
  1199. Option - Pointer to Boot Option that succeeded to boot.
  1200. Returns:
  1201. None.
  1202. --*/
  1203. {
  1204. CHAR16 *TmpStr;
  1205. //
  1206. // If Boot returned with EFI_SUCCESS and there is not in the boot device
  1207. // select loop then we need to pop up a UI and wait for user input.
  1208. //
  1209. TmpStr = Option->StatusString;
  1210. if (TmpStr != NULL) {
  1211. BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
  1212. gBS->FreePool (TmpStr);
  1213. }
  1214. }
  1215. VOID
  1216. EFIAPI
  1217. PlatformBdsBootFail (
  1218. IN BDS_COMMON_OPTION *Option,
  1219. IN EFI_STATUS Status,
  1220. IN CHAR16 *ExitData,
  1221. IN UINTN ExitDataSize
  1222. )
  1223. /*++
  1224. Routine Description:
  1225. Hook point after a boot attempt fails.
  1226. Arguments:
  1227. Option - Pointer to Boot Option that failed to boot.
  1228. Status - Status returned from failed boot.
  1229. ExitData - Exit data returned from failed boot.
  1230. ExitDataSize - Exit data size returned from failed boot.
  1231. Returns:
  1232. None.
  1233. --*/
  1234. {
  1235. CHAR16 *TmpStr;
  1236. //
  1237. // If Boot returned with failed status then we need to pop up a UI and wait
  1238. // for user input.
  1239. //
  1240. TmpStr = Option->StatusString;
  1241. if (TmpStr != NULL) {
  1242. BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
  1243. gBS->FreePool (TmpStr);
  1244. }
  1245. }
  1246. EFI_STATUS
  1247. ConvertSystemTable (
  1248. IN EFI_GUID *TableGuid,
  1249. IN OUT VOID **Table
  1250. )
  1251. /*++
  1252. Routine Description:
  1253. Convert ACPI Table /Smbios Table /MP Table if its location is lower than Address:0x100000
  1254. Assumption here:
  1255. As in legacy Bios, ACPI/Smbios/MP table is required to place in E/F Seg,
  1256. So here we just check if the range is E/F seg,
  1257. and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
  1258. Arguments:
  1259. TableGuid - Guid of the table
  1260. Table - pointer to the table
  1261. Returns:
  1262. EFI_SUCEESS - Convert Table successfully
  1263. Other - Failed
  1264. --*/
  1265. {
  1266. EFI_STATUS Status;
  1267. VOID *AcpiHeader;
  1268. UINTN AcpiTableLen;
  1269. //
  1270. // If match acpi guid (1.0, 2.0, or later), Convert ACPI table according to version.
  1271. //
  1272. AcpiHeader = (VOID*)(UINTN)(*(UINT64 *)(*Table));
  1273. if (CompareGuid(TableGuid, &gEfiAcpiTableGuid) || CompareGuid(TableGuid, &gEfiAcpi20TableGuid)){
  1274. if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved == 0x00){
  1275. //
  1276. // If Acpi 1.0 Table, then RSDP structure doesn't contain Length field, use structure size
  1277. //
  1278. AcpiTableLen = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
  1279. } else if (((EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Reserved >= 0x02){
  1280. //
  1281. // If Acpi 2.0 or later, use RSDP Length fied.
  1282. //
  1283. AcpiTableLen = ((EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiHeader)->Length;
  1284. } else {
  1285. //
  1286. // Invalid Acpi Version, return
  1287. //
  1288. return EFI_UNSUPPORTED;
  1289. }
  1290. Status = ConvertAcpiTable (AcpiTableLen, Table);
  1291. return Status;
  1292. }
  1293. //
  1294. // If matches smbios guid, convert Smbios table.
  1295. //
  1296. if (CompareGuid(TableGuid, &gEfiSmbiosTableGuid)){
  1297. Status = ConvertSmbiosTable (Table);
  1298. return Status;
  1299. }
  1300. //
  1301. // If the table is MP table?
  1302. //
  1303. if (CompareGuid(TableGuid, &gEfiMpsTableGuid)){
  1304. Status = ConvertMpsTable (Table);
  1305. return Status;
  1306. }
  1307. return EFI_UNSUPPORTED;
  1308. }
  1309. EFI_STATUS
  1310. ConvertAcpiTable (
  1311. IN UINTN TableLen,
  1312. IN OUT VOID **Table
  1313. )
  1314. /*++
  1315. Routine Description:
  1316. Convert RSDP of ACPI Table if its location is lower than Address:0x100000
  1317. Assumption here:
  1318. As in legacy Bios, ACPI table is required to place in E/F Seg,
  1319. So here we just check if the range is E/F seg,
  1320. and if Not, assume the Memory type is EfiACPIReclaimMemory/EfiACPIMemoryNVS
  1321. Arguments:
  1322. TableLen - Acpi RSDP length
  1323. Table - pointer to the table
  1324. Returns:
  1325. EFI_SUCEESS - Convert Table successfully
  1326. Other - Failed
  1327. --*/
  1328. {
  1329. VOID *AcpiTableOri;
  1330. VOID *AcpiTableNew;
  1331. EFI_STATUS Status;
  1332. EFI_PHYSICAL_ADDRESS BufferPtr;
  1333. AcpiTableOri = (VOID *)(UINTN)(*(UINT64*)(*Table));
  1334. if (((UINTN)AcpiTableOri < 0x100000) && ((UINTN)AcpiTableOri > 0xE0000)) {
  1335. BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
  1336. Status = gBS->AllocatePages (
  1337. AllocateMaxAddress,
  1338. EfiACPIMemoryNVS,
  1339. EFI_SIZE_TO_PAGES(TableLen),
  1340. &BufferPtr
  1341. );
  1342. ASSERT_EFI_ERROR (Status);
  1343. AcpiTableNew = (VOID *)(UINTN)BufferPtr;
  1344. CopyMem (AcpiTableNew, AcpiTableOri, TableLen);
  1345. } else {
  1346. AcpiTableNew = AcpiTableOri;
  1347. }
  1348. //
  1349. // Change configuration table Pointer
  1350. //
  1351. *Table = AcpiTableNew;
  1352. return EFI_SUCCESS;
  1353. }
  1354. EFI_STATUS
  1355. ConvertSmbiosTable (
  1356. IN OUT VOID **Table
  1357. )
  1358. /*++
  1359. Routine Description:
  1360. Convert Smbios Table if the Location of the SMBios Table is lower than Addres 0x100000
  1361. Assumption here:
  1362. As in legacy Bios, Smbios table is required to place in E/F Seg,
  1363. So here we just check if the range is F seg,
  1364. and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
  1365. Arguments:
  1366. Table - pointer to the table
  1367. Returns:
  1368. EFI_SUCEESS - Convert Table successfully
  1369. Other - Failed
  1370. --*/
  1371. {
  1372. SMBIOS_TABLE_ENTRY_POINT *SmbiosTableNew;
  1373. SMBIOS_TABLE_ENTRY_POINT *SmbiosTableOri;
  1374. EFI_STATUS Status;
  1375. UINT32 SmbiosEntryLen;
  1376. UINT32 BufferLen;
  1377. EFI_PHYSICAL_ADDRESS BufferPtr;
  1378. SmbiosTableNew = NULL;
  1379. SmbiosTableOri = NULL;
  1380. //
  1381. // Get Smibos configuration Table
  1382. //
  1383. SmbiosTableOri = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)(*(UINT64*)(*Table));
  1384. if ((SmbiosTableOri == NULL) ||
  1385. ((UINTN)SmbiosTableOri > 0x100000) ||
  1386. ((UINTN)SmbiosTableOri < 0xF0000)){
  1387. return EFI_SUCCESS;
  1388. }
  1389. //
  1390. // Relocate the Smibos memory
  1391. //
  1392. BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
  1393. if (SmbiosTableOri->SmbiosBcdRevision != 0x21) {
  1394. SmbiosEntryLen = SmbiosTableOri->EntryPointLength;
  1395. } else {
  1396. //
  1397. // According to Smbios Spec 2.4, we should set entry point length as 0x1F if version is 2.1
  1398. //
  1399. SmbiosEntryLen = 0x1F;
  1400. }
  1401. BufferLen = SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen) + SmbiosTableOri->TableLength;
  1402. Status = gBS->AllocatePages (
  1403. AllocateMaxAddress,
  1404. EfiACPIMemoryNVS,
  1405. EFI_SIZE_TO_PAGES(BufferLen),
  1406. &BufferPtr
  1407. );
  1408. ASSERT_EFI_ERROR (Status);
  1409. SmbiosTableNew = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN)BufferPtr;
  1410. CopyMem (
  1411. SmbiosTableNew,
  1412. SmbiosTableOri,
  1413. SmbiosEntryLen
  1414. );
  1415. //
  1416. // Get Smbios Structure table address, and make sure the start address is 32-bit align
  1417. //
  1418. BufferPtr += SmbiosEntryLen + SYS_TABLE_PAD(SmbiosEntryLen);
  1419. CopyMem (
  1420. (VOID *)(UINTN)BufferPtr,
  1421. (VOID *)(UINTN)(SmbiosTableOri->TableAddress),
  1422. SmbiosTableOri->TableLength
  1423. );
  1424. SmbiosTableNew->TableAddress = (UINT32)BufferPtr;
  1425. SmbiosTableNew->IntermediateChecksum = 0;
  1426. SmbiosTableNew->IntermediateChecksum =
  1427. CalculateCheckSum8 ((UINT8*)SmbiosTableNew + 0x10, SmbiosEntryLen -0x10);
  1428. //
  1429. // Change the SMBIOS pointer
  1430. //
  1431. *Table = SmbiosTableNew;
  1432. return EFI_SUCCESS;
  1433. }
  1434. EFI_STATUS
  1435. ConvertMpsTable (
  1436. IN OUT VOID **Table
  1437. )
  1438. /*++
  1439. Routine Description:
  1440. Convert MP Table if the Location of the SMBios Table is lower than Addres 0x100000
  1441. Assumption here:
  1442. As in legacy Bios, MP table is required to place in E/F Seg,
  1443. So here we just check if the range is E/F seg,
  1444. and if Not, assume the Memory type is EfiACPIMemoryNVS/EfiRuntimeServicesData
  1445. Arguments:
  1446. Table - pointer to the table
  1447. Returns:
  1448. EFI_SUCEESS - Convert Table successfully
  1449. Other - Failed
  1450. --*/
  1451. {
  1452. UINT32 Data32;
  1453. UINT32 FPLength;
  1454. EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerOri;
  1455. EFI_LEGACY_MP_TABLE_FLOATING_POINTER *MpsFloatingPointerNew;
  1456. EFI_LEGACY_MP_TABLE_HEADER *MpsTableOri;
  1457. EFI_LEGACY_MP_TABLE_HEADER *MpsTableNew;
  1458. VOID *OemTableOri;
  1459. VOID *OemTableNew;
  1460. EFI_STATUS Status;
  1461. EFI_PHYSICAL_ADDRESS BufferPtr;
  1462. //
  1463. // Get MP configuration Table
  1464. //
  1465. MpsFloatingPointerOri = (EFI_LEGACY_MP_TABLE_FLOATING_POINTER *)(UINTN)(*(UINT64*)(*Table));
  1466. if (!(((UINTN)MpsFloatingPointerOri <= 0x100000) &&
  1467. ((UINTN)MpsFloatingPointerOri >= 0xF0000))){
  1468. return EFI_SUCCESS;
  1469. }
  1470. //
  1471. // Get Floating pointer structure length
  1472. //
  1473. FPLength = MpsFloatingPointerOri->Length * 16;
  1474. Data32 = FPLength + SYS_TABLE_PAD (FPLength);
  1475. MpsTableOri = (EFI_LEGACY_MP_TABLE_HEADER *)(UINTN)(MpsFloatingPointerOri->PhysicalAddress);
  1476. if (MpsTableOri != NULL) {
  1477. Data32 += MpsTableOri->BaseTableLength;
  1478. Data32 += MpsTableOri->ExtendedTableLength;
  1479. if (MpsTableOri->OemTablePointer != 0x00) {
  1480. Data32 += SYS_TABLE_PAD (Data32);
  1481. Data32 += MpsTableOri->OemTableSize;
  1482. }
  1483. } else {
  1484. return EFI_SUCCESS;
  1485. }
  1486. //
  1487. // Relocate memory
  1488. //
  1489. BufferPtr = EFI_SYSTEM_TABLE_MAX_ADDRESS;
  1490. Status = gBS->AllocatePages (
  1491. AllocateMaxAddress,

Large files files are truncated, but you can click here to view the full file