Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1615 lines
42 KiB

  1. #include "bldr.h"
  2. #include "bootefi.h"
  3. #include "efi.h"
  4. #include "smbios.h"
  5. #include "stdlib.h"
  6. #if defined(_IA64_)
  7. #include "bootia64.h"
  8. #endif
  9. extern EFI_HANDLE EfiImageHandle;
  10. extern EFI_SYSTEM_TABLE *EfiST;
  11. extern EFI_BOOT_SERVICES *EfiBS;
  12. //
  13. // macro definition
  14. //
  15. #define EfiPrint(_X) \
  16. { \
  17. if (IsPsrDtOn()) { \
  18. FlipToPhysical(); \
  19. EfiST->ConOut->OutputString(EfiST->ConOut, (_X)); \
  20. FlipToVirtual(); \
  21. } \
  22. else { \
  23. EfiST->ConOut->OutputString(EfiST->ConOut, (_X)); \
  24. } \
  25. }
  26. INTN
  27. RUNTIMEFUNCTION
  28. CompareGuid(
  29. IN EFI_GUID *Guid1,
  30. IN EFI_GUID *Guid2
  31. )
  32. /*++
  33. Routine Description:
  34. Compares two GUIDs
  35. Arguments:
  36. Guid1 - guid to compare
  37. Guid2 - guid to compare
  38. Returns:
  39. = 0 if Guid1 == Guid2
  40. --*/
  41. {
  42. INT32 *g1, *g2, r;
  43. //
  44. // Compare 32 bits at a time
  45. //
  46. g1 = (INT32 *) Guid1;
  47. g2 = (INT32 *) Guid2;
  48. r = g1[0] - g2[0];
  49. r |= g1[1] - g2[1];
  50. r |= g1[2] - g2[2];
  51. r |= g1[3] - g2[3];
  52. return r;
  53. }
  54. EFI_STATUS
  55. GetSystemConfigurationTable(
  56. IN EFI_GUID *TableGuid,
  57. IN OUT VOID **Table
  58. )
  59. {
  60. UINTN Index;
  61. //
  62. // ST is system table
  63. //
  64. for(Index=0;Index<EfiST->NumberOfTableEntries;Index++) {
  65. if (CompareGuid(TableGuid,&(EfiST->ConfigurationTable[Index].VendorGuid))==0) {
  66. *Table = EfiST->ConfigurationTable[Index].VendorTable;
  67. return EFI_SUCCESS;
  68. }
  69. }
  70. return EFI_NOT_FOUND;
  71. }
  72. ARC_STATUS
  73. BlGetEfiProtocolHandles(
  74. IN EFI_GUID *ProtocolType,
  75. OUT EFI_HANDLE **pHandleArray,
  76. OUT ULONG *NumberOfDevices
  77. )
  78. /*++
  79. Routine Description:
  80. Finds all of the handles that support a given protocol type.
  81. This routine requires that BlInitializeMemory() has already been
  82. called.
  83. Arguments:
  84. ProtocolType - GUID that describes handle type to search for.
  85. pHandleArray - receives an array of handles that support the specified
  86. protocol.
  87. The page that these handles reside in can be freed via
  88. BlFreeDescriptor.
  89. NumberOfDevices - receives the number of device handles that support the
  90. given protocol
  91. Returns:
  92. ARC_STATUS indicating outcome.
  93. --*/
  94. {
  95. EFI_HANDLE *HandleArray = NULL;
  96. ULONGLONG HandleArraySize = 0;
  97. ULONG MemoryPage;
  98. ARC_STATUS ArcStatus;
  99. EFI_STATUS EfiStatus;
  100. *pHandleArray = NULL;
  101. *NumberOfDevices = 0;
  102. //
  103. // Change to physical mode so that we can make EFI calls
  104. //
  105. FlipToPhysical();
  106. // EfiPrint(L"In BlGetEfiProtocolHandles\r\n");
  107. //
  108. // Try to find out how much space we need.
  109. //
  110. EfiStatus = EfiBS->LocateHandle (
  111. ByProtocol,
  112. ProtocolType,
  113. 0,
  114. (UINTN *) &HandleArraySize,
  115. HandleArray
  116. );
  117. FlipToVirtual();
  118. if (EfiStatus != EFI_BUFFER_TOO_SMALL) {
  119. //
  120. // yikes. something is really messed up. return failure.
  121. //
  122. // EfiPrint(L"LocateHandle returned failure\r\n");
  123. return(EINVAL);
  124. }
  125. // EfiPrint(L"About to BlAllocateAlignedDescriptor\r\n");
  126. //
  127. // allocate space for the handles.
  128. //
  129. ArcStatus = BlAllocateAlignedDescriptor(
  130. LoaderFirmwareTemporary,
  131. 0,
  132. (ULONG) BYTES_TO_PAGES(HandleArraySize),
  133. 0,
  134. &MemoryPage);
  135. if (ArcStatus != ESUCCESS) {
  136. // EfiPrint(L"BlAllocateAlignedDescriptor failed\r\n");
  137. return(ArcStatus);
  138. }
  139. HandleArray = (EFI_HANDLE *)(ULONGLONG)((ULONGLONG)MemoryPage << PAGE_SHIFT);
  140. FlipToPhysical();
  141. RtlZeroMemory(HandleArray, HandleArraySize);
  142. // EfiPrint(L"calling LocateHandle again\r\n");
  143. //
  144. // now get the handles now that we have enough space.
  145. //
  146. EfiStatus = EfiBS->LocateHandle (
  147. ByProtocol,
  148. ProtocolType,
  149. 0,
  150. (UINTN *) &HandleArraySize,
  151. (EFI_HANDLE *)HandleArray
  152. );
  153. // EfiPrint(L"back from LocateHandle\r\n");
  154. FlipToVirtual();
  155. if (EFI_ERROR(EfiStatus)) {
  156. //
  157. // cleanup and return
  158. //
  159. // EfiPrint(L"LocateHandle failed\r\n");
  160. BlFreeDescriptor( MemoryPage );
  161. return(EINVAL);
  162. }
  163. // EfiPrint(L"LocateHandle succeeded, return success\r\n");
  164. *NumberOfDevices = (ULONG)(HandleArraySize / sizeof (EFI_HANDLE));
  165. *pHandleArray = HandleArray;
  166. // BlPrint(TEXT("BlGetEfiProtocolHandles: found %x devices\r\n"), *NumberOfDevices );
  167. return(ESUCCESS);
  168. }
  169. CHAR16 *sprintf_buf;
  170. UINT16 count;
  171. VOID
  172. __cdecl
  173. putbuf(CHAR16 c)
  174. {
  175. *sprintf_buf++ = c;
  176. count++;
  177. }
  178. VOID
  179. bzero(CHAR16 *cp, int len)
  180. {
  181. while (len--) {
  182. *(cp + len) = 0;
  183. }
  184. }
  185. VOID
  186. __cdecl
  187. doprnt(VOID (*func)(CHAR16 c), const CHAR16 *fmt, va_list args);
  188. //
  189. // BUGBUG this is a semi-sprintf hacked together just to get it to work
  190. //
  191. UINT16
  192. __cdecl
  193. wsprintf(CHAR16 *buf, const CHAR16 *fmt, ...)
  194. {
  195. va_list args;
  196. sprintf_buf = buf;
  197. va_start(args, fmt);
  198. doprnt(putbuf, fmt, args);
  199. va_end(args);
  200. putbuf('\0');
  201. return count--;
  202. }
  203. void
  204. __cdecl
  205. printbase(VOID (*func)(CHAR16), ULONG x, int base, int width)
  206. {
  207. static CHAR16 itoa[] = L"0123456789abcdef";
  208. ULONG j;
  209. LONG k;
  210. CHAR16 buf[32], *s = buf;
  211. bzero(buf, 16);
  212. if (x == 0 ) {
  213. *s++ = itoa[0];
  214. }
  215. while (x) {
  216. j = x % base;
  217. *s++ = itoa[j];
  218. x -= j;
  219. x /= base;
  220. }
  221. if( s-buf < width ) {
  222. for( k = 0; k < width - (s-buf); k++ ) {
  223. func('0');
  224. }
  225. }
  226. for (--s; s >= buf; --s) {
  227. func(*s);
  228. }
  229. }
  230. void
  231. __cdecl
  232. printguid(
  233. VOID (*func)( CHAR16),
  234. GUID *pGuid
  235. )
  236. {
  237. func(L'{');
  238. printbase(func, pGuid->Data1, 16, 8);
  239. func(L'-');
  240. printbase(func, pGuid->Data2, 16, 4);
  241. func(L'-');
  242. printbase(func, pGuid->Data3, 16, 4);
  243. func(L'-');
  244. printbase(func, pGuid->Data4[0], 16, 2);
  245. printbase(func, pGuid->Data4[1], 16, 2);
  246. func(L'-');
  247. printbase(func, pGuid->Data4[2], 16, 2);
  248. printbase(func, pGuid->Data4[3], 16, 2);
  249. printbase(func, pGuid->Data4[4], 16, 2);
  250. printbase(func, pGuid->Data4[5], 16, 2);
  251. printbase(func, pGuid->Data4[6], 16, 2);
  252. printbase(func, pGuid->Data4[7], 16, 2);
  253. func(L'}');
  254. }
  255. void
  256. __cdecl
  257. doprnt(VOID (*func)( CHAR16 c), const CHAR16 *fmt, va_list args)
  258. {
  259. ULONG x;
  260. LONG l;
  261. LONG width;
  262. CHAR16 c, *s;
  263. GUID * g;
  264. count = 0;
  265. while ((c = *fmt++) != 0) {
  266. if (c != '%') {
  267. func(c);
  268. continue;
  269. }
  270. width=0;
  271. c=*fmt++;
  272. if(c == '0') {
  273. while( (c = *fmt++) != 0) {
  274. if (!isdigit(c)) {
  275. break;
  276. }
  277. width = width*10;
  278. width = width+(c-48);
  279. }
  280. }
  281. fmt--; // back it up one char
  282. switch (c = *fmt++) {
  283. case 'x':
  284. x = va_arg(args, ULONG);
  285. printbase(func, x, 16, width);
  286. break;
  287. case 'o':
  288. x = va_arg(args, ULONG);
  289. printbase(func, x, 8, width);
  290. break;
  291. case 'd':
  292. l = va_arg(args, LONG);
  293. if (l < 0) {
  294. func('-');
  295. l = -l;
  296. }
  297. printbase(func, (ULONG) l, 10, width);
  298. break;
  299. case 'u':
  300. l = va_arg(args, ULONG);
  301. printbase(func, (ULONG) l, 10, width);
  302. break;
  303. case 'g':
  304. g = va_arg(args, GUID *);
  305. printguid(func, g);
  306. break;
  307. case 'c':
  308. c = va_arg(args, CHAR16);
  309. func(c);
  310. break;
  311. case 's':
  312. s = va_arg(args, CHAR16 *);
  313. while (*s) {
  314. func(*s++);
  315. }
  316. break;
  317. default:
  318. func(c);
  319. break;
  320. }
  321. }
  322. }
  323. VOID
  324. CatPrint(
  325. IN UNICODE_STRING *String,
  326. IN CHAR16* Format,
  327. ...
  328. )
  329. {
  330. CHAR16* pString = String->Buffer;
  331. va_list args;
  332. if (*pString != '\0') {
  333. pString = String->Buffer + wcslen(String->Buffer);
  334. }
  335. sprintf_buf = pString;
  336. va_start(args, Format);
  337. doprnt(putbuf, Format, args);
  338. va_end(args);
  339. putbuf('\0');
  340. }
  341. VOID
  342. _DevPathPci (
  343. IN OUT UNICODE_STRING *Str,
  344. IN VOID *DevPath
  345. )
  346. {
  347. PCI_DEVICE_PATH UNALIGNED *Pci;
  348. Pci = DevPath;
  349. CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);
  350. }
  351. VOID
  352. _DevPathPccard (
  353. IN OUT UNICODE_STRING *Str,
  354. IN VOID *DevPath
  355. )
  356. {
  357. PCCARD_DEVICE_PATH UNALIGNED *Pccard;
  358. Pccard = DevPath;
  359. CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber);
  360. }
  361. VOID
  362. _DevPathMemMap (
  363. IN OUT UNICODE_STRING *Str,
  364. IN VOID *DevPath
  365. )
  366. {
  367. MEMMAP_DEVICE_PATH UNALIGNED *MemMap;
  368. MemMap = DevPath;
  369. CatPrint(Str, L"MemMap(%d:%x-%x)",
  370. MemMap->MemoryType,
  371. MemMap->StartingAddress,
  372. MemMap->EndingAddress
  373. );
  374. }
  375. VOID
  376. _DevPathController (
  377. IN OUT UNICODE_STRING *Str,
  378. IN VOID *DevPath
  379. )
  380. {
  381. CONTROLLER_DEVICE_PATH UNALIGNED *Controller;
  382. Controller = DevPath;
  383. CatPrint(Str, L"Ctrl(%d)",
  384. Controller->Controller
  385. );
  386. }
  387. VOID
  388. _DevPathVendor (
  389. IN OUT UNICODE_STRING *Str,
  390. IN VOID *DevPath
  391. )
  392. {
  393. VENDOR_DEVICE_PATH UNALIGNED *Vendor;
  394. CHAR16 *Type;
  395. UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UNALIGNED *UnknownDevPath;
  396. EFI_GUID UnknownDevice = UNKNOWN_DEVICE_GUID;
  397. EFI_GUID VendorGuid;
  398. Vendor = DevPath;
  399. switch (DevicePathType(&Vendor->Header)) {
  400. case HARDWARE_DEVICE_PATH: Type = L"Hw"; break;
  401. case MESSAGING_DEVICE_PATH: Type = L"Msg"; break;
  402. case MEDIA_DEVICE_PATH: Type = L"Media"; break;
  403. default: Type = L"?"; break;
  404. }
  405. RtlCopyMemory( &VendorGuid, &Vendor->Guid, sizeof(EFI_GUID));
  406. CatPrint(Str, L"Ven%s(%g", Type, &VendorGuid);
  407. if (CompareGuid (&VendorGuid, &UnknownDevice) == 0) {
  408. /*
  409. * GUID used by EFI to enumerate an EDD 1.1 device
  410. */
  411. UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UNALIGNED *)Vendor;
  412. CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
  413. } else {
  414. CatPrint(Str, L")");
  415. }
  416. }
  417. VOID
  418. _DevPathAcpi (
  419. IN OUT UNICODE_STRING *Str,
  420. IN VOID *DevPath
  421. )
  422. {
  423. ACPI_HID_DEVICE_PATH UNALIGNED *Acpi;
  424. Acpi = DevPath;
  425. if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
  426. CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
  427. } else {
  428. CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
  429. }
  430. }
  431. VOID
  432. _DevPathAtapi (
  433. IN OUT UNICODE_STRING *Str,
  434. IN VOID *DevPath
  435. )
  436. {
  437. ATAPI_DEVICE_PATH UNALIGNED *Atapi;
  438. Atapi = DevPath;
  439. CatPrint(Str, L"Ata(%s,%s)",
  440. Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
  441. Atapi->SlaveMaster ? L"Slave" : L"Master"
  442. );
  443. }
  444. VOID
  445. _DevPathScsi (
  446. IN OUT UNICODE_STRING *Str,
  447. IN VOID *DevPath
  448. )
  449. {
  450. SCSI_DEVICE_PATH UNALIGNED *Scsi;
  451. Scsi = DevPath;
  452. CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);
  453. }
  454. VOID
  455. _DevPathFibre (
  456. IN OUT UNICODE_STRING *Str,
  457. IN VOID *DevPath
  458. )
  459. {
  460. FIBRECHANNEL_DEVICE_PATH UNALIGNED *Fibre;
  461. Fibre = DevPath;
  462. CatPrint(Str, L"Fibre(%lx)", Fibre->WWN);
  463. }
  464. VOID
  465. _DevPath1394 (
  466. IN OUT UNICODE_STRING *Str,
  467. IN VOID *DevPath
  468. )
  469. {
  470. F1394_DEVICE_PATH UNALIGNED *F1394;
  471. F1394 = DevPath;
  472. CatPrint(Str, L"1394(%g)", &F1394->Guid);
  473. }
  474. VOID
  475. _DevPathUsb (
  476. IN OUT UNICODE_STRING *Str,
  477. IN VOID *DevPath
  478. )
  479. {
  480. USB_DEVICE_PATH UNALIGNED *Usb;
  481. Usb = DevPath;
  482. CatPrint(Str, L"Usb(%x)", Usb->Port);
  483. }
  484. VOID
  485. _DevPathI2O (
  486. IN OUT UNICODE_STRING *Str,
  487. IN VOID *DevPath
  488. )
  489. {
  490. I2O_DEVICE_PATH UNALIGNED *I2O;
  491. I2O = DevPath;
  492. CatPrint(Str, L"I2O(%x)", I2O->Tid);
  493. }
  494. VOID
  495. _DevPathMacAddr (
  496. IN OUT UNICODE_STRING *Str,
  497. IN VOID *DevPath
  498. )
  499. {
  500. MAC_ADDR_DEVICE_PATH UNALIGNED *MAC;
  501. UINTN HwAddressSize;
  502. UINTN Index;
  503. MAC = DevPath;
  504. HwAddressSize = sizeof(EFI_MAC_ADDRESS);
  505. if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
  506. HwAddressSize = 6;
  507. }
  508. CatPrint(Str, L"Mac(");
  509. for(Index = 0; Index < HwAddressSize; Index++) {
  510. CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
  511. }
  512. CatPrint(Str, L")");
  513. }
  514. VOID
  515. _DevPathIPv4 (
  516. IN OUT UNICODE_STRING *Str,
  517. IN VOID *DevPath
  518. )
  519. {
  520. IPv4_DEVICE_PATH UNALIGNED *IP;
  521. IP = DevPath;
  522. CatPrint(Str, L"IPv4(not-done)");
  523. }
  524. VOID
  525. _DevPathIPv6 (
  526. IN OUT UNICODE_STRING *Str,
  527. IN VOID *DevPath
  528. )
  529. {
  530. IPv6_DEVICE_PATH UNALIGNED *IP;
  531. IP = DevPath;
  532. CatPrint(Str, L"IP-v6(not-done)");
  533. }
  534. VOID
  535. _DevPathInfiniBand (
  536. IN OUT UNICODE_STRING *Str,
  537. IN VOID *DevPath
  538. )
  539. {
  540. INFINIBAND_DEVICE_PATH UNALIGNED *InfiniBand;
  541. InfiniBand = DevPath;
  542. CatPrint(Str, L"InfiniBand(not-done)");
  543. }
  544. VOID
  545. _DevPathUart (
  546. IN OUT UNICODE_STRING *Str,
  547. IN VOID *DevPath
  548. )
  549. {
  550. UART_DEVICE_PATH UNALIGNED *Uart;
  551. CHAR8 Parity;
  552. Uart = DevPath;
  553. switch (Uart->Parity) {
  554. case 0 : Parity = 'D'; break;
  555. case 1 : Parity = 'N'; break;
  556. case 2 : Parity = 'E'; break;
  557. case 3 : Parity = 'O'; break;
  558. case 4 : Parity = 'M'; break;
  559. case 5 : Parity = 'S'; break;
  560. default : Parity = 'x'; break;
  561. }
  562. if (Uart->BaudRate == 0) {
  563. CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity);
  564. } else {
  565. CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity);
  566. }
  567. if (Uart->DataBits == 0) {
  568. CatPrint(Str, L"D");
  569. } else {
  570. CatPrint(Str, L"%d",Uart->DataBits);
  571. }
  572. switch (Uart->StopBits) {
  573. case 0 : CatPrint(Str, L"D)"); break;
  574. case 1 : CatPrint(Str, L"1)"); break;
  575. case 2 : CatPrint(Str, L"1.5)"); break;
  576. case 3 : CatPrint(Str, L"2)"); break;
  577. default : CatPrint(Str, L"x)"); break;
  578. }
  579. }
  580. VOID
  581. _DevPathHardDrive (
  582. IN OUT UNICODE_STRING *Str,
  583. IN VOID *DevPath
  584. )
  585. {
  586. HARDDRIVE_DEVICE_PATH UNALIGNED *Hd;
  587. Hd = DevPath;
  588. switch (Hd->SignatureType) {
  589. case SIGNATURE_TYPE_MBR:
  590. CatPrint(Str, L"HD(Part%d,Sig%08X)",
  591. Hd->PartitionNumber,
  592. *((UINT32 *)(&(Hd->Signature[0])))
  593. );
  594. break;
  595. case SIGNATURE_TYPE_GUID:
  596. CatPrint(Str, L"HD(Part%d,Sig%g)",
  597. Hd->PartitionNumber,
  598. (EFI_GUID *) &(Hd->Signature[0])
  599. );
  600. break;
  601. default:
  602. CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)",
  603. Hd->PartitionNumber,
  604. Hd->MBRType,
  605. Hd->SignatureType
  606. );
  607. break;
  608. }
  609. }
  610. VOID
  611. _DevPathCDROM (
  612. IN OUT UNICODE_STRING *Str,
  613. IN VOID *DevPath
  614. )
  615. {
  616. CDROM_DEVICE_PATH UNALIGNED *Cd;
  617. Cd = DevPath;
  618. CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry);
  619. }
  620. VOID
  621. _DevPathFilePath (
  622. IN OUT UNICODE_STRING *Str,
  623. IN VOID *DevPath
  624. )
  625. {
  626. FILEPATH_DEVICE_PATH UNALIGNED *Fp;
  627. Fp = DevPath;
  628. CatPrint(Str, L"%s", Fp->PathName);
  629. }
  630. VOID
  631. _DevPathMediaProtocol (
  632. IN OUT UNICODE_STRING *Str,
  633. IN VOID *DevPath
  634. )
  635. {
  636. MEDIA_PROTOCOL_DEVICE_PATH UNALIGNED *MediaProt;
  637. MediaProt = DevPath;
  638. CatPrint(Str, L"%g", &MediaProt->Protocol);
  639. }
  640. VOID
  641. _DevPathBssBss (
  642. IN OUT UNICODE_STRING *Str,
  643. IN VOID *DevPath
  644. )
  645. {
  646. BBS_BBS_DEVICE_PATH UNALIGNED *Bss;
  647. CHAR16 *Type;
  648. Bss = DevPath;
  649. switch (Bss->DeviceType) {
  650. case BBS_TYPE_FLOPPY: Type = L"Floppy"; break;
  651. case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break;
  652. case BBS_TYPE_CDROM: Type = L"CDROM"; break;
  653. case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break;
  654. case BBS_TYPE_USB: Type = L"Usb"; break;
  655. case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break;
  656. default: Type = L"?"; break;
  657. }
  658. CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String);
  659. }
  660. VOID
  661. _DevPathEndInstance (
  662. IN OUT UNICODE_STRING *Str,
  663. IN VOID *DevPath
  664. )
  665. {
  666. UNREFERENCED_PARAMETER( DevPath );
  667. CatPrint(Str, L",");
  668. }
  669. VOID
  670. _DevPathNodeUnknown (
  671. IN OUT UNICODE_STRING *Str,
  672. IN VOID *DevPath
  673. )
  674. {
  675. UNREFERENCED_PARAMETER( DevPath );
  676. CatPrint(Str, L"?");
  677. }
  678. struct {
  679. UINT8 Type;
  680. UINT8 SubType;
  681. VOID (*Function)(UNICODE_STRING *, VOID *);
  682. } DevPathTable[] = {
  683. HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci,
  684. HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard,
  685. HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap,
  686. HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor,
  687. HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController,
  688. ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi,
  689. MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi,
  690. MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi,
  691. MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre,
  692. MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394,
  693. MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb,
  694. MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O,
  695. MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr,
  696. MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4,
  697. MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6,
  698. MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand,
  699. MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart,
  700. MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor,
  701. MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive,
  702. MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM,
  703. MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor,
  704. MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath,
  705. MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol,
  706. BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss,
  707. END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance,
  708. 0, 0, NULL
  709. };
  710. #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
  711. EFI_DEVICE_PATH UNALIGNED *
  712. UnpackDevicePath (
  713. IN EFI_DEVICE_PATH UNALIGNED *DevPath
  714. )
  715. {
  716. EFI_DEVICE_PATH UNALIGNED *Src, *Dest, *NewPath;
  717. UINTN Size;
  718. /*
  719. * Walk device path and round sizes to valid boundries
  720. * */
  721. Src = DevPath;
  722. Size = 0;
  723. for (; ;) {
  724. Size += DevicePathNodeLength(Src);
  725. Size += ALIGN_SIZE(Size);
  726. if (IsDevicePathEnd(Src)) {
  727. break;
  728. }
  729. Src = NextDevicePathNode(Src);
  730. }
  731. /*
  732. * Allocate space for the unpacked path
  733. */
  734. EfiAllocateAndZeroMemory( EfiLoaderData,
  735. Size,
  736. (VOID **) &NewPath );
  737. if (NewPath) {
  738. /*
  739. * Copy each node
  740. */
  741. Src = DevPath;
  742. Dest = NewPath;
  743. for (; ;) {
  744. Size = DevicePathNodeLength(Src);
  745. RtlCopyMemory (Dest, Src, Size);
  746. Size += ALIGN_SIZE(Size);
  747. SetDevicePathNodeLength (Dest, Size);
  748. Dest->Type |= EFI_DP_TYPE_UNPACKED;
  749. Dest = (EFI_DEVICE_PATH UNALIGNED *) (((UINT8 *) Dest) + Size);
  750. if (IsDevicePathEnd(Src)) {
  751. break;
  752. }
  753. Src = NextDevicePathNode(Src);
  754. }
  755. }
  756. return NewPath;
  757. }
  758. WCHAR DbgDevicePathStringBuffer[1000];
  759. CHAR16 *
  760. DevicePathToStr (
  761. EFI_DEVICE_PATH UNALIGNED *DevPath
  762. )
  763. /*++
  764. Turns the Device Path into a printable string. Allcoates
  765. the string from pool. The caller must FreePool the returned
  766. string.
  767. --*/
  768. {
  769. UNICODE_STRING Str;
  770. EFI_DEVICE_PATH UNALIGNED *DevPathNode;
  771. VOID (*DumpNode)(UNICODE_STRING *, VOID *);
  772. UINTN Index;
  773. RtlZeroMemory(DbgDevicePathStringBuffer, sizeof(DbgDevicePathStringBuffer));
  774. Str.Buffer= DbgDevicePathStringBuffer;
  775. Str.Length = sizeof(DbgDevicePathStringBuffer);
  776. Str.MaximumLength = sizeof(DbgDevicePathStringBuffer);
  777. /*
  778. * Unpacked the device path
  779. */
  780. DevPath = UnpackDevicePath(DevPath);
  781. ASSERT (DevPath);
  782. /*
  783. * Process each device path node
  784. * */
  785. DevPathNode = DevPath;
  786. while (!IsDevicePathEnd(DevPathNode)) {
  787. /*
  788. * Find the handler to dump this device path node
  789. */
  790. DumpNode = NULL;
  791. for (Index = 0; DevPathTable[Index].Function; Index += 1) {
  792. if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
  793. DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
  794. DumpNode = DevPathTable[Index].Function;
  795. break;
  796. }
  797. }
  798. /*
  799. * If not found, use a generic function
  800. */
  801. if (!DumpNode) {
  802. DumpNode = _DevPathNodeUnknown;
  803. }
  804. /*
  805. * Put a path seperator in if needed
  806. */
  807. if (Str.Length && DumpNode != _DevPathEndInstance) {
  808. CatPrint (&Str, L"/");
  809. }
  810. /*
  811. * Print this node of the device path
  812. */
  813. DumpNode (&Str, DevPathNode);
  814. /*
  815. * Next device path node
  816. */
  817. DevPathNode = NextDevicePathNode(DevPathNode);
  818. }
  819. /*
  820. * Shrink pool used for string allocation
  821. */
  822. EfiBS->FreePool (DevPath);
  823. return Str.Buffer;
  824. }
  825. PVOID
  826. FindSMBIOSTable(
  827. UCHAR RequestedTableType
  828. )
  829. /*++
  830. Routine Description:
  831. This routine searches through the SMBIOS tables for the specified table
  832. type.
  833. Arguments:
  834. RequestedTableType - Which SMBIOS table are we looking for?
  835. Return Value:
  836. NULL - THe specified table was not found.
  837. PVOID - A pointer to the specified table.
  838. --*/
  839. {
  840. extern PVOID SMBiosTable;
  841. PUCHAR StartPtr = NULL;
  842. PUCHAR EndPtr = NULL;
  843. PSMBIOS_EPS_HEADER SMBiosEPSHeader = NULL;
  844. PDMIBIOS_EPS_HEADER DMIBiosEPSHeader = NULL;
  845. PSMBIOS_STRUCT_HEADER SMBiosHeader = NULL;
  846. if( SMBiosTable == NULL ) {
  847. return NULL;
  848. }
  849. //
  850. // Set up our search pointers.
  851. //
  852. SMBiosEPSHeader = (PSMBIOS_EPS_HEADER)SMBiosTable;
  853. DMIBiosEPSHeader = (PDMIBIOS_EPS_HEADER)&SMBiosEPSHeader->Signature2[0];
  854. StartPtr = (PUCHAR)ULongToPtr(DMIBiosEPSHeader->StructureTableAddress);
  855. EndPtr = StartPtr + DMIBiosEPSHeader->StructureTableLength;
  856. if( BdDebuggerEnabled ) {
  857. DbgPrint( "FindSMBIOSTable: About to start searching for table type %d at address (%x)...\r\n",
  858. RequestedTableType,
  859. PtrToUlong(StartPtr) );
  860. }
  861. while( StartPtr < EndPtr ) {
  862. SMBiosHeader = (PSMBIOS_STRUCT_HEADER)StartPtr;
  863. if( SMBiosHeader->Type == RequestedTableType ) {
  864. // This is the table we're looking for.
  865. if( BdDebuggerEnabled ) {
  866. DbgPrint( "FindSMBIOSTable: Found requested table type %d at address %x\r\n",
  867. RequestedTableType,
  868. PtrToUlong(StartPtr) );
  869. }
  870. return (PVOID)StartPtr;
  871. } else {
  872. //
  873. // It's not him. Go to the next table.
  874. //
  875. if( BdDebuggerEnabled ) {
  876. DbgPrint( "FindSMBIOSTable: Inspected table type %d at address %x\r\n",
  877. SMBiosHeader->Type,
  878. PtrToUlong(StartPtr) );
  879. }
  880. StartPtr += SMBiosHeader->Length;
  881. //
  882. // jump over any trailing string-list that may be appeneded onto the
  883. // end of this table.
  884. //
  885. while ( (*((USHORT UNALIGNED *)StartPtr) != 0) &&
  886. (StartPtr < EndPtr) ) {
  887. StartPtr++;
  888. }
  889. StartPtr += 2;
  890. }
  891. }
  892. return NULL;
  893. }
  894. VOID
  895. EfiCheckFirmwareRevision(
  896. VOID
  897. )
  898. /*++
  899. Routine Description:
  900. This routine will retrieve the BIOS revision value then parse it to determine
  901. if the revision is new enough.
  902. If the revision is not new enough, we won't be returning from this function.
  903. Arguments:
  904. None.
  905. Return Value:
  906. None.
  907. --*/
  908. {
  909. #define FIRMWARE_MINIMUM_SOFTSUR (103)
  910. #define FIRMWARE_MINIMUM_LION (71)
  911. PUCHAR FirmwareString = NULL;
  912. PUCHAR VendorString = NULL;
  913. PUCHAR TmpPtr = NULL;
  914. ULONG FirmwareVersion = 0;
  915. ULONG FirmwareMinimum = 0;
  916. BOOLEAN IsSoftSur = FALSE;
  917. BOOLEAN IsVendorIntel = FALSE;
  918. WCHAR OutputBuffer[256];
  919. PSMBIOS_BIOS_INFORMATION_STRUCT BiosInfoHeader = NULL;
  920. ULONG i = 0;
  921. BiosInfoHeader = (PSMBIOS_BIOS_INFORMATION_STRUCT)FindSMBIOSTable( SMBIOS_BIOS_INFORMATION_TYPE );
  922. if( BiosInfoHeader ) {
  923. //
  924. // Get the firmware version string.
  925. //
  926. if( (ULONG)BiosInfoHeader->Version > 0 ) {
  927. // Jump to the end of the formatted portion of the SMBIOS table.
  928. FirmwareString = (PUCHAR)BiosInfoHeader + BiosInfoHeader->Length;
  929. //
  930. // Now jump over some number of strings to get to our string.
  931. //
  932. // This is a bit scary because we're trusting what SMBIOS
  933. // has handed us. If he gave us something bogus, then
  934. // we're about run off the end of the world looking for NULL
  935. // string terminators.
  936. //
  937. for( i = 0; i < ((ULONG)BiosInfoHeader->Version-1); i++ ) {
  938. while( *FirmwareString != 0 ) {
  939. FirmwareString++;
  940. }
  941. FirmwareString++;
  942. }
  943. //
  944. // Determine platform and firmware version.
  945. //
  946. // FirmwareString should look something like:
  947. // W460GXBS2.86E.0103B.P05.200103281759
  948. // -------- ----
  949. // | |
  950. // | ------- Firmware version
  951. // |
  952. // -------------------- Platform identifier. "W460GXBS" means softsur.
  953. // Anything else means Lion.
  954. //
  955. //
  956. if( FirmwareString ) {
  957. IsSoftSur = (BOOLEAN)(!strncmp( (PCHAR)FirmwareString, "W460GXBS", 8 ));
  958. // Get the minimum firmware that's okay, based on the platform.
  959. FirmwareMinimum = (IsSoftSur) ? FIRMWARE_MINIMUM_SOFTSUR : FIRMWARE_MINIMUM_LION;
  960. // Get the version.
  961. TmpPtr = (PUCHAR)strchr( (PCHAR)FirmwareString, '.' );
  962. if( TmpPtr ) {
  963. TmpPtr++;
  964. TmpPtr = (PUCHAR)strchr( (PCHAR)TmpPtr, '.' );
  965. if( TmpPtr ) {
  966. TmpPtr++;
  967. FirmwareVersion = strtoul( (PCHAR)TmpPtr, NULL, 10 );
  968. #if DBG
  969. swprintf( OutputBuffer,
  970. L"EfiCheckFirmwareRevision: Successfully retrieved the Firmware String: %S\r\n",
  971. FirmwareString );
  972. EfiPrint(OutputBuffer );
  973. swprintf( OutputBuffer,
  974. L"EfiCheckFirmwareRevision: Detected platform: %S\r\n",
  975. IsSoftSur ? "Softsur" : "Lion" );
  976. EfiPrint(OutputBuffer );
  977. swprintf( OutputBuffer,
  978. L"EfiCheckFirmwareRevision: FirmwareVersion: %d\r\n",
  979. FirmwareVersion );
  980. EfiPrint(OutputBuffer );
  981. swprintf( OutputBuffer,
  982. L"EfiCheckFirmwareRevision: Minimum FirmwareVersion requirement: %d\r\n",
  983. FirmwareMinimum );
  984. EfiPrint(OutputBuffer );
  985. #endif
  986. }
  987. }
  988. }
  989. }
  990. //
  991. // Get the BIOS vendor and see if it's Intel.
  992. //
  993. if( (ULONG)BiosInfoHeader->Vendor > 0 ) {
  994. // Jump to the end of the formatted portion of the SMBIOS table.
  995. VendorString = (PUCHAR)BiosInfoHeader + BiosInfoHeader->Length;
  996. //
  997. // Now jump over some number of strings to get to our string.
  998. //
  999. for( i = 0; i < ((ULONG)BiosInfoHeader->Vendor-1); i++ ) {
  1000. while( *VendorString != 0 ) {
  1001. VendorString++;
  1002. }
  1003. VendorString++;
  1004. }
  1005. //
  1006. // Remember firmware vendor.
  1007. //
  1008. if( VendorString ) {
  1009. IsVendorIntel = (BOOLEAN)(!_strnicmp( (PCHAR)VendorString, "INTEL", 5 ));
  1010. #if DBG
  1011. swprintf( OutputBuffer,
  1012. L"EfiCheckFirmwareRevision: Firmware Vendor String: %S\r\n",
  1013. VendorString );
  1014. EfiPrint(OutputBuffer );
  1015. #endif
  1016. }
  1017. }
  1018. }
  1019. if( (FirmwareVersion) &&
  1020. (IsVendorIntel) ) {
  1021. if( FirmwareVersion < FirmwareMinimum ) {
  1022. swprintf(OutputBuffer, L"Your system's firmware version is less than %d.\n\r", FirmwareMinimum);
  1023. EfiPrint(OutputBuffer);
  1024. swprintf(OutputBuffer, L"You must upgrade your system firmware in order to proceed.\n\r" );
  1025. EfiPrint(OutputBuffer);
  1026. while( 1 );
  1027. }
  1028. }
  1029. }
  1030. ARC_STATUS
  1031. BlLoadEFIImage(
  1032. IN PCCHAR PartitionArcName,
  1033. IN PCCHAR ImagePath,
  1034. IN PCCHAR ImageName OPTIONAL,
  1035. IN BOOLEAN StartImage,
  1036. OUT EFI_HANDLE* EfiHandle OPTIONAL
  1037. )
  1038. /*++
  1039. Routine Description:
  1040. Loads an EFI image by calling LoadImage boot service and optionally starts the image.
  1041. Arguments:
  1042. PartitionArcName - The arc name of the partition the files is located on
  1043. ImagePath - The path to the file to load (from the root directory) on the partition specified by PartitionArcName.
  1044. This can be the full file path or a partial path (e.g. only the directory).
  1045. ImageName - Optional. The file name of the image to load. If not NULL, it is simply appended to ImagePath to form the complete
  1046. path to the file. If NULL or empty string, ImagePath must contain the complete path.
  1047. Note that the complete path must not exceed 128 characters, including the zero terminator.
  1048. StartImage - If TRUE, the image is also started by calling StartImage boot service.
  1049. EfiHandle - Optional. Pointer to a location to receive the loaded image EFI handle.
  1050. Return value:
  1051. ESUCCESS on success or the error code on failure.
  1052. --*/
  1053. {
  1054. ARC_STATUS Status = ESUCCESS;
  1055. CHAR Buffer[128];
  1056. ULONG PartitionId = BL_INVALID_FILE_ID;
  1057. ULONG FileId = BL_INVALID_FILE_ID;
  1058. ULONG PageBase = 0;
  1059. EFI_HANDLE _EfiHandle = 0;
  1060. EFI_STATUS EfiStatus;
  1061. PVOID ImageBase;
  1062. ULONG PathSize;
  1063. ULONG NameSize;
  1064. ULONG PageCount;
  1065. ULONG BytesRead;
  1066. PCHAR CompletePath;
  1067. FILE_INFORMATION FileInfo;
  1068. EFI_DEVICE_PATH DevPath;
  1069. EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
  1070. EFI_LOADED_IMAGE *LoadedEfiImageInfo = NULL;
  1071. if(NULL == PartitionArcName || NULL == ImagePath) {
  1072. Status = EINVAL;
  1073. goto exit;
  1074. }
  1075. if(NULL == ImageName || 0 == ImageName[0]) {
  1076. CompletePath = ImagePath;
  1077. } else {
  1078. PathSize = (ULONG)strlen(ImagePath);
  1079. NameSize = (ULONG)strlen(ImageName);
  1080. if(PathSize + NameSize >= sizeof(Buffer) / sizeof(Buffer[0])) {
  1081. Status = ENAMETOOLONG;
  1082. goto exit;
  1083. }
  1084. RtlCopyMemory(Buffer, ImagePath, PathSize * sizeof(ImagePath[0]));
  1085. RtlCopyMemory(Buffer + PathSize, ImageName, (NameSize + 1) * sizeof(ImagePath[0]));
  1086. CompletePath = Buffer;
  1087. }
  1088. Status = ArcOpen(PartitionArcName, ArcOpenReadOnly, &PartitionId);
  1089. if(Status != ESUCCESS) {
  1090. goto exit;
  1091. }
  1092. Status = BlOpen(PartitionId, CompletePath, ArcOpenReadOnly, &FileId);
  1093. if(Status != ESUCCESS) {
  1094. goto exit;
  1095. }
  1096. Status = BlGetFileInformation(FileId, &FileInfo);
  1097. if(Status != ESUCCESS) {
  1098. goto exit;
  1099. }
  1100. if(FileInfo.EndingAddress.HighPart != 0 || 0 == FileInfo.EndingAddress.LowPart) {
  1101. Status = EINVAL;
  1102. goto exit;
  1103. }
  1104. PageCount = (FileInfo.EndingAddress.LowPart + PAGE_SIZE - 1) / PAGE_SIZE;
  1105. Status = BlAllocateDescriptor(LoaderFirmwareTemporary, 0, PageCount, &PageBase);
  1106. if(Status != ESUCCESS) {
  1107. goto exit;
  1108. }
  1109. ImageBase = (PVOID) ((ULONG_PTR) PageBase * PAGE_SIZE);
  1110. Status = BlRead(FileId, ImageBase, FileInfo.EndingAddress.LowPart, &BytesRead);
  1111. if(Status != ESUCCESS) {
  1112. goto exit;
  1113. }
  1114. if(BytesRead != FileInfo.EndingAddress.LowPart) {
  1115. Status = EIO;
  1116. goto exit;
  1117. }
  1118. //
  1119. // LoadImage does not like a NULL device path so create an empty one
  1120. //
  1121. DevPath.Type = END_DEVICE_PATH_TYPE;
  1122. DevPath.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
  1123. DevPath.Length[0] = sizeof(DevPath);
  1124. DevPath.Length[1] = 0;
  1125. FlipToPhysical();
  1126. EfiStatus = EfiST->BootServices->LoadImage(FALSE, EfiImageHandle, &DevPath, ImageBase, FileInfo.EndingAddress.LowPart, &_EfiHandle);
  1127. if(!EFI_ERROR(EfiStatus)) {
  1128. if(StartImage) {
  1129. EfiStatus = EfiST->BootServices->StartImage(_EfiHandle, NULL, NULL);
  1130. if(EFI_ALREADY_STARTED == EfiStatus) {
  1131. //
  1132. // The image is already started so don't unload
  1133. //
  1134. EfiStatus = EFI_SUCCESS;
  1135. }
  1136. if(EFI_ERROR(EfiStatus)) {
  1137. EfiST->BootServices->UnloadImage(_EfiHandle);
  1138. }
  1139. }
  1140. }
  1141. // EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, image is loaded.\r\n");
  1142. //
  1143. // if the image is loaded then we need to make sure the OS knows about it.
  1144. //
  1145. if (!EFI_ERROR(EfiStatus)) {
  1146. //EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, Getting Loaded image protocol.\r\n");
  1147. EfiStatus = EfiST->BootServices->HandleProtocol(
  1148. _EfiHandle,
  1149. &EfiLoadedImageProtocol,
  1150. &LoadedEfiImageInfo );
  1151. //EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, got Loaded image protocol.\r\n");
  1152. }
  1153. FlipToVirtual();
  1154. #if 0
  1155. if (LoadedEfiImageInfo) {
  1156. MEMORY_ALLOCATION_DESCRIPTOR *Descriptor;
  1157. ULONG NewBasePage, NewPageCount;
  1158. NewBasePage = (ULONG)((ULONG_PTR)LoadedEfiImageInfo->ImageBase) >> PAGE_SHIFT;
  1159. NewPageCount = (ULONG) BYTES_TO_PAGES(LoadedEfiImageInfo->ImageSize);
  1160. //
  1161. // locate the descriptor containing the data.
  1162. //
  1163. Descriptor = BlFindMemoryDescriptor( NewBasePage );
  1164. if (!Descriptor) {
  1165. // EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, no descriptor.\r\n");
  1166. //
  1167. // no descriptor describes this range. So create a new one and
  1168. // insert it.
  1169. //
  1170. Descriptor = (PMEMORY_ALLOCATION_DESCRIPTOR)BlAllocateHeap(
  1171. sizeof(MEMORY_ALLOCATION_DESCRIPTOR));
  1172. if (Descriptor == NULL) {
  1173. EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, allocate MEMORY_ALLOCATION_DESCRIPTOR failed.\r\n");
  1174. Status = ENOMEM;
  1175. goto exit;
  1176. }
  1177. Descriptor->MemoryType = MemoryFirmwarePermanent;
  1178. Descriptor->BasePage = NewBasePage;
  1179. Descriptor->PageCount = NewPageCount;
  1180. BlInsertDescriptor(Descriptor);
  1181. //EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, finished inserting descriptor.\r\n");
  1182. } else {
  1183. //EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, calling BlGenerateDescriptor .\r\n");
  1184. Status = BlGenerateDescriptor(
  1185. Descriptor,
  1186. MemoryFirmwarePermanent,
  1187. NewBasePage,
  1188. NewPageCount);
  1189. //EfiST->ConOut->OutputString(EfiST->ConOut, L"In BlLoadEFIImage, back from BlGenerateDescriptor .\r\n");
  1190. }
  1191. }
  1192. #endif
  1193. if(EFI_ERROR(EfiStatus)) {
  1194. Status = EFAULT;
  1195. _EfiHandle = NULL;
  1196. }
  1197. exit:
  1198. if(EfiHandle != NULL) {
  1199. *EfiHandle = _EfiHandle;
  1200. }
  1201. if(PageBase != 0) {
  1202. BlFreeDescriptor(PageBase);
  1203. }
  1204. if(FileId != -1) {
  1205. BlClose(FileId);
  1206. }
  1207. if(PartitionId != -1) {
  1208. ArcClose(PartitionId);
  1209. }
  1210. return Status;
  1211. }
  1212. EFI_STATUS
  1213. EfiAllocateAndZeroMemory(
  1214. EFI_MEMORY_TYPE MemoryType,
  1215. UINTN Size,
  1216. PVOID *ReturnPtr
  1217. )
  1218. /*++
  1219. Routine Description:
  1220. Returns a memory pointer which points to a newly allocated block
  1221. of memory. If the memory allocation succeeds, the block is
  1222. zero'd out.
  1223. Arguments:
  1224. MemoryType Specified EFI memory type to be tagged
  1225. Size Size (in bytes) of the requested memory block.
  1226. ReturnPtr Recieves the pointer allocated memory.
  1227. Returns:
  1228. EFI_STATUS determining if the allocation was successful.
  1229. --*/
  1230. {
  1231. EFI_STATUS Status = EFI_SUCCESS;
  1232. BOOLEAN FlipBackToVirtual = FALSE;
  1233. //
  1234. // Check parameters and initialize.
  1235. //
  1236. if( !ReturnPtr ) {
  1237. return EFI_INVALID_PARAMETER;
  1238. }
  1239. *ReturnPtr = NULL;
  1240. if( (Size == 0) || (MemoryType >= EfiMaxMemoryType) ) {
  1241. return EFI_INVALID_PARAMETER;
  1242. }
  1243. // If we aren't already in physical mode, get there now.
  1244. if (IsPsrDtOn()) {
  1245. FlipToPhysical();
  1246. FlipBackToVirtual = TRUE;
  1247. }
  1248. // try to allocate the requested block.
  1249. Status = EfiST->BootServices->AllocatePool( MemoryType,
  1250. Size,
  1251. ReturnPtr );
  1252. if( FlipBackToVirtual ) {
  1253. FlipToVirtual();
  1254. }
  1255. //
  1256. // If everything went okay, zero the block before returning.
  1257. //
  1258. if( (Status == EFI_SUCCESS) &&
  1259. (*ReturnPtr != NULL) ) {
  1260. RtlZeroMemory( *ReturnPtr, Size );
  1261. ASSERT (((UINTN)(*ReturnPtr)) % MIN_ALIGNMENT_SIZE == 0);
  1262. }
  1263. return Status;
  1264. }