Source code of Windows XP (NT5)
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.

476 lines
12 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. typedef struct _PAL_RETURN_VALUES {
  19. ULONGLONG ReturnValue0;
  20. ULONGLONG ReturnValue1;
  21. ULONGLONG ReturnValue2;
  22. ULONGLONG ReturnValue3;
  23. } PAL_RETURN_VALUES, *PPAL_RETURN_VALUES;
  24. typedef union _PAL_REVISION {
  25. struct {
  26. ULONGLONG PalBRevLower:4;
  27. ULONGLONG PalBRevUpper:4;
  28. ULONGLONG PalBModel:8;
  29. ULONGLONG Reserved0:8;
  30. ULONGLONG PalVendor:8;
  31. ULONGLONG PalARevision:8;
  32. ULONGLONG PalAModel:8;
  33. ULONGLONG Reserved1:16;
  34. };
  35. ULONGLONG PalVersion;
  36. } PAL_REVISION;
  37. extern
  38. PAL_RETURN_VALUES
  39. BlpPalProc(
  40. IN ULONGLONG FunctionIndex,
  41. IN ULONGLONG Arg1,
  42. IN ULONGLONG Arg2,
  43. IN ULONGLONG Arg3
  44. );
  45. VOID
  46. CallPal(
  47. IN ULONGLONG FunctionIndex,
  48. IN ULONGLONG Argument0,
  49. IN ULONGLONG Argument1,
  50. IN ULONGLONG Argument2,
  51. OUT PULONGLONG ReturnValue0,
  52. OUT PULONGLONG ReturnValue1,
  53. OUT PULONGLONG ReturnValue2,
  54. OUT PULONGLONG ReturnValue3
  55. )
  56. {
  57. PAL_RETURN_VALUES RetVal;
  58. RetVal = BlpPalProc(FunctionIndex, Argument0, Argument1, Argument2);
  59. *ReturnValue0 = RetVal.ReturnValue0;
  60. *ReturnValue1 = RetVal.ReturnValue1;
  61. *ReturnValue2 = RetVal.ReturnValue2;
  62. *ReturnValue3 = RetVal.ReturnValue3;
  63. }
  64. VOID
  65. ReadProcessorConfigInfo(
  66. PPROCESSOR_CONFIG_INFO ProcessorConfigInfo
  67. )
  68. {
  69. ULONGLONG Status;
  70. ULONGLONG Reserved;
  71. if ((PUCHAR) ProcessorConfigInfo >= (PUCHAR) KSEG0_BASE) {
  72. (PUCHAR) ProcessorConfigInfo -= KSEG0_BASE;
  73. }
  74. CallPal (
  75. PAL_VM_PAGE_SIZE,
  76. 0,
  77. 0,
  78. 0,
  79. &Status,
  80. &ProcessorConfigInfo->InsertPageSizeInfo,
  81. &ProcessorConfigInfo->PurgePageSizeInfo,
  82. &Reserved
  83. );
  84. if (Status) {
  85. EfiST->ConOut->OutputString(EfiST->ConOut,
  86. L"ReadProcessorConfigInfo: PAL call PAL_VM_PAGE_SIZE failed.\n\r");
  87. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  88. }
  89. CallPal (
  90. PAL_VM_SUMMARY,
  91. 0,
  92. 0,
  93. 0,
  94. &Status,
  95. &ProcessorConfigInfo->VmSummaryInfo1.Ulong64,
  96. &ProcessorConfigInfo->VmSummaryInfo2.Ulong64,
  97. &Reserved
  98. );
  99. if (Status) {
  100. EfiST->ConOut->OutputString(EfiST->ConOut,
  101. L"ReadProcessorConfigInfo: PAL call PAL_VM_SUMMARY failed.\n\r");
  102. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  103. }
  104. CallPal (
  105. PAL_RSE_INFO,
  106. 0,
  107. 0,
  108. 0,
  109. &Status,
  110. &ProcessorConfigInfo->NumOfPhysStackedRegs,
  111. &ProcessorConfigInfo->RseHints,
  112. &Reserved
  113. );
  114. if (Status) {
  115. EfiST->ConOut->OutputString(EfiST->ConOut,
  116. L"ReadProcessorConfigInfo: PAL call PAL_RSE_INFO failed.\n\r");
  117. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  118. }
  119. CallPal (
  120. PAL_PTCE_INFO,
  121. 0,
  122. 0,
  123. 0,
  124. &Status,
  125. &ProcessorConfigInfo->PtceInfo.PtceBase,
  126. &ProcessorConfigInfo->PtceInfo.PtceTcCount.Ulong64,
  127. &ProcessorConfigInfo->PtceInfo.PtceStrides.Ulong64
  128. );
  129. if (Status) {
  130. EfiST->ConOut->OutputString(EfiST->ConOut,
  131. L"ReadProcessorConfigInfo: PAL call PAL_PTCE_INFO failed.\n\r");
  132. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  133. }
  134. CallPal (
  135. PAL_PROC_GET_FEATURES,
  136. 0,
  137. 0,
  138. 0,
  139. &Status,
  140. &ProcessorConfigInfo->FeaturesImplemented.Ulong64,
  141. &ProcessorConfigInfo->FeaturesCurSetting.Ulong64,
  142. &ProcessorConfigInfo->FeaturesSoftControl.Ulong64
  143. );
  144. if (Status) {
  145. EfiST->ConOut->OutputString(EfiST->ConOut,
  146. L"ReadProcessorConfigInfo: PAL call PAL_PROC_GET_FEATURES failed.\n\r");
  147. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  148. }
  149. }
  150. VOID
  151. CpuSpecificWork(
  152. )
  153. /*++
  154. Routine Description:
  155. This routine checks for CPU ID and applies processor specific workarounds.
  156. Arguments:
  157. None
  158. Returns:
  159. None
  160. --*/
  161. {
  162. ULONGLONG CpuId;
  163. ULONGLONG CpuFamily;
  164. CpuId = __getReg(CV_IA64_CPUID3);
  165. CpuFamily = (CpuId >> 24) & 0xff;
  166. //
  167. // if the processor is an Itanium...
  168. //
  169. if (CpuFamily == 7) {
  170. //
  171. // We must ensure that the processor and PAL are supported before continuing.
  172. //
  173. EnforcePostB2Processor();
  174. EnforcePostVersion16PAL();
  175. EfiCheckFirmwareRevision();
  176. #if 0
  177. //
  178. // This is redundant since A2 < B3
  179. //
  180. CheckForPreA2Processors();
  181. #endif
  182. }
  183. }
  184. VOID
  185. EnforcePostB2Processor(
  186. )
  187. /*++
  188. Routine Description:
  189. This routine checks enforces that the system has a post B2 processor stepping.
  190. Arguments:
  191. None
  192. Returns:
  193. None
  194. --*/
  195. {
  196. ULONGLONG CpuId3;
  197. CpuId3 = __getReg(CV_IA64_CPUID3);
  198. #if 0
  199. {
  200. WCHAR Buffer[256];
  201. ULONGLONG x;
  202. x = (CpuId3 >> 0) & 0xff;
  203. wsprintf(Buffer, L"Number = %x\r\n", x);
  204. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  205. x = (CpuId3 >> 8) & 0xff;
  206. wsprintf(Buffer, L"Revision = %x\r\n", x);
  207. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  208. x = (CpuId3 >> 16) & 0xff;
  209. wsprintf(Buffer, L"Model = %x\r\n", x);
  210. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  211. x = (CpuId3 >> 24) & 0xff;
  212. wsprintf(Buffer, L"Family = %x\r\n", x);
  213. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  214. x = (CpuId3 >> 32) & 0xff;
  215. wsprintf(Buffer, L"Archrev = %x\r\n", x);
  216. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  217. DBG_EFI_PAUSE();
  218. }
  219. #endif
  220. //
  221. // Block Processor steppings below B3
  222. //
  223. // Note: this switch came from: ntos\ke\ia64\initkr.c
  224. //
  225. switch (CpuId3) {
  226. case 0x0007000004: // Itanium, A stepping
  227. case 0x0007000104: // Itanium, B0 stepping
  228. case 0x0007000204: // Itanium, B1 stepping
  229. case 0x0007000304: // Itanium, B2 stepping
  230. //
  231. // unsupported steppings
  232. //
  233. EfiST->ConOut->OutputString(EfiST->ConOut,
  234. L"Your Itanium system contains a pre-B3 stepping processor.\n\r");
  235. EfiST->ConOut->OutputString(EfiST->ConOut,
  236. L"You need to upgrade it to a B3 or later stepping to run Win64.\n\r");
  237. EfiBS->Exit(EfiImageHandle, 0, 0, 0);
  238. break;
  239. case 0x0007000404: // Itanium, B3 stepping
  240. case 0x0007000504: // Itanium, B4 stepping
  241. case 0x0007000604: // Itanium, C0 or later stepping
  242. default:
  243. //
  244. // supported steppings, do nothing
  245. //
  246. break;
  247. }
  248. }
  249. VOID
  250. EnforcePostVersion16PAL(
  251. )
  252. /*++
  253. Routine Description:
  254. This routine enforces that the system has a PAL version >= 20.
  255. Note:
  256. The return value from get PAL version call has the
  257. PAL B model and revision has the least significant
  258. 16 bits (Intel IA-64 Architecture Software Developer's Manual, Rav. 1.0, Page 11-109).
  259. We should be using this to determine a minimum PAL revision for the firmware.
  260. The first byte has the PAL_B_revision which is a monotonically increasing number
  261. and is 0x17 for Lion 71b and 0x20 for Softsur 103b.
  262. The PAL_B model indicates the stepping of the processor supported (We can ignore this one).
  263. So we need to be using PAL B revision for our minimum firmware test.
  264. Just an FYI:
  265. There is a disconnect in the PAL_REVISION structure and what appears to be the specified
  266. PAL revision layout. We use PAL_B_REVISION to get the PAL version rather than PAL_A_REVISION.
  267. Arguments:
  268. None
  269. Returns:
  270. None
  271. --*/
  272. {
  273. ULONGLONG Status;
  274. PAL_REVISION MinimumPalVersion;
  275. PAL_REVISION CurrentPalVersion;
  276. ULONGLONG Reserved;
  277. #define MIN_PAL_REVISION 0x23
  278. CallPal (
  279. PAL_VERSION,
  280. 0,
  281. 0,
  282. 0,
  283. &Status,
  284. &MinimumPalVersion.PalVersion,
  285. &CurrentPalVersion.PalVersion,
  286. &Reserved
  287. );
  288. if (Status) {
  289. EfiST->ConOut->OutputString(EfiST->ConOut,
  290. L"CheckForPreA2Processors: PAL call PAL_VERSION failed.\n\r");
  291. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  292. }
  293. #if 0
  294. {
  295. WCHAR Buffer[256];
  296. wsprintf(Buffer, L"PalBRevLower = %x\r\n", CurrentPalVersion.PalBRevLower);
  297. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  298. wsprintf(Buffer, L"PalBRevUpper = %x\r\n", CurrentPalVersion.PalBRevUpper);
  299. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  300. wsprintf(Buffer, L"PalBModel = %x\r\n", CurrentPalVersion.PalBModel);
  301. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  302. wsprintf(Buffer, L"Reserved0 = %x\r\n", CurrentPalVersion.Reserved0);
  303. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  304. wsprintf(Buffer, L"PalVendor = %x\r\n", CurrentPalVersion.PalVendor);
  305. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  306. wsprintf(Buffer, L"PalARevision = %x\r\n", CurrentPalVersion.PalARevision);
  307. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  308. wsprintf(Buffer, L"PalAModel = %x\r\n", CurrentPalVersion.PalAModel);
  309. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  310. wsprintf(Buffer, L"Reserved1 = %x\r\n", CurrentPalVersion.Reserved1);
  311. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  312. DBG_EFI_PAUSE();
  313. }
  314. #endif
  315. if (CurrentPalVersion.PalARevision < MIN_PAL_REVISION) {
  316. WCHAR Buffer[256];
  317. wsprintf(Buffer, L"Your Itanium system's PAL version is less than 0x%x.\n\r", MIN_PAL_REVISION);
  318. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  319. wsprintf(Buffer, L"You need to upgrade it to version 0x%x or later to run Win64.\n\r", MIN_PAL_REVISION);
  320. EfiST->ConOut->OutputString(EfiST->ConOut, Buffer);
  321. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  322. }
  323. }
  324. VOID
  325. CheckForPreA2Processors(
  326. )
  327. {
  328. ULONGLONG Status;
  329. PAL_REVISION MinimumPalVersion;
  330. PAL_REVISION CurrentPalVersion;
  331. ULONGLONG Reserved;
  332. CallPal (
  333. PAL_VERSION,
  334. 0,
  335. 0,
  336. 0,
  337. &Status,
  338. &MinimumPalVersion.PalVersion,
  339. &CurrentPalVersion.PalVersion,
  340. &Reserved
  341. );
  342. if (Status) {
  343. EfiST->ConOut->OutputString(EfiST->ConOut,
  344. L"CheckForPreA2Processors: PAL call PAL_VERSION failed.\n\r");
  345. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  346. }
  347. //
  348. // If PalBRevUpper if 0, 1, 3 or 4 then it is A0/A1 stepping.
  349. //
  350. if (CurrentPalVersion.PalBModel == 0) {
  351. if ( (CurrentPalVersion.PalBRevUpper == 0) ||
  352. (CurrentPalVersion.PalBRevUpper == 1) ||
  353. (CurrentPalVersion.PalBRevUpper == 3) ||
  354. (CurrentPalVersion.PalBRevUpper == 4) ) {
  355. //
  356. // Since PAL version 27 supports A2 and A3 but
  357. // it returns 0, we need to special case this and
  358. // just return.
  359. //
  360. if ((CurrentPalVersion.PalBRevUpper == 0) &&
  361. (CurrentPalVersion.PalBRevLower == 0) ) {
  362. return;
  363. }
  364. EfiST->ConOut->OutputString(EfiST->ConOut,
  365. L"Your Itanium system contains an pre-A2 stepping processor.\n\r");
  366. EfiST->ConOut->OutputString(EfiST->ConOut,
  367. L"You need to upgrade it to an A2 or later stepping to run Win64.\n\r");
  368. EfiBS->Exit(EfiImageHandle, Status, 0, 0);
  369. }
  370. }
  371. }