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

677 lines
18 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Copyright (c) 1992 Intel Corporation
  4. All rights reserved
  5. INTEL CORPORATION PROPRIETARY INFORMATION
  6. This software is supplied to Microsoft under the terms
  7. of a license agreement with Intel Corporation and may not be
  8. copied nor disclosed except in accordance with the terms
  9. of that agreement.
  10. Module Name:
  11. mpdebug.c
  12. Abstract:
  13. This module has some useful modules for debug aid.
  14. Author:
  15. Ron Mosgrove (Intel) - Aug 1993.
  16. Environment:
  17. Kernel mode or from textmode setup.
  18. Revision History:
  19. --*/
  20. #ifndef _NTOS_
  21. #include "halp.h"
  22. #endif
  23. #include "apic.inc"
  24. #include "pcmp_nt.inc"
  25. #include "stdio.h"
  26. #define PCMP_TABLE_PTR_BASE 0x09f000
  27. #define PCMP_TABLE_PTR_OFFSET 0x00000c00
  28. // Create dummy PC+MP table at physical address 400K
  29. #define PCMP_TEST_TABLE 0x64000
  30. #define TEST_FLOAT_PTR 0x7d000
  31. extern struct PcMpTable *PcMpTablePtr, *PcMpDefaultTablePtrs[];
  32. //extern struct HalpMpInfo *HalpMpInfoPtr;
  33. CHAR Cbuf[120];
  34. UCHAR
  35. ComputeCheckSum(
  36. IN PUCHAR SourcePtr,
  37. IN USHORT NumOfBytes
  38. );
  39. #ifdef OLD_DEBUG
  40. extern struct PcMpConfigTable *PcMpTablePtr;
  41. #endif
  42. #ifdef DEBUGGING
  43. ULONG HalpUseDbgPrint = 0;
  44. void
  45. HalpDisplayString(
  46. IN PVOID String
  47. )
  48. {
  49. if (!HalpUseDbgPrint) {
  50. HalDisplayString(String);
  51. } else {
  52. DbgPrint(String);
  53. }
  54. }
  55. void
  56. HalpDisplayItemBuf(
  57. IN UCHAR Length,
  58. IN PUCHAR Buffer,
  59. IN PVOID Name
  60. )
  61. {
  62. ULONG i;
  63. CHAR TmpBuf[80];
  64. sprintf(TmpBuf, " %s -", Name);
  65. HalpDisplayString(TmpBuf);
  66. for (i=0; i< Length; i++) {
  67. sprintf(TmpBuf, " 0x%x", Buffer[i]);
  68. HalpDisplayString(TmpBuf);
  69. }
  70. HalpDisplayString("\n");
  71. }
  72. void
  73. HalpDisplayULItemBuf(
  74. IN UCHAR Length,
  75. IN PULONG Buffer,
  76. IN PVOID Name
  77. )
  78. {
  79. ULONG i;
  80. CHAR TmpBuf[80];
  81. sprintf(TmpBuf, " %s -", Name);
  82. HalpDisplayString(TmpBuf);
  83. for (i=0; i< Length; i++) {
  84. sprintf(TmpBuf, " 0x%lx", Buffer[i]);
  85. HalpDisplayString(TmpBuf);
  86. }
  87. HalpDisplayString("\n");
  88. }
  89. void
  90. HalpDisplayItem(
  91. IN ULONG Item,
  92. IN PVOID ItemStr
  93. )
  94. {
  95. CHAR TmpBuf[80];
  96. sprintf(TmpBuf, " %s - 0x%x\n", ItemStr, Item);
  97. HalpDisplayString(TmpBuf);
  98. }
  99. VOID
  100. HalpDisplayBIOSSysCfg(
  101. IN struct SystemConfigTable *SysCfgPtr
  102. )
  103. {
  104. HalpDisplayString("BIOS System Configuration Table\n");
  105. HalpDisplayItem(SysCfgPtr->ModelType, "ModelType");
  106. HalpDisplayItem(SysCfgPtr->SubModelType, "SubModelType");
  107. HalpDisplayItem(SysCfgPtr->BIOSRevision, "BIOSRevision");
  108. HalpDisplayItemBuf(3,SysCfgPtr->FeatureInfoByte,"FeatureInfoByte");
  109. HalpDisplayItem(SysCfgPtr->MpFeatureInfoByte1, "MpFeatureInfoByte1");
  110. HalpDisplayItem(SysCfgPtr->MpFeatureInfoByte2, "MpFeatureInfoByte2");
  111. }
  112. VOID
  113. HalpDisplayLocalUnit(
  114. )
  115. {
  116. ULONG Data;
  117. PKPCR pPCR;
  118. pPCR = KeGetPcr();
  119. sprintf(Cbuf, "\nLocal Apic for P%d\n", pPCR->Prcb->Number);
  120. HalpDisplayString(Cbuf);
  121. #define DisplayLuReg(Reg, RegStr) Data = *((PVULONG) (LOCALAPIC+Reg)); \
  122. HalpDisplayItem(Data , RegStr);
  123. DisplayLuReg( LU_ID_REGISTER , "LU_ID_REGISTER" );
  124. DisplayLuReg( LU_VERS_REGISTER, "LU_VERS_REGISTER" );
  125. DisplayLuReg( LU_TPR, "LU_TPR");
  126. DisplayLuReg( LU_APR, "LU_APR");
  127. DisplayLuReg( LU_PPR, "LU_PPR");
  128. DisplayLuReg( LU_EOI, "LU_EOI");
  129. DisplayLuReg( LU_REMOTE_REGISTER, "LU_REMOTE_REGISTER");
  130. DisplayLuReg( LU_LOGICAL_DEST, "LU_LOGICAL_DEST");
  131. DisplayLuReg( LU_DEST_FORMAT, "LU_DEST_FORMAT");
  132. DisplayLuReg( LU_SPURIOUS_VECTOR , "LU_SPURIOUS_VECTOR" );
  133. DisplayLuReg( LU_ISR_0, "LU_ISR_0");
  134. DisplayLuReg( LU_TMR_0, "LU_TMR_0");
  135. DisplayLuReg( LU_IRR_0, "LU_IRR_0");
  136. DisplayLuReg( LU_ERROR_STATUS, "LU_ERROR_STATUS");
  137. DisplayLuReg( LU_INT_CMD_LOW, "LU_INT_CMD_LOW");
  138. DisplayLuReg( LU_INT_CMD_HIGH, "LU_INT_CMD_HIGH");
  139. DisplayLuReg( LU_TIMER_VECTOR, "LU_TIMER_VECTOR");
  140. DisplayLuReg( LU_INT_VECTOR_0, "LU_INT_VECTOR_0");
  141. DisplayLuReg( LU_INT_VECTOR_1, "LU_INT_VECTOR_1");
  142. DisplayLuReg( LU_INITIAL_COUNT, "LU_INITIAL_COUNT");
  143. DisplayLuReg( LU_CURRENT_COUNT, "LU_CURRENT_COUNT");
  144. DisplayLuReg( LU_DIVIDER_CONFIG, "LU_DIVIDER_CONFIG");
  145. HalpDisplayString("\n");
  146. }
  147. VOID
  148. HalpDisplayIoUnit(
  149. )
  150. /*++
  151. Routine Description:
  152. Verify that an IO Unit exists at the specified address
  153. Arguments:
  154. BaseAddress - Address of the IO Unit to test.
  155. Return Value:
  156. BOOLEAN - TRUE if a IO Unit was found at the passed address
  157. - FALSE otherwise
  158. --*/
  159. {
  160. #if 0
  161. struct ApicIoUnit *IoUnitPtr;
  162. ULONG Data,i,j;
  163. PKPCR pPCR;
  164. pPCR = KeGetPcr();
  165. //
  166. // The documented detection mechanism is to write all zeros to
  167. // the Version register. Then read it back. The IO Unit exists if the
  168. // same result is read both times and the Version is valid.
  169. //
  170. for (j=0; j<HalpMpInfoPtr->IOApicCount; j++) {
  171. IoUnitPtr = (struct ApicIoUnit *) HalpMpInfoPtr->IoApicBase[j];
  172. sprintf(Cbuf,"\nIoApic %d at Vaddr 0x%x\n",j,(ULONG) IoUnitPtr);
  173. HalpDisplayString(Cbuf);
  174. IoUnitPtr->RegisterSelect = IO_ID_REGISTER;
  175. HalpDisplayItem(IoUnitPtr->RegisterWindow, "IO_ID_REGISTER");
  176. IoUnitPtr->RegisterSelect = IO_VERS_REGISTER;
  177. HalpDisplayItem(IoUnitPtr->RegisterWindow, "IO_VERS_REGISTER");
  178. for (i=0; i<16; i++) {
  179. IoUnitPtr->RegisterSelect = IO_REDIR_00_LOW+(i*2);
  180. Data = IoUnitPtr->RegisterWindow;
  181. sprintf(Cbuf, " Redir [0x%x] - 0x%x, ", i, Data);
  182. HalpDisplayString(Cbuf);
  183. IoUnitPtr->RegisterSelect = IO_REDIR_00_LOW+(i*2)+1;
  184. Data = IoUnitPtr->RegisterWindow;
  185. sprintf(Cbuf, "0x%x\n", Data);
  186. HalpDisplayString(Cbuf);
  187. } // for each Redirection entry
  188. } // for all Io Apics
  189. #endif
  190. }
  191. void
  192. HalpDisplayConfigTable ()
  193. /*+++
  194. Debug routine to display the PC+MP config table
  195. --*/
  196. {
  197. struct PcMpTable *MpPtr = PcMpTablePtr;
  198. PPCMPPROCESSOR ProcPtr;
  199. ULONG EntriesInTable = MpPtr->NumOfEntries;
  200. union PL {
  201. USHORT us;
  202. POLARITYANDLEVEL PnL;
  203. };
  204. HalpDisplayString("PcMp Configuration Table\n");
  205. HalpDisplayItem(MpPtr->Signature, "Signature");
  206. HalpDisplayItem(MpPtr->TableLength, "TableLength");
  207. HalpDisplayItem(MpPtr->Revision, "Revision");
  208. HalpDisplayItem(MpPtr->Checksum, "Checksum");
  209. HalpDisplayItemBuf(sizeof(MpPtr->OemId),
  210. MpPtr->OemId,"OemId");
  211. HalpDisplayItemBuf(sizeof(MpPtr->OemProductId),
  212. MpPtr->OemProductId,"OemProductId");
  213. HalpDisplayItem((ULONG) MpPtr->OemTablePtr, "OemTablePtr");
  214. HalpDisplayItem(MpPtr->OemTableSize, "OemTableSize");
  215. HalpDisplayItem(MpPtr->NumOfEntries, "NumOfEntries");
  216. HalpDisplayItem((ULONG) MpPtr->LocalApicAddress, "LocalApicAddress");
  217. HalpDisplayItem(MpPtr->Reserved, "Reserved");
  218. ProcPtr = (PPCMPPROCESSOR) ((PUCHAR) MpPtr + HEADER_SIZE);
  219. while (EntriesInTable) {
  220. EntriesInTable--;
  221. switch ( ProcPtr->EntryType ) {
  222. case ENTRY_PROCESSOR: {
  223. union xxx {
  224. ULONG ul;
  225. CPUIDENTIFIER CpuId;
  226. } u;
  227. sprintf (Cbuf, "Proc..: ApicId %x, Apic ver %x, Flags %x\n",
  228. ProcPtr->LocalApicId,
  229. ProcPtr->LocalApicVersion,
  230. ProcPtr->CpuFlags
  231. );
  232. HalpDisplayString (Cbuf);
  233. ProcPtr++;
  234. break;
  235. }
  236. case ENTRY_BUS: {
  237. PPCMPBUS BusPtr = (PPCMPBUS) ProcPtr;
  238. sprintf (Cbuf, "Bus...: id %02x, type '%.6s'\n",
  239. BusPtr->BusId, BusPtr->BusType);
  240. HalpDisplayString (Cbuf);
  241. BusPtr++;
  242. ProcPtr = (PPCMPPROCESSOR) BusPtr;
  243. break;
  244. }
  245. case ENTRY_IOAPIC: {
  246. PPCMPIOAPIC IoApPtr = (PPCMPIOAPIC) ProcPtr;
  247. sprintf (Cbuf, "IoApic: id %02x, ver %x, Flags %x, Address %x\n",
  248. IoApPtr->IoApicId,
  249. IoApPtr->IoApicVersion,
  250. IoApPtr->IoApicFlag,
  251. (ULONG) IoApPtr->IoApicAddress
  252. );
  253. HalpDisplayString (Cbuf);
  254. IoApPtr++;
  255. ProcPtr = (PPCMPPROCESSOR) IoApPtr;
  256. break;
  257. }
  258. case ENTRY_INTI: {
  259. PPCMPINTI IntiPtr = (PPCMPINTI) ProcPtr;
  260. union PL u;
  261. u.PnL = IntiPtr->Signal;
  262. sprintf (Cbuf, "Inti..: t%x, s%x, SInt %x-%x, Inti %x-%x\n",
  263. IntiPtr->IntType,
  264. u.us,
  265. IntiPtr->SourceBusId,
  266. IntiPtr->SourceBusIrq,
  267. IntiPtr->IoApicId,
  268. IntiPtr->IoApicInti
  269. );
  270. HalpDisplayString (Cbuf);
  271. IntiPtr++;
  272. ProcPtr = (PPCMPPROCESSOR) IntiPtr;
  273. break;
  274. }
  275. case ENTRY_LINTI: {
  276. PPCMPLINTI LIntiPtr = (PPCMPLINTI) ProcPtr;
  277. union PL u;
  278. u.PnL = LIntiPtr->Signal;
  279. sprintf (Cbuf, "Linti.: t%x, s%x, SInt %x-%x, Linti %x-%x\n",
  280. LIntiPtr->IntType,
  281. u.us,
  282. LIntiPtr->SourceBusId,
  283. LIntiPtr->SourceBusIrq,
  284. LIntiPtr->DestLocalApicId,
  285. LIntiPtr->DestLocalApicInti
  286. );
  287. HalpDisplayString (Cbuf);
  288. LIntiPtr++;
  289. ProcPtr = (PPCMPPROCESSOR) LIntiPtr;
  290. break;
  291. }
  292. default: {
  293. HalpDisplayItem(ProcPtr->EntryType, "Unknown Type");
  294. return;
  295. }
  296. }
  297. }
  298. }
  299. void
  300. HalpDisplayExtConfigTable ()
  301. {
  302. PMPS_EXTENTRY ExtTable;
  303. extern struct HalpMpInfo HalpMpInfoTable;
  304. ExtTable = HalpMpInfoTable.ExtensionTable;
  305. while (ExtTable < HalpMpInfoTable.EndOfExtensionTable) {
  306. switch (ExtTable->Type) {
  307. case EXTTYPE_BUS_ADDRESS_MAP:
  308. sprintf (Cbuf, "BusMap: id %02x, t%x Base %08x Len %08x\n",
  309. ExtTable->u.AddressMap.BusId,
  310. ExtTable->u.AddressMap.Type,
  311. (ULONG) ExtTable->u.AddressMap.Base,
  312. (ULONG) ExtTable->u.AddressMap.Length
  313. );
  314. HalpDisplayString (Cbuf);
  315. break;
  316. case EXTTYPE_BUS_HIERARCHY:
  317. sprintf (Cbuf, "BusHie: id %02x, Parent:%x sd:%x\n",
  318. ExtTable->u.BusHierarchy.BusId,
  319. ExtTable->u.BusHierarchy.ParentBusId,
  320. ExtTable->u.BusHierarchy.SubtractiveDecode
  321. );
  322. HalpDisplayString (Cbuf);
  323. break;
  324. case EXTTYPE_BUS_COMPATIBLE_MAP:
  325. sprintf (Cbuf, "ComBus: id %02x %c List %x\n",
  326. ExtTable->u.CompatibleMap.BusId,
  327. ExtTable->u.CompatibleMap.Modifier ? '-' : '+',
  328. ExtTable->u.CompatibleMap.List
  329. );
  330. HalpDisplayString (Cbuf);
  331. break;
  332. case EXTTYPE_PERSISTENT_STORE:
  333. sprintf (Cbuf, "PreSTR: Address %08x Len %08x\n",
  334. (ULONG) ExtTable->u.PersistentStore.Address,
  335. (ULONG) ExtTable->u.PersistentStore.Length
  336. );
  337. HalpDisplayString (Cbuf);
  338. break;
  339. default:
  340. HalpDisplayItem(ExtTable->Type, "Unknown Type");
  341. break;
  342. }
  343. ExtTable = (PMPS_EXTENTRY) (((PUCHAR) ExtTable) + ExtTable->Length);
  344. }
  345. }
  346. void
  347. HalpDisplayMpInfo()
  348. {
  349. #if 0
  350. struct HalpMpInfo *MpPtr = HalpMpInfoPtr;
  351. HalpDisplayString("\nHAL: Private Mp Info\n");
  352. HalpDisplayItem(MpPtr->ApicVersion, "ApicVersion");
  353. HalpDisplayItem(MpPtr->ProcessorCount, "ProcessorCount");
  354. HalpDisplayItem(MpPtr->BusCount, "BusCount");
  355. HalpDisplayItem(MpPtr->IOApicCount, "IOApicCount");
  356. HalpDisplayItem(MpPtr->IntiCount, "IntiCount");
  357. HalpDisplayItem(MpPtr->LintiCount, "LintiCount");
  358. HalpDisplayItem(MpPtr->IMCRPresent, "IMCRPresent");
  359. HalpDisplayULItemBuf(4,(PULONG) MpPtr->IoApicBase,"IoApicBase");
  360. HalpDisplayString("\n");
  361. HalpDisplayConfigTable();
  362. #endif
  363. }
  364. #ifdef OLD_DEBUG
  365. BOOLEAN
  366. HalpVerifyLocalUnit(
  367. IN UCHAR ApicID
  368. )
  369. /*++
  370. Routine Description:
  371. Verify that a Local Apic has the specified Apic Id.
  372. Arguments:
  373. ApicId - Id to verify.
  374. Return Value:
  375. BOOLEAN - TRUE if found
  376. - FALSE otherwise
  377. --*/
  378. {
  379. union ApicUnion Temp;
  380. //
  381. // The remote read command must be:
  382. //
  383. // Vector - Bits 4-9 of the Version register
  384. // Destination Mode - Physical
  385. // Trigger Mode - Edge
  386. // Delivery Mode - Remote Read
  387. // Destination Shorthand - Destination Field
  388. //
  389. #define LU_READ_REMOTE_VERSION ( (LU_VERS_REGISTER >> 4) | \
  390. DELIVER_REMOTE_READ | \
  391. ICR_USE_DEST_FIELD)
  392. #define DEFAULT_DELAY 100
  393. PVULONG LuDestAddress = (PVULONG) (LOCALAPIC + LU_INT_CMD_HIGH);
  394. PVULONG LuICR = (PVULONG) (LOCALAPIC + LU_INT_CMD_LOW);
  395. PVULONG LuRemoteReg = (PVULONG) (LOCALAPIC + LU_REMOTE_REGISTER);
  396. ULONG RemoteReadStatus;
  397. ULONG DelayCount = DEFAULT_DELAY;
  398. //
  399. // First make sure we can get to the Apic Bus
  400. //
  401. while ( ( DelayCount-- ) && ( *LuICR & DELIVERY_PENDING ) );
  402. if (DelayCount == 0) {
  403. //
  404. // We're toast, can't gain access to the APIC Bus
  405. //
  406. return (FALSE);
  407. }
  408. //
  409. // Set the Address of the APIC we're looking for
  410. //
  411. *LuDestAddress = (ApicID << DESTINATION_SHIFT);
  412. //
  413. // Issue the request
  414. //
  415. *LuICR = LU_READ_REMOTE_VERSION;
  416. //
  417. // Reset the Delay so we can get out of here just in case...
  418. //
  419. DelayCount = DEFAULT_DELAY;
  420. while (DelayCount--) {
  421. RemoteReadStatus = *LuICR & ICR_RR_STATUS_MASK;
  422. if ( RemoteReadStatus == ICR_RR_INVALID) {
  423. //
  424. // No One responded, device timed out
  425. //
  426. return (FALSE);
  427. }
  428. if ( RemoteReadStatus == ICR_RR_VALID) {
  429. //
  430. // Someone is there and the Remote Register is valid
  431. //
  432. Temp.Raw = *LuRemoteReg;
  433. //
  434. // Do what we can to verify the Version
  435. //
  436. if (Temp.Ver.Version > 0x1f) {
  437. //
  438. // Only known devices are 0.x and 1.x
  439. //
  440. return (FALSE);
  441. }
  442. return (TRUE);
  443. } // RemoteRead Successfull
  444. } // While DelayCount
  445. //
  446. // No One responded, and the device did not time out
  447. // This should never happen
  448. //
  449. return (FALSE);
  450. }
  451. #endif // OLD_DEBUG
  452. VOID
  453. CreateBIOSTables(
  454. VOID)
  455. /*++
  456. Routine Description:
  457. This routine is used to test the PC+MP detect code in the HAL.
  458. It creates the PC+MP structures that are really created by the
  459. BIOS. Since we presently do not have a BIOS that builds a PC+MP
  460. table, we need this for now.
  461. Arguments:
  462. None.
  463. Return Value:
  464. None.
  465. --*/
  466. {
  467. PUCHAR TempPtr, BytePtr;
  468. UCHAR CheckSum;
  469. PULONG TraversePtr;
  470. USHORT BytesToCopy;
  471. HalpDisplayString("CreateBIOSTables : Entered\n");
  472. // First, copy default PC+MP configuration 2 table at physical
  473. // address PCMP_TEST_TABLE
  474. TempPtr = (PUCHAR) HalpMapPhysicalMemory(
  475. (PVOID) PCMP_TEST_TABLE, 1);
  476. BytesToCopy = (PcMpDefaultTablePtrs[1])->TableLength;
  477. RtlMoveMemory(TempPtr, (PUCHAR)PcMpDefaultTablePtrs[1],
  478. BytesToCopy);
  479. // Populate the checksum entry for the table.
  480. CheckSum = ComputeCheckSum(TempPtr, BytesToCopy);
  481. sprintf(Cbuf, "CreateBIOSTables: PC+MP table computed checksum = %x\n",
  482. CheckSum);
  483. HalpDisplayString(Cbuf);
  484. CheckSum = ~CheckSum + 1;
  485. ((struct PcMpTable *)TempPtr)->Checksum = CheckSum;
  486. sprintf(Cbuf, "CreateBIOSTables: PC+MP table written checksum = %x\n",
  487. CheckSum);
  488. HalpDisplayString(Cbuf);
  489. // Now create the floating pointer structure for the table.
  490. TraversePtr = (PULONG) HalpMapPhysicalMemory( (PVOID) TEST_FLOAT_PTR, 1);
  491. TempPtr = (PUCHAR) TraversePtr;
  492. *TraversePtr++ = MP_PTR_SIGNATURE;
  493. *TraversePtr++ = PCMP_TEST_TABLE;
  494. BytePtr = (PUCHAR)TraversePtr;
  495. *BytePtr++ = 1; // Length in number of 16 byte paragraphs
  496. *BytePtr++ = 1; // Spec Rev.
  497. *BytePtr++ = 0; // CheckSum
  498. *BytePtr++ = 0; // Reserved
  499. TraversePtr = (PULONG)BytePtr;
  500. *TraversePtr = 0; // Reserved
  501. CheckSum = ComputeCheckSum(TempPtr,16);
  502. sprintf(Cbuf, "CreateBIOSTables: FLOAT_PTR computed checksum = %x\n",
  503. CheckSum);
  504. HalpDisplayString(Cbuf);
  505. CheckSum = ~CheckSum + 1;
  506. sprintf(Cbuf, "CreateBIOSTables: FLOAT_PTR written checksum = %x\n",
  507. CheckSum);
  508. HalpDisplayString(Cbuf);
  509. ((struct PcMpTableLocator *)TempPtr)->TableChecksum = CheckSum;
  510. HalpDisplayString("CreateBIOSTables : Done\n");
  511. }
  512. #endif // DEBUGGING