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.

3580 lines
104 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. cpuinfo.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Peter Johnston (peterj) 19-April-1999
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #include "i386.h"
  15. #include "amd64.h"
  16. #include "ia64.h"
  17. #pragma hdrstop
  18. #define MAXIMUM_IA64_VECTOR 256
  19. #if !defined(ROUND_UP)
  20. //
  21. // Macro to round Val up to the next Bnd boundary. Bnd must be an integral
  22. // power of two.
  23. //
  24. #define ROUND_UP( Val, Bnd ) \
  25. (((Val) + ((Bnd) - 1)) & ~((Bnd) - 1))
  26. #endif // !ROUND_UP
  27. VOID
  28. DumpCpuInfoIA64(
  29. ULONG processor,
  30. BOOLEAN doHead
  31. )
  32. {
  33. HRESULT Hr;
  34. ULONG number;
  35. ULONG64 prcb;
  36. UCHAR vendorString[16];
  37. if (doHead)
  38. {
  39. dprintf("CP M/R/F/A Manufacturer SerialNumber Features\n");
  40. }
  41. Hr = g_ExtData->ReadProcessorSystemData(processor,
  42. DEBUG_DATA_KPRCB_OFFSET,
  43. &prcb,
  44. sizeof(prcb),
  45. NULL);
  46. if (Hr != S_OK)
  47. {
  48. return;
  49. }
  50. if ( GetFieldValue(prcb, "nt!_KPRCB", "ProcessorVendorString", vendorString) ) {
  51. dprintf("Unable to read VendorString from Processor %u KPRCB, quitting\n", processor);
  52. return;
  53. }
  54. if ( InitTypeRead( prcb, nt!_KPRCB )) {
  55. dprintf("Unable to read KPRCB for processor %u, quitting.\n", processor);
  56. return;
  57. }
  58. number = (ULONG)ReadField(Number);
  59. if ( number != processor ) {
  60. //
  61. // Processor number isn't what we expected. Bail out.
  62. // This will need revisiting at some stage in the future
  63. // when we support a discontiguous set of processor numbers.
  64. //
  65. dprintf("Processor %d mismatch with processor number in KPRCB = %d, quitting\n",
  66. processor,
  67. number );
  68. return;
  69. }
  70. dprintf("%2d %d,%d,%d,%d %-16s %016I64x %016I64x\n",
  71. number,
  72. (ULONG) ReadField(ProcessorModel),
  73. (ULONG) ReadField(ProcessorRevision),
  74. (ULONG) ReadField(ProcessorFamily),
  75. (ULONG) ReadField(ProcessorArchRev),
  76. vendorString,
  77. (ULONGLONG) ReadField(ProcessorSerialNumber),
  78. (ULONGLONG) ReadField(ProcessorFeatureBits)
  79. );
  80. return;
  81. }
  82. VOID
  83. DumpCpuInfoX86(
  84. ULONG processor,
  85. BOOLEAN doHead
  86. )
  87. {
  88. HRESULT Hr;
  89. ULONG64 Prcb;
  90. UCHAR sigWarn1, sigWarn2;
  91. LARGE_INTEGER updateSignature;
  92. PROCESSORINFO pi;
  93. if (doHead)
  94. {
  95. dprintf("CP F/M/S Manufacturer MHz Update Signature Features\n");
  96. }
  97. if (!Ioctl(IG_KD_CONTEXT, &pi, sizeof(pi))) {
  98. dprintf("Unable to get processor info, quitting\n");
  99. return;
  100. }
  101. CHAR VendorString[20]={0};
  102. Hr = g_ExtData->ReadProcessorSystemData(processor,
  103. DEBUG_DATA_KPRCB_OFFSET,
  104. &Prcb,
  105. sizeof(Prcb),
  106. NULL);
  107. if (Hr != S_OK)
  108. {
  109. return;
  110. }
  111. if (InitTypeRead(Prcb, nt!_KPRCB)) {
  112. dprintf("Unable to read PRCB for processor %u, quitting.\n",
  113. processor);
  114. return;
  115. }
  116. if ((ULONG) ReadField(Number) != processor) {
  117. //
  118. // Processor number isn't what I expected. Bail out.
  119. // This will need revisiting at some stage in the future
  120. // when we support a discontiguous set of processor numbers.
  121. //
  122. dprintf("Processor %d mismatch with processor number in PRCB %d, quitting\n",
  123. processor,
  124. (ULONG) ReadField(Number));
  125. return;
  126. }
  127. if (ReadField(CpuID) == 0) {
  128. //
  129. // This processor doesn't support CPUID,... not likely in
  130. // an MP environment but also means we don't have anything
  131. // useful to say.
  132. //
  133. dprintf("Processor %d doesn't support CPUID, quitting.\n",
  134. processor);
  135. return;
  136. }
  137. //
  138. // If this is an Intel processor, family 6 (or, presumably
  139. // above family 6) read the current UpdateSignature from
  140. // the processor rather than using what was there when we
  141. // booted,... it may havee been updated.
  142. //
  143. // Actually, this can't be done unless we can switch processors
  144. // from within an extension. So, mark the processor we did
  145. // it for (unless there's only one processor).
  146. //
  147. *((PULONG64) &updateSignature) = ReadField(UpdateSignature);
  148. sigWarn1 = sigWarn2 = ' ';
  149. GetFieldValue(Prcb, "nt!_KPRCB", "VendorString", VendorString);
  150. if ((!strcmp(VendorString, "GenuineIntel")) &&
  151. ((ULONG) ReadField(CpuType) >= 6)) {
  152. if ((ULONG) ReadField(Number) == pi.Processor)
  153. {
  154. if (TargetMachine == IMAGE_FILE_MACHINE_I386)
  155. {
  156. READ_WRITE_MSR msr;
  157. msr.Msr = 0x8b;
  158. msr.Value = 0;
  159. if (Ioctl(IG_READ_MSR, &msr, sizeof(msr)))
  160. {
  161. updateSignature.QuadPart = msr.Value;
  162. }
  163. }
  164. if (pi.NumberProcessors != 1)
  165. {
  166. sigWarn1 = '>';
  167. sigWarn2 = '<';
  168. }
  169. }
  170. }
  171. //
  172. // This extension could pretty much be !PRCB but it's a
  173. // subset,... perhaps we should have a !PRCB?
  174. //
  175. dprintf("%2d %d,%d,%d %12s%5d%c%08x%08x%c%08x\n",
  176. (ULONG) ReadField(Number),
  177. (ULONG) ReadField(CpuType),
  178. ((ULONG) ReadField(CpuStep) >> 8) & 0xff,
  179. (ULONG) ReadField(CpuStep) & 0xff,
  180. VendorString,
  181. (ULONG) ReadField(MHz),
  182. sigWarn1,
  183. updateSignature.u.HighPart,
  184. updateSignature.u.LowPart,
  185. sigWarn2,
  186. (ULONG) ReadField(FeatureBits));
  187. }
  188. DECLARE_API( cpuinfo )
  189. /*++
  190. Routine Description:
  191. Gather up any info we know is still in memory that we gleaned
  192. using the CPUID instruction,.... and a few other interesting
  193. tidbits as well.
  194. Arguments:
  195. None
  196. Return Value:
  197. None
  198. --*/
  199. {
  200. ULONG64 processor;
  201. BOOLEAN first = TRUE;
  202. ULONG64 NumProcessors = 0;
  203. INIT_API();
  204. g_ExtControl->GetNumberProcessors((PULONG) &NumProcessors);
  205. if (GetExpressionEx(args, &processor, &args))
  206. {
  207. //
  208. // The user specified a procesor number.
  209. //
  210. if (processor >= NumProcessors)
  211. {
  212. dprintf("cpuinfo: invalid processor number specified\n");
  213. }
  214. else
  215. {
  216. NumProcessors = processor + 1;
  217. }
  218. }
  219. else
  220. {
  221. //
  222. // Enumerate all the processors
  223. //
  224. processor = 0;
  225. }
  226. while (processor < NumProcessors)
  227. {
  228. switch( TargetMachine )
  229. {
  230. case IMAGE_FILE_MACHINE_I386:
  231. DumpCpuInfoX86((ULONG)processor, first);
  232. break;
  233. case IMAGE_FILE_MACHINE_IA64:
  234. DumpCpuInfoIA64((ULONG)processor, first);
  235. break;
  236. default:
  237. dprintf("!cpuinfo not supported for this target machine: %ld\n", TargetMachine);
  238. processor = NumProcessors;
  239. }
  240. processor++;
  241. first = FALSE;
  242. }
  243. EXIT_API();
  244. return S_OK;
  245. }
  246. DECLARE_API( prcb )
  247. /*++
  248. Routine Description:
  249. Displays the PRCB
  250. Arguments:
  251. args - the processor number ( default is 0 )
  252. Return Value:
  253. None
  254. --*/
  255. {
  256. HRESULT Hr;
  257. ULONG64 Address=0;
  258. ULONG Processor;
  259. ULONG Prcb;
  260. INIT_API();
  261. Processor = (ULONG) GetExpression(args);
  262. Hr = g_ExtData->ReadProcessorSystemData(Processor,
  263. DEBUG_DATA_KPRCB_OFFSET,
  264. &Address,
  265. sizeof(Address),
  266. NULL);
  267. if (Hr != S_OK)
  268. {
  269. dprintf("Cannot get PRCB address\n");
  270. return E_INVALIDARG;
  271. }
  272. if (InitTypeRead(Address, nt!_KPRCB) )
  273. {
  274. dprintf("Unable to read PRCB\n");
  275. return E_INVALIDARG;
  276. }
  277. dprintf("PRCB for Processor %d at %16p:\n",
  278. Processor, Address);
  279. dprintf("Major %d Minor %d\n",
  280. (ULONG) ReadField(MajorVersion),
  281. (ULONG) ReadField(MinorVersion));
  282. dprintf("Threads-- Current %16p Next %16p Idle %16p\n",
  283. ReadField(CurrentThread),
  284. ReadField(NextThread),
  285. ReadField(IdleThread));
  286. dprintf("Number %d SetMember %08lx\n",
  287. (ULONG) ReadField(Number),
  288. (ULONG) ReadField(SetMember));
  289. dprintf("Interrupt Count -- %08lx\n",
  290. (ULONG) ReadField(InterruptCount));
  291. dprintf("Times -- Dpc %08lx Interrupt %08lx \n",
  292. (ULONG) ReadField(DpcTime),
  293. (ULONG) ReadField(InterruptTime));
  294. dprintf(" Kernel %08lx User %08lx \n",
  295. (ULONG) ReadField(KernelTime),
  296. (ULONG) ReadField(UserTime));
  297. EXIT_API();
  298. return S_OK;
  299. }
  300. VOID
  301. DumpPcrX86(
  302. ULONG64 pPcr
  303. )
  304. {
  305. ULONG ListHeadOff;
  306. PROCESSORINFO pi;
  307. ULONG Result;
  308. ULONG64 Prcb, DpcFlink;
  309. InitTypeRead(pPcr, nt!_KPCR);
  310. //
  311. // Print out the PCR
  312. //
  313. dprintf("\tNtTib.ExceptionList: %08lx\n", (ULONG) ReadField(NtTib.ExceptionList));
  314. dprintf("\t NtTib.StackBase: %08lx\n", (ULONG) ReadField(NtTib.StackBase));
  315. dprintf("\t NtTib.StackLimit: %08lx\n", (ULONG) ReadField(NtTib.StackLimit));
  316. dprintf("\t NtTib.SubSystemTib: %08lx\n", (ULONG) ReadField(NtTib.SubSystemTib));
  317. dprintf("\t NtTib.Version: %08lx\n", (ULONG) ReadField(NtTib.Version));
  318. dprintf("\t NtTib.UserPointer: %08lx\n", (ULONG) ReadField(NtTib.ArbitraryUserPointer));
  319. dprintf("\t NtTib.SelfTib: %08lx\n", (ULONG) ReadField(NtTib.Self));
  320. dprintf("\n");
  321. dprintf("\t SelfPcr: %08lx\n", (ULONG) ReadField(SelfPcr));
  322. dprintf("\t Prcb: %08lx\n", (ULONG) ReadField(Prcb));
  323. dprintf("\t Irql: %08lx\n", (ULONG) ReadField(Irql));
  324. dprintf("\t IRR: %08lx\n", (ULONG) ReadField(IRR));
  325. dprintf("\t IDR: %08lx\n", (ULONG) ReadField(IDR));
  326. dprintf("\t InterruptMode: %08lx\n", (ULONG) ReadField(InterruptMode));
  327. dprintf("\t IDT: %08lx\n", (ULONG) ReadField(IDT));
  328. dprintf("\t GDT: %08lx\n", (ULONG) ReadField(GDT));
  329. dprintf("\t TSS: %08lx\n", (ULONG) ReadField(TSS));
  330. dprintf("\n");
  331. dprintf("\t CurrentThread: %08lx\n", (ULONG) ReadField(PrcbData.CurrentThread));
  332. dprintf("\t NextThread: %08lx\n", (ULONG) ReadField(PrcbData.NextThread));
  333. dprintf("\t IdleThread: %08lx\n", (ULONG) ReadField(PrcbData.IdleThread));
  334. GetKdContext( &pi );
  335. dprintf("\n");
  336. dprintf( "\t DpcQueue: ");
  337. DpcFlink = ReadField(PrcbData.DpcListHead.Flink);
  338. GetFieldOffset("nt!_KPRCB", "DpcListHead", &ListHeadOff);
  339. Prcb = ReadField(Prcb);
  340. while (DpcFlink != (Prcb + ListHeadOff )) {
  341. CHAR Name[0x100];
  342. ULONG64 Displacement, DeferredRoutine;
  343. Name[0] = 0;
  344. dprintf(" 0x%p ", (DpcFlink) - 4 );
  345. if (GetFieldValue( DpcFlink - 4, "nt!_KDPC", "DeferredRoutine", DeferredRoutine )) {
  346. dprintf( "Failed to read DPC at 0x%p\n", DpcFlink - 4 );
  347. break;
  348. }
  349. GetSymbol( DeferredRoutine, Name, &Displacement );
  350. dprintf("0x%p %s\n\t ", DeferredRoutine, Name );
  351. if (CheckControlC()) {
  352. break;
  353. }
  354. GetFieldValue( DpcFlink - 4, "nt!_KDPC", "DpcListEntry.Flink", DpcFlink);
  355. }
  356. dprintf("\n");
  357. }
  358. DECLARE_API( pcr )
  359. /*++
  360. Routine Description:
  361. Arguments:
  362. args -
  363. Return Value:
  364. None
  365. --*/
  366. {
  367. ULONG Processor = 0;
  368. ULONG64 Pkpcr;
  369. ULONG MajorVersion, Off;
  370. HRESULT Hr;
  371. INIT_API();
  372. if (!*args) {
  373. GetCurrentProcessor(Client, &Processor, NULL);
  374. } else {
  375. Processor = (ULONG) GetExpression(args);
  376. }
  377. Hr = g_ExtData->ReadProcessorSystemData(Processor,
  378. DEBUG_DATA_KPCR_OFFSET,
  379. &Pkpcr,
  380. sizeof(Pkpcr),
  381. NULL);
  382. if (Hr != S_OK)
  383. {
  384. dprintf("Cannot get PRCB address\n");
  385. return E_INVALIDARG;
  386. }
  387. if (GetFieldValue(Pkpcr, "nt!_KPCR", "MajorVersion", MajorVersion)) {
  388. dprintf("Unable to read the PCR at %p\n", Pkpcr);
  389. return E_INVALIDARG;
  390. }
  391. //
  392. // Print out some interesting fields
  393. //
  394. InitTypeRead(Pkpcr, nt!_KPCR);
  395. dprintf("KPCR for Processor %d at %08p:\n", Processor, Pkpcr);
  396. dprintf(" Major %d Minor %d\n",
  397. MajorVersion,
  398. (ULONG) ReadField(MinorVersion));
  399. switch (TargetMachine) {
  400. case IMAGE_FILE_MACHINE_I386:
  401. DumpPcrX86(Pkpcr);
  402. break;
  403. case IMAGE_FILE_MACHINE_IA64:
  404. dprintf("\n");
  405. dprintf("\t Prcb: %016I64X\n", ReadField(Prcb));
  406. dprintf("\t CurrentThread: %016I64X\n", ReadField(CurrentThread));
  407. dprintf("\t InitialStack: %016I64X\n", ReadField(InitialStack));
  408. dprintf("\t StackLimit: %016I64X\n", ReadField(StackLimit));
  409. dprintf("\t InitialBStore: %016I64X\n", ReadField(InitialBStore));
  410. dprintf("\t BStoreLimit: %016I64X\n", ReadField(BStoreLimit));
  411. dprintf("\t PanicStack: %016I64X\n", ReadField(PanicStack));
  412. dprintf("\t CurrentIrql: 0x%lx\n", (ULONG)ReadField(CurrentIrql));
  413. dprintf("\n");
  414. break;
  415. default:
  416. dprintf("Panic Stack %08p\n", ReadField(PanicStack));
  417. dprintf("Dpc Stack %08p\n", ReadField(DpcStack));
  418. dprintf("Irql addresses:\n");
  419. GetFieldOffset("KPCR", "IrqlMask", &Off);
  420. dprintf(" Mask %08p\n",Pkpcr + Off);
  421. GetFieldOffset("KPCR", "IrqlTable", &Off);
  422. dprintf(" Table %08p\n", Pkpcr + Off);
  423. GetFieldOffset("KPCR", "InterruptRoutine", &Off);
  424. dprintf(" Routine %08p\n", Pkpcr + Off);
  425. } /* switch */
  426. EXIT_API();
  427. return S_OK;
  428. }
  429. #define TYPE_NO_MATCH 0xFFFE
  430. #define IH_WITH_SYMBOLS TRUE
  431. #define IH_WITHOUT_SYMBOLS FALSE
  432. typedef struct _INTERRUPTION_MAP {
  433. ULONG Type;
  434. PCSTR Name;
  435. PCSTR OptionalField;
  436. } INTERRUPTION_MAP;
  437. static INTERRUPTION_MAP CodeToName[] = {
  438. 0x0, "VHPT FAULT", "IFA",
  439. 0x4, "ITLB FAULT", "IIPA",
  440. 0x8, "DTLB FAULT", "IFA",
  441. 0xc, "ALT ITLB FAULT", "IIPA",
  442. 0x10, "ALT DTLB FAULT", "IFA",
  443. 0x14, "DATA NESTED TLB", "IFA",
  444. 0x18, "INST KEY MISS", "IIPA",
  445. 0x1c, "DATA KEY MISS", "IFA",
  446. 0x20, "DIRTY BIT FAULT", "IFA",
  447. 0x24, "INST ACCESS BIT", "IIPA",
  448. 0x28, "DATA ACCESS BIT", "IFA",
  449. 0x2c, "BREAK INST FAULT", "IIM",
  450. 0x30, "EXTERNAL INTERRUPT", "IVR",
  451. 0x50, "PAGE NOT PRESENT", "IFA",
  452. 0x51, "KEY PERMISSION", "IFA",
  453. 0x52, "INST ACCESS RIGHT", "IIPA",
  454. 0x53, "DATA ACCESS RIGHT", "IFA",
  455. 0x54, "GENERAL EXCEPTION", "ISR",
  456. 0x55, "DISABLED FP FAULT", "ISR",
  457. 0x56, "NAT CONSUMPTION", "ISR",
  458. 0x57, "SPECULATION FAULT", "IIM",
  459. 0x59, "DEBUG FAULT", "ISR",
  460. 0x5a, "UNALIGNED REF", "IFA",
  461. 0x5b, "LOCKED DATA REF", "ISR",
  462. 0x5c, "FP FAULT", "ISR",
  463. 0x5d, "FP TRAP", "ISR",
  464. 0x5e, "LOWER PRIV TRAP", "IIPA",
  465. 0x5f, "TAKEN BRANCH TRAP", "IIPA",
  466. 0x60, "SINGLE STEP TRAP", "IIPA",
  467. 0x69, "IA32 EXCEPTION", "R0",
  468. 0x6a, "IA32 INTERCEPT", "R0",
  469. 0x6b, "IA32 INTERRUPT", "R0",
  470. 0x80, "KERNEL SYSCALL", "Num",
  471. 0x81, "USER SYSCALL", "Num",
  472. 0x90, "THREAD SWITCH", "OSP",
  473. 0x91, "PROCESS SWITCH", "OSP",
  474. TYPE_NO_MATCH, " ", "OPT"
  475. };
  476. #define DumpHistoryValidIIP( _IHistoryRecord ) \
  477. ( ((_IHistoryRecord).InterruptionType != 0x90 /* THREAD_SWITCH */) && \
  478. ((_IHistoryRecord).InterruptionType != 0x91 /* PROCESS_SWITCH */) )
  479. VOID
  480. DumpHistory(
  481. IHISTORY_RECORD History[],
  482. ULONG Count,
  483. BOOLEAN WithSymbols
  484. )
  485. {
  486. ULONG index;
  487. ULONG i;
  488. BOOL printed;
  489. dprintf("Total # of interruptions = %lu\n", Count);
  490. dprintf("Vector IIP IPSR ExtraField %s\n", WithSymbols ? " IIP Symbol" : "" );
  491. Count = (ULONG)(Count % MAX_NUMBER_OF_IHISTORY_RECORDS);
  492. for (index = 0; index < MAX_NUMBER_OF_IHISTORY_RECORDS; index++) {
  493. printed = FALSE;
  494. for (i = 0; i < sizeof(CodeToName)/sizeof(CodeToName[0]); i++) {
  495. if (History[Count].InterruptionType == CodeToName[i].Type) {
  496. CCHAR symbol[256];
  497. PCHAR s;
  498. ULONG64 displacement;
  499. ULONGLONG iip;
  500. iip = History[Count].IIP;
  501. s = "";
  502. if ( WithSymbols && DumpHistoryValidIIP( History[Count]) ) {
  503. symbol[0] = '!';
  504. GetSymbol( iip, symbol, &displacement);
  505. s = (PCHAR)symbol + strlen( (PCHAR)symbol );
  506. if (s == (PCHAR)symbol ) {
  507. // sprintf( s, (IsPtr64() ? "0x%I64x" : "0x%08x"), iip );
  508. sprintf( s, "0x%016I64x", iip );
  509. }
  510. else {
  511. if ( displacement ) {
  512. // sprintf( s, (IsPtr64() ? "+0x%016I64x" : "+0x%08x"), displacement );
  513. sprintf( s, "+0x%I64x", displacement );
  514. }
  515. }
  516. s = symbol;
  517. }
  518. dprintf( "%18s %16I64x %16I64x %s= %16I64x %s\n",
  519. CodeToName[i].Name,
  520. iip,
  521. History[Count].IPSR,
  522. CodeToName[i].OptionalField,
  523. History[Count].Extra0,
  524. s
  525. );
  526. printed = TRUE;
  527. break;
  528. }
  529. }
  530. if ( !printed ) {
  531. dprintf("VECTOR 0x%lx - unknown for !ih...\n", History[Count].InterruptionType);
  532. }
  533. Count++;
  534. if (Count == MAX_NUMBER_OF_IHISTORY_RECORDS) Count = 0;
  535. }
  536. return;
  537. } // DumpHistory
  538. HRESULT DoIH(
  539. PDEBUG_CLIENT Client,
  540. PCSTR args,
  541. BOOLEAN WithSymbols
  542. )
  543. /*++
  544. Routine Description:
  545. WorkHorse function to dump processors interrupt history records
  546. Arguments:
  547. Client - debug engine interface client
  548. args - the processor number ( default is the current )
  549. WithSymbols - BOOLEAN to specify with or without the IIP Symbols
  550. Return Value:
  551. HRESULT
  552. --*/
  553. {
  554. ULONG processor;
  555. ULONG interruptionCount;
  556. ULONG64 pcrAddress;
  557. HRESULT Hr;
  558. //
  559. // This extension is IA64 specific...
  560. //
  561. if ( TargetMachine != IMAGE_FILE_MACHINE_IA64 )
  562. {
  563. dprintf("ih: IA64 specific extension...\n");
  564. return E_INVALIDARG;
  565. }
  566. INIT_API();
  567. GetCurrentProcessor(Client, &processor, NULL);
  568. if ( *args )
  569. {
  570. processor = (ULONG)GetExpression( args );
  571. }
  572. Hr = g_ExtData->ReadProcessorSystemData(processor,
  573. DEBUG_DATA_KPCR_OFFSET,
  574. &pcrAddress,
  575. sizeof(pcrAddress),
  576. NULL);
  577. if (Hr != S_OK)
  578. {
  579. dprintf("ih: Cannot get PCR address\n");
  580. }
  581. else
  582. {
  583. if (GetFieldValue( pcrAddress, "NT!_KPCR", "InterruptionCount", interruptionCount ) )
  584. {
  585. dprintf("ih: failed to read KPCR for processor %lu\n", processor);
  586. Hr = E_INVALIDARG;
  587. }
  588. else
  589. {
  590. //
  591. // Read and display Interrupt history
  592. //
  593. ULONG result;
  594. IHISTORY_RECORD history[MAX_NUMBER_OF_IHISTORY_RECORDS];
  595. if (!ReadMemory(pcrAddress+0x1000,
  596. (PVOID)history,
  597. sizeof(history),
  598. &result))
  599. {
  600. dprintf("ih: unable to read interrupt history records at %p - result=%lu\n",
  601. pcrAddress + 0x1000, result);
  602. Hr = E_INVALIDARG;
  603. }
  604. else
  605. {
  606. DumpHistory(history, interruptionCount, WithSymbols);
  607. }
  608. }
  609. }
  610. EXIT_API();
  611. return Hr;
  612. } // DoIH()
  613. DECLARE_API( ihs )
  614. /*++
  615. Routine Description:
  616. Dumps the interrupt history records with IIP symbols
  617. Arguments:
  618. args - the processor number ( default is current processor )
  619. Return Value:
  620. None
  621. --*/
  622. {
  623. return( DoIH( Client, args, IH_WITH_SYMBOLS ) );
  624. } // !ihs
  625. DECLARE_API( ih )
  626. /*++
  627. Routine Description:
  628. Dumps the interrupt history records
  629. Arguments:
  630. args - the processor number ( default is current processor )
  631. Return Value:
  632. None
  633. --*/
  634. {
  635. return( DoIH( Client, args, IH_WITHOUT_SYMBOLS ) );
  636. } // !ih
  637. VOID
  638. DumpBTHistory(
  639. ULONGLONG Bth[], // Branch Trace record
  640. ULONG64 BthAddress, // BTH Virtual Address
  641. ULONG MaxBtrNumber // Maximum number of records
  642. )
  643. {
  644. ULONG rec;
  645. dprintf( "BTH @ 0x%I64x:\n"
  646. " b mp slot address symbol\n"
  647. , BthAddress);
  648. for ( rec = 0; rec < (MaxBtrNumber - 1) ; rec++ ) {
  649. DisplayBtbPmdIA64( " ", Bth[rec], DISPLAY_MIN );
  650. }
  651. DisplayBtbIndexPmdIA64( "BTB Index: ", Bth[rec], DISPLAY_MIN );
  652. return;
  653. } // DumpBTHistory()
  654. DECLARE_API( bth )
  655. /*++
  656. Routine Description:
  657. Dumps the IA-64 branch trace buffer saved in _KPCR.
  658. The '!btb' extension dumps the processor branch trace buffer configuration and trace registers.
  659. Arguments:
  660. args - the processor number ( default is the current processor )
  661. Return Value:
  662. None
  663. --*/
  664. {
  665. ULONG processor;
  666. ULONG interruptionCount;
  667. ULONG64 pcrAddress;
  668. HRESULT Hr;
  669. //
  670. // This extension is IA64 specific...
  671. //
  672. if ( TargetMachine != IMAGE_FILE_MACHINE_IA64 )
  673. {
  674. dprintf("ih: IA64 specific extension...\n");
  675. return E_INVALIDARG;
  676. }
  677. INIT_API();
  678. GetCurrentProcessor(Client, &processor, NULL);
  679. if ( *args )
  680. {
  681. processor = (ULONG)GetExpression( args );
  682. }
  683. Hr = g_ExtData->ReadProcessorSystemData(processor,
  684. DEBUG_DATA_KPCR_OFFSET,
  685. &pcrAddress,
  686. sizeof(pcrAddress),
  687. NULL);
  688. if (Hr != S_OK)
  689. {
  690. dprintf("Cannot get PCR address\n");
  691. }
  692. else
  693. {
  694. ULONG pcrSize;
  695. pcrSize = GetTypeSize("nt!_KPCR");
  696. if ( pcrSize == 0 ) {
  697. dprintf( "bth: failed to get _KPCR size\n" );
  698. Hr = E_FAIL;
  699. }
  700. else {
  701. ULONG result;
  702. ULONG64 bthAddress;
  703. ULONGLONG bth[MAX_NUMBER_OF_BTBHISTORY_RECORDS];
  704. pcrSize = ROUND_UP( pcrSize, 16 );
  705. bthAddress = pcrAddress + (ULONG64)pcrSize;
  706. if ( !ReadMemory( bthAddress, bth, sizeof(bth), &result ) ) {
  707. dprintf( "bth: unable to read branch trace history records at %p - result=%lu\n",
  708. bthAddress, result);
  709. Hr = E_FAIL;
  710. }
  711. else {
  712. DumpBTHistory( bth, bthAddress, (ULONG)(sizeof(bth)/sizeof(bth[0])) );
  713. }
  714. }
  715. }
  716. EXIT_API();
  717. return Hr;
  718. } // !bth
  719. DECLARE_API( btb )
  720. /*++
  721. Routine Description:
  722. Dumps the IA-64 branch trace buffer.
  723. Arguments:
  724. args - the processor number ( default is the current processor )
  725. Return Value:
  726. None
  727. --*/
  728. {
  729. ULONG processor;
  730. ULONG interruptionCount;
  731. ULONG64 pcrAddress;
  732. ULONG64 msr;
  733. ULONG reg;
  734. HRESULT Hr = S_OK;
  735. //
  736. // This extension is IA64 specific...
  737. //
  738. if ( TargetMachine != IMAGE_FILE_MACHINE_IA64 )
  739. {
  740. dprintf("ih: IA64 specific extension...\n");
  741. return E_INVALIDARG;
  742. }
  743. INIT_API();
  744. GetCurrentProcessor(Client, &processor, NULL);
  745. dprintf("BTB for processor %ld:\n"
  746. " b mp slot address symbol\n"
  747. , processor);
  748. // Thierry 11/20/2000 - FIXFIX - This is Itanium specific. Should be using PMD[] but
  749. // not currently collected in _KSPECIAL_REGISTERS.
  750. for ( reg = 0; reg < 8; reg++) {
  751. msr = 0;
  752. ReadMsr( 680 + reg, &msr );
  753. DisplayBtbPmdIA64( " ", msr, DISPLAY_MIN );
  754. }
  755. EXIT_API();
  756. return Hr;
  757. } // !btb
  758. DECLARE_API( idt )
  759. {
  760. ULONG64 Pkpcr;
  761. ULONG64 Address;
  762. ULONG64 IdtAddress;
  763. ULONG DispatchCodeOffset;
  764. ULONG ListEntryOffset;
  765. UCHAR currentIdt, endIdt;
  766. ULONG64 displacement;
  767. ULONG64 unexpectedStart, unexpectedEnd;
  768. BOOLEAN argsPresent = FALSE;
  769. ULONG64 firstIntObj;
  770. ULONG64 flink;
  771. ULONG idtEntrySize;
  772. CHAR buffer[100];
  773. ULONG processor;
  774. ULONG idtChainCount;
  775. HRESULT Hr;
  776. USHORT interruptObjectType;
  777. if ( TargetMachine != IMAGE_FILE_MACHINE_I386 &&
  778. TargetMachine != IMAGE_FILE_MACHINE_AMD64 ) {
  779. dprintf("Unsupported platform\n");
  780. if ( TargetMachine == IMAGE_FILE_MACHINE_IA64 ) {
  781. dprintf("Use !ivt on IA64\n");
  782. }
  783. return E_INVALIDARG;
  784. }
  785. INIT_API();
  786. GetCurrentProcessor(Client, &processor, NULL);
  787. Hr = g_ExtData->ReadProcessorSystemData(processor,
  788. DEBUG_DATA_KPCR_OFFSET,
  789. &Pkpcr,
  790. sizeof(Pkpcr),
  791. NULL);
  792. EXIT_API();
  793. if (Hr != S_OK)
  794. {
  795. dprintf("Cannot get PCR address\n");
  796. return E_INVALIDARG;
  797. }
  798. if (argsPresent = strlen(args) ? TRUE : FALSE) {
  799. currentIdt = endIdt = (UCHAR)strtoul(args, NULL, 16);
  800. } else {
  801. if (TargetMachine == IMAGE_FILE_MACHINE_AMD64) {
  802. currentIdt = 0;
  803. } else {
  804. currentIdt = 0x30;
  805. }
  806. endIdt = 0xfe;
  807. }
  808. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  809. unexpectedStart = GetExpression("nt!KiStartUnexpectedRange");
  810. unexpectedEnd = GetExpression("nt!KiEndUnexpectedRange");
  811. } else if (TargetMachine == IMAGE_FILE_MACHINE_AMD64) {
  812. unexpectedStart = GetExpression("nt!KxUnexpectedInterrupt1");
  813. unexpectedEnd = GetExpression("nt!KxUnexpectedInterrupt255");
  814. }
  815. if (!unexpectedStart || !unexpectedEnd) {
  816. dprintf("\n\nCan't read kernel symbols.\n");
  817. return E_INVALIDARG;
  818. }
  819. dprintf("\nDumping IDT:\n\n");
  820. //
  821. // Find the offset of the Dispatch Code in the
  822. // interrupt object, so that we can simulate
  823. // a "CONTAINING_RECORD" later.
  824. //
  825. GetFieldOffset("nt!_KINTERRUPT", "DispatchCode", &DispatchCodeOffset);
  826. GetFieldOffset("nt!_KINTERRUPT", "InterruptListEntry", &ListEntryOffset);
  827. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  828. idtEntrySize = GetTypeSize("nt!_KIDTENTRY");
  829. } else if (TargetMachine == IMAGE_FILE_MACHINE_AMD64) {
  830. idtEntrySize = GetTypeSize("nt!_KIDTENTRY64");
  831. }
  832. interruptObjectType = (USHORT)GetExpression("val nt!InterruptObject");
  833. InitTypeRead(Pkpcr, nt!_KPCR);
  834. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  835. IdtAddress = ReadField(IDT);
  836. } else if (TargetMachine == IMAGE_FILE_MACHINE_AMD64) {
  837. IdtAddress = ReadField(IdtBase);
  838. }
  839. for (; currentIdt <= endIdt; currentIdt++) {
  840. Address = (ULONG64)(IdtAddress + (currentIdt * idtEntrySize));
  841. if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
  842. InitTypeRead(Address, nt!_KIDTENTRY);
  843. Address = ReadField(ExtendedOffset) & 0xFFFFFFFF;
  844. Address <<= 16;
  845. Address |= ReadField(Offset) & 0xFFFF;
  846. Address |= 0xFFFFFFFF00000000;
  847. } else if (TargetMachine == IMAGE_FILE_MACHINE_AMD64) {
  848. InitTypeRead(Address, nt!_KIDTENTRY64);
  849. Address = ReadField(OffsetHigh) & 0xFFFFFFFF;
  850. Address <<= 16;
  851. Address |= ReadField(OffsetMiddle) & 0xFFFF;
  852. Address <<= 16;
  853. Address |= ReadField(OffsetLow) & 0xFFFF;
  854. }
  855. if (Address >= unexpectedStart && Address <= unexpectedEnd) {
  856. //
  857. // IDT entry contains "unexpected interrupt." This
  858. // means that this vector isn't interesting.
  859. //
  860. if (argsPresent) {
  861. //
  862. // The user was specifying a specific vector.
  863. //
  864. dprintf("Vector %x not connected\n", currentIdt);
  865. }
  866. continue;
  867. }
  868. dprintf("\n%x:\n", currentIdt);
  869. //
  870. // Work backwards from the code to the containing interrupt
  871. // object.
  872. //
  873. Address -= DispatchCodeOffset;
  874. firstIntObj = Address;
  875. idtChainCount = 0;
  876. InitTypeRead(Address, nt!_KINTERRUPT);
  877. if (ReadField(Type) != interruptObjectType)
  878. {
  879. GetSymbol(Address + DispatchCodeOffset, buffer, &displacement);
  880. if (buffer[0] != '\0') {
  881. if (displacement != 0) {
  882. dprintf("\t%s+0x%I64X\n", buffer, displacement);
  883. } else {
  884. dprintf("\t%s\n", buffer);
  885. }
  886. } else {
  887. dprintf("\t%I64X\n", Address + DispatchCodeOffset);
  888. }
  889. continue;
  890. }
  891. while (TRUE) {
  892. GetSymbol(ReadField(ServiceRoutine), buffer, &displacement);
  893. if (buffer[0] != '\0') {
  894. if (displacement != 0) {
  895. dprintf("\t%s+0x%I64X (%I64X)\n", buffer, displacement, Address);
  896. } else {
  897. dprintf("\t%s (%I64X)\n", buffer, Address);
  898. }
  899. } else {
  900. dprintf("\t%I64X (%I64X)\n", ReadField(ServiceRoutine), Address);
  901. }
  902. InitTypeRead(ListEntryOffset + Address, nt!_LIST_ENTRY);
  903. flink = ReadField(Flink);
  904. if (flink == 0 ||
  905. flink == (firstIntObj + ListEntryOffset)) {
  906. break;
  907. }
  908. Address = flink - ListEntryOffset;
  909. InitTypeRead(Address, nt!_KINTERRUPT);
  910. if (CheckControlC()) {
  911. break;
  912. }
  913. if (idtChainCount++ > 50) {
  914. //
  915. // We are clearly going nowhere.
  916. //
  917. break;
  918. }
  919. }
  920. }
  921. dprintf("\n");
  922. return S_OK;
  923. }
  924. DECLARE_API( ivt )
  925. {
  926. ULONG64 Pkpcr;
  927. ULONG64 Address;
  928. ULONG64 idtEntry;
  929. ULONG DispatchCodeOffset;
  930. ULONG ListEntryOffset;
  931. ULONG InterruptRoutineOffset;
  932. ULONG64 unexpectedInterrupt;
  933. ULONG64 chainedDispatch;
  934. ULONG64 currentInterruptAddress;
  935. ULONG64 PcrInterruptRoutineAddress;
  936. ULONG currentIdt, endIdt;
  937. BOOLEAN argsPresent = FALSE;
  938. ULONG64 firstIntObj;
  939. ULONG idtEntrySize;
  940. CHAR buffer[100];
  941. ULONG processor;
  942. ULONG idtChainCount;
  943. HRESULT Hr;
  944. ULONG64 displacement;
  945. ULONG result;
  946. USHORT interruptObjectType;
  947. if ( IMAGE_FILE_MACHINE_IA64 != TargetMachine) {
  948. dprintf("Don't know how to dump the IVT on anything but IA64, use !idt on x86\n");
  949. return E_INVALIDARG;
  950. }
  951. INIT_API();
  952. GetCurrentProcessor(Client, &processor, NULL);
  953. Hr = g_ExtData->ReadProcessorSystemData(processor,
  954. DEBUG_DATA_KPCR_OFFSET,
  955. &Pkpcr,
  956. sizeof(Pkpcr),
  957. NULL);
  958. EXIT_API();
  959. if (Hr != S_OK)
  960. {
  961. dprintf("Cannot get PCR address\n");
  962. return E_INVALIDARG;
  963. }
  964. unexpectedInterrupt = GetExpression("nt!KxUnexpectedInterrupt");
  965. if (unexpectedInterrupt == 0) {
  966. dprintf("\n\nCan't read kernel symbols.\n");
  967. return E_INVALIDARG;
  968. }
  969. chainedDispatch = GetExpression("nt!KiChainedDispatch");
  970. interruptObjectType = (USHORT)GetExpression("val nt!InterruptObject");
  971. GetFieldOffset("nt!_KINTERRUPT", "DispatchCode", &DispatchCodeOffset);
  972. GetFieldOffset("nt!_KINTERRUPT", "InterruptListEntry", &ListEntryOffset);
  973. GetFieldOffset("nt!_KPCR", "InterruptRoutine", &InterruptRoutineOffset);
  974. unexpectedInterrupt += DispatchCodeOffset;
  975. idtEntrySize = GetTypeSize("nt!PKINTERRUPT_ROUTINE");
  976. if (argsPresent = strlen(args) ? TRUE : FALSE) {
  977. currentIdt = endIdt = strtoul(args, NULL, 16);
  978. if (currentIdt >= MAXIMUM_IA64_VECTOR) {
  979. dprintf("\n\nInvalid argument \"%s\", maximum vector = %d\n", args, MAXIMUM_IA64_VECTOR);
  980. return E_INVALIDARG;
  981. }
  982. } else {
  983. currentIdt = 0;
  984. endIdt = MAXIMUM_IA64_VECTOR - 1;
  985. }
  986. dprintf("\nDumping IA64 IVT:\n\n");
  987. PcrInterruptRoutineAddress = Pkpcr + InterruptRoutineOffset;
  988. for (; currentIdt <= endIdt; currentIdt++) {
  989. Address = (ULONG64)(PcrInterruptRoutineAddress + (currentIdt * idtEntrySize));
  990. if (!ReadMemory(Address, &idtEntry, sizeof(idtEntry), &result)) {
  991. dprintf( "Can't read entry for vector %02X at %p - result=%lu\n",
  992. currentIdt, Address, result);
  993. break;
  994. }
  995. Address = idtEntry;
  996. if (Address == unexpectedInterrupt) {
  997. //
  998. // IDT entry contains "unexpected interrupt." This
  999. // means that this vector isn't interesting.
  1000. //
  1001. if (argsPresent) {
  1002. //
  1003. // The user was specifying a specific vector.
  1004. //
  1005. dprintf("Vector %x not connected\n", currentIdt);
  1006. }
  1007. continue;
  1008. }
  1009. dprintf("\n%x:\n", currentIdt);
  1010. //
  1011. // Work backwards from the code to the containing interrupt
  1012. // object.
  1013. //
  1014. Address -= DispatchCodeOffset;
  1015. firstIntObj = Address;
  1016. idtChainCount = 0;
  1017. InitTypeRead(Address, nt!_KINTERRUPT);
  1018. if (ReadField(Type) != interruptObjectType)
  1019. {
  1020. GetSymbol(Address + DispatchCodeOffset, buffer, &displacement);
  1021. if (buffer[0] != '\0') {
  1022. if (displacement != 0) {
  1023. dprintf("\t%s+0x%I64X\n", buffer, displacement);
  1024. } else {
  1025. dprintf("\t%s\n", buffer);
  1026. }
  1027. } else {
  1028. dprintf("\t%p\n", Address + DispatchCodeOffset);
  1029. }
  1030. continue;
  1031. }
  1032. while (TRUE) {
  1033. GetSymbol(ReadField(ServiceRoutine), buffer, &displacement);
  1034. if (buffer[0] != '\0') {
  1035. if (displacement != 0) {
  1036. dprintf("\t%s+0x%I64X (%p)\n", buffer, displacement, Address);
  1037. } else {
  1038. dprintf("\t%s (%p)\n", buffer, Address);
  1039. }
  1040. } else {
  1041. dprintf("\t%p (%p)\n", ReadField(ServiceRoutine), Address);
  1042. }
  1043. if (ReadField(DispatchAddress) != chainedDispatch) {
  1044. break;
  1045. }
  1046. InitTypeRead(ListEntryOffset + Address, nt!_LIST_ENTRY);
  1047. if (ReadField(Flink) == (firstIntObj + ListEntryOffset)) {
  1048. break;
  1049. }
  1050. Address = ReadField(Flink) - ListEntryOffset;
  1051. InitTypeRead(Address, nt!_KINTERRUPT);
  1052. if (CheckControlC()) {
  1053. break;
  1054. }
  1055. if (idtChainCount++ > 50) {
  1056. //
  1057. // We are clearly going nowhere.
  1058. //
  1059. break;
  1060. }
  1061. }
  1062. }
  1063. dprintf("\n");
  1064. return S_OK;
  1065. }
  1066. //
  1067. // MCA MSR architecture definitions
  1068. //
  1069. //
  1070. // MSR addresses for Pentium Style Machine Check Exception
  1071. //
  1072. #define MCE_MSR_MC_ADDR 0x0
  1073. #define MCE_MSR_MC_TYPE 0x1
  1074. //
  1075. // MSR addresses for Pentium Pro Style Machine Check Architecture
  1076. //
  1077. //
  1078. // Global capability, status and control register addresses
  1079. //
  1080. #define MCA_MSR_MCG_CAP 0x179
  1081. #define MCA_MSR_MCG_STATUS 0x17a
  1082. #define MCA_MSR_MCG_CTL 0x17b
  1083. #define MCA_MSR_MCG_EAX 0x180
  1084. #define MCA_MSR_MCG_EFLAGS 0x188
  1085. #define MCA_MSR_MCG_EIP 0x189
  1086. //
  1087. // Control, Status, Address, and Misc register address for
  1088. // bank 0. Other bank registers are at a stride of MCA_NUM_REGS
  1089. // from corresponding bank 0 register.
  1090. //
  1091. #define MCA_NUM_REGS 4
  1092. #define MCA_MSR_MC0_CTL 0x400
  1093. #define MCA_MSR_MC0_STATUS 0x401
  1094. #define MCA_MSR_MC0_ADDR 0x402
  1095. #define MCA_MSR_MC0_MISC 0x403
  1096. //
  1097. // Flags used to determine if the MCE or MCA feature is
  1098. // available. Used with HalpFeatureBits.
  1099. //
  1100. #define HAL_MCA_PRESENT 0x4
  1101. #define HAL_MCE_PRESENT 0x8
  1102. //
  1103. // Flags to decode errors in MCI_STATUS register of MCA banks
  1104. //
  1105. #define MCA_EC_NO_ERROR 0x0000
  1106. #define MCA_EC_UNCLASSIFIED 0x0001
  1107. #define MCA_EC_ROMPARITY 0x0002
  1108. #define MCA_EC_EXTERN 0x0003
  1109. #define MCA_EC_FRC 0x0004
  1110. #include "pshpack1.h"
  1111. //
  1112. // Global Machine Check Capability Register
  1113. //
  1114. typedef struct _MCA_MCG_CAPABILITY {
  1115. union {
  1116. struct {
  1117. ULONG McaCnt:8;
  1118. ULONG McaCntlPresent:1;
  1119. ULONG McaExtPresent:1;
  1120. ULONG Reserved_1: 6;
  1121. ULONG McaExtCnt: 8;
  1122. ULONG Reserved_2: 8;
  1123. ULONG Reserved_3;
  1124. } hw;
  1125. ULONGLONG QuadPart;
  1126. } u;
  1127. } MCA_MCG_CAPABILITY, *PMCA_MCG_CAPABILITY;
  1128. //
  1129. // Global Machine Check Status Register
  1130. //
  1131. typedef struct _MCA_MCG_STATUS {
  1132. union {
  1133. struct {
  1134. ULONG RestartIPValid:1;
  1135. ULONG ErrorIPValid:1;
  1136. ULONG McCheckInProgress:1;
  1137. ULONG Reserved_1:29;
  1138. ULONG Reserved_2;
  1139. } hw;
  1140. ULONGLONG QuadPart;
  1141. } u;
  1142. } MCA_MCG_STATUS, *PMCA_MCG_STATUS;
  1143. //
  1144. // MCA COD field in status register for interpreting errors
  1145. //
  1146. typedef struct _MCA_COD {
  1147. union {
  1148. struct {
  1149. USHORT Level:2;
  1150. USHORT Type:2;
  1151. USHORT Request:4;
  1152. USHORT BusErrInfo:4;
  1153. USHORT Other:4;
  1154. } hw;
  1155. USHORT ShortPart;
  1156. } u;
  1157. } MCA_COD, *PMCA_COD;
  1158. //
  1159. // STATUS register for each MCA bank.
  1160. //
  1161. typedef struct _MCA_MCI_STATUS {
  1162. union {
  1163. struct {
  1164. MCA_COD McaCod;
  1165. USHORT MsCod;
  1166. ULONG OtherInfo:25;
  1167. ULONG Damage:1;
  1168. ULONG AddressValid:1;
  1169. ULONG MiscValid:1;
  1170. ULONG Enabled:1;
  1171. ULONG UnCorrected:1;
  1172. ULONG OverFlow:1;
  1173. ULONG Valid:1;
  1174. } hw;
  1175. ULONGLONG QuadPart;
  1176. } u;
  1177. } MCA_MCI_STATUS, *PMCA_MCI_STATUS;
  1178. //
  1179. // ADDR register for each MCA bank
  1180. //
  1181. typedef struct _MCA_MCI_ADDR{
  1182. union {
  1183. struct {
  1184. ULONG Address;
  1185. ULONG Reserved;
  1186. } hw;
  1187. ULONGLONG QuadPart;
  1188. } u;
  1189. } MCA_MCI_ADDR, *PMCA_MCI_ADDR;
  1190. #include "poppack.h"
  1191. //
  1192. // Machine Check Error Description
  1193. //
  1194. // Any Reserved/Generic entry
  1195. CHAR Reserved[] = "Reserved";
  1196. CHAR Generic[] = "Generic";
  1197. // Transaction Types
  1198. CHAR TransInstruction[] = "Instruction";
  1199. CHAR TransData[] = "Data";
  1200. static CHAR *TransType[] = {TransInstruction,
  1201. TransData,
  1202. Generic,
  1203. Reserved
  1204. };
  1205. // Level Encodings
  1206. CHAR Level0[] = "Level 0";
  1207. CHAR Level1[] = "Level 1";
  1208. CHAR Level2[] = "Level 2";
  1209. static CHAR *Level[] = {
  1210. Level0,
  1211. Level1,
  1212. Level2,
  1213. Generic
  1214. };
  1215. // Request Encodings
  1216. CHAR ReqGenericRead[] = "Generic Read";
  1217. CHAR ReqGenericWrite[] = "Generic Write";
  1218. CHAR ReqDataRead[] = "Data Read";
  1219. CHAR ReqDataWrite[] = "Data Write";
  1220. CHAR ReqInstrFetch[] = "Instruction Fetch";
  1221. CHAR ReqPrefetch[] = "Prefetch";
  1222. CHAR ReqEviction[] = "Eviction";
  1223. CHAR ReqSnoop[] = "Snoop";
  1224. static CHAR *Request[] = {
  1225. Generic,
  1226. ReqGenericRead,
  1227. ReqGenericWrite,
  1228. ReqDataRead,
  1229. ReqDataWrite,
  1230. ReqInstrFetch,
  1231. ReqPrefetch,
  1232. ReqEviction,
  1233. ReqSnoop,
  1234. Reserved,
  1235. Reserved,
  1236. Reserved,
  1237. Reserved,
  1238. Reserved,
  1239. Reserved,
  1240. Reserved
  1241. };
  1242. // Memory Hierarchy Error Encodings
  1243. CHAR MemHierMemAccess[] = "Memory Access";
  1244. CHAR MemHierIO[] = "I/O";
  1245. CHAR MemHierOther[] = "Other Transaction";
  1246. static CHAR *MemoryHierarchy[] = {
  1247. MemHierMemAccess,
  1248. Reserved,
  1249. MemHierIO,
  1250. MemHierOther
  1251. };
  1252. // Time Out Status
  1253. CHAR TimeOut[] = "Timed Out";
  1254. CHAR NoTimeOut[] = "Did Not Time Out";
  1255. static CHAR *TimeOutCode[] = {
  1256. NoTimeOut,
  1257. TimeOut
  1258. };
  1259. // Participation Status
  1260. CHAR PartSource[] = "Source";
  1261. CHAR PartResponds[] = "Responds";
  1262. CHAR PartObserver[] = "Observer";
  1263. static CHAR *ParticipCode[] = {
  1264. PartSource,
  1265. PartResponds,
  1266. PartObserver,
  1267. Generic
  1268. };
  1269. //
  1270. // Register names for registers starting at MCA_MSR_MCG_EAX
  1271. //
  1272. char *RegNames[] = {
  1273. "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp",
  1274. "eflags", "eip", "misc"
  1275. };
  1276. VOID
  1277. DecodeError (
  1278. IN MCA_MCI_STATUS MciStatus
  1279. )
  1280. /*++
  1281. Routine Description:
  1282. Decode the machine check error logged to the status register
  1283. Model specific errors are not decoded.
  1284. Arguments:
  1285. MciStatus: Contents of Machine Check Status register
  1286. Return Value:
  1287. None
  1288. --*/
  1289. {
  1290. MCA_COD McaCod;
  1291. McaCod = MciStatus.u.hw.McaCod;
  1292. //
  1293. // Decode Errors: First identify simple errors and then
  1294. // handle compound errors as default case
  1295. //
  1296. switch(McaCod.u.ShortPart) {
  1297. case MCA_EC_NO_ERROR:
  1298. dprintf("\t\tNo Error\n");
  1299. break;
  1300. case MCA_EC_UNCLASSIFIED:
  1301. dprintf("\t\tUnclassified Error\n");
  1302. break;
  1303. case MCA_EC_ROMPARITY:
  1304. dprintf("\t\tMicrocode ROM Parity Error\n");
  1305. break;
  1306. case MCA_EC_EXTERN:
  1307. dprintf("\t\tExternal Error\n");
  1308. break;
  1309. case MCA_EC_FRC:
  1310. dprintf("\t\tFRC Error\n");
  1311. break;
  1312. default: // check for complex error conditions
  1313. if (McaCod.u.hw.BusErrInfo == 0x4) {
  1314. dprintf("\t\tInternal Unclassified Error\n");
  1315. } else if (McaCod.u.hw.BusErrInfo == 0) {
  1316. // TLB Unit Error
  1317. dprintf("\t\t%s TLB %s Error\n",
  1318. TransType[McaCod.u.hw.Type],
  1319. Level[McaCod.u.hw.Level]);
  1320. } else if (McaCod.u.hw.BusErrInfo == 1) {
  1321. // Memory Unit Error
  1322. dprintf("\t\t%s Cache %s %s Error\n",
  1323. TransType[McaCod.u.hw.Type],
  1324. Level[McaCod.u.hw.Level],
  1325. Request[McaCod.u.hw.Request]);
  1326. } else if (McaCod.u.hw.BusErrInfo >= 8) {
  1327. // Bus/Interconnect Error
  1328. dprintf("\t\tBus %s, Local Processor: %s, %s Error\n",
  1329. Level[McaCod.u.hw.Level],
  1330. ParticipCode[((McaCod.u.hw.BusErrInfo & 0x6)>>1)],
  1331. Request[McaCod.u.hw.Request]);
  1332. dprintf("%s Request %s\n",
  1333. MemoryHierarchy[McaCod.u.hw.Type],
  1334. TimeOutCode[McaCod.u.hw.BusErrInfo & 0x1]);
  1335. } else {
  1336. dprintf("\t\tUnresolved compound error code\n");
  1337. }
  1338. break;
  1339. }
  1340. }
  1341. HRESULT
  1342. McaX86(
  1343. PCSTR args
  1344. )
  1345. /*++
  1346. Routine Description:
  1347. Dumps X86 processors machine check architecture registers
  1348. and interprets any logged errors
  1349. Arguments:
  1350. args
  1351. Return Value:
  1352. HRESULT
  1353. --*/
  1354. {
  1355. MCA_MCG_CAPABILITY Capabilities;
  1356. MCA_MCG_STATUS McgStatus;
  1357. MCA_MCI_STATUS MciStatus;
  1358. MCA_MCI_ADDR MciAddress;
  1359. ULONGLONG MciControl;
  1360. ULONGLONG MciMisc;
  1361. ULONG Index,i;
  1362. PUCHAR p;
  1363. ULONG FeatureBits = 0;
  1364. ULONG Cr4Value;
  1365. BOOLEAN Cr4MCEnabled = FALSE;
  1366. BOOLEAN RegsValid = FALSE;
  1367. ULONGLONG MachineCheckAddress, MachineCheckType;
  1368. ULARGE_INTEGER RegValue;
  1369. //
  1370. // Quick sanity check for Machine Check availability.
  1371. // Support included for both Pentium Style MCE and Pentium
  1372. // Pro Style MCA.
  1373. //
  1374. i = (ULONG) GetExpression(args);
  1375. if (i != 1) {
  1376. i = (ULONG) GetExpression("hal!HalpFeatureBits");
  1377. if (!i) {
  1378. dprintf ("HalpFeatureBits not found\n");
  1379. return E_INVALIDARG;
  1380. }
  1381. FeatureBits = 0;
  1382. ReadMemory(i, &FeatureBits, sizeof(i), &i);
  1383. if (FeatureBits == -1 ||
  1384. (!(FeatureBits & HAL_MCA_PRESENT) &&
  1385. !(FeatureBits & HAL_MCE_PRESENT))) {
  1386. dprintf ("Machine Check feature not present\n");
  1387. return E_INVALIDARG;
  1388. }
  1389. }
  1390. //
  1391. // Read cr4 to determine if CR4.MCE is enabled.
  1392. // This enables the Machine Check exception reporting
  1393. //
  1394. Cr4Value = (ULONG) GetExpression("@Cr4");
  1395. if (Cr4Value & CR4_MCE_X86) {
  1396. Cr4MCEnabled = TRUE;
  1397. }
  1398. if (FeatureBits & HAL_MCE_PRESENT) {
  1399. // Read P5_MC_ADDR Register and P5_MC_TYPE Register
  1400. ReadMsr(MCE_MSR_MC_ADDR, &MachineCheckAddress);
  1401. ReadMsr(MCE_MSR_MC_TYPE, &MachineCheckType);
  1402. dprintf ("MCE: %s, Cycle Address: 0x%.8x%.8x, Type: 0x%.8x%.8x\n\n",
  1403. (Cr4MCEnabled ? "Enabled" : "Disabled"),
  1404. (ULONG)(MachineCheckAddress >> 32),
  1405. (ULONG)(MachineCheckAddress),
  1406. (ULONG)(MachineCheckType >> 32),
  1407. (ULONG)(MachineCheckType));
  1408. }
  1409. Capabilities.u.QuadPart = (ULONGLONG)0;
  1410. if (FeatureBits & HAL_MCA_PRESENT) {
  1411. //
  1412. // Dump MCA registers
  1413. //
  1414. ReadMsr(MCA_MSR_MCG_CAP, &Capabilities.u.QuadPart);
  1415. ReadMsr(MCA_MSR_MCG_STATUS, &McgStatus.u.QuadPart);
  1416. dprintf ("MCA: %s, Banks %d, Control Reg: %s, Machine Check: %s.\n",
  1417. (Cr4MCEnabled ? "Enabled" : "Disabled"),
  1418. Capabilities.u.hw.McaCnt,
  1419. Capabilities.u.hw.McaCntlPresent ? "Supported" : "Not Supported",
  1420. McgStatus.u.hw.McCheckInProgress ? "In Progress" : "None"
  1421. );
  1422. if (McgStatus.u.hw.McCheckInProgress && McgStatus.u.hw.ErrorIPValid) {
  1423. dprintf ("MCA: Error IP Valid\n");
  1424. }
  1425. if (McgStatus.u.hw.McCheckInProgress && McgStatus.u.hw.RestartIPValid) {
  1426. dprintf ("MCA: Restart IP Valid\n");
  1427. }
  1428. //
  1429. // Scan all the banks to check if any machines checks have been
  1430. // logged and decode the errors if any.
  1431. //
  1432. dprintf ("Bank Error Control Register Status Register\n");
  1433. for (Index=0; Index < (ULONG) Capabilities.u.hw.McaCnt; Index++) {
  1434. ReadMsr(MCA_MSR_MC0_CTL+MCA_NUM_REGS*Index, &MciControl);
  1435. ReadMsr(MCA_MSR_MC0_STATUS+MCA_NUM_REGS*Index, &MciStatus.u.QuadPart);
  1436. dprintf (" %2d. %s 0x%.8x%.8x 0x%.8x%.8x\n",
  1437. Index,
  1438. (MciStatus.u.hw.Valid ? "Valid" : "None "),
  1439. (ULONG) (MciControl >> 32),
  1440. (ULONG) (MciControl),
  1441. (ULONG) (MciStatus.u.QuadPart>>32),
  1442. (ULONG) (MciStatus.u.QuadPart)
  1443. );
  1444. if (MciStatus.u.hw.Valid) {
  1445. DecodeError(MciStatus);
  1446. }
  1447. if (MciStatus.u.hw.AddressValid) {
  1448. ReadMsr(MCA_MSR_MC0_ADDR+MCA_NUM_REGS*Index, &MciAddress.u.QuadPart);
  1449. dprintf ("\t\tAddress Reg 0x%.8x%.8x ",
  1450. (ULONG) (MciAddress.u.QuadPart>>32),
  1451. (ULONG) (MciAddress.u.QuadPart)
  1452. );
  1453. }
  1454. if (MciStatus.u.hw.MiscValid) {
  1455. ReadMsr(MCA_MSR_MC0_MISC+MCA_NUM_REGS*Index, &MciMisc);
  1456. dprintf ("\t\tMisc Reg 0x%.8x%.8x ",
  1457. (ULONG) (MciMisc >> 32),
  1458. (ULONG) (MciMisc)
  1459. );
  1460. }
  1461. dprintf("\n");
  1462. }
  1463. }
  1464. if (Capabilities.u.hw.McaExtPresent && Capabilities.u.hw.McaExtCnt) {
  1465. dprintf ("Registers Saved: %d.", Capabilities.u.hw.McaExtCnt);
  1466. RegsValid = FALSE;
  1467. for (i = 0; i < Capabilities.u.hw.McaExtCnt; i++) {
  1468. if (i % 2 == 0) {
  1469. dprintf("\n");
  1470. }
  1471. ReadMsr(MCA_MSR_MCG_EAX+i, &RegValue.QuadPart);
  1472. if ((i == MCA_MSR_MCG_EFLAGS-MCA_MSR_MCG_EAX) && RegValue.LowPart) {
  1473. RegsValid = TRUE;
  1474. }
  1475. if (i < sizeof(RegNames)/sizeof(RegNames[0])) {
  1476. dprintf("%7s: 0x%08x 0x%08x", RegNames[i], RegValue.HighPart, RegValue.LowPart);
  1477. } else {
  1478. dprintf(" Reg%02d: 0x%08x 0x%08x", i, RegValue.HighPart, RegValue.LowPart);
  1479. }
  1480. }
  1481. dprintf("\n");
  1482. if (!RegsValid) {
  1483. dprintf("(Register state does not appear to be valid.)\n");
  1484. }
  1485. dprintf("\n");
  1486. } else {
  1487. dprintf("No register state available.\n\n");
  1488. }
  1489. return S_OK;
  1490. } // McaX86()
  1491. #define ERROR_RECORD_HEADER_FORMAT_IA64 \
  1492. "MCA Error Record Header @ 0x%I64x 0x%I64x\n" \
  1493. "\tId : 0x%I64x\n" \
  1494. "\tRevision : 0x%x\n" \
  1495. "\t\tMajor : %x\n" \
  1496. "\t\tMinor : %x\n" \
  1497. "\tSeverity : 0x%x [%s]\n" \
  1498. "\tValid : 0x%x\n" \
  1499. "\t\tPlatformId: %x\n" \
  1500. "\tLength : 0x%x\n" \
  1501. "\tTimeStamp : 0x%I64x\n" \
  1502. "\t\tSeconds: %x\n" \
  1503. "\t\tMinutes: %x\n" \
  1504. "\t\tHours : %x\n" \
  1505. "\t\tDay : %x\n" \
  1506. "\t\tMonth : %x\n" \
  1507. "\t\tYear : %x\n" \
  1508. "\t\tCentury: %x\n" \
  1509. "\tPlatformId: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n" \
  1510. "%s\n\n"
  1511. #define ERROR_SECTION_HEADER_FORMAT_IA64 \
  1512. "MCA Error Section Header @ 0x%I64x 0x%I64x\n" \
  1513. "\t%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X [%s]\n" \
  1514. "\tRevision : 0x%x\n" \
  1515. "\t\tMajor : %x\n" \
  1516. "\t\tMinor : %x\n" \
  1517. "\tRecoveryInfo: 0x%x\n" \
  1518. "\t\tCorrected : %x\n" \
  1519. "\t\tNotContained: %x\n" \
  1520. "\t\tReset : %x\n" \
  1521. "\t\tReserved : %x\n" \
  1522. "\t\tValid : %x\n" \
  1523. "\tReserved : 0x%x\n" \
  1524. "\tLength : 0x%x\n"
  1525. #define ERROR_PROCESSOR_FORMAT_IA64 \
  1526. "\tValid : 0x%I64x\n" \
  1527. "\t\tErrorMap : %x\n" \
  1528. "\t\tStateParameter : %x\n" \
  1529. "\t\tCRLid : %x\n" \
  1530. "\t\tStaticStruct : %x\n" \
  1531. "\t\tCacheCheckNum : %x\n" \
  1532. "\t\tTlbCheckNum : %x\n" \
  1533. "\t\tBusCheckNum : %x\n" \
  1534. "\t\tRegFileCheckNum : %x\n" \
  1535. "\t\tMsCheckNum : %x\n" \
  1536. "\t\tCpuIdInfo : %x\n" \
  1537. "\t\tReserved : %I64x\n"
  1538. #define ERROR_PROCESSOR_ERROR_MAP_FORMAT_IA64 \
  1539. "\tErrorMap : 0x%I64x\n" \
  1540. "\t\tCid : %x\n" \
  1541. "\t\tTid : %x\n" \
  1542. "\t\tEic : %x\n" \
  1543. "\t\tEdc : %x\n" \
  1544. "\t\tEit : %x\n" \
  1545. "\t\tEdt : %x\n" \
  1546. "\t\tEbh : %x\n" \
  1547. "\t\tErf : %x\n" \
  1548. "\t\tEms : %x\n" \
  1549. "\t\tReserved : %x\n"
  1550. #define ERROR_MODINFO_FORMAT_IA64 \
  1551. "\t%s[%ld]:\n" \
  1552. "\t\tValid : 0x%I64x\n" \
  1553. "\t\t\tCheckInfo : %x\n" \
  1554. "\t\t\tRequestorIdentifier: %x\n" \
  1555. "\t\t\tResponderIdentifier: %x\n" \
  1556. "\t\t\tTargetIdentifier : %x\n" \
  1557. "\t\t\tPreciseIP : %x\n" \
  1558. "\t\t\tReserved : %I64x\n" \
  1559. "\t\tCheckInfo : 0x%I64x\n" \
  1560. "\t\tRequestedId: 0x%I64x\n" \
  1561. "\t\tResponderId: 0x%I64x\n" \
  1562. "\t\tTargetId : 0x%I64x\n" \
  1563. "\t\tPreciseIP : 0x%I64x\n"
  1564. #define ERROR_PROCESSOR_CPUID_INFO_FORMAT_IA64 \
  1565. "\t\tCpuId0 : 0x%I64x\n" \
  1566. "\t\tCpuId1 : 0x%I64x\n" \
  1567. "\t\tCpuId2 : 0x%I64x\n" \
  1568. "\t\tCpuId3 : 0x%I64x\n" \
  1569. "\t\tCpuId4 : 0x%I64x\n" \
  1570. "\t\tReserved: 0x%I64x\n"
  1571. #define ERROR_PROCESSOR_STATIC_INFO_FORMAT_IA64 \
  1572. "\t\tValid : 0x%I64x\n" \
  1573. "\t\t\tMinState: %x\n" \
  1574. "\t\t\tBRs : %x\n" \
  1575. "\t\t\tCRs : %x\n" \
  1576. "\t\t\tARs : %x\n" \
  1577. "\t\t\tRRs : %x\n" \
  1578. "\t\t\tFRs : %x\n" \
  1579. "\t\t\tReserved: %I64x\n"
  1580. #define ERROR_PLATFORM_SPECIFIC_FORMAT_IA64 \
  1581. "\tValid : 0x%I64x\n" \
  1582. "\t\tErrorStatus : %x\n" \
  1583. "\t\tRequestorId : %x\n" \
  1584. "\t\tResponderId : %x\n" \
  1585. "\t\tTargetId : %x\n" \
  1586. "\t\tBusSpecificData : %x\n" \
  1587. "\t\tOemId : %x\n" \
  1588. "\t\tOemData : %x\n" \
  1589. "\t\tOemDevicePath : %x\n" \
  1590. "\t\tReserved : %I64x\n" \
  1591. "\tErrorStatus : 0x%I64x\n" \
  1592. "\tRequestorId : 0x%I64x\n" \
  1593. "\tResponderId : 0x%I64x\n" \
  1594. "\tTargetId : 0x%I64x\n" \
  1595. "\tBusSpecificData : 0x%I64x\n"
  1596. typedef enum _ERROR_SECTION_HEADER_TYPE_IA64 {
  1597. ERROR_SECTION_UNKNOWN = 0,
  1598. ERROR_SECTION_PROCESSOR,
  1599. ERROR_SECTION_MEMORY,
  1600. ERROR_SECTION_PCI_BUS,
  1601. ERROR_SECTION_PCI_COMPONENT,
  1602. ERROR_SECTION_SYSTEM_EVENT_LOG,
  1603. ERROR_SECTION_SMBIOS,
  1604. ERROR_SECTION_PLATFORM_SPECIFIC,
  1605. ERROR_SECTION_PLATFORM_BUS,
  1606. ERROR_SECTION_PLATFORM_HOST_CONTROLLER,
  1607. } ERROR_SECTION_HEADER_TYPE_IA64;
  1608. ERROR_DEVICE_GUID_IA64 gErrorProcessorGuid = ERROR_PROCESSOR_GUID_IA64;
  1609. ERROR_DEVICE_GUID_IA64 gErrorMemoryGuid = ERROR_MEMORY_GUID_IA64;
  1610. ERROR_DEVICE_GUID_IA64 gErrorPciBusGuid = ERROR_PCI_BUS_GUID_IA64;
  1611. ERROR_DEVICE_GUID_IA64 gErrorPciComponentGuid = ERROR_PCI_COMPONENT_GUID_IA64;
  1612. ERROR_DEVICE_GUID_IA64 gErrorSystemEventLogGuid = ERROR_SYSTEM_EVENT_LOG_GUID_IA64;
  1613. ERROR_DEVICE_GUID_IA64 gErrorSmbiosGuid = ERROR_SMBIOS_GUID_IA64;
  1614. ERROR_DEVICE_GUID_IA64 gErrorPlatformSpecificGuid = ERROR_PLATFORM_SPECIFIC_GUID_IA64;
  1615. ERROR_DEVICE_GUID_IA64 gErrorPlatformBusGuid = ERROR_PLATFORM_BUS_GUID_IA64;
  1616. ERROR_DEVICE_GUID_IA64 gErrorPlatformHostControllerGuid = ERROR_PLATFORM_HOST_CONTROLLER_GUID_IA64;
  1617. //
  1618. // _HALP_SAL_PAL_DATA.Flags definitions
  1619. // <extracted from i64fw.h>
  1620. //
  1621. #ifndef HALP_SALPAL_FIX_MCE_LOG_ID
  1622. #define HALP_SALPAL_FIX_MCE_LOG_ID 0x1
  1623. #define HALP_SALPAL_MCE_PROCESSOR_CPUIDINFO_OMITTED 0x2
  1624. #define HALP_SALPAL_MCE_PROCESSOR_STATICINFO_PARTIAL 0x4
  1625. #endif // !HALP_SALPAL_FIX_MCE_LOG_ID
  1626. USHORT gHalpSalPalDataFlags = 0;
  1627. VOID
  1628. ExecCommand(
  1629. IN PCSTR Cmd
  1630. )
  1631. {
  1632. if (g_ExtClient && (ExtQuery(g_ExtClient) == S_OK)) {
  1633. g_ExtControl->Execute(DEBUG_OUTCTL_AMBIENT, Cmd, DEBUG_EXECUTE_DEFAULT );
  1634. }
  1635. } // ExecCommand()
  1636. BOOLEAN /* TRUE: Error was found, FALSE: successful */
  1637. SetErrorDeviceGuid(
  1638. PCSTR DeviceGuidString,
  1639. PERROR_DEVICE_GUID_IA64 DeviceGuid,
  1640. BOOLEAN ErrorType
  1641. )
  1642. {
  1643. ULONG64 guidAddress;
  1644. guidAddress = GetExpression( DeviceGuidString );
  1645. if ( guidAddress && !ErrorType ) {
  1646. //
  1647. // WARNING: the following code assumes ERROR_DEVICE_GUID will not change
  1648. // its definition and is identical to ERROR_DEVICE_GUID_IA64.
  1649. //
  1650. ERROR_DEVICE_GUID_IA64 devGuid;
  1651. ULONG cbRead;
  1652. if ( ReadMemory( guidAddress, &devGuid, sizeof(devGuid), &cbRead ) &&
  1653. (cbRead == sizeof(devGuid)) ) {
  1654. *DeviceGuid = devGuid;
  1655. return FALSE;
  1656. }
  1657. dprintf("%s memory-read failed", DeviceGuidString );
  1658. }
  1659. else {
  1660. dprintf("%s not found", DeviceGuidString );
  1661. }
  1662. dprintf(": using known Error Device GUID...\n");
  1663. return TRUE;
  1664. } // SetErrorDeviceGuid()
  1665. VOID
  1666. SetErrorDeviceGuids(
  1667. VOID
  1668. )
  1669. {
  1670. ULONG64 guidAddress;
  1671. BOOLEAN errorFound;
  1672. BOOLEAN errorType;
  1673. ULONG errorDeviceGuidSize;
  1674. errorFound = FALSE;
  1675. errorType = FALSE;
  1676. //
  1677. // WARNING: the following code assumes the ERROR_DEVICE_GUID definition will not change
  1678. // and is identical to ERROR_DEVICE_GUID_IA64.
  1679. //
  1680. errorDeviceGuidSize = GetTypeSize( "hal!_ERROR_DEVICE_GUID" );
  1681. if ( errorDeviceGuidSize == 0 ) {
  1682. // pre-SAL 3.0 check-in hal
  1683. errorType = TRUE;
  1684. }
  1685. else if ( errorDeviceGuidSize != sizeof( ERROR_DEVICE_GUID_IA64 ) ) {
  1686. errorType = TRUE;
  1687. dprintf("!mca: ERROR_DEVICE_GUID invalid definition...\n");
  1688. }
  1689. //
  1690. // Initialize extension-global Error Device Guids.
  1691. //
  1692. errorFound |= SetErrorDeviceGuid("hal!HalpErrorProcessorGuid", &gErrorProcessorGuid,errorType);
  1693. errorFound |= SetErrorDeviceGuid("hal!HalpErrorMemoryGuid", &gErrorMemoryGuid,errorType);
  1694. errorFound |= SetErrorDeviceGuid("hal!HalpErrorPciBusGuid", &gErrorPciBusGuid,errorType);
  1695. errorFound |= SetErrorDeviceGuid("hal!HalpErrorPciComponentGuid", &gErrorPciComponentGuid,errorType);
  1696. errorFound |= SetErrorDeviceGuid("hal!HalpErrorSystemEventLogGuid", &gErrorSystemEventLogGuid,errorType);
  1697. errorFound |= SetErrorDeviceGuid("hal!HalpErrorSmbiosGuid", &gErrorSmbiosGuid,errorType);
  1698. errorFound |= SetErrorDeviceGuid("hal!HalpErrorPlatformSpecificGuid", &gErrorPlatformSpecificGuid,errorType);
  1699. errorFound |= SetErrorDeviceGuid("hal!HalpErrorPlatformBusGuid", &gErrorPlatformBusGuid,errorType);
  1700. errorFound |= SetErrorDeviceGuid("hal!HalpErrorPlatformHostControllerGuid", &gErrorPlatformHostControllerGuid,errorType);
  1701. if ( errorFound ) {
  1702. dprintf("\n");
  1703. }
  1704. return;
  1705. } // SetErrorDeviceGuids()
  1706. typedef struct _TYPED_SYMBOL_HANDLE {
  1707. ULONG64 Module;
  1708. ULONG TypeId;
  1709. ULONG Spare;
  1710. BOOLEAN Found;
  1711. CHAR Name[MAX_PATH];
  1712. } TYPED_SYMBOL_HANDLE, *PTYPED_SYMBOL_HANDLE;
  1713. __inline
  1714. VOID
  1715. InitTypedSymbol(
  1716. PTYPED_SYMBOL_HANDLE Handle,
  1717. ULONG64 Module,
  1718. ULONG TypeId,
  1719. BOOLEAN Found
  1720. )
  1721. {
  1722. Handle->Module = Module;
  1723. Handle->TypeId = TypeId;
  1724. Handle->Found = Found;
  1725. Handle->Name[0] = '\0';
  1726. return;
  1727. } // InitTypedSymbol()
  1728. __inline
  1729. BOOLEAN
  1730. IsTypedSymbolFound(
  1731. PTYPED_SYMBOL_HANDLE Handle
  1732. )
  1733. {
  1734. return Handle->Found;
  1735. } // IsTypedSymbolFound()
  1736. __inline
  1737. HRESULT
  1738. GetTypedSymbolName(
  1739. PTYPED_SYMBOL_HANDLE Handle,
  1740. ULONG64 Value
  1741. )
  1742. {
  1743. HRESULT hr;
  1744. if ( !IsTypedSymbolFound( Handle ) ) {
  1745. return E_INVALIDARG;
  1746. }
  1747. return( g_ExtSymbols->GetConstantName( Handle->Module,
  1748. Handle->TypeId,
  1749. Value,
  1750. Handle->Name,
  1751. sizeof(Handle->Name),
  1752. NULL) );
  1753. } // GetTypedSymbolName()
  1754. TYPED_SYMBOL_HANDLE gErrorSeverity;
  1755. #if 0
  1756. VOID
  1757. SetErrorSeverityValues(
  1758. VOID
  1759. )
  1760. {
  1761. HRESULT hr;
  1762. ULONG typeId;
  1763. ULONG64 module;
  1764. hr = g_ExtSymbols->GetSymbolTypeId("hal!_ERROR_SEVERITY_VALUE", &typeId, &module);
  1765. if ( SUCCEEDED(hr) ) {
  1766. InitTypedSymbol( &gErrorSeverity, module, typeId, TRUE );
  1767. }
  1768. return;
  1769. } // SetErrorSeverityValues()
  1770. #endif
  1771. __inline
  1772. VOID
  1773. SetTypedSymbol(
  1774. PTYPED_SYMBOL_HANDLE Handle,
  1775. PCSTR Symbol
  1776. )
  1777. {
  1778. HRESULT hr;
  1779. ULONG typeId;
  1780. ULONG64 module;
  1781. hr = g_ExtSymbols->GetSymbolTypeId( Symbol, &typeId, &module);
  1782. if ( SUCCEEDED(hr) ) {
  1783. InitTypedSymbol( Handle, module, typeId, TRUE );
  1784. }
  1785. return;
  1786. } // SetTypedSymbol()
  1787. #define SetErrorTypedSymbol( _Handle, _Symbol ) SetTypedSymbol( &(_Handle), #_Symbol )
  1788. #define SetErrorSeverityValues() SetErrorTypedSymbol( gErrorSeverity, hal!_ERROR_SEVERITY_VALUE )
  1789. PCSTR
  1790. ErrorSeverityValueString(
  1791. ULONG SeverityValue
  1792. )
  1793. {
  1794. HRESULT hr;
  1795. hr = GetTypedSymbolName( &gErrorSeverity, SeverityValue );
  1796. if ( SUCCEEDED( hr ) ) {
  1797. return gErrorSeverity.Name;
  1798. }
  1799. //
  1800. // Fall back to known values...
  1801. //
  1802. switch( SeverityValue ) {
  1803. case ErrorRecoverable_IA64:
  1804. return("ErrorRecoverable");
  1805. case ErrorFatal_IA64:
  1806. return("ErrorFatal");
  1807. case ErrorCorrected_IA64:
  1808. return("ErrorCorrected");
  1809. default:
  1810. return("ErrorOthers");
  1811. }
  1812. } // ErrorSeverityValueString()
  1813. BOOLEAN
  1814. CompareTypedErrorDeviceGuid(
  1815. PERROR_DEVICE_GUID_IA64 RefGuid
  1816. )
  1817. {
  1818. if ( ( RefGuid->Data1 == (ULONG) ReadField(Guid.Data1) ) &&
  1819. ( RefGuid->Data2 == (USHORT) ReadField(Guid.Data2) ) &&
  1820. ( RefGuid->Data3 == (USHORT) ReadField(Guid.Data3) ) &&
  1821. ( RefGuid->Data4[0] == (UCHAR) ReadField(Guid.Data4[0]) ) &&
  1822. ( RefGuid->Data4[1] == (UCHAR) ReadField(Guid.Data4[1]) ) &&
  1823. ( RefGuid->Data4[2] == (UCHAR) ReadField(Guid.Data4[2]) ) &&
  1824. ( RefGuid->Data4[3] == (UCHAR) ReadField(Guid.Data4[3]) ) &&
  1825. ( RefGuid->Data4[4] == (UCHAR) ReadField(Guid.Data4[4]) ) &&
  1826. ( RefGuid->Data4[5] == (UCHAR) ReadField(Guid.Data4[5]) ) &&
  1827. ( RefGuid->Data4[6] == (UCHAR) ReadField(Guid.Data4[6]) ) &&
  1828. ( RefGuid->Data4[7] == (UCHAR) ReadField(Guid.Data4[7]) ) ) {
  1829. return TRUE;
  1830. }
  1831. return FALSE;
  1832. } // CompareTypedErrorDeviceGuid()
  1833. UCHAR gZeroedOemPlatformId[16] = { 0 };
  1834. BOOLEAN
  1835. CompareTypedOemPlatformId(
  1836. UCHAR RefOemPlatformId[]
  1837. )
  1838. {
  1839. ULONG i;
  1840. for ( i = 0; i < 16; i++ ) {
  1841. if (RefOemPlatformId[i] != (UCHAR) ReadField(OemPlatformId[i]) ) {
  1842. return FALSE;
  1843. }
  1844. }
  1845. return TRUE;
  1846. } // CompareTypedOemPlatformId()
  1847. ERROR_SECTION_HEADER_TYPE_IA64
  1848. GetTypedErrorSectionType(
  1849. VOID
  1850. )
  1851. {
  1852. if ( CompareTypedErrorDeviceGuid( &gErrorProcessorGuid ) ) {
  1853. return ERROR_SECTION_PROCESSOR;
  1854. }
  1855. if ( CompareTypedErrorDeviceGuid( &gErrorMemoryGuid ) ) {
  1856. return ERROR_SECTION_MEMORY;
  1857. }
  1858. if ( CompareTypedErrorDeviceGuid( &gErrorPciBusGuid ) ) {
  1859. return ERROR_SECTION_PCI_BUS;
  1860. }
  1861. if ( CompareTypedErrorDeviceGuid( &gErrorPciComponentGuid ) ) {
  1862. return ERROR_SECTION_PCI_COMPONENT;
  1863. }
  1864. if ( CompareTypedErrorDeviceGuid( &gErrorSystemEventLogGuid ) ) {
  1865. return ERROR_SECTION_SYSTEM_EVENT_LOG;
  1866. }
  1867. if ( CompareTypedErrorDeviceGuid( &gErrorSmbiosGuid ) ) {
  1868. return ERROR_SECTION_SMBIOS;
  1869. }
  1870. if ( CompareTypedErrorDeviceGuid( &gErrorPlatformSpecificGuid ) ) {
  1871. return ERROR_SECTION_PLATFORM_SPECIFIC;
  1872. }
  1873. if ( CompareTypedErrorDeviceGuid( &gErrorPlatformBusGuid ) ) {
  1874. return ERROR_SECTION_PLATFORM_BUS;
  1875. }
  1876. if ( CompareTypedErrorDeviceGuid( &gErrorPlatformHostControllerGuid ) ) {
  1877. return ERROR_SECTION_PLATFORM_HOST_CONTROLLER;
  1878. }
  1879. return ERROR_SECTION_UNKNOWN;
  1880. } // GetTypedErrorSectionType()
  1881. PCSTR
  1882. ErrorSectionTypeString(
  1883. ERROR_SECTION_HEADER_TYPE_IA64 ErrorSectionType
  1884. )
  1885. {
  1886. switch( ErrorSectionType ) {
  1887. case ERROR_SECTION_PROCESSOR:
  1888. return( "Processor" );
  1889. case ERROR_SECTION_MEMORY:
  1890. return( "Memory" );
  1891. case ERROR_SECTION_PCI_BUS:
  1892. return( "PciBus" );
  1893. case ERROR_SECTION_PCI_COMPONENT:
  1894. return( "PciComponent" );
  1895. case ERROR_SECTION_SYSTEM_EVENT_LOG:
  1896. return( "SystemEventLog" );
  1897. case ERROR_SECTION_SMBIOS:
  1898. return( "Smbios" );
  1899. case ERROR_SECTION_PLATFORM_SPECIFIC:
  1900. return( "PlatformSpecific" );
  1901. case ERROR_SECTION_PLATFORM_BUS:
  1902. return( "PlatformBus" );
  1903. case ERROR_SECTION_PLATFORM_HOST_CONTROLLER:
  1904. return( "PlatformHostController" );
  1905. default:
  1906. return( "Unknown Error Device" );
  1907. }
  1908. } // ErrorSectionTypeString()
  1909. VOID
  1910. DumpIa64ErrorRecordHeader(
  1911. PERROR_RECORD_HEADER_IA64 Header,
  1912. ULONG64 HeaderAddress
  1913. )
  1914. {
  1915. ULONG errorSeverity;
  1916. errorSeverity = Header->ErrorSeverity;
  1917. dprintf( ERROR_RECORD_HEADER_FORMAT_IA64,
  1918. (ULONGLONG) HeaderAddress, (HeaderAddress + (ULONG64)Header->Length),
  1919. (ULONGLONG) Header->Id,
  1920. (ULONG) Header->Revision.Revision,
  1921. (ULONG) Header->Revision.Major, (ULONG) Header->Revision.Minor,
  1922. errorSeverity, ErrorSeverityValueString( errorSeverity ),
  1923. (ULONG) Header->Valid.Valid,
  1924. (ULONG) Header->Valid.OemPlatformID,
  1925. (ULONG) Header->Length,
  1926. (ULONGLONG) Header->TimeStamp.TimeStamp,
  1927. (ULONG) Header->TimeStamp.Seconds,
  1928. (ULONG) Header->TimeStamp.Minutes,
  1929. (ULONG) Header->TimeStamp.Hours,
  1930. (ULONG) Header->TimeStamp.Day,
  1931. (ULONG) Header->TimeStamp.Month,
  1932. (ULONG) Header->TimeStamp.Year,
  1933. (ULONG) Header->TimeStamp.Century,
  1934. (ULONG) ReadField(OemPlatformId[0x0]),
  1935. (ULONG) ReadField(OemPlatformId[0x1]),
  1936. (ULONG) ReadField(OemPlatformId[0x2]),
  1937. (ULONG) ReadField(OemPlatformId[0x3]),
  1938. (ULONG) ReadField(OemPlatformId[0x4]),
  1939. (ULONG) ReadField(OemPlatformId[0x5]),
  1940. (ULONG) ReadField(OemPlatformId[0x6]),
  1941. (ULONG) ReadField(OemPlatformId[0x7]),
  1942. (ULONG) ReadField(OemPlatformId[0x8]),
  1943. (ULONG) ReadField(OemPlatformId[0x9]),
  1944. (ULONG) ReadField(OemPlatformId[0xa]),
  1945. (ULONG) ReadField(OemPlatformId[0xb]),
  1946. (ULONG) ReadField(OemPlatformId[0xc]),
  1947. (ULONG) ReadField(OemPlatformId[0xd]),
  1948. (ULONG) ReadField(OemPlatformId[0xe]),
  1949. (ULONG) ReadField(OemPlatformId[0xf]),
  1950. ""
  1951. );
  1952. return;
  1953. } // DumpIa64ErrorRecordHeader()
  1954. ULONG64
  1955. DtErrorModInfos(
  1956. ULONG64 ModInfo,
  1957. ULONG CheckNum,
  1958. ULONG ModInfoSize,
  1959. PCSTR ModInfoName
  1960. )
  1961. {
  1962. ULONG64 modInfo;
  1963. ULONG modInfoSize;
  1964. ULONG64 modInfoMax;
  1965. ERROR_MODINFO_IA64 modInfoStruct;
  1966. ULONG modInfoNum;
  1967. modInfo = ModInfo;
  1968. modInfoSize = ModInfoSize ? ModInfoSize : sizeof(modInfoStruct);
  1969. modInfoMax = modInfo + (CheckNum * modInfoSize);
  1970. modInfoNum = 0;
  1971. dprintf("\t%s[%ld]\n", ModInfoName, CheckNum);
  1972. while( modInfo < modInfoMax ) {
  1973. if ( ModInfoSize ) {
  1974. CHAR cmd[MAX_PATH];
  1975. sprintf(cmd, "dt -o -r hal!_ERROR_MODINFO 0x%I64x", modInfo);
  1976. dprintf("\t%s[%ld]:\n", ModInfoName, modInfoNum);
  1977. ExecCommand(cmd);
  1978. }
  1979. else {
  1980. ULONG bytesRead = 0;
  1981. ReadMemory(modInfo, &modInfoStruct, modInfoSize, &bytesRead );
  1982. if ( bytesRead >= modInfoSize ) {
  1983. dprintf( ERROR_MODINFO_FORMAT_IA64,
  1984. ModInfoName, modInfoNum,
  1985. modInfoStruct.Valid,
  1986. (ULONG) modInfoStruct.Valid.CheckInfo,
  1987. (ULONG) modInfoStruct.Valid.RequestorIdentifier,
  1988. (ULONG) modInfoStruct.Valid.ResponderIdentifier,
  1989. (ULONG) modInfoStruct.Valid.TargetIdentifier,
  1990. (ULONG) modInfoStruct.Valid.PreciseIP,
  1991. (ULONGLONG) modInfoStruct.Valid.Reserved,
  1992. (ULONGLONG) modInfoStruct.CheckInfo,
  1993. (ULONGLONG) modInfoStruct.RequestedId,
  1994. (ULONGLONG) modInfoStruct.ResponderId,
  1995. (ULONGLONG) modInfoStruct.TargetId,
  1996. (ULONGLONG) modInfoStruct.PreciseIP
  1997. );
  1998. }
  1999. else {
  2000. dprintf("Reading _ERROR_MODINFO directly from memory failed @ 0x%I64x.\n", modInfo );
  2001. }
  2002. }
  2003. modInfo += (ULONG64)modInfoSize;
  2004. modInfoNum++;
  2005. }
  2006. return( modInfo );
  2007. } // DtErrorModInfos()
  2008. ULONG64
  2009. DtErrorProcessorStaticInfo(
  2010. ULONG64 StaticInfo,
  2011. ULONG64 SectionMax
  2012. )
  2013. {
  2014. ULONG offset;
  2015. ULONG64 valid;
  2016. CHAR cmd[MAX_PATH];
  2017. ULONG i;
  2018. HRESULT hr;
  2019. ULONG64 moduleValid;
  2020. ULONG typeIdValid;
  2021. ULONG64 moduleStaticInfo;
  2022. ULONG typeIdStaticInfo;
  2023. CHAR field[MAX_PATH];
  2024. hr = g_ExtSymbols->GetSymbolTypeId( "hal!_ERROR_PROCESSOR_STATIC_INFO_VALID",
  2025. &typeIdValid,
  2026. &moduleValid);
  2027. if ( !SUCCEEDED(hr) ) {
  2028. dprintf("Unable to get hal!_ERROR_PROCESSOR_STATIC_INFO_VALID type. Stop processing...\n");
  2029. return( 0 );
  2030. }
  2031. hr = g_ExtSymbols->GetSymbolTypeId( "hal!_ERROR_PROCESSOR_STATIC_INFO",
  2032. &typeIdStaticInfo,
  2033. &moduleStaticInfo);
  2034. if ( !SUCCEEDED(hr) ) {
  2035. dprintf("Unable to get hal!_ERROR_PROCESSOR_STATIC_INFO type. Stop processing...\n");
  2036. return( 0 );
  2037. }
  2038. //
  2039. //
  2040. // Display the valid structure.
  2041. //
  2042. offset = 0;
  2043. GetFieldOffset("hal!_ERROR_PROCESSOR_STATIC_INFO" , "Valid", &offset );
  2044. valid = StaticInfo + (ULONG64)offset;
  2045. dprintf("\t\tValid @ 0x%I64x\n", valid);
  2046. sprintf(cmd, "dt -o -r hal!_ERROR_PROCESSOR_STATIC_INFO_VALID 0x%I64x", valid );
  2047. ExecCommand( cmd );
  2048. //
  2049. // Pass through all the valid _ERROR_PROCESSOR_STATIC_INFO fields and dump them.
  2050. //
  2051. for (i=0; ;i++) {
  2052. hr = g_ExtSymbols->GetFieldName(moduleValid, typeIdValid, i, field, sizeof(field), NULL);
  2053. if ( hr == S_OK) {
  2054. ULONG64 val;
  2055. ULONG size = 0;
  2056. // g_ExtSymbols->GetFieldOffset(moduleValid, typeIdValid, field, &offset);
  2057. GetFieldValue(valid, "hal!_ERROR_PROCESSOR_STATIC_INFO_VALID", field, val);
  2058. // dprintf("XX\t %lx (+%03lx) %s %ld\n", i, offset, field, (ULONG)val);
  2059. // g_ExtSymbols->GetFieldOffset(moduleStaticInfo, typeIdStaticInfo, field, &offset);
  2060. GetFieldOffsetEx("hal!_ERROR_PROCESSOR_STATIC_INFO", field, &offset, &size);
  2061. // dprintf("XX\t\t %lx (+%03lx) %ld %s\n", i, offset, size, field);
  2062. if (val && offset ) { // Valid is the first entry.
  2063. ULONG64 fieldAddress, fieldAddressMax;
  2064. // XXTF: Get the field size here...
  2065. // g_ExtSymbols->GetFieldSize(moduleStaticInfo, typeIdStaticInfo, field, &size);
  2066. fieldAddress = StaticInfo + (ULONG64)offset;
  2067. fieldAddressMax = fieldAddress + (ULONG64)size - sizeof(ULONG64);
  2068. dprintf("\t\t%s @ 0x%I64x 0x%I64x\n", field, fieldAddress, fieldAddressMax);
  2069. if ( fieldAddressMax > SectionMax ) {
  2070. dprintf("\t\tInvalid Entry: %s size greater than SectionMax 0x%I64x", SectionMax);
  2071. }
  2072. if ( strcmp(field, "MinState") && size ) {
  2073. sprintf(cmd, "dqs 0x%I64x 0x%I64x", fieldAddress, fieldAddressMax );
  2074. ExecCommand( cmd );
  2075. }
  2076. }
  2077. } else if (hr == E_INVALIDARG) {
  2078. // All Fields done
  2079. break;
  2080. } else {
  2081. dprintf("GetFieldName Failed %lx\n", hr);
  2082. break;
  2083. }
  2084. }
  2085. // XXTF: Later we should set to length of _ERROR_PROCESSOR_STATIC_INFO if success
  2086. return 0;
  2087. } // DtErrorProcessorStaticInfo()
  2088. HRESULT
  2089. DtErrorSectionProcessor(
  2090. IN ULONG64 Section
  2091. )
  2092. {
  2093. ULONG64 sectionMax;
  2094. ULONG sectionSize;
  2095. ULONG sectionLength;
  2096. ULONG modInfoSize;
  2097. ULONG cacheModInfos, tlbModInfos;
  2098. ULONG busModInfos, regFileModInfos, msModInfos;
  2099. ULONG64 modInfo, modInfoMax;
  2100. ULONG64 cpuidInfo;
  2101. ULONG cpuidInfoSize;
  2102. ULONG64 staticInfo;
  2103. ULONG staticInfoSize;
  2104. BOOLEAN stateParameterValid;
  2105. ULONG stateParameterSize;
  2106. ULONG stateParameterOffset;
  2107. BOOLEAN crLidValid;
  2108. ULONG crLidSize;
  2109. ULONG crLidOffset;
  2110. BOOLEAN errorMapValid;
  2111. CHAR cmd[MAX_PATH];
  2112. sectionSize = GetTypeSize( "hal!_ERROR_PROCESSOR" );
  2113. if ( sectionSize == 0 ) {
  2114. dprintf( "Unable to get HAL!_ERROR_PROCESSOR type size\n" );
  2115. return( E_FAIL );
  2116. }
  2117. stateParameterValid = FALSE;
  2118. stateParameterSize = GetTypeSize( "hal!_ERROR_PROCESSOR_STATE_PARAMETER" );
  2119. if ( stateParameterSize &&
  2120. !GetFieldOffset("hal!_ERROR_PROCESSOR", "StateParameter", &stateParameterOffset ) ) {
  2121. stateParameterValid = TRUE;
  2122. }
  2123. crLidValid = FALSE;
  2124. crLidSize = GetTypeSize( "hal!_PROCESSOR_LOCAL_ID" );
  2125. if ( crLidSize &&
  2126. !GetFieldOffset("hal!_ERROR_PROCESSOR", "CRLid", &crLidOffset ) ) {
  2127. crLidValid = TRUE;
  2128. }
  2129. errorMapValid = FALSE;
  2130. if ( GetTypeSize( "hal!_ERROR_PROCESSOR_ERROR_MAP" ) ) {
  2131. errorMapValid = TRUE;
  2132. }
  2133. if ( InitTypeRead( Section, hal!_ERROR_PROCESSOR ) ) {
  2134. dprintf( "Unable to read HAL!_ERROR_PROCESSOR at 0x%I64x\n", Section );
  2135. return( E_FAIL );
  2136. }
  2137. sectionLength = (ULONG) ReadField(Header.Length);
  2138. sectionMax = Section + (ULONG64)sectionLength;
  2139. cacheModInfos = (ULONG) ReadField(Valid.CacheCheckNum);
  2140. tlbModInfos = (ULONG) ReadField(Valid.TlbCheckNum);
  2141. busModInfos = (ULONG) ReadField(Valid.BusCheckNum);
  2142. regFileModInfos = (ULONG) ReadField(Valid.RegFileCheckNum);
  2143. msModInfos = (ULONG) ReadField(Valid.MsCheckNum);
  2144. dprintf( ERROR_PROCESSOR_FORMAT_IA64,
  2145. (ULONGLONG) ReadField(Valid),
  2146. (ULONG) ReadField(Valid.ErrorMap),
  2147. (ULONG) ReadField(Valid.StateParameter),
  2148. (ULONG) ReadField(Valid.CRLid),
  2149. (ULONG) ReadField(Valid.StaticStruct),
  2150. cacheModInfos,
  2151. tlbModInfos,
  2152. busModInfos,
  2153. regFileModInfos,
  2154. msModInfos,
  2155. (ULONG) ReadField(Valid.CpuIdInfo),
  2156. (ULONGLONG) ReadField(Valid.Reserved)
  2157. );
  2158. if ( errorMapValid ) {
  2159. dprintf( ERROR_PROCESSOR_ERROR_MAP_FORMAT_IA64,
  2160. (ULONGLONG) ReadField(ErrorMap),
  2161. (ULONG) ReadField(ErrorMap.Cid),
  2162. (ULONG) ReadField(ErrorMap.Tid),
  2163. (ULONG) ReadField(ErrorMap.Eic),
  2164. (ULONG) ReadField(ErrorMap.Edc),
  2165. (ULONG) ReadField(ErrorMap.Eit),
  2166. (ULONG) ReadField(ErrorMap.Edt),
  2167. (ULONG) ReadField(ErrorMap.Ebh),
  2168. (ULONG) ReadField(ErrorMap.Erf),
  2169. (ULONG) ReadField(ErrorMap.Ems),
  2170. (ULONG) ReadField(ErrorMap.Reserved)
  2171. );
  2172. }
  2173. else {
  2174. ERROR_PROCESSOR_ERROR_MAP_IA64 errorMap;
  2175. errorMap.ErrorMap = (ULONGLONG) ReadField(ErrorMap);
  2176. dprintf( ERROR_PROCESSOR_ERROR_MAP_FORMAT_IA64,
  2177. (ULONGLONG) errorMap.ErrorMap,
  2178. (ULONG) errorMap.Cid,
  2179. (ULONG) errorMap.Tid,
  2180. (ULONG) errorMap.Eic,
  2181. (ULONG) errorMap.Edc,
  2182. (ULONG) errorMap.Eit,
  2183. (ULONG) errorMap.Edt,
  2184. (ULONG) errorMap.Ebh,
  2185. (ULONG) errorMap.Erf,
  2186. (ULONG) errorMap.Ems,
  2187. (ULONG) errorMap.Reserved
  2188. );
  2189. }
  2190. dprintf("\tStateParameter: 0x%I64x\n", (ULONGLONG) ReadField(StateParameter));
  2191. if ( stateParameterValid ) {
  2192. sprintf(cmd, "dt -o -r hal!_ERROR_PROCESSOR_STATE_PARAMETER 0x%I64x",
  2193. Section + (ULONG64)stateParameterOffset );
  2194. ExecCommand( cmd );
  2195. }
  2196. dprintf("\tCRLid : 0x%I64x\n", (ULONGLONG) ReadField(CRLid));
  2197. if ( crLidValid ) {
  2198. sprintf(cmd, "dt -o -r hal!_PROCESSOR_LOCAL_ID 0x%I64x", Section + (ULONG64)crLidOffset );
  2199. ExecCommand( cmd );
  2200. }
  2201. //
  2202. // Check if _ERROR_MODINFO a known type?
  2203. //
  2204. modInfo = Section + (ULONG64)sectionSize;
  2205. modInfoSize = GetTypeSize( "hal!_ERROR_MODINFO" );
  2206. //
  2207. // Dump Cache ModInfo structures if any
  2208. //
  2209. if ( cacheModInfos ) {
  2210. modInfo = DtErrorModInfos( modInfo, cacheModInfos, modInfoSize, "CacheErrorInfo" );
  2211. }
  2212. //
  2213. // Dump TLB ModInfo structures if any
  2214. //
  2215. if ( tlbModInfos ) {
  2216. modInfo = DtErrorModInfos( modInfo, tlbModInfos, modInfoSize, "TlbErrorInfo" );
  2217. }
  2218. //
  2219. // Dump BUS ModInfo structures if any
  2220. //
  2221. if ( busModInfos ) {
  2222. modInfo = DtErrorModInfos( modInfo, busModInfos, modInfoSize, "BusErrorInfo" );
  2223. }
  2224. //
  2225. // Dump REGISTERS FILES ModInfo structures if any
  2226. //
  2227. if ( regFileModInfos ) {
  2228. modInfo = DtErrorModInfos( modInfo, regFileModInfos, modInfoSize, "RegFileErrorInfo" );
  2229. }
  2230. //
  2231. // Dump MS ModInfo structures if any
  2232. //
  2233. if ( msModInfos ) {
  2234. modInfo = DtErrorModInfos( modInfo, msModInfos, modInfoSize, "MsErrorInfo" );
  2235. }
  2236. //
  2237. // Dump CPUID Info
  2238. //
  2239. // XXTF: DO NOT CHECK this in - This is for Raj's private SAL test - Lion Build 270D.
  2240. // gHalpSalPalDataFlags |= HALP_SALPAL_MCE_PROCESSOR_CPUIDINFO_OMITTED;
  2241. cpuidInfo = modInfo;
  2242. if ( gHalpSalPalDataFlags & HALP_SALPAL_MCE_PROCESSOR_CPUIDINFO_OMITTED ) {
  2243. dprintf("\tCpuIdInfo @ 0x%I64x FW-omitted\n", cpuidInfo);
  2244. cpuidInfoSize = 0;
  2245. }
  2246. else {
  2247. if ( cpuidInfo >= sectionMax ) {
  2248. dprintf("\tCpuIdInfo @ 0x%I64x\n", cpuidInfo);
  2249. dprintf("Invalid ERROR_PROCESSOR: cpuidInfo >= sectionMax\n");
  2250. return E_FAIL;
  2251. }
  2252. cpuidInfoSize = GetTypeSize( "hal!_ERROR_PROCESSOR_CPUID_INFO" );
  2253. dprintf("\tCpuIdInfo @ 0x%I64x", cpuidInfo);
  2254. if ( cpuidInfoSize ) {
  2255. dprintf(" 0x%I64x\n", cpuidInfo + (ULONG64)cpuidInfoSize);
  2256. if ( (cpuidInfo + cpuidInfoSize) > sectionMax ) {
  2257. dprintf("\nInvalid ERROR_PROCESSOR: (cpuidInfo+cpuidInfoSize) > sectionMax\n");
  2258. return E_FAIL;
  2259. }
  2260. sprintf(cmd, "dt -o -r hal!_ERROR_PROCESSOR_CPUID_INFO 0x%I64x", cpuidInfo );
  2261. ExecCommand( cmd );
  2262. }
  2263. else {
  2264. ERROR_PROCESSOR_CPUID_INFO_IA64 cpuidInfoStruct;
  2265. ULONG bytesRead;
  2266. bytesRead = 0;
  2267. cpuidInfoSize = sizeof(cpuidInfoStruct);
  2268. dprintf(" 0x%I64x\n", cpuidInfo + (ULONG64)cpuidInfoSize);
  2269. if ( (cpuidInfo + cpuidInfoSize) > sectionMax ) {
  2270. dprintf("\nInvalid ERROR_PROCESSOR: (cpuidInfo+cpuidInfoSize) > sectionMax\n");
  2271. return E_FAIL;
  2272. }
  2273. ReadMemory(cpuidInfo, &cpuidInfoStruct, cpuidInfoSize, &bytesRead );
  2274. if ( bytesRead >= cpuidInfoSize ) {
  2275. dprintf( ERROR_PROCESSOR_CPUID_INFO_FORMAT_IA64,
  2276. cpuidInfoStruct.CpuId0,
  2277. cpuidInfoStruct.CpuId1,
  2278. cpuidInfoStruct.CpuId2,
  2279. cpuidInfoStruct.CpuId3,
  2280. cpuidInfoStruct.CpuId4,
  2281. cpuidInfoStruct.Reserved
  2282. );
  2283. }
  2284. else {
  2285. dprintf("Reading _ERROR_PROCESSOR_CPUID_INFO directly from memory failed @ 0x%I64x.\n", cpuidInfo );
  2286. }
  2287. }
  2288. }
  2289. //
  2290. // Dump Processor Static Info
  2291. //
  2292. // XXTF BUGBUG - 04/16/2001 - TEMP for kd extension test.
  2293. // XXTF: DO NOT CHECK this in - This is for Raj's private SAL test - Lion Build 270D.
  2294. // gHalpSalPalDataFlags |= HALP_SALPAL_MCE_PROCESSOR_STATICINFO_PARTIAL;
  2295. staticInfo = cpuidInfo + cpuidInfoSize;
  2296. if ( staticInfo >= sectionMax ) {
  2297. dprintf("Invalid ERROR_PROCESSOR: staticInfo >= sectionMax\n");
  2298. return E_FAIL;
  2299. }
  2300. staticInfoSize = GetTypeSize( "hal!_ERROR_PROCESSOR_STATIC_INFO" );
  2301. dprintf("\tStaticInfo @ 0x%I64x", staticInfo);
  2302. if ( staticInfoSize ) {
  2303. dprintf(" 0x%I64x\n", staticInfo + (ULONG64)staticInfoSize);
  2304. if ( !(gHalpSalPalDataFlags & HALP_SALPAL_MCE_PROCESSOR_STATICINFO_PARTIAL) &&
  2305. (staticInfo + staticInfoSize) > sectionMax ) {
  2306. dprintf("\nInvalid ERROR_PROCESSOR: (staticInfo+staticInfoSize) > sectionMax\n");
  2307. return E_FAIL;
  2308. }
  2309. (VOID) DtErrorProcessorStaticInfo( staticInfo, sectionMax );
  2310. }
  2311. else {
  2312. ERROR_PROCESSOR_STATIC_INFO_IA64 staticInfoStruct;
  2313. ULONG bytesRead;
  2314. bytesRead = 0;
  2315. staticInfoSize = sizeof(staticInfoStruct);
  2316. dprintf(" 0x%I64x\n", staticInfo + (ULONG64)staticInfoSize);
  2317. if ( !(gHalpSalPalDataFlags & HALP_SALPAL_MCE_PROCESSOR_STATICINFO_PARTIAL) &&
  2318. (staticInfo + staticInfoSize) > sectionMax ) {
  2319. dprintf("\nInvalid ERROR_PROCESSOR: (staticInfo+staticInfoSize) > sectionMax\n");
  2320. return E_FAIL;
  2321. }
  2322. ReadMemory(staticInfo, &staticInfoStruct, staticInfoSize, &bytesRead );
  2323. if ( bytesRead >= staticInfoSize ) {
  2324. ULONG64 minState, brs, crs, ars, rrs, frs;
  2325. PULONG64 minStateValuePtr;
  2326. minState = staticInfo + FIELD_OFFSET( _ERROR_PROCESSOR_STATIC_INFO_IA64, MinState);
  2327. brs = staticInfo + FIELD_OFFSET( _ERROR_PROCESSOR_STATIC_INFO_IA64, BR);
  2328. crs = staticInfo + FIELD_OFFSET( _ERROR_PROCESSOR_STATIC_INFO_IA64, CR);
  2329. ars = staticInfo + FIELD_OFFSET( _ERROR_PROCESSOR_STATIC_INFO_IA64, AR);
  2330. rrs = staticInfo + FIELD_OFFSET( _ERROR_PROCESSOR_STATIC_INFO_IA64, RR);
  2331. frs = staticInfo + FIELD_OFFSET( _ERROR_PROCESSOR_STATIC_INFO_IA64, FR);
  2332. minStateValuePtr = (PULONG64)&(staticInfoStruct.MinState[0]);
  2333. dprintf( ERROR_PROCESSOR_STATIC_INFO_FORMAT_IA64,
  2334. (ULONGLONG) staticInfoStruct.Valid.Valid,
  2335. (ULONG) staticInfoStruct.Valid.MinState,
  2336. (ULONG) staticInfoStruct.Valid.BRs,
  2337. (ULONG) staticInfoStruct.Valid.CRs,
  2338. (ULONG) staticInfoStruct.Valid.ARs,
  2339. (ULONG) staticInfoStruct.Valid.RRs,
  2340. (ULONG) staticInfoStruct.Valid.FRs,
  2341. (ULONGLONG) staticInfoStruct.Valid.Reserved
  2342. );
  2343. dprintf( "\t\tMinState @ 0x%I64x 0x%I64x\n", minState, brs - sizeof(ULONGLONG) );
  2344. sprintf(cmd, "dqs 0x%I64x 0x%I64x", minState, brs - sizeof(ULONGLONG) );
  2345. ExecCommand( cmd );
  2346. dprintf( "\t\tBRs @ 0x%I64x\n", brs, crs - sizeof(ULONGLONG) );
  2347. sprintf(cmd, "dqs 0x%I64x 0x%I64x", brs, crs - sizeof(ULONGLONG) );
  2348. ExecCommand( cmd );
  2349. dprintf( "\t\tCRs @ 0x%I64x 0x%I64x\n", crs, ars - sizeof(ULONGLONG) );
  2350. sprintf(cmd, "dqs 0x%I64x 0x%I64x", crs, ars - sizeof(ULONGLONG) );
  2351. ExecCommand( cmd );
  2352. dprintf( "\t\tARs @ 0x%I64x 0x%I64x\n", ars, rrs - sizeof(ULONGLONG) );
  2353. sprintf(cmd, "dqs 0x%I64x 0x%I64x", ars, rrs - sizeof(ULONGLONG) );
  2354. ExecCommand( cmd );
  2355. dprintf( "\t\tRRs @ 0x%I64x 0x%I64x\n", rrs, frs - sizeof(ULONGLONG) );
  2356. sprintf(cmd, "dqs 0x%I64x 0x%I64x", rrs, frs - sizeof(ULONGLONG) );
  2357. ExecCommand( cmd );
  2358. dprintf( "\t\tFRs @ 0x%I64x 0x%I64x\n", frs, staticInfo + (ULONG64)staticInfoSize - sizeof(ULONGLONG) );
  2359. sprintf(cmd, "dqs 0x%I64x 0x%I64x", frs, staticInfo + (ULONG64)staticInfoSize - sizeof(ULONGLONG) );
  2360. ExecCommand( cmd );
  2361. }
  2362. else {
  2363. dprintf("Reading _ERROR_PROCESSOR_STATIC_INFO directly from memory failed @ 0x%I64x.\n", staticInfo );
  2364. }
  2365. }
  2366. // ouf!
  2367. return S_OK;
  2368. } // DtErrrorSectionProcessor()
  2369. ULONG64
  2370. DtErrorOemData(
  2371. ULONG64 OemData,
  2372. USHORT OemDataLength
  2373. )
  2374. {
  2375. ULONG oemDataSize;
  2376. CHAR cmd[MAX_PATH];
  2377. // XXTF: should be fixed later and use field type and offset, instead of USHORT type.
  2378. USHORT length;
  2379. length = OemDataLength;
  2380. oemDataSize = GetTypeSize("hal!_ERROR_OEM_DATA");
  2381. // Do not print the following header if 'dt -r hal!_ERROR_PLATFORM_SPECIFIC type was found.
  2382. if ( !oemDataSize ) {
  2383. dprintf("\tOemData @ 0x%I64x", OemData);
  2384. dprintf(" 0x%I64x\n\t\tLength\t: 0x%x\n", OemData + (ULONG64)length - sizeof(BYTE), length);
  2385. oemDataSize = sizeof(_ERROR_OEM_DATA_IA64);
  2386. }
  2387. sprintf(cmd, "db 0x%I64x 0x%I64x\n", OemData + (ULONG64)oemDataSize,
  2388. OemData + (ULONG64)(length - sizeof(length)) - sizeof(BYTE));
  2389. ExecCommand(cmd);
  2390. return( OemData + (ULONG64)length );
  2391. } // DtErrorOemData()
  2392. VOID
  2393. DtErrorOemDevicePath(
  2394. ULONG64 OemDevicePath,
  2395. ULONG64 OemDevicePathMax
  2396. )
  2397. {
  2398. CHAR cmd[MAX_PATH];
  2399. dprintf("\tOemDevicePath @ 0x%I64x 0x%I64x\n", OemDevicePath, OemDevicePathMax );
  2400. sprintf(cmd, "db 0x%I64x 0x%I64x\n", OemDevicePath, OemDevicePathMax - sizeof(UCHAR) );
  2401. ExecCommand( cmd );
  2402. return;
  2403. } // DtErrorOemDevicePath()
  2404. VOID
  2405. DtErrorOemId(
  2406. ULONG64 OemId
  2407. )
  2408. {
  2409. CHAR cmd[MAX_PATH];
  2410. dprintf("\tOemId @ 0x%I64x 0x%I64x\n", OemId, OemId + (ULONG64)16 );
  2411. sprintf(cmd, "db 0x%I64x 0x%I64x\n", OemId, OemId + (ULONG64)15 );
  2412. ExecCommand( cmd );
  2413. return;
  2414. } // DtErrorOemId()
  2415. HRESULT
  2416. DtErrorSectionPlatformSpecific(
  2417. IN ULONG64 Section
  2418. )
  2419. {
  2420. ULONG sectionSize;
  2421. ULONG64 oemData;
  2422. ULONG64 devicePath;
  2423. ULONG sectionLength;
  2424. ULONG oemDataLength;
  2425. sectionSize = GetTypeSize( "hal!_ERROR_PLATFORM_SPECIFIC" );
  2426. if ( sectionSize ) {
  2427. CHAR cmd[MAX_PATH];
  2428. sprintf(cmd, "dt -r hal!_ERROR_PLATFORM_SPECIFIC 0x%I64x", Section);
  2429. ExecCommand( cmd );
  2430. oemData = Section + (ULONG64)sectionSize;
  2431. GetFieldValue( Section, "hal!_ERROR_PLATFORM_SPECIFIC", "OemData.Length", oemDataLength );
  2432. devicePath = DtErrorOemData( oemData, (USHORT)oemDataLength );
  2433. GetFieldValue( Section, "hal!_ERROR_PLATFORM_SPECIFIC", "Header.Length", sectionLength );
  2434. DtErrorOemDevicePath( devicePath, Section + (ULONG64)sectionLength );
  2435. }
  2436. else {
  2437. ERROR_PLATFORM_SPECIFIC_IA64 platformSpecific;
  2438. ULONG cbRead = 0;
  2439. ULONG64 oemId;
  2440. sectionSize = sizeof(platformSpecific);
  2441. ReadMemory( Section, &platformSpecific, sectionSize, &cbRead );
  2442. if ( cbRead >= sectionSize ) {
  2443. sectionLength = platformSpecific.Header.Length;
  2444. dprintf( ERROR_PLATFORM_SPECIFIC_FORMAT_IA64,
  2445. platformSpecific.Valid.Valid,
  2446. (ULONG) platformSpecific.Valid.ErrorStatus,
  2447. (ULONG) platformSpecific.Valid.RequestorId,
  2448. (ULONG) platformSpecific.Valid.ResponderId,
  2449. (ULONG) platformSpecific.Valid.TargetId,
  2450. (ULONG) platformSpecific.Valid.BusSpecificData,
  2451. (ULONG) platformSpecific.Valid.OemId,
  2452. (ULONG) platformSpecific.Valid.OemData,
  2453. (ULONG) platformSpecific.Valid.OemDevicePath,
  2454. (ULONGLONG) platformSpecific.Valid.Reserved,
  2455. (ULONGLONG) platformSpecific.ErrorStatus.Status,
  2456. (ULONGLONG) platformSpecific.RequestorId,
  2457. (ULONGLONG) platformSpecific.ResponderId,
  2458. (ULONGLONG) platformSpecific.TargetId,
  2459. (ULONGLONG) platformSpecific.BusSpecificData.BusSpecificData
  2460. );
  2461. oemId = Section + (ULONG64)FIELD_OFFSET(_ERROR_PLATFORM_SPECIFIC_IA64, OemId);
  2462. DtErrorOemId( oemId );
  2463. oemData = Section + (ULONG64)FIELD_OFFSET(_ERROR_PLATFORM_SPECIFIC_IA64, OemData);
  2464. DtErrorOemData( oemData, platformSpecific.OemData.Length );
  2465. devicePath = oemData + platformSpecific.OemData.Length;
  2466. DtErrorOemDevicePath( devicePath, Section + (ULONG64)sectionLength );
  2467. }
  2468. else {
  2469. dprintf("Reading _ERROR_PLATFORM_SPECIFIC directly from memory failed @ 0x%I64x.\n", Section );
  2470. }
  2471. }
  2472. return S_OK;
  2473. } // DtErrorSectionPlatformSpecific()
  2474. ULONGLONG gMceProcNumberMaskTimeStamp = 0;
  2475. HRESULT
  2476. DtMcaLog(
  2477. IN ULONG64 McaLog,
  2478. IN ULONG RecordSize
  2479. )
  2480. {
  2481. ULONG recordLength;
  2482. ULONG recordRevision;
  2483. ULONG64 section;
  2484. ULONG64 sectionMax;
  2485. ULONG errorSeverity;
  2486. ULONG sectionSize;
  2487. CHAR procNumberString[64];
  2488. ULONGLONG timeStamp;
  2489. HRESULT hr;
  2490. //
  2491. // Handle pre-SAL 3.0 formats with zero'ed OEM Platform Id appended to the SAL 2.0 version,
  2492. // but with HAL exporting _ERROR_RECORD_HEADER type.
  2493. //
  2494. recordRevision = (ULONG)ReadField(Revision);
  2495. if ( recordRevision < 0x2 /* ERROR_REVISION_SAL_03_00 */ ) {
  2496. if ( CompareTypedOemPlatformId( gZeroedOemPlatformId ) ) {
  2497. RecordSize += sizeof( gZeroedOemPlatformId );
  2498. }
  2499. gHalpSalPalDataFlags |= HALP_SALPAL_MCE_PROCESSOR_CPUIDINFO_OMITTED;
  2500. gHalpSalPalDataFlags |= HALP_SALPAL_MCE_PROCESSOR_STATICINFO_PARTIAL;
  2501. }
  2502. else if ( RecordSize == 0x18 ) {
  2503. //
  2504. // Handle SAL 3.0 formats but with HAL exposing _ERROR_RECORD_HEADER definition
  2505. // without PlatformId field.
  2506. //
  2507. RecordSize += sizeof( gZeroedOemPlatformId );
  2508. //
  2509. // Handle SAL 3.0 formats but without CPUID_INFO member and with HAL not exposing
  2510. // _ERROR_PROCESSOR_CPUID_INFO and as such HALs which do not support the SAL/PAL FW
  2511. // workaround framework.
  2512. //
  2513. gHalpSalPalDataFlags |= HALP_SALPAL_MCE_PROCESSOR_CPUIDINFO_OMITTED;
  2514. gHalpSalPalDataFlags |= HALP_SALPAL_MCE_PROCESSOR_STATICINFO_PARTIAL;
  2515. }
  2516. //
  2517. // If HAL added the processor number to the ERROR_RECORD_HEADER,
  2518. // consider this here.
  2519. //
  2520. procNumberString[0] = '\0';
  2521. timeStamp = ReadField(TimeStamp);
  2522. if ( gMceProcNumberMaskTimeStamp ) {
  2523. ULONG procNumber;
  2524. procNumber = (ULONG) ReadField(TimeStamp.Reserved);
  2525. (void)sprintf(procNumberString, "\tProcNumber: %ld", procNumber);
  2526. timeStamp &= gMceProcNumberMaskTimeStamp;
  2527. }
  2528. //
  2529. // Back to standard processing here.
  2530. //
  2531. recordLength = (ULONG)ReadField(Length);
  2532. errorSeverity = (ULONG)ReadField(ErrorSeverity);
  2533. dprintf( ERROR_RECORD_HEADER_FORMAT_IA64,
  2534. McaLog, (McaLog + (ULONG64)recordLength),
  2535. (ULONGLONG) ReadField(Id),
  2536. (ULONG) ReadField(Revision),
  2537. (ULONG) ReadField(Revision.Major), (ULONG) ReadField(Revision.Minor),
  2538. errorSeverity, ErrorSeverityValueString( errorSeverity ),
  2539. (ULONG) ReadField(Valid),
  2540. (ULONG) ReadField(Valid.OemPlatformID),
  2541. recordLength,
  2542. timeStamp,
  2543. (ULONG) ReadField(TimeStamp.Seconds),
  2544. (ULONG) ReadField(TimeStamp.Minutes),
  2545. (ULONG) ReadField(TimeStamp.Hours),
  2546. (ULONG) ReadField(TimeStamp.Day),
  2547. (ULONG) ReadField(TimeStamp.Month),
  2548. (ULONG) ReadField(TimeStamp.Year),
  2549. (ULONG) ReadField(TimeStamp.Century),
  2550. (ULONG) ReadField(OemPlatformId[0x0]),
  2551. (ULONG) ReadField(OemPlatformId[0x1]),
  2552. (ULONG) ReadField(OemPlatformId[0x2]),
  2553. (ULONG) ReadField(OemPlatformId[0x3]),
  2554. (ULONG) ReadField(OemPlatformId[0x4]),
  2555. (ULONG) ReadField(OemPlatformId[0x5]),
  2556. (ULONG) ReadField(OemPlatformId[0x6]),
  2557. (ULONG) ReadField(OemPlatformId[0x7]),
  2558. (ULONG) ReadField(OemPlatformId[0x8]),
  2559. (ULONG) ReadField(OemPlatformId[0x9]),
  2560. (ULONG) ReadField(OemPlatformId[0xa]),
  2561. (ULONG) ReadField(OemPlatformId[0xb]),
  2562. (ULONG) ReadField(OemPlatformId[0xc]),
  2563. (ULONG) ReadField(OemPlatformId[0xd]),
  2564. (ULONG) ReadField(OemPlatformId[0xe]),
  2565. (ULONG) ReadField(OemPlatformId[0xf]),
  2566. procNumberString
  2567. );
  2568. if ( recordLength <= RecordSize ) {
  2569. dprintf( "Invalid RecordLength = %ld. <= RecordSize = %ld. Stop processing...\n\n",
  2570. recordLength,
  2571. RecordSize );
  2572. return( E_FAIL );
  2573. }
  2574. sectionSize = GetTypeSize( "hal!_ERROR_SECTION_HEADER" );
  2575. if ( sectionSize == 0 ) {
  2576. dprintf( "Unable to get HAL!_ERROR_SECTION_HEADER type size\n\n" );
  2577. return( E_FAIL );
  2578. }
  2579. if ( recordLength < (RecordSize + sectionSize) ) {
  2580. dprintf("Invalid RecordLength = %ld. < (RecordSize=%ld + SectionSize = %ld). Stop processing...\n\n",
  2581. recordLength,
  2582. RecordSize,
  2583. sectionSize );
  2584. return( E_FAIL );
  2585. }
  2586. //
  2587. // Initialize Error Sections processing.
  2588. //
  2589. SetErrorDeviceGuids();
  2590. //
  2591. // Pass through all the record sections.
  2592. //
  2593. section = McaLog + (ULONG64)RecordSize;
  2594. sectionMax = McaLog + recordLength;
  2595. if ( sectionMax <= (section + sectionSize) ) { // This should not happen...
  2596. dprintf("Invalid RecordLength = %ld. SectionMax < (Section + SectionSize). Stop processing...\n\n",
  2597. recordLength);
  2598. return( E_FAIL );
  2599. }
  2600. hr = S_OK;
  2601. while( (section < sectionMax) /* successful or not, we proceed... && SUCCEEDED(hr) */ ) {
  2602. ULONG sectionLength;
  2603. ERROR_SECTION_HEADER_TYPE_IA64 sectionType;
  2604. if ( InitTypeRead( section, hal!_ERROR_SECTION_HEADER ) ) {
  2605. dprintf( "Unable to read HAL!_ERROR_SECTION_HEADER at 0x%I64x. Stop processing...\n\n", section );
  2606. return( E_FAIL );
  2607. }
  2608. sectionLength = (ULONG)ReadField( Length );
  2609. sectionType = GetTypedErrorSectionType();
  2610. dprintf( ERROR_SECTION_HEADER_FORMAT_IA64,
  2611. section, (section + (ULONG64)sectionLength),
  2612. (ULONG) ReadField(Guid.Data1),
  2613. (ULONG) ReadField(Guid.Data2),
  2614. (ULONG) ReadField(Guid.Data3),
  2615. (ULONG) ReadField(Guid.Data4[0]),
  2616. (ULONG) ReadField(Guid.Data4[1]),
  2617. (ULONG) ReadField(Guid.Data4[2]),
  2618. (ULONG) ReadField(Guid.Data4[3]),
  2619. (ULONG) ReadField(Guid.Data4[4]),
  2620. (ULONG) ReadField(Guid.Data4[5]),
  2621. (ULONG) ReadField(Guid.Data4[6]),
  2622. (ULONG) ReadField(Guid.Data4[7]),
  2623. ErrorSectionTypeString( sectionType ),
  2624. (ULONG) ReadField(Revision),
  2625. (ULONG) ReadField(Revision.Major), (ULONG) ReadField(Revision.Minor),
  2626. (ULONG) ReadField(RecoveryInfo),
  2627. (ULONG) ReadField(RecoveryInfo.Corrected),
  2628. (ULONG) ReadField(RecoveryInfo.NotContained),
  2629. (ULONG) ReadField(RecoveryInfo.Reset),
  2630. (ULONG) ReadField(RecoveryInfo.Reserved),
  2631. (ULONG) ReadField(RecoveryInfo.Valid),
  2632. (ULONG) ReadField(Reserved),
  2633. sectionLength
  2634. );
  2635. switch( sectionType ) {
  2636. case ERROR_SECTION_PROCESSOR:
  2637. hr = DtErrorSectionProcessor( section );
  2638. break;
  2639. case ERROR_SECTION_PLATFORM_SPECIFIC:
  2640. hr = DtErrorSectionPlatformSpecific( section );
  2641. break;
  2642. case ERROR_SECTION_UNKNOWN:
  2643. default: // includes all the section types with incomplete processing...
  2644. hr = S_OK;
  2645. break;
  2646. }
  2647. if ( sectionLength ) {
  2648. dprintf( "\n" );
  2649. }
  2650. else {
  2651. // Prevents looping on the same section...
  2652. dprintf("Invalid section Length = 0. Stop processing...\n\n");
  2653. return( E_FAIL );
  2654. }
  2655. section += sectionLength;
  2656. }
  2657. return( hr );
  2658. } // DtMcaLog()
  2659. #define LOW2HIGH FALSE
  2660. #define HIGH2LOW TRUE
  2661. HRESULT
  2662. DtBitMapEnum(
  2663. ULONG64 Module,
  2664. ULONG TypeId,
  2665. UINT BitMap, // Enums are unsigned ints
  2666. BOOLEAN HighToLow
  2667. )
  2668. /*++
  2669. Routine Description:
  2670. This function dumps out a bitmap value composed of enums
  2671. Arugments:
  2672. Module -
  2673. TypeId -
  2674. BitMap -
  2675. Return Value:
  2676. HRESULT
  2677. --*/
  2678. {
  2679. ULONG size;
  2680. HRESULT hr;
  2681. hr = g_ExtSymbols->GetTypeSize( Module, TypeId, &size );
  2682. if ( SUCCEEDED(hr) ) {
  2683. CHAR name[MAX_PATH];
  2684. if ( BitMap ) {
  2685. ULONG map = (ULONG)BitMap;
  2686. ULONG i = 0;
  2687. BOOLEAN first = TRUE;
  2688. size *= 8;
  2689. dprintf("[");
  2690. while( map && (i <size) ) {
  2691. ULONG val;
  2692. val = (HighToLow) ? ((ULONG)0x80000000 >> i) : (0x1 << i);
  2693. if ( map & val ) {
  2694. hr = g_ExtSymbols->GetConstantName( Module,
  2695. TypeId,
  2696. (ULONG64)val,
  2697. name,
  2698. sizeof(name),
  2699. NULL );
  2700. if ( first ) {
  2701. first = FALSE;
  2702. }
  2703. else {
  2704. dprintf("|");
  2705. }
  2706. if ( SUCCEEDED(hr) ) {
  2707. dprintf("%s", name);
  2708. if ( !strcmp(name, "HAL_MCE_PROCNUMBER") ) {
  2709. gMceProcNumberMaskTimeStamp = (ULONGLONG)(LONG)~val;
  2710. }
  2711. }
  2712. else {
  2713. dprintf("0x%lx", val);
  2714. }
  2715. map &= ~val;
  2716. }
  2717. i++;
  2718. }
  2719. dprintf("]");
  2720. }
  2721. else {
  2722. // BitMap = 0
  2723. hr = g_ExtSymbols->GetConstantName( Module,
  2724. TypeId,
  2725. (ULONG64)BitMap,
  2726. name,
  2727. sizeof(name),
  2728. NULL
  2729. );
  2730. if ( SUCCEEDED(hr) ) {
  2731. dprintf("[%s]", name);
  2732. }
  2733. }
  2734. }
  2735. return hr;
  2736. } // DtBitMapEnum()
  2737. VOID
  2738. InitMcaIa64(
  2739. PCSTR args
  2740. )
  2741. //
  2742. // IA-64 !mca extension global initializations
  2743. //
  2744. {
  2745. USHORT flags;
  2746. ULONG64 halpSalPalDataAddress;
  2747. halpSalPalDataAddress = GetExpression("hal!HalpSalPalData");
  2748. if ( !InitTypeRead( halpSalPalDataAddress, hal!_HALP_SAL_PAL_DATA) ) {
  2749. gHalpSalPalDataFlags = (USHORT)ReadField( Flags );
  2750. }
  2751. // TF 04/27/01 TEMPTEMP
  2752. // Added the feature to force gHalpSalPalDataFlags to a known value to
  2753. // handle IA64 developers-release Firmware, without rebuilding the target hal.
  2754. flags = 0;
  2755. if (args && *args) {
  2756. flags = (USHORT)GetExpression( args );
  2757. dprintf("hal!HalpSalPalDataFlags is forced to 0x%lx - was 0x%lx\n\n", flags, gHalpSalPalDataFlags);
  2758. gHalpSalPalDataFlags = flags;
  2759. }
  2760. SetErrorSeverityValues();
  2761. return;
  2762. } // InitMcaIa64()
  2763. HRESULT
  2764. McaIa64(
  2765. PCSTR args
  2766. )
  2767. /*++
  2768. Routine Description:
  2769. Dumps processors IA64 Machine Check record and interprets any logged errors
  2770. Arguments:
  2771. PCSTR args
  2772. Return Value:
  2773. None
  2774. --*/
  2775. {
  2776. HRESULT status;
  2777. ULONG64 mcaLog;
  2778. ULONG recordSize;
  2779. ULONG featureBits;
  2780. // Thierry: 10/01/2000
  2781. // Very simple processing for now. We will be adding features with time.
  2782. // As a first enhancement, we could access the fist mca log address directly from
  2783. // _KPCR.OsMcaResource.EventPool.
  2784. //
  2785. status = S_OK;
  2786. if (!GetExpressionEx(args,&mcaLog, &args)) {
  2787. dprintf("USAGE: !mca 0xValue\n");
  2788. return E_INVALIDARG;
  2789. }
  2790. //
  2791. // Present HAL Feature Bits
  2792. //
  2793. status = GetGlobal("hal!HalpFeatureBits", featureBits);
  2794. if ( SUCCEEDED(status) ) {
  2795. ULONG typeId;
  2796. ULONG64 module;
  2797. dprintf("hal!HalpFeatureBits: 0x%lx ", featureBits);
  2798. status = g_ExtSymbols->GetSymbolTypeId("hal!_HALP_FEATURE", &typeId, &module);
  2799. if ( SUCCEEDED(status) ) {
  2800. DtBitMapEnum( module, typeId, featureBits, LOW2HIGH );
  2801. }
  2802. dprintf("\n\n");
  2803. }
  2804. else {
  2805. dprintf ("hal!HalpFeatureBits not found... sympath problems?.\n\n");
  2806. }
  2807. //
  2808. // Global initializations for record processing functions.
  2809. //
  2810. InitMcaIa64( args );
  2811. //
  2812. // Does our HAL pdb file have knowledge of IA64 Error formats?
  2813. //
  2814. recordSize = GetTypeSize( "hal!_ERROR_RECORD_HEADER" );
  2815. if ( recordSize && (InitTypeRead( mcaLog, hal!_ERROR_RECORD_HEADER ) == 0) ) {
  2816. status = DtMcaLog( mcaLog, recordSize );
  2817. }
  2818. else {
  2819. //
  2820. // In case we cannot extract the ERROR_RECORD_HEADER type, fall back here...
  2821. //
  2822. ERROR_RECORD_HEADER_IA64 recordHeader;
  2823. ULONG recordHeaderSize = (ULONG)sizeof(recordHeader);
  2824. ULONG bytesRead = 0;
  2825. status = E_FAIL;
  2826. dprintf("Unable to read HAL!_ERROR_RECORD_HEADER at 0x%I64x\n", mcaLog );
  2827. dprintf("Trying to read _ERROR_RECORD_HEADER directly from memory...\n" );
  2828. //
  2829. // Let's try to read error record from memory.
  2830. //
  2831. ReadMemory( mcaLog, &recordHeader, recordHeaderSize, &bytesRead );
  2832. if ( bytesRead >= recordHeaderSize ) {
  2833. DumpIa64ErrorRecordHeader( &recordHeader, mcaLog );
  2834. //
  2835. // no validity check is done inside the current version of DumpIa64ErrorRecordHeader
  2836. // Simply return S_OK.
  2837. status = S_OK;
  2838. }
  2839. else {
  2840. dprintf("Reading _ERROR_RECORD_HEADER directly from memory failed.\n" );
  2841. }
  2842. }
  2843. return status;
  2844. } // McaIa64()
  2845. DECLARE_API( mca )
  2846. /*++
  2847. Routine Description:
  2848. Dumps processors machine check architecture registers
  2849. and interprets any logged errors
  2850. Arguments:
  2851. PDEBUG_CLIENT Client
  2852. PCSTR args
  2853. Return Value:
  2854. None
  2855. --*/
  2856. {
  2857. HRESULT status;
  2858. ULONG processor = 0;
  2859. INIT_API();
  2860. GetCurrentProcessor(Client, &processor, NULL);
  2861. //
  2862. // Simply dispatch to the right target machine handler.
  2863. //
  2864. switch( TargetMachine ) {
  2865. case IMAGE_FILE_MACHINE_I386:
  2866. // Display architectural MCA information.
  2867. status = McaX86( args );
  2868. // Finally, Display stepping information for current processor.
  2869. DumpCpuInfoX86( processor, TRUE );
  2870. break;
  2871. case IMAGE_FILE_MACHINE_IA64:
  2872. // Display architectural MCA information.
  2873. status = McaIa64( args );
  2874. // Finally, Display stepping information for current processor.
  2875. DumpCpuInfoIA64( processor, TRUE );
  2876. break;
  2877. default:
  2878. dprintf("!mca is not supported for this target machine:%ld\n", TargetMachine);
  2879. status = E_INVALIDARG;
  2880. }
  2881. EXIT_API();
  2882. return status;
  2883. } // !mca