FrontPage.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  1. /** @file
  2. FrontPage routines to handle the callbacks and browser calls
  3. Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
  4. (C) Copyright 2018 Hewlett Packard Enterprise Development LP<BR>
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #include "FrontPage.h"
  8. #include "FrontPageCustomizedUi.h"
  9. #define MAX_STRING_LEN 200
  10. EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID;
  11. BOOLEAN mResetRequired = FALSE;
  12. EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2;
  13. CHAR8 *mLanguageString;
  14. BOOLEAN mModeInitialized = FALSE;
  15. //
  16. // Boot video resolution and text mode.
  17. //
  18. UINT32 mBootHorizontalResolution = 0;
  19. UINT32 mBootVerticalResolution = 0;
  20. UINT32 mBootTextModeColumn = 0;
  21. UINT32 mBootTextModeRow = 0;
  22. //
  23. // BIOS setup video resolution and text mode.
  24. //
  25. UINT32 mSetupTextModeColumn = 0;
  26. UINT32 mSetupTextModeRow = 0;
  27. UINT32 mSetupHorizontalResolution = 0;
  28. UINT32 mSetupVerticalResolution = 0;
  29. FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = {
  30. FRONT_PAGE_CALLBACK_DATA_SIGNATURE,
  31. NULL,
  32. NULL,
  33. NULL,
  34. {
  35. FakeExtractConfig,
  36. FakeRouteConfig,
  37. FrontPageCallback
  38. }
  39. };
  40. HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = {
  41. {
  42. {
  43. HARDWARE_DEVICE_PATH,
  44. HW_VENDOR_DP,
  45. {
  46. (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
  47. (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
  48. }
  49. },
  50. //
  51. // {8E6D99EE-7531-48f8-8745-7F6144468FF2}
  52. //
  53. { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } }
  54. },
  55. {
  56. END_DEVICE_PATH_TYPE,
  57. END_ENTIRE_DEVICE_PATH_SUBTYPE,
  58. {
  59. (UINT8) (END_DEVICE_PATH_LENGTH),
  60. (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
  61. }
  62. }
  63. };
  64. /**
  65. Update the banner information for the Front Page based on Smbios information.
  66. **/
  67. VOID
  68. UpdateFrontPageBannerStrings (
  69. VOID
  70. );
  71. /**
  72. This function allows a caller to extract the current configuration for one
  73. or more named elements from the target driver.
  74. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  75. @param Request A null-terminated Unicode string in <ConfigRequest> format.
  76. @param Progress On return, points to a character in the Request string.
  77. Points to the string's null terminator if request was successful.
  78. Points to the most recent '&' before the first failing name/value
  79. pair (or the beginning of the string if the failure is in the
  80. first name/value pair) if the request was not successful.
  81. @param Results A null-terminated Unicode string in <ConfigAltResp> format which
  82. has all values filled in for the names in the Request string.
  83. String to be allocated by the called function.
  84. @retval EFI_SUCCESS The Results is filled with the requested values.
  85. @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
  86. @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
  87. @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
  88. **/
  89. EFI_STATUS
  90. EFIAPI
  91. FakeExtractConfig (
  92. IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
  93. IN CONST EFI_STRING Request,
  94. OUT EFI_STRING *Progress,
  95. OUT EFI_STRING *Results
  96. )
  97. {
  98. if (Progress == NULL || Results == NULL) {
  99. return EFI_INVALID_PARAMETER;
  100. }
  101. *Progress = Request;
  102. return EFI_NOT_FOUND;
  103. }
  104. /**
  105. This function processes the results of changes in configuration.
  106. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  107. @param Configuration A null-terminated Unicode string in <ConfigResp> format.
  108. @param Progress A pointer to a string filled in with the offset of the most
  109. recent '&' before the first failing name/value pair (or the
  110. beginning of the string if the failure is in the first
  111. name/value pair) or the terminating NULL if all was successful.
  112. @retval EFI_SUCCESS The Results is processed successfully.
  113. @retval EFI_INVALID_PARAMETER Configuration is NULL.
  114. @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
  115. **/
  116. EFI_STATUS
  117. EFIAPI
  118. FakeRouteConfig (
  119. IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
  120. IN CONST EFI_STRING Configuration,
  121. OUT EFI_STRING *Progress
  122. )
  123. {
  124. if (Configuration == NULL || Progress == NULL) {
  125. return EFI_INVALID_PARAMETER;
  126. }
  127. *Progress = Configuration;
  128. return EFI_NOT_FOUND;
  129. }
  130. /**
  131. This function processes the results of changes in configuration.
  132. @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  133. @param Action Specifies the type of action taken by the browser.
  134. @param QuestionId A unique value which is sent to the original exporting driver
  135. so that it can identify the type of data to expect.
  136. @param Type The type of value for the question.
  137. @param Value A pointer to the data being sent to the original exporting driver.
  138. @param ActionRequest On return, points to the action requested by the callback function.
  139. @retval EFI_SUCCESS The callback successfully handled the action.
  140. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
  141. @retval EFI_DEVICE_ERROR The variable could not be saved.
  142. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
  143. **/
  144. EFI_STATUS
  145. EFIAPI
  146. FrontPageCallback (
  147. IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
  148. IN EFI_BROWSER_ACTION Action,
  149. IN EFI_QUESTION_ID QuestionId,
  150. IN UINT8 Type,
  151. IN EFI_IFR_TYPE_VALUE *Value,
  152. OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
  153. )
  154. {
  155. return UiFrontPageCallbackHandler (gFrontPagePrivate.HiiHandle, Action, QuestionId, Type, Value, ActionRequest);
  156. }
  157. /**
  158. Update the menus in the front page.
  159. **/
  160. VOID
  161. UpdateFrontPageForm (
  162. VOID
  163. )
  164. {
  165. VOID *StartOpCodeHandle;
  166. VOID *EndOpCodeHandle;
  167. EFI_IFR_GUID_LABEL *StartGuidLabel;
  168. EFI_IFR_GUID_LABEL *EndGuidLabel;
  169. //
  170. // Allocate space for creation of UpdateData Buffer
  171. //
  172. StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  173. ASSERT (StartOpCodeHandle != NULL);
  174. EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  175. ASSERT (EndOpCodeHandle != NULL);
  176. //
  177. // Create Hii Extend Label OpCode as the start opcode
  178. //
  179. StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  180. StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  181. StartGuidLabel->Number = LABEL_FRANTPAGE_INFORMATION;
  182. //
  183. // Create Hii Extend Label OpCode as the end opcode
  184. //
  185. EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  186. EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  187. EndGuidLabel->Number = LABEL_END;
  188. //
  189. //Updata Front Page form
  190. //
  191. UiCustomizeFrontPage (
  192. gFrontPagePrivate.HiiHandle,
  193. StartOpCodeHandle
  194. );
  195. HiiUpdateForm (
  196. gFrontPagePrivate.HiiHandle,
  197. &mFrontPageGuid,
  198. FRONT_PAGE_FORM_ID,
  199. StartOpCodeHandle,
  200. EndOpCodeHandle
  201. );
  202. HiiFreeOpCodeHandle (StartOpCodeHandle);
  203. HiiFreeOpCodeHandle (EndOpCodeHandle);
  204. }
  205. /**
  206. Initialize HII information for the FrontPage
  207. @retval EFI_SUCCESS The operation is successful.
  208. @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
  209. **/
  210. EFI_STATUS
  211. InitializeFrontPage (
  212. VOID
  213. )
  214. {
  215. EFI_STATUS Status;
  216. //
  217. // Locate Hii relative protocols
  218. //
  219. Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);
  220. if (EFI_ERROR (Status)) {
  221. return Status;
  222. }
  223. //
  224. // Install Device Path Protocol and Config Access protocol to driver handle
  225. //
  226. gFrontPagePrivate.DriverHandle = NULL;
  227. Status = gBS->InstallMultipleProtocolInterfaces (
  228. &gFrontPagePrivate.DriverHandle,
  229. &gEfiDevicePathProtocolGuid,
  230. &mFrontPageHiiVendorDevicePath,
  231. &gEfiHiiConfigAccessProtocolGuid,
  232. &gFrontPagePrivate.ConfigAccess,
  233. NULL
  234. );
  235. ASSERT_EFI_ERROR (Status);
  236. //
  237. // Publish our HII data
  238. //
  239. gFrontPagePrivate.HiiHandle = HiiAddPackages (
  240. &mFrontPageGuid,
  241. gFrontPagePrivate.DriverHandle,
  242. FrontPageVfrBin,
  243. UiAppStrings,
  244. NULL
  245. );
  246. ASSERT (gFrontPagePrivate.HiiHandle != NULL);
  247. //
  248. //Updata Front Page banner strings
  249. //
  250. UpdateFrontPageBannerStrings ();
  251. //
  252. // Update front page menus.
  253. //
  254. UpdateFrontPageForm();
  255. return Status;
  256. }
  257. /**
  258. Call the browser and display the front page
  259. @return Status code that will be returned by
  260. EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
  261. **/
  262. EFI_STATUS
  263. CallFrontPage (
  264. VOID
  265. )
  266. {
  267. EFI_STATUS Status;
  268. EFI_BROWSER_ACTION_REQUEST ActionRequest;
  269. //
  270. // Begin waiting for USER INPUT
  271. //
  272. REPORT_STATUS_CODE (
  273. EFI_PROGRESS_CODE,
  274. (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)
  275. );
  276. ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
  277. Status = gFormBrowser2->SendForm (
  278. gFormBrowser2,
  279. &gFrontPagePrivate.HiiHandle,
  280. 1,
  281. &mFrontPageGuid,
  282. 0,
  283. NULL,
  284. &ActionRequest
  285. );
  286. //
  287. // Check whether user change any option setting which needs a reset to be effective
  288. //
  289. if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
  290. EnableResetRequired ();
  291. }
  292. return Status;
  293. }
  294. /**
  295. Remove the installed packages from the HiiDatabase.
  296. **/
  297. VOID
  298. FreeFrontPage(
  299. VOID
  300. )
  301. {
  302. EFI_STATUS Status;
  303. Status = gBS->UninstallMultipleProtocolInterfaces (
  304. gFrontPagePrivate.DriverHandle,
  305. &gEfiDevicePathProtocolGuid,
  306. &mFrontPageHiiVendorDevicePath,
  307. &gEfiHiiConfigAccessProtocolGuid,
  308. &gFrontPagePrivate.ConfigAccess,
  309. NULL
  310. );
  311. ASSERT_EFI_ERROR (Status);
  312. //
  313. // Publish our HII data
  314. //
  315. HiiRemovePackages (gFrontPagePrivate.HiiHandle);
  316. if (gFrontPagePrivate.LanguageToken != NULL) {
  317. FreePool (gFrontPagePrivate.LanguageToken);
  318. gFrontPagePrivate.LanguageToken = NULL;
  319. }
  320. }
  321. /**
  322. Convert Processor Frequency Data to a string.
  323. @param ProcessorFrequency The frequency data to process
  324. @param Base10Exponent The exponent based on 10
  325. @param String The string that is created
  326. **/
  327. VOID
  328. ConvertProcessorToString (
  329. IN UINT16 ProcessorFrequency,
  330. IN UINT16 Base10Exponent,
  331. OUT CHAR16 **String
  332. )
  333. {
  334. CHAR16 *StringBuffer;
  335. UINTN Index;
  336. UINTN DestMax;
  337. UINT32 FreqMhz;
  338. if (Base10Exponent >= 6) {
  339. FreqMhz = ProcessorFrequency;
  340. for (Index = 0; Index < (UINT32) Base10Exponent - 6; Index++) {
  341. FreqMhz *= 10;
  342. }
  343. } else {
  344. FreqMhz = 0;
  345. }
  346. DestMax = 0x20 / sizeof (CHAR16);
  347. StringBuffer = AllocateZeroPool (0x20);
  348. ASSERT (StringBuffer != NULL);
  349. UnicodeValueToStringS (StringBuffer, sizeof (CHAR16) * DestMax, LEFT_JUSTIFY, FreqMhz / 1000, 3);
  350. Index = StrnLenS (StringBuffer, DestMax);
  351. StrCatS (StringBuffer, DestMax, L".");
  352. UnicodeValueToStringS (
  353. StringBuffer + Index + 1,
  354. sizeof (CHAR16) * (DestMax - (Index + 1)),
  355. PREFIX_ZERO,
  356. (FreqMhz % 1000) / 10,
  357. 2
  358. );
  359. StrCatS (StringBuffer, DestMax, L" GHz");
  360. *String = (CHAR16 *) StringBuffer;
  361. return ;
  362. }
  363. /**
  364. Convert Memory Size to a string.
  365. @param MemorySize The size of the memory to process
  366. @param String The string that is created
  367. **/
  368. VOID
  369. ConvertMemorySizeToString (
  370. IN UINT32 MemorySize,
  371. OUT CHAR16 **String
  372. )
  373. {
  374. CHAR16 *StringBuffer;
  375. StringBuffer = AllocateZeroPool (0x24);
  376. ASSERT (StringBuffer != NULL);
  377. UnicodeValueToStringS (StringBuffer, 0x24, LEFT_JUSTIFY, MemorySize, 10);
  378. StrCatS (StringBuffer, 0x24 / sizeof (CHAR16), L" MB RAM");
  379. *String = (CHAR16 *) StringBuffer;
  380. return ;
  381. }
  382. /**
  383. Acquire the string associated with the Index from smbios structure and return it.
  384. The caller is responsible for free the string buffer.
  385. @param OptionalStrStart The start position to search the string
  386. @param Index The index of the string to extract
  387. @param String The string that is extracted
  388. @retval EFI_SUCCESS The function returns EFI_SUCCESS always.
  389. **/
  390. EFI_STATUS
  391. GetOptionalStringByIndex (
  392. IN CHAR8 *OptionalStrStart,
  393. IN UINT8 Index,
  394. OUT CHAR16 **String
  395. )
  396. {
  397. UINTN StrSize;
  398. if (Index == 0) {
  399. *String = AllocateZeroPool (sizeof (CHAR16));
  400. return EFI_SUCCESS;
  401. }
  402. StrSize = 0;
  403. do {
  404. Index--;
  405. OptionalStrStart += StrSize;
  406. StrSize = AsciiStrSize (OptionalStrStart);
  407. } while (OptionalStrStart[StrSize] != 0 && Index != 0);
  408. if ((Index != 0) || (StrSize == 1)) {
  409. //
  410. // Meet the end of strings set but Index is non-zero, or
  411. // Find an empty string
  412. //
  413. *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
  414. } else {
  415. *String = AllocatePool (StrSize * sizeof (CHAR16));
  416. AsciiStrToUnicodeStrS (OptionalStrStart, *String, StrSize);
  417. }
  418. return EFI_SUCCESS;
  419. }
  420. /**
  421. Update the banner information for the Front Page based on Smbios information.
  422. **/
  423. VOID
  424. UpdateFrontPageBannerStrings (
  425. VOID
  426. )
  427. {
  428. UINT8 StrIndex;
  429. CHAR16 *NewString;
  430. CHAR16 *FirmwareVersionString;
  431. EFI_STATUS Status;
  432. EFI_SMBIOS_HANDLE SmbiosHandle;
  433. EFI_SMBIOS_PROTOCOL *Smbios;
  434. SMBIOS_TABLE_TYPE0 *Type0Record;
  435. SMBIOS_TABLE_TYPE1 *Type1Record;
  436. SMBIOS_TABLE_TYPE4 *Type4Record;
  437. SMBIOS_TABLE_TYPE19 *Type19Record;
  438. EFI_SMBIOS_TABLE_HEADER *Record;
  439. UINT64 InstalledMemory;
  440. BOOLEAN FoundCpu;
  441. InstalledMemory = 0;
  442. FoundCpu = 0;
  443. //
  444. // Update default banner string.
  445. //
  446. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NULL);
  447. UiCustomizeFrontPageBanner (4, TRUE, &NewString);
  448. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NewString, NULL);
  449. FreePool (NewString);
  450. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NULL);
  451. UiCustomizeFrontPageBanner (4, FALSE, &NewString);
  452. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_RIGHT), NewString, NULL);
  453. FreePool (NewString);
  454. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NULL);
  455. UiCustomizeFrontPageBanner (5, TRUE, &NewString);
  456. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_LEFT), NewString, NULL);
  457. FreePool (NewString);
  458. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NULL);
  459. UiCustomizeFrontPageBanner (5, FALSE, &NewString);
  460. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE5_RIGHT), NewString, NULL);
  461. FreePool (NewString);
  462. //
  463. // Update Front Page banner strings base on SmBios Table.
  464. //
  465. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **) &Smbios);
  466. if (EFI_ERROR (Status)) {
  467. //
  468. // Smbios protocol not found, get the default value.
  469. //
  470. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NULL);
  471. UiCustomizeFrontPageBanner (1, TRUE, &NewString);
  472. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL);
  473. FreePool (NewString);
  474. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NULL);
  475. UiCustomizeFrontPageBanner (2, TRUE, &NewString);
  476. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL);
  477. FreePool (NewString);
  478. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NULL);
  479. UiCustomizeFrontPageBanner (2, FALSE, &NewString);
  480. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
  481. FreePool (NewString);
  482. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NULL);
  483. UiCustomizeFrontPageBanner (3, TRUE, &NewString);
  484. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
  485. FreePool (NewString);
  486. NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NULL);
  487. UiCustomizeFrontPageBanner (3, FALSE, &NewString);
  488. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL);
  489. FreePool (NewString);
  490. return;
  491. }
  492. SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  493. Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  494. while (!EFI_ERROR(Status)) {
  495. if (Record->Type == SMBIOS_TYPE_BIOS_INFORMATION) {
  496. Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;
  497. StrIndex = Type0Record->BiosVersion;
  498. GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);
  499. FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
  500. if (*FirmwareVersionString != 0x0000 ) {
  501. FreePool (NewString);
  502. NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
  503. UiCustomizeFrontPageBanner (3, TRUE, &NewString);
  504. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
  505. } else {
  506. UiCustomizeFrontPageBanner (3, TRUE, &NewString);
  507. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION), NewString, NULL);
  508. FreePool (NewString);
  509. }
  510. }
  511. if (Record->Type == SMBIOS_TYPE_SYSTEM_INFORMATION) {
  512. Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;
  513. StrIndex = Type1Record->ProductName;
  514. GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);
  515. UiCustomizeFrontPageBanner (1, TRUE, &NewString);
  516. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL), NewString, NULL);
  517. FreePool (NewString);
  518. }
  519. if ((Record->Type == SMBIOS_TYPE_PROCESSOR_INFORMATION) && !FoundCpu) {
  520. Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;
  521. //
  522. // The information in the record should be only valid when the CPU Socket is populated.
  523. //
  524. if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {
  525. StrIndex = Type4Record->ProcessorVersion;
  526. GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);
  527. UiCustomizeFrontPageBanner (2, TRUE, &NewString);
  528. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL), NewString, NULL);
  529. FreePool (NewString);
  530. ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);
  531. UiCustomizeFrontPageBanner (2, FALSE, &NewString);
  532. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED), NewString, NULL);
  533. FreePool (NewString);
  534. FoundCpu = TRUE;
  535. }
  536. }
  537. if ( Record->Type == SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {
  538. Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;
  539. if (Type19Record->StartingAddress != 0xFFFFFFFF ) {
  540. InstalledMemory += RShiftU64(Type19Record->EndingAddress -
  541. Type19Record->StartingAddress + 1, 10);
  542. } else {
  543. InstalledMemory += RShiftU64(Type19Record->ExtendedEndingAddress -
  544. Type19Record->ExtendedStartingAddress + 1, 20);
  545. }
  546. }
  547. Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
  548. }
  549. //
  550. // Now update the total installed RAM size
  551. //
  552. ConvertMemorySizeToString ((UINT32)InstalledMemory, &NewString );
  553. UiCustomizeFrontPageBanner (3, FALSE, &NewString);
  554. HiiSetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE), NewString, NULL);
  555. FreePool (NewString);
  556. }
  557. /**
  558. This function will change video resolution and text mode
  559. according to defined setup mode or defined boot mode
  560. @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
  561. @retval EFI_SUCCESS Mode is changed successfully.
  562. @retval Others Mode failed to be changed.
  563. **/
  564. EFI_STATUS
  565. UiSetConsoleMode (
  566. BOOLEAN IsSetupMode
  567. )
  568. {
  569. EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
  570. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
  571. UINTN SizeOfInfo;
  572. EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
  573. UINT32 MaxGopMode;
  574. UINT32 MaxTextMode;
  575. UINT32 ModeNumber;
  576. UINT32 NewHorizontalResolution;
  577. UINT32 NewVerticalResolution;
  578. UINT32 NewColumns;
  579. UINT32 NewRows;
  580. UINTN HandleCount;
  581. EFI_HANDLE *HandleBuffer;
  582. EFI_STATUS Status;
  583. UINTN Index;
  584. UINTN CurrentColumn;
  585. UINTN CurrentRow;
  586. MaxGopMode = 0;
  587. MaxTextMode = 0;
  588. //
  589. // Get current video resolution and text mode
  590. //
  591. Status = gBS->HandleProtocol (
  592. gST->ConsoleOutHandle,
  593. &gEfiGraphicsOutputProtocolGuid,
  594. (VOID**)&GraphicsOutput
  595. );
  596. if (EFI_ERROR (Status)) {
  597. GraphicsOutput = NULL;
  598. }
  599. Status = gBS->HandleProtocol (
  600. gST->ConsoleOutHandle,
  601. &gEfiSimpleTextOutProtocolGuid,
  602. (VOID**)&SimpleTextOut
  603. );
  604. if (EFI_ERROR (Status)) {
  605. SimpleTextOut = NULL;
  606. }
  607. if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
  608. return EFI_UNSUPPORTED;
  609. }
  610. if (IsSetupMode) {
  611. //
  612. // The required resolution and text mode is setup mode.
  613. //
  614. NewHorizontalResolution = mSetupHorizontalResolution;
  615. NewVerticalResolution = mSetupVerticalResolution;
  616. NewColumns = mSetupTextModeColumn;
  617. NewRows = mSetupTextModeRow;
  618. } else {
  619. //
  620. // The required resolution and text mode is boot mode.
  621. //
  622. NewHorizontalResolution = mBootHorizontalResolution;
  623. NewVerticalResolution = mBootVerticalResolution;
  624. NewColumns = mBootTextModeColumn;
  625. NewRows = mBootTextModeRow;
  626. }
  627. if (GraphicsOutput != NULL) {
  628. MaxGopMode = GraphicsOutput->Mode->MaxMode;
  629. }
  630. if (SimpleTextOut != NULL) {
  631. MaxTextMode = SimpleTextOut->Mode->MaxMode;
  632. }
  633. //
  634. // 1. If current video resolution is same with required video resolution,
  635. // video resolution need not be changed.
  636. // 1.1. If current text mode is same with required text mode, text mode need not be changed.
  637. // 1.2. If current text mode is different from required text mode, text mode need be changed.
  638. // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
  639. //
  640. for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
  641. Status = GraphicsOutput->QueryMode (
  642. GraphicsOutput,
  643. ModeNumber,
  644. &SizeOfInfo,
  645. &Info
  646. );
  647. if (!EFI_ERROR (Status)) {
  648. if ((Info->HorizontalResolution == NewHorizontalResolution) &&
  649. (Info->VerticalResolution == NewVerticalResolution)) {
  650. if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
  651. (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {
  652. //
  653. // Current resolution is same with required resolution, check if text mode need be set
  654. //
  655. Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
  656. ASSERT_EFI_ERROR (Status);
  657. if (CurrentColumn == NewColumns && CurrentRow == NewRows) {
  658. //
  659. // If current text mode is same with required text mode. Do nothing
  660. //
  661. FreePool (Info);
  662. return EFI_SUCCESS;
  663. } else {
  664. //
  665. // If current text mode is different from required text mode. Set new video mode
  666. //
  667. for (Index = 0; Index < MaxTextMode; Index++) {
  668. Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
  669. if (!EFI_ERROR(Status)) {
  670. if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
  671. //
  672. // Required text mode is supported, set it.
  673. //
  674. Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
  675. ASSERT_EFI_ERROR (Status);
  676. //
  677. // Update text mode PCD.
  678. //
  679. Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn);
  680. ASSERT_EFI_ERROR (Status);
  681. Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow);
  682. ASSERT_EFI_ERROR (Status);
  683. FreePool (Info);
  684. return EFI_SUCCESS;
  685. }
  686. }
  687. }
  688. if (Index == MaxTextMode) {
  689. //
  690. // If required text mode is not supported, return error.
  691. //
  692. FreePool (Info);
  693. return EFI_UNSUPPORTED;
  694. }
  695. }
  696. } else {
  697. //
  698. // If current video resolution is not same with the new one, set new video resolution.
  699. // In this case, the driver which produces simple text out need be restarted.
  700. //
  701. Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
  702. if (!EFI_ERROR (Status)) {
  703. FreePool (Info);
  704. break;
  705. }
  706. }
  707. }
  708. FreePool (Info);
  709. }
  710. }
  711. if (ModeNumber == MaxGopMode) {
  712. //
  713. // If the resolution is not supported, return error.
  714. //
  715. return EFI_UNSUPPORTED;
  716. }
  717. //
  718. // Set PCD to Inform GraphicsConsole to change video resolution.
  719. // Set PCD to Inform Consplitter to change text mode.
  720. //
  721. Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
  722. ASSERT_EFI_ERROR (Status);
  723. Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
  724. ASSERT_EFI_ERROR (Status);
  725. Status = PcdSet32S (PcdConOutColumn, NewColumns);
  726. ASSERT_EFI_ERROR (Status);
  727. Status = PcdSet32S (PcdConOutRow, NewRows);
  728. ASSERT_EFI_ERROR (Status);
  729. //
  730. // Video mode is changed, so restart graphics console driver and higher level driver.
  731. // Reconnect graphics console driver and higher level driver.
  732. // Locate all the handles with GOP protocol and reconnect it.
  733. //
  734. Status = gBS->LocateHandleBuffer (
  735. ByProtocol,
  736. &gEfiSimpleTextOutProtocolGuid,
  737. NULL,
  738. &HandleCount,
  739. &HandleBuffer
  740. );
  741. if (!EFI_ERROR (Status)) {
  742. for (Index = 0; Index < HandleCount; Index++) {
  743. gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
  744. }
  745. for (Index = 0; Index < HandleCount; Index++) {
  746. gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
  747. }
  748. if (HandleBuffer != NULL) {
  749. FreePool (HandleBuffer);
  750. }
  751. }
  752. return EFI_SUCCESS;
  753. }
  754. /**
  755. The user Entry Point for Application. The user code starts with this function
  756. as the real entry point for the image goes into a library that calls this
  757. function.
  758. @param[in] ImageHandle The firmware allocated handle for the EFI image.
  759. @param[in] SystemTable A pointer to the EFI System Table.
  760. @retval EFI_SUCCESS The entry point is executed successfully.
  761. @retval other Some error occurs when executing this entry point.
  762. **/
  763. EFI_STATUS
  764. EFIAPI
  765. InitializeUserInterface (
  766. IN EFI_HANDLE ImageHandle,
  767. IN EFI_SYSTEM_TABLE *SystemTable
  768. )
  769. {
  770. EFI_HII_HANDLE HiiHandle;
  771. EFI_STATUS Status;
  772. EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
  773. EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
  774. UINTN BootTextColumn;
  775. UINTN BootTextRow;
  776. if (!mModeInitialized) {
  777. //
  778. // After the console is ready, get current video resolution
  779. // and text mode before launching setup at first time.
  780. //
  781. Status = gBS->HandleProtocol (
  782. gST->ConsoleOutHandle,
  783. &gEfiGraphicsOutputProtocolGuid,
  784. (VOID**)&GraphicsOutput
  785. );
  786. if (EFI_ERROR (Status)) {
  787. GraphicsOutput = NULL;
  788. }
  789. Status = gBS->HandleProtocol (
  790. gST->ConsoleOutHandle,
  791. &gEfiSimpleTextOutProtocolGuid,
  792. (VOID**)&SimpleTextOut
  793. );
  794. if (EFI_ERROR (Status)) {
  795. SimpleTextOut = NULL;
  796. }
  797. if (GraphicsOutput != NULL) {
  798. //
  799. // Get current video resolution and text mode.
  800. //
  801. mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
  802. mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
  803. }
  804. if (SimpleTextOut != NULL) {
  805. Status = SimpleTextOut->QueryMode (
  806. SimpleTextOut,
  807. SimpleTextOut->Mode->Mode,
  808. &BootTextColumn,
  809. &BootTextRow
  810. );
  811. mBootTextModeColumn = (UINT32)BootTextColumn;
  812. mBootTextModeRow = (UINT32)BootTextRow;
  813. }
  814. //
  815. // Get user defined text mode for setup.
  816. //
  817. mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
  818. mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
  819. mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
  820. mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
  821. mModeInitialized = TRUE;
  822. }
  823. gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
  824. gST->ConOut->ClearScreen (gST->ConOut);
  825. //
  826. // Install customized fonts needed by Front Page
  827. //
  828. HiiHandle = ExportFonts ();
  829. ASSERT (HiiHandle != NULL);
  830. InitializeStringSupport ();
  831. UiSetConsoleMode (TRUE);
  832. UiEntry (FALSE);
  833. UiSetConsoleMode (FALSE);
  834. UninitializeStringSupport ();
  835. HiiRemovePackages (HiiHandle);
  836. return EFI_SUCCESS;
  837. }
  838. /**
  839. This function is the main entry of the UI entry.
  840. The function will present the main menu of the system UI.
  841. @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all.
  842. **/
  843. VOID
  844. EFIAPI
  845. UiEntry (
  846. IN BOOLEAN ConnectAllHappened
  847. )
  848. {
  849. EFI_STATUS Status;
  850. EFI_BOOT_LOGO_PROTOCOL *BootLogo;
  851. //
  852. // Enter Setup page.
  853. //
  854. REPORT_STATUS_CODE (
  855. EFI_PROGRESS_CODE,
  856. (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP)
  857. );
  858. //
  859. // Indicate if the connect all has been performed before.
  860. // If has not been performed before, do here.
  861. //
  862. if (!ConnectAllHappened) {
  863. EfiBootManagerConnectAll ();
  864. }
  865. //
  866. // The boot option enumeration time is acceptable in Ui driver
  867. //
  868. EfiBootManagerRefreshAllBootOption ();
  869. //
  870. // Boot Logo is corrupted, report it using Boot Logo protocol.
  871. //
  872. Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
  873. if (!EFI_ERROR (Status) && (BootLogo != NULL)) {
  874. BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
  875. }
  876. InitializeFrontPage ();
  877. CallFrontPage ();
  878. FreeFrontPage ();
  879. if (mLanguageString != NULL) {
  880. FreePool (mLanguageString);
  881. mLanguageString = NULL;
  882. }
  883. //
  884. //Will leave browser, check any reset required change is applied? if yes, reset system
  885. //
  886. SetupResetReminder ();
  887. }
  888. //
  889. // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
  890. // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
  891. // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
  892. //
  893. /**
  894. Record the info that a reset is required.
  895. A module boolean variable is used to record whether a reset is required.
  896. **/
  897. VOID
  898. EFIAPI
  899. EnableResetRequired (
  900. VOID
  901. )
  902. {
  903. mResetRequired = TRUE;
  904. }
  905. /**
  906. Check if user changed any option setting which needs a system reset to be effective.
  907. **/
  908. BOOLEAN
  909. EFIAPI
  910. IsResetRequired (
  911. VOID
  912. )
  913. {
  914. return mResetRequired;
  915. }
  916. /**
  917. Check whether a reset is needed, and finish the reset reminder feature.
  918. If a reset is needed, Popup a menu to notice user, and finish the feature
  919. according to the user selection.
  920. **/
  921. VOID
  922. EFIAPI
  923. SetupResetReminder (
  924. VOID
  925. )
  926. {
  927. EFI_INPUT_KEY Key;
  928. CHAR16 *StringBuffer1;
  929. CHAR16 *StringBuffer2;
  930. //
  931. //check any reset required change is applied? if yes, reset system
  932. //
  933. if (IsResetRequired ()) {
  934. StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
  935. ASSERT (StringBuffer1 != NULL);
  936. StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
  937. ASSERT (StringBuffer2 != NULL);
  938. StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now.");
  939. StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset");
  940. //
  941. // Popup a menu to notice user
  942. //
  943. do {
  944. CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
  945. } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  946. FreePool (StringBuffer1);
  947. FreePool (StringBuffer2);
  948. gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
  949. }
  950. }