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.

760 lines
21 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. miscc.c
  5. Abstract:
  6. This file contains misc. functions used by NTLDR.
  7. Author:
  8. Allen Kay (akay) 03-Mar-1999
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include "bldr.h"
  14. #include "stdio.h"
  15. #include "bootia64.h"
  16. #include "efi.h"
  17. #include "extern.h"
  18. WCHAR EfiBuffer[256];
  19. void
  20. EfiPrintf(
  21. IN PWCHAR Format,
  22. ...
  23. )
  24. {
  25. va_list arglist;
  26. va_start(arglist, Format);
  27. if (_vsnwprintf( EfiBuffer, sizeof(EfiBuffer), Format, arglist) > 0) {
  28. EfiPrint(EfiBuffer);
  29. }
  30. }
  31. typedef struct _PAL_RETURN_VALUES {
  32. ULONGLONG ReturnValue0;
  33. ULONGLONG ReturnValue1;
  34. ULONGLONG ReturnValue2;
  35. ULONGLONG ReturnValue3;
  36. } PAL_RETURN_VALUES, *PPAL_RETURN_VALUES;
  37. typedef union _PAL_REVISION {
  38. struct {
  39. ULONGLONG PalBRevLower:4;
  40. ULONGLONG PalBRevUpper:4;
  41. ULONGLONG PalBModel:8;
  42. ULONGLONG Reserved0:8;
  43. ULONGLONG PalVendor:8;
  44. ULONGLONG PalARevision:8;
  45. ULONGLONG PalAModel:8;
  46. ULONGLONG Reserved1:16;
  47. };
  48. ULONGLONG PalVersion;
  49. } PAL_REVISION;
  50. extern
  51. PAL_RETURN_VALUES
  52. BlpPalProc(
  53. IN ULONGLONG FunctionIndex,
  54. IN ULONGLONG Arg1,
  55. IN ULONGLONG Arg2,
  56. IN ULONGLONG Arg3
  57. );
  58. VOID
  59. CallPal(
  60. IN ULONGLONG FunctionIndex,
  61. IN ULONGLONG Argument0,
  62. IN ULONGLONG Argument1,
  63. IN ULONGLONG Argument2,
  64. OUT PULONGLONG ReturnValue0,
  65. OUT PULONGLONG ReturnValue1,
  66. OUT PULONGLONG ReturnValue2,
  67. OUT PULONGLONG ReturnValue3
  68. )
  69. {
  70. PAL_RETURN_VALUES RetVal;
  71. RetVal = BlpPalProc(FunctionIndex, Argument0, Argument1, Argument2);
  72. *ReturnValue0 = RetVal.ReturnValue0;
  73. *ReturnValue1 = RetVal.ReturnValue1;
  74. *ReturnValue2 = RetVal.ReturnValue2;
  75. *ReturnValue3 = RetVal.ReturnValue3;
  76. }
  77. VOID
  78. ReadProcessorConfigInfo(
  79. PPROCESSOR_CONFIG_INFO ProcessorConfigInfo
  80. )
  81. {
  82. ULONGLONG Status;
  83. ULONGLONG Reserved;
  84. ULONGLONG CacheLevels;
  85. ULONGLONG UniqueCaches;
  86. ULONGLONG CacheIndex;
  87. IA64_CACHE_INFO1 CacheInfo1;
  88. IA64_CACHE_INFO2 CacheInfo2;
  89. if ((PUCHAR) ProcessorConfigInfo >= (PUCHAR) KSEG0_BASE) {
  90. ProcessorConfigInfo = (PPROCESSOR_CONFIG_INFO)((PUCHAR)ProcessorConfigInfo - KSEG0_BASE);
  91. }
  92. ProcessorConfigInfo->CpuId3 = __getReg(CV_IA64_CPUID3);
  93. CallPal (
  94. PAL_VM_PAGE_SIZE,
  95. 0,
  96. 0,
  97. 0,
  98. &Status,
  99. &ProcessorConfigInfo->InsertPageSizeInfo,
  100. &ProcessorConfigInfo->PurgePageSizeInfo,
  101. &Reserved
  102. );
  103. if (Status) {
  104. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_VM_PAGE_SIZE failed.\n\r");
  105. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  106. }
  107. CallPal (
  108. PAL_VM_SUMMARY,
  109. 0,
  110. 0,
  111. 0,
  112. &Status,
  113. &ProcessorConfigInfo->VmSummaryInfo1.Ulong64,
  114. &ProcessorConfigInfo->VmSummaryInfo2.Ulong64,
  115. &Reserved
  116. );
  117. if (Status) {
  118. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_VM_SUMMARY failed.\n\r");
  119. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  120. }
  121. CallPal (
  122. PAL_RSE_INFO,
  123. 0,
  124. 0,
  125. 0,
  126. &Status,
  127. &ProcessorConfigInfo->NumOfPhysStackedRegs,
  128. &ProcessorConfigInfo->RseHints,
  129. &Reserved
  130. );
  131. if (Status) {
  132. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_RSE_INFO failed.\n\r");
  133. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  134. }
  135. CallPal (
  136. PAL_PTCE_INFO,
  137. 0,
  138. 0,
  139. 0,
  140. &Status,
  141. &ProcessorConfigInfo->PtceInfo.PtceBase,
  142. &ProcessorConfigInfo->PtceInfo.PtceTcCount.Ulong64,
  143. &ProcessorConfigInfo->PtceInfo.PtceStrides.Ulong64
  144. );
  145. if (Status) {
  146. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_PTCE_INFO failed.\n\r");
  147. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  148. }
  149. CallPal (
  150. PAL_PROC_GET_FEATURES,
  151. 0,
  152. 0,
  153. 0,
  154. &Status,
  155. &ProcessorConfigInfo->FeaturesImplemented.Ulong64,
  156. &ProcessorConfigInfo->FeaturesCurSetting.Ulong64,
  157. &ProcessorConfigInfo->FeaturesSoftControl.Ulong64
  158. );
  159. if (Status) {
  160. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_PROC_GET_FEATURES failed.\n\r");
  161. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  162. }
  163. CallPal(
  164. PAL_CACHE_SUMMARY,
  165. 0,
  166. 0,
  167. 0,
  168. &Status,
  169. &CacheLevels,
  170. &UniqueCaches,
  171. &Reserved
  172. );
  173. if (Status) {
  174. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_CACHE_SUMMARY failed.\r\n");
  175. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  176. }
  177. if (CacheLevels < 2) {
  178. EfiPrint(L"ReadProcessorConfigInfo: Invalid number of Cache Levels.\r\n");
  179. EfiBS->Exit(EfiImageHandle, (EFI_STATUS)-1, 0, 0);
  180. }
  181. ProcessorConfigInfo->NumberOfCacheLevels = CONFIG_INFO_CACHE_LEVELS;
  182. ProcessorConfigInfo->LargestCacheLine = 0;
  183. if (CacheLevels < CONFIG_INFO_CACHE_LEVELS) {
  184. ProcessorConfigInfo->NumberOfCacheLevels = (ULONG) CacheLevels;
  185. }
  186. for (CacheIndex = 0; CacheIndex < ProcessorConfigInfo->NumberOfCacheLevels; CacheIndex++) {
  187. CallPal(
  188. PAL_CACHE_INFO,
  189. CacheIndex, // Cache Level
  190. 2, // Data or Unified Cache
  191. 0, // Not used
  192. &Status,
  193. &ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_DCACHE][CacheIndex].Ulong64,
  194. &ProcessorConfigInfo->CacheInfo2[CONFIG_INFO_DCACHE][CacheIndex].Ulong64,
  195. &Reserved
  196. );
  197. if (Status != 0) {
  198. EfiPrintf(L"ReadProcessorConfigInfo: PAL call PAL_CACHE_INFO D cache failed. Index = %d, Status = %d\r\n", CacheIndex, Status);
  199. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  200. }
  201. //
  202. // Detemine the largest stride for memory allocation.
  203. //
  204. if ((1UL << ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_DCACHE][CacheIndex].LineSize) >
  205. ProcessorConfigInfo->LargestCacheLine) {
  206. ProcessorConfigInfo->LargestCacheLine =
  207. 1UL << ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_DCACHE][CacheIndex].LineSize;
  208. }
  209. //
  210. // If this is a unified cache then data and instructions are the same so skip
  211. // the instruction cache.
  212. //
  213. if (ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_DCACHE][CacheIndex].Unified) {
  214. ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_ICACHE][CacheIndex] = ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_DCACHE][CacheIndex];
  215. ProcessorConfigInfo->CacheInfo2[CONFIG_INFO_ICACHE][CacheIndex] = ProcessorConfigInfo->CacheInfo2[CONFIG_INFO_DCACHE][CacheIndex];
  216. continue;
  217. }
  218. CallPal(
  219. PAL_CACHE_INFO,
  220. CacheIndex, // Cache Level
  221. 1, // Instruction Cache
  222. 0, // Not used
  223. &Status,
  224. &ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_ICACHE][CacheIndex].Ulong64,
  225. &ProcessorConfigInfo->CacheInfo2[CONFIG_INFO_ICACHE][CacheIndex].Ulong64,
  226. &Reserved
  227. );
  228. if (Status != 0) {
  229. EfiPrintf(L"ReadProcessorConfigInfo: PAL call PAL_CACHE_INFO I cache failed. Index = %d, Status = %d\r\n", CacheIndex, Status);
  230. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  231. }
  232. }
  233. //
  234. // Scan the any remaining cache levels for a the maximum line size value.
  235. //
  236. for (CacheIndex = ProcessorConfigInfo->NumberOfCacheLevels; CacheIndex < CacheLevels; CacheIndex++) {
  237. CallPal(
  238. PAL_CACHE_INFO,
  239. CacheIndex, // Cache Level
  240. 2, // Data Cache
  241. 0, // Not used
  242. &Status,
  243. &CacheInfo1.Ulong64,
  244. &CacheInfo2.Ulong64,
  245. &Reserved
  246. );
  247. if (Status != 0) {
  248. EfiPrintf(L"ReadProcessorConfigInfo: PAL call PAL_CACHE_INFO Line failed. Index = %d, Status = %d\r\n", CacheIndex, Status);
  249. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  250. }
  251. //
  252. // Detemine the largest stride for memory allocation.
  253. //
  254. if ((1UL << CacheInfo1.LineSize) > ProcessorConfigInfo->LargestCacheLine) {
  255. ProcessorConfigInfo->LargestCacheLine = 1UL << CacheInfo1.LineSize;
  256. }
  257. }
  258. //
  259. // We need to retrieve the stride value for the "FC" instruction. Since the
  260. // "FC" instruction isn't targetted at a specific cache rather it is
  261. // supposed to flush all the caches the stride value should be the same for
  262. // all cache levels. Unfortunately this isn't currently true for
  263. // Itanium systems.
  264. //
  265. // Fortunately the value for Level 2 (index 1) is correct on both Itanium
  266. // and McKinley systems. So we will just retrieve it.
  267. //
  268. ProcessorConfigInfo->CacheFlushStride = 1 << (ProcessorConfigInfo->CacheInfo1[CONFIG_INFO_DCACHE][1].Stride);
  269. #if 0
  270. {
  271. //
  272. // Dump out all the cache info for debugging purposes.
  273. //
  274. EfiPrintf(L"ReadProcessorConfigInfo: CacheLevels = %d, UniqueCaches = %d\r\n", CacheLevels, UniqueCaches);
  275. EfiPrintf(L"ReadProcessorConfigInfo: CacheFlushStride = %d, LargestCacheLine = %d\r\n", ProcessorConfigInfo->CacheFlushStride, ProcessorConfigInfo->LargestCacheLine);
  276. for (CacheIndex = 0; CacheIndex < (2 * CacheLevels); CacheIndex++) {
  277. CallPal(
  278. PAL_CACHE_INFO,
  279. CacheIndex >> 1,
  280. (CacheIndex & 0x01) + 1,
  281. 0,
  282. &Status,
  283. &CacheInfo1.Ulong64,
  284. &CacheInfo2.Ulong64,
  285. &Reserved
  286. );
  287. if (Status == 0) {
  288. EfiPrintf(L"ReadProcessorConfigInfo: CacheLevel(%s) = %d, ConfigInfo1 = 0x%I64X, ConfigInfo2 = 0x%I64X\r\n",
  289. (CacheIndex & 0x01) ? L"Data" : L"Instruction",
  290. CacheIndex >> 1,
  291. CacheInfo1.Ulong64, CacheInfo2.Ulong64);
  292. EfiPrintf(L" Stride = %d, LineSize = %d, Associativity = %d, Attributes = %d, Unified = %d\r\n",
  293. CacheInfo1.Stride,
  294. CacheInfo1.LineSize,
  295. CacheInfo1.Associativity,
  296. CacheInfo1.Attributes,
  297. CacheInfo1.Unified
  298. );
  299. EfiPrintf(L" LoadHints = %d, StoreHints = %d, LoadLatency = %d, StoreLatency = %d\r\n",
  300. CacheInfo1.LoadHints,
  301. CacheInfo1.StoreHints,
  302. CacheInfo1.LoadLatency,
  303. CacheInfo1.StoreLatency
  304. );
  305. EfiPrintf(L" CacheSize = %d, TagMSBit = %d, TagLSBit = %d, AliasBoundary = %d\r\n",
  306. CacheInfo2.Size,
  307. CacheInfo2.TagLeastBit,
  308. CacheInfo2.TagMostBit,
  309. CacheInfo2.Alias);
  310. } else {
  311. EfiPrintf(L"ReadProcessorConfigInfo: PAL call PAL_CACHE_INFO failed, Status = %d.\r\n", Status);
  312. // EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  313. }
  314. }
  315. }
  316. #endif
  317. //
  318. // IA64 Debug Registers info.
  319. //
  320. CallPal (
  321. PAL_DEBUG_INFO,
  322. 0,
  323. 0,
  324. 0,
  325. &ProcessorConfigInfo->DebugInfo.Status,
  326. &ProcessorConfigInfo->DebugInfo.InstDebugRegisterPairs,
  327. &ProcessorConfigInfo->DebugInfo.DataDebugRegisterPairs,
  328. 0
  329. );
  330. if (ProcessorConfigInfo->DebugInfo.Status) {
  331. #if DBG
  332. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_DEBUG_INFO failed.\n\r");
  333. EfiPrint(L"ReadProcessorConfigInfo: Fixing DebugInfo with architected default values.\n\r");
  334. #endif
  335. ProcessorConfigInfo->DebugInfo.InstDebugRegisterPairs = NUMBER_OF_DEBUG_REGISTER_PAIRS;
  336. ProcessorConfigInfo->DebugInfo.DataDebugRegisterPairs = NUMBER_OF_DEBUG_REGISTER_PAIRS;
  337. }
  338. //
  339. // IA64 Performance Monitor Registers info.
  340. //
  341. CallPal (
  342. PAL_PERF_MON_INFO,
  343. (ULONGLONG)&ProcessorConfigInfo->PerfMonInfo.PerfMonCnfgMask[0],
  344. 0,
  345. 0,
  346. &ProcessorConfigInfo->PerfMonInfo.Status,
  347. &ProcessorConfigInfo->PerfMonInfo.Ulong64,
  348. 0,
  349. 0
  350. );
  351. if (ProcessorConfigInfo->PerfMonInfo.Status) {
  352. //
  353. // Workaround known family or models values.
  354. //
  355. ULONGLONG cpuFamily = (ProcessorConfigInfo->CpuId3 >> 24) && 0xff;
  356. ULONGLONG counterWidth = 47; // Default McKinley-core Family PMU.
  357. if ( cpuFamily == 7 ) {
  358. counterWidth = 32;
  359. }
  360. #if DBG
  361. EfiPrint(L"ReadProcessorConfigInfo: PAL call PAL_PERF_MON_INFO failed.\n\r");
  362. EfiPrint(L"ReadProcessorConfigInfo: Fixing PerfMonInfo with architected default values.\n\r");
  363. #endif
  364. ProcessorConfigInfo->PerfMonInfo.PerfMonGenericPairs = NUMBER_OF_PERFMON_REGISTER_PAIRS;
  365. ProcessorConfigInfo->PerfMonInfo.ImplementedCounterWidth = counterWidth;
  366. ProcessorConfigInfo->PerfMonInfo.ProcessorCyclesEventType = 0x12;
  367. ProcessorConfigInfo->PerfMonInfo.RetiredInstructionBundlesEventType = 0x8;
  368. ProcessorConfigInfo->PerfMonInfo.PerfMonCnfgMask[0] = (UCHAR)0xff;
  369. ProcessorConfigInfo->PerfMonInfo.PerfMonCnfgMask[1] = (UCHAR)0xff;
  370. ProcessorConfigInfo->PerfMonInfo.PerfMonDataMask[0] = (UCHAR)0xff;
  371. ProcessorConfigInfo->PerfMonInfo.PerfMonDataMask[1] = (UCHAR)0xff;
  372. ProcessorConfigInfo->PerfMonInfo.PerfMonDataMask[2] = (UCHAR)0x03;
  373. ProcessorConfigInfo->PerfMonInfo.ProcessorCyclesMask[0] = (UCHAR)0xf0;
  374. ProcessorConfigInfo->PerfMonInfo.RetiredInstructionBundlesMask[0] = (UCHAR)0xf0;
  375. }
  376. }
  377. VOID
  378. CpuSpecificWork(
  379. )
  380. /*++
  381. Routine Description:
  382. This routine checks for CPU ID and applies processor specific workarounds.
  383. Arguments:
  384. None
  385. Returns:
  386. None
  387. --*/
  388. {
  389. ULONGLONG CpuId;
  390. ULONGLONG CpuFamily;
  391. CpuId = __getReg(CV_IA64_CPUID3);
  392. CpuFamily = (CpuId >> 24) & 0xff;
  393. //
  394. // if the processor is an Itanium...
  395. //
  396. if (CpuFamily == 7) {
  397. //
  398. // We must ensure that the processor and PAL are supported before continuing.
  399. //
  400. EnforcePostB2Processor();
  401. EnforcePostVersion16PAL();
  402. EfiCheckFirmwareRevision();
  403. #if 0
  404. //
  405. // This is redundant since A2 < B3
  406. //
  407. CheckForPreA2Processors();
  408. #endif
  409. }
  410. }
  411. VOID
  412. EnforcePostB2Processor(
  413. )
  414. /*++
  415. Routine Description:
  416. This routine checks enforces that the system has a post B2 processor stepping.
  417. Arguments:
  418. None
  419. Returns:
  420. None
  421. --*/
  422. {
  423. ULONGLONG CpuId3;
  424. CpuId3 = __getReg(CV_IA64_CPUID3);
  425. #if 0
  426. {
  427. WCHAR Buffer[256];
  428. ULONGLONG x;
  429. x = (CpuId3 >> 0) & 0xff;
  430. wsprintf(Buffer, L"Number = %x\r\n", x);
  431. EfiPrint(Buffer);
  432. x = (CpuId3 >> 8) & 0xff;
  433. wsprintf(Buffer, L"Revision = %x\r\n", x);
  434. EfiPrint(Buffer);
  435. x = (CpuId3 >> 16) & 0xff;
  436. wsprintf(Buffer, L"Model = %x\r\n", x);
  437. EfiPrint(Buffer);
  438. x = (CpuId3 >> 24) & 0xff;
  439. wsprintf(Buffer, L"Family = %x\r\n", x);
  440. EfiPrint(Buffer);
  441. x = (CpuId3 >> 32) & 0xff;
  442. wsprintf(Buffer, L"Archrev = %x\r\n", x);
  443. EfiPrint(Buffer);
  444. DBG_EFI_PAUSE();
  445. }
  446. #endif
  447. //
  448. // Block Processor steppings below B3
  449. //
  450. // Note: this switch came from: ntos\ke\ia64\initkr.c
  451. //
  452. switch (CpuId3) {
  453. case 0x0007000004: // Itanium, A stepping
  454. case 0x0007000104: // Itanium, B0 stepping
  455. case 0x0007000204: // Itanium, B1 stepping
  456. case 0x0007000304: // Itanium, B2 stepping
  457. //
  458. // unsupported steppings
  459. //
  460. EfiPrint(L"Your Itanium system contains a pre-B3 stepping processor.\n\r");
  461. EfiPrint(L"You need to upgrade it to a B3 or later stepping to run Win64.\n\r");
  462. EfiBS->Exit(EfiImageHandle, 0, 0, 0);
  463. break;
  464. case 0x0007000404: // Itanium, B3 stepping
  465. case 0x0007000504: // Itanium, B4 stepping
  466. case 0x0007000604: // Itanium, C0 or later stepping
  467. default:
  468. //
  469. // supported steppings, do nothing
  470. //
  471. break;
  472. }
  473. }
  474. VOID
  475. EnforcePostVersion16PAL(
  476. )
  477. /*++
  478. Routine Description:
  479. This routine enforces that the system has a PAL version >= 20.
  480. Note:
  481. The return value from get PAL version call has the
  482. PAL B model and revision has the least significant
  483. 16 bits (Intel IA-64 Architecture Software Developer's Manual, Rav. 1.0, Page 11-109).
  484. We should be using this to determine a minimum PAL revision for the firmware.
  485. The first byte has the PAL_B_revision which is a monotonically increasing number
  486. and is 0x17 for Lion 71b and 0x20 for Softsur 103b.
  487. The PAL_B model indicates the stepping of the processor supported (We can ignore this one).
  488. So we need to be using PAL B revision for our minimum firmware test.
  489. Just an FYI:
  490. There is a disconnect in the PAL_REVISION structure and what appears to be the specified
  491. PAL revision layout. We use PAL_B_REVISION to get the PAL version rather than PAL_A_REVISION.
  492. Arguments:
  493. None
  494. Returns:
  495. None
  496. --*/
  497. {
  498. ULONGLONG Status;
  499. PAL_REVISION MinimumPalVersion;
  500. PAL_REVISION CurrentPalVersion;
  501. ULONGLONG Reserved;
  502. #define MIN_PAL_REVISION 0x23
  503. CallPal (
  504. PAL_VERSION,
  505. 0,
  506. 0,
  507. 0,
  508. &Status,
  509. &MinimumPalVersion.PalVersion,
  510. &CurrentPalVersion.PalVersion,
  511. &Reserved
  512. );
  513. if (Status) {
  514. EfiPrint(L"CheckForPreA2Processors: PAL call PAL_VERSION failed.\n\r");
  515. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  516. }
  517. #if 0
  518. {
  519. WCHAR Buffer[256];
  520. wsprintf(Buffer, L"PalBRevLower = %x\r\n", CurrentPalVersion.PalBRevLower);
  521. EfiPrint(Buffer);
  522. wsprintf(Buffer, L"PalBRevUpper = %x\r\n", CurrentPalVersion.PalBRevUpper);
  523. EfiPrint(Buffer);
  524. wsprintf(Buffer, L"PalBModel = %x\r\n", CurrentPalVersion.PalBModel);
  525. EfiPrint(Buffer);
  526. wsprintf(Buffer, L"Reserved0 = %x\r\n", CurrentPalVersion.Reserved0);
  527. EfiPrint(Buffer);
  528. wsprintf(Buffer, L"PalVendor = %x\r\n", CurrentPalVersion.PalVendor);
  529. EfiPrint(Buffer);
  530. wsprintf(Buffer, L"PalARevision = %x\r\n", CurrentPalVersion.PalARevision);
  531. EfiPrint(Buffer);
  532. wsprintf(Buffer, L"PalAModel = %x\r\n", CurrentPalVersion.PalAModel);
  533. EfiPrint(Buffer);
  534. wsprintf(Buffer, L"Reserved1 = %x\r\n", CurrentPalVersion.Reserved1);
  535. EfiPrint(Buffer);
  536. DBG_EFI_PAUSE();
  537. }
  538. #endif
  539. if (CurrentPalVersion.PalARevision < MIN_PAL_REVISION) {
  540. WCHAR Buffer[256];
  541. wsprintf(Buffer, L"Your Itanium system's PAL version is less than 0x%x.\n\r", MIN_PAL_REVISION);
  542. EfiPrint(Buffer);
  543. wsprintf(Buffer, L"To upgrade system's PAL version, please update the system's firmware.\n\r");
  544. EfiPrint(Buffer);
  545. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  546. }
  547. }
  548. VOID
  549. CheckForPreA2Processors(
  550. )
  551. {
  552. ULONGLONG Status;
  553. PAL_REVISION MinimumPalVersion;
  554. PAL_REVISION CurrentPalVersion;
  555. ULONGLONG Reserved;
  556. CallPal (
  557. PAL_VERSION,
  558. 0,
  559. 0,
  560. 0,
  561. &Status,
  562. &MinimumPalVersion.PalVersion,
  563. &CurrentPalVersion.PalVersion,
  564. &Reserved
  565. );
  566. if (Status) {
  567. EfiPrint(L"CheckForPreA2Processors: PAL call PAL_VERSION failed.\n\r");
  568. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  569. }
  570. //
  571. // If PalBRevUpper if 0, 1, 3 or 4 then it is A0/A1 stepping.
  572. //
  573. if (CurrentPalVersion.PalBModel == 0) {
  574. if ( (CurrentPalVersion.PalBRevUpper == 0) ||
  575. (CurrentPalVersion.PalBRevUpper == 1) ||
  576. (CurrentPalVersion.PalBRevUpper == 3) ||
  577. (CurrentPalVersion.PalBRevUpper == 4) ) {
  578. //
  579. // Since PAL version 27 supports A2 and A3 but
  580. // it returns 0, we need to special case this and
  581. // just return.
  582. //
  583. if ((CurrentPalVersion.PalBRevUpper == 0) &&
  584. (CurrentPalVersion.PalBRevLower == 0) ) {
  585. return;
  586. }
  587. EfiPrint(L"Your Itanium system contains an pre-A2 stepping processor.\n\r");
  588. EfiPrint(L"You need to upgrade it to an A2 or later stepping to run Win64.\n\r");
  589. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  590. }
  591. }
  592. }