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.

3661 lines
95 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. acpi.c
  5. Abstract:
  6. WinDbg Extension Api for interpretting ACPI data structures
  7. Supports rsdt, fadt, facs, mapic, gbl and inf
  8. Author:
  9. Ported to 64 bit by Graham Laverty (t-gralav) 10-Mar-2000
  10. Based on Code by:
  11. Stephane Plante (splante) 21-Mar-1997
  12. Peter Wieland (peterwie) 16-Oct-1995
  13. Ken Reneris (kenr) 06-June-1994
  14. Environment:
  15. User Mode.
  16. Revision History:
  17. Ported to 64 bit by Graham Laverty (t-gralav) 10-Mar-2000
  18. --*/
  19. #include "precomp.h"
  20. #pragma hdrstop // Needed ? (what does it do?)
  21. //
  22. // Verbose flags (for device extensions)
  23. //
  24. #define VERBOSE_1 0x01
  25. #define VERBOSE_2 0x02
  26. //
  27. // BUG BUG
  28. // These need to be converted to enums in the ACPI Driver
  29. //
  30. #define DATAF_BUFF_ALIAS 0x00000001
  31. #define DATAF_GLOBAL_LOCK 0x00000002
  32. #define OBJTYPE_UNKNOWN 0x00
  33. #define OBJTYPE_INTDATA 0x01
  34. #define OBJTYPE_STRDATA 0x02
  35. #define OBJTYPE_BUFFDATA 0x03
  36. #define OBJTYPE_PKGDATA 0x04
  37. #define OBJTYPE_FIELDUNIT 0x05
  38. #define OBJTYPE_DEVICE 0x06
  39. #define OBJTYPE_EVENT 0x07
  40. #define OBJTYPE_METHOD 0x08
  41. #define OBJTYPE_MUTEX 0x09
  42. #define OBJTYPE_OPREGION 0x0a
  43. #define OBJTYPE_POWERRES 0x0b
  44. #define OBJTYPE_PROCESSOR 0x0c
  45. #define OBJTYPE_THERMALZONE 0x0d
  46. #define OBJTYPE_BUFFFIELD 0x0e
  47. #define OBJTYPE_DDBHANDLE 0x0f
  48. #define OBJTYPE_DEBUG 0x10
  49. #define OBJTYPE_INTERNAL 0x80
  50. #define OBJTYPE_OBJALIAS (OBJTYPE_INTERNAL + 0x00)
  51. #define OBJTYPE_DATAALIAS (OBJTYPE_INTERNAL + 0x01)
  52. #define OBJTYPE_BANKFIELD (OBJTYPE_INTERNAL + 0x02)
  53. #define OBJTYPE_FIELD (OBJTYPE_INTERNAL + 0x03)
  54. #define OBJTYPE_INDEXFIELD (OBJTYPE_INTERNAL + 0x04)
  55. #define OBJTYPE_DATA (OBJTYPE_INTERNAL + 0x05)
  56. #define OBJTYPE_DATAFIELD (OBJTYPE_INTERNAL + 0x06)
  57. #define OBJTYPE_DATAOBJ (OBJTYPE_INTERNAL + 0x07)
  58. // definition of FADT.flags bits
  59. // this one bit flag indicates whether or not the WBINVD instruction works properly,if this bit is not set we can not use S2, S3 states, or
  60. // C3 on MP machines
  61. #define WRITEBACKINVALIDATE_WORKS_BIT 0
  62. #define WRITEBACKINVALIDATE_WORKS (1 << WRITEBACKINVALIDATE_WORKS_BIT)
  63. // this flag indicates if wbinvd works EXCEPT that it does not invalidate the cache
  64. #define WRITEBACKINVALIDATE_DOESNT_INVALIDATE_BIT 1
  65. #define WRITEBACKINVALIDATE_DOESNT_INVALIDATE (1 << WRITEBACKINVALIDATE_DOESNT_INVALIDATE_BIT)
  66. // this flag indicates that the C1 state is supported on all processors.
  67. #define SYSTEM_SUPPORTS_C1_BIT 2
  68. #define SYSTEM_SUPPORTS_C1 (1 << SYSTEM_SUPPORTS_C1_BIT)
  69. // this one bit flag indicates whether support for the C2 state is restricted to uniprocessor machines
  70. #define P_LVL2_UP_ONLY_BIT 3
  71. #define P_LVL2_UP_ONLY (1 << P_LVL2_UP_ONLY_BIT)
  72. // this bit indicates whether the PWR button is treated as a fix feature (0) or a generic feature (1)
  73. #define PWR_BUTTON_GENERIC_BIT 4
  74. #define PWR_BUTTON_GENERIC (1 << PWR_BUTTON_GENERIC_BIT)
  75. #define SLEEP_BUTTON_GENERIC_BIT 5
  76. #define SLEEP_BUTTON_GENERIC (1 << SLEEP_BUTTON_GENERIC_BIT)
  77. // this bit indicates whether the RTC wakeup status is reported in fix register space (0) or not (1)
  78. #define RTC_WAKE_GENERIC_BIT 6
  79. #define RTC_WAKE_GENERIC (1 << RTC_WAKE_GENERIC_BIT)
  80. #define RTC_WAKE_FROM_S4_BIT 7
  81. #define RTC_WAKE_FROM_S4 (1 << RTC_WAKE_FROM_S4_BIT)
  82. // This bit indicates whether the machine implements a 24 or 32 bit timer.
  83. #define TMR_VAL_EXT_BIT 8
  84. #define TMR_VAL_EXT (1 << TMR_VAL_EXT_BIT)
  85. // This bit indicates whether the machine supports docking
  86. //#define DCK_CAP_BIT 9
  87. //#define DCK_CAP (1 << DCK_CAP_BIT)
  88. // This bit indicates whether the machine supports reset
  89. #define RESET_CAP_BIT 10
  90. #define RESET_CAP (1 << RESET_CAP_BIT)
  91. //
  92. // Definition of FADT.boot_arch flags
  93. //
  94. #define LEGACY_DEVICES 1
  95. #define I8042 2
  96. //
  97. // Verbose flags (for contexts)
  98. //
  99. #define VERBOSE_CONTEXT 0x01
  100. #define VERBOSE_CALL 0x02
  101. #define VERBOSE_HEAP 0x04
  102. #define VERBOSE_OBJECT 0x08
  103. #define VERBOSE_NSOBJ 0x10
  104. #define VERBOSE_RECURSE 0x20
  105. UCHAR Buffer[2048];
  106. #define RSDP_SIGNATURE 0x2052545020445352 // "RSD PTR "
  107. #define RSDT_SIGNATURE 0x54445352 // "RSDT"
  108. #define FADT_SIGNATURE 0x50434146 // "FACP"
  109. #define FACS_SIGNATURE 0x53434146 // "FACS"
  110. #define APIC_SIGNATURE 0x43495041 // "APIC"
  111. #ifndef NEC_98
  112. #define RSDP_SEARCH_RANGE_BEGIN 0xE0000 // physical address where we begin searching for the RSDP
  113. #else // NEC_98
  114. #define RSDP_SEARCH_RANGE_BEGIN 0xE8000 // physical address where we begin searching for the RSDP
  115. #endif // NEC_98
  116. #define RSDP_SEARCH_RANGE_END 0xFFFFF
  117. #define RSDP_SEARCH_RANGE_LENGTH (RSDP_SEARCH_RANGE_END-RSDP_SEARCH_RANGE_BEGIN+1)
  118. #define RSDP_SEARCH_INTERVAL 16 // search on 16 byte boundaries
  119. // FACS Stuff ************************************************************************************
  120. // FACS Flags definitions
  121. #define FACS_S4BIOS_SUPPORTED_BIT 0 // flag indicates whether or not the BIOS will save/restore memory around S4
  122. #define FACS_S4BIOS_SUPPORTED (1 << FACS_S4BIOS_SUPPORTED_BIT)
  123. // FACS.GlobalLock bit field definitions
  124. #define GL_PENDING_BIT 0x00
  125. #define GL_PENDING (1 << GL_PENDING_BIT)
  126. #define GL_OWNER_BIT 0x01
  127. #define GL_OWNER (1 << GL_OWNER_BIT)
  128. //#define GL_NON_RESERVED_BITS_MASK (GL_PENDING+GL_OWNED)
  129. // MAPIC Stuff ************************************************************************************
  130. // Multiple APIC description table
  131. // Multiple APIC structure flags
  132. #define PCAT_COMPAT_BIT 0 // indicates that the system also has a dual 8259 pic setup.
  133. #define PCAT_COMPAT (1 << PCAT_COMPAT_BIT)
  134. // APIC Structure Types
  135. #define PROCESSOR_LOCAL_APIC 0
  136. #define IO_APIC 1
  137. #define ISA_VECTOR_OVERRIDE 2
  138. #define IO_NMI_SOURCE 3
  139. #define LOCAL_NMI_SOURCE 4
  140. #define ADDRESS_EXTENSION_STRUCTURE 5
  141. #define IO_SAPIC 6
  142. #define LOCAL_SAPIC 7
  143. #define PLATFORM_INTERRUPT_SOURCE 8
  144. #define PROCESSOR_LOCAL_APIC_LENGTH 8
  145. #define IO_APIC_LENGTH 12
  146. #define ISA_VECTOR_OVERRIDE_LENGTH 10
  147. #define IO_NMI_SOURCE_LENGTH 8
  148. #define LOCAL_NMI_SOURCE_LENGTH 6
  149. #define PLATFORM_INTERRUPT_SOURCE_LENGTH 16
  150. #define IO_SAPIC_LENGTH 16
  151. #define PROCESSOR_LOCAL_SAPIC_LENGTH 12
  152. // Platform Interrupt Types
  153. #define PLATFORM_INT_PMI 1
  154. #define PLATFORM_INT_INIT 2
  155. #define PLATFORM_INT_CPE 3
  156. // Processor Local APIC Flags
  157. #define PLAF_ENABLED_BIT 0
  158. #define PLAF_ENABLED (1 << PLAF_ENABLED_BIT)
  159. // These defines come from the MPS 1.4 spec, section 4.3.4 and they are referenced as
  160. // such in the ACPI spec.
  161. #define PO_BITS 3
  162. #define POLARITY_HIGH 1
  163. #define POLARITY_LOW 3
  164. #define POLARITY_CONFORMS_WITH_BUS 0
  165. #define EL_BITS 0xc
  166. #define EL_BIT_SHIFT 2
  167. #define EL_EDGE_TRIGGERED 4
  168. #define EL_LEVEL_TRIGGERED 0xc
  169. #define EL_CONFORMS_WITH_BUS 0
  170. #define FADT_REV_1_SIZE 116
  171. #define FADT_REV_2_SIZE 129
  172. #define FADT_REV_3_SIZE 244
  173. // GBL Stuff ************************************************************************************
  174. //
  175. // This structure lets us know the state of one entry in the RSDT
  176. //
  177. // INF Stuff ************************************************************************************
  178. //
  179. // descriptions of bits in ACPIInformation.ACPI_Flags
  180. //
  181. #define C2_SUPPORTED_BIT 3
  182. #define C2_SUPPORTED (1 << C2_SUPPORTED_BIT)
  183. #define C3_SUPPORTED_BIT 4
  184. #define C3_SUPPORTED (1 << C3_SUPPORTED_BIT)
  185. #define C3_PREFERRED_BIT 5
  186. #define C3_PREFERRED (1 << C3_PREFERRED_BIT)
  187. //
  188. // descriptions of bits in ACPIInformation.ACPI_Capabilities
  189. //
  190. #define CSTATE_C1_BIT 4
  191. #define CSTATE_C1 (1 << CSTATE_C1_BIT)
  192. #define CSTATE_C2_BIT 5
  193. #define CSTATE_C2 (1 << CSTATE_C2_BIT)
  194. #define CSTATE_C3_BIT 6
  195. #define CSTATE_C3 (1 << CSTATE_C3_BIT)
  196. #define DUMP_FLAG_NO_INDENT 0x000001
  197. #define DUMP_FLAG_NO_EOL 0x000002
  198. #define DUMP_FLAG_SINGLE_LINE 0x000004
  199. #define DUMP_FLAG_TABLE 0x000008
  200. #define DUMP_FLAG_LONG_NAME 0x000010
  201. #define DUMP_FLAG_SHORT_NAME 0x000020
  202. #define DUMP_FLAG_SHOW_BIT 0x000040
  203. #define DUMP_FLAG_ALREADY_INDENTED 0x000080
  204. typedef struct _FLAG_RECORD {
  205. ULONGLONG Bit;
  206. PCCHAR ShortName;
  207. PCCHAR LongName;
  208. PCCHAR NotShortName;
  209. PCCHAR NotLongName;
  210. } FLAG_RECORD, *PFLAG_RECORD;
  211. FLAG_RECORD PM1ControlFlags[] = {
  212. { 0x0001, "", "SCI_EN" , NULL, NULL },
  213. { 0x0002, "", "BM_RLD" , NULL, NULL },
  214. { 0x0004, "", "GBL_RLS" , NULL, NULL },
  215. { 0x0400, "", "SLP_TYP0" , NULL, NULL },
  216. { 0x0800, "", "SLP_TYP1" , NULL, NULL },
  217. { 0x1000, "", "SLP_TYP2" , NULL, NULL },
  218. { 0x2000, "", "SLP_EN" , NULL, NULL },
  219. };
  220. FLAG_RECORD PM1StatusFlags[] = {
  221. { 0x0001, "", "TMR_STS" , NULL, NULL },
  222. { 0x0010, "", "BM_STS" , NULL, NULL },
  223. { 0x0020, "", "GBL_STS" , NULL, NULL },
  224. { 0x0100, "", "PWRBTN_STS" , NULL, NULL },
  225. { 0x0200, "", "SLPBTN_STS" , NULL, NULL },
  226. { 0x0400, "", "RTC_STS" , NULL, NULL },
  227. { 0x8000, "", "WAK_STS" , NULL, NULL },
  228. };
  229. FLAG_RECORD PM1EnableFlags[] = {
  230. { 0x0001, "", "TMR_EN" , NULL, NULL },
  231. { 0x0020, "", "GBL_EN" , NULL, NULL },
  232. { 0x0100, "", "PWRBTN_EN" , NULL, NULL },
  233. { 0x0200, "", "SLPBTN_EN" , NULL, NULL },
  234. { 0x0400, "", "RTC_EN" , NULL, NULL },
  235. };
  236. #define RSDTELEMENT_MAPPED 0x1
  237. ULONG64 AcpiRsdtAddress = 0;
  238. ULONG64 AcpiFadtAddress = 0;
  239. ULONG64 AcpiFacsAddress = 0;
  240. ULONG64 AcpiMapicAddress = 0;
  241. //
  242. // Local Function Prototypes
  243. //
  244. VOID dumpNSObject(IN ULONG64 Address, IN ULONG Verbose, IN ULONG IndentLevel);
  245. //
  246. // Actual code
  247. //
  248. BOOL
  249. ReadPhysicalOrVirtual(
  250. IN ULONG64 Address,
  251. IN PVOID Buffer,
  252. IN ULONG Size,
  253. IN OUT PULONG ReturnLength,
  254. IN BOOL Virtual
  255. )
  256. /*++
  257. Routine Description:
  258. This is a way to abstract out the differences between ROM images
  259. and mapped memory
  260. Arguments:
  261. Address - Where (either physical, or virtual) the buffer is located
  262. Buffer - Address of where to copy the memory to
  263. Size - How many bytes to copy (maximum)
  264. ReturnLength - How many bytes where copied
  265. Virtual - False if this is physical memory
  266. --*/
  267. {
  268. BOOL status = TRUE;
  269. PHYSICAL_ADDRESS physicalAddress = { 0L, 0L };
  270. if (Virtual) {
  271. status = ReadMemory(
  272. Address,
  273. Buffer,
  274. Size,
  275. ReturnLength
  276. );
  277. } else {
  278. physicalAddress.QuadPart = Address;
  279. ReadPhysical(
  280. physicalAddress.QuadPart,
  281. Buffer,
  282. Size,
  283. ReturnLength
  284. );
  285. }
  286. if (ReturnLength && *ReturnLength != Size) {
  287. //
  288. // Didn't get enough memory
  289. //
  290. status = FALSE;
  291. }
  292. return status;
  293. }
  294. BOOLEAN
  295. findRSDT(
  296. IN PULONG64 Address
  297. )
  298. /*++
  299. Routine Description:
  300. This searchs the memory on the target system for the RSDT pointer
  301. Arguments:
  302. Address - Where to store the result
  303. Return Value:
  304. TRUE - If we found the RSDT
  305. --*/
  306. {
  307. PHYSICAL_ADDRESS address = { 0L, 0L };
  308. UCHAR index;
  309. UCHAR sum;
  310. ULONG64 limit;
  311. ULONG returnLength = 0;
  312. ULONG64 start, initAddress;
  313. ULONGLONG compSignature;
  314. ULONG addr;
  315. int siz;
  316. //
  317. // Calculate the start and end of the search range
  318. //
  319. start = RSDP_SEARCH_RANGE_BEGIN;
  320. limit = start + RSDP_SEARCH_RANGE_LENGTH - RSDP_SEARCH_INTERVAL;
  321. dprintf( "Searching for RSDP.");
  322. //
  323. // Loop for a while
  324. //
  325. for (; start <= limit; start += RSDP_SEARCH_INTERVAL) {
  326. if (start % (RSDP_SEARCH_INTERVAL * 100 ) == 0) {
  327. dprintf(".");
  328. if (CheckControlC()) {
  329. return FALSE;
  330. }
  331. }
  332. //
  333. // Read the data from the target
  334. //
  335. address.LowPart = (ULONG) start;
  336. memset( Buffer, 0, GetTypeSize("hal!_RSDT_32") );
  337. ReadPhysical( address.QuadPart, &Buffer, GetTypeSize("hal!_RSDP"), &returnLength);
  338. if (returnLength != GetTypeSize("hal!_RSDP")) {
  339. dprintf(
  340. "%#08lx: Read %#08lx of %#08lx bytes\n",
  341. start,
  342. returnLength,
  343. GetTypeSize("hal!_RSDP")
  344. );
  345. return FALSE;
  346. }
  347. //
  348. // Is this a match?
  349. //
  350. // INIT TYPE READ PHYSICAL TAKES MAYBE 15 TIME LONGER!
  351. initAddress = InitTypeReadPhysical( address.QuadPart, hal!_RSDP );
  352. if ( ReadField(Signature) != RSDP_SIGNATURE) {
  353. continue;
  354. }
  355. //
  356. // Check the checksum out
  357. //
  358. for (index = 0, sum = 0; index < GetTypeSize("hal!_RSDP"); index++) {
  359. sum = (UCHAR) (sum + *( (UCHAR *) ( (ULONG64) &Buffer + index ) ) );
  360. }
  361. if (sum != 0) {
  362. continue;
  363. }
  364. //
  365. // Found RSDP
  366. //
  367. dprintf("\nRSDP - %016I64x\n", start );
  368. initAddress = InitTypeReadPhysical( address.QuadPart, hal!_RSDP );
  369. // The following error message has been remarked out because the FIRST call to
  370. // a InitTypeReadPhysical does NOT access the memory (and returns error 0x01:
  371. // MEMORY_READ_ERROR. This is done when ReadField happens, so IT STILL WORKS.
  372. // The false error message is a kd bug, and will be fixed in a later build.
  373. // Once this has been done, feel free to unremark it.
  374. // if (initAddress) {
  375. // dprintf("Failed to initialize hal!_RSDP. Error code: %d.", initAddress);
  376. // }
  377. initAddress = ReadField(Signature);
  378. memset( Buffer, 0, 2048 );
  379. memcpy( Buffer, &initAddress, GetTypeSize("ULONGLONG") );
  380. dprintf(" Signature: %s\n", Buffer );
  381. dprintf(" Checksum: %#03x\n", (UCHAR) ReadField(Checksum) );
  382. initAddress = ReadField(OEMID);
  383. GetFieldOffset( "hal!_RSDP", "OEMID", &addr);
  384. memset( Buffer, 0, GetTypeSize("ULONGLONG") );
  385. ReadPhysical( (address.QuadPart + (ULONG64) addr), &Buffer, 6, &returnLength);
  386. if (returnLength != 6) { // 6 is hard-coded in the specs
  387. dprintf( "%#08lx: Read %#08lx of 6 bytes in OEMID\n", (address.QuadPart + (ULONG64)addr), returnLength, GetTypeSize("hal!_RSDP") );
  388. return FALSE;
  389. }
  390. dprintf(" OEMID: %s\n", Buffer );
  391. dprintf(" Reserved: %#02x\n", ReadField(Reserved) );
  392. dprintf(" RsdtAddress: %016I64x\n", ReadField(RsdtAddress) );
  393. //
  394. // Done
  395. //
  396. *Address = ReadField(RsdtAddress);//rsdp.RsdtAddress;
  397. return TRUE;
  398. }
  399. return FALSE;
  400. }
  401. PUCHAR
  402. ReadPhysVirField(
  403. IN ULONG64 Address,
  404. IN PUCHAR StructName,
  405. IN PUCHAR FieldName,
  406. IN ULONG Length,
  407. IN BOOLEAN Physical
  408. )
  409. /*++
  410. Routine Description:
  411. This function returns a text string field from physical or virtual memory
  412. into Buffer, then returns Buffer
  413. Arugments:
  414. Address - Where the table is located
  415. StructName - Structure name
  416. FieldName - Field name
  417. Length - Length (number of characters) in field
  418. Physical - Read from Physical (TRUE) or Virtual Memory
  419. Return Value:
  420. String containing contents
  421. --*/
  422. {
  423. ULONG addr;
  424. ULONG returnLength;
  425. memset( Buffer, 0, Length + 1);
  426. GetFieldOffset( StructName, FieldName, &addr);
  427. if (Physical) {
  428. ReadPhysical( (Address + (ULONG64) addr), &Buffer, Length, &returnLength);
  429. } else {
  430. ReadMemory( (Address + (ULONG64) addr), &Buffer, Length, &returnLength);
  431. }
  432. return Buffer;
  433. }
  434. VOID
  435. dumpHeader(
  436. IN ULONG64 Address,
  437. IN BOOLEAN Verbose,
  438. IN BOOLEAN Physical
  439. )
  440. /*++
  441. Routine Description:
  442. This function dumps out a table header
  443. Arugments:
  444. Address - Where the table is located
  445. Header - The table header
  446. Verbose - How much information to give
  447. Return Value:
  448. NULL
  449. --*/
  450. {
  451. if (Physical) {
  452. InitTypeReadPhysical( Address, hal!_DESCRIPTION_HEADER);
  453. } else {
  454. InitTypeRead( Address, hal!_DESCRIPTION_HEADER);
  455. }
  456. if (Verbose) {
  457. dprintf(
  458. "HEADER - %016I64x\n"
  459. " Signature: %s\n"
  460. " Length: 0x%08lx\n"
  461. " Revision: 0x%02x\n"
  462. " Checksum: 0x%02x\n",
  463. Address,
  464. ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "Signature", sizeof(ULONG), Physical),
  465. (ULONG) ReadField(Length),
  466. (UCHAR) ReadField(Revision),
  467. (UCHAR) ReadField(Checksum)
  468. );
  469. dprintf(" OEMID: %s\n", ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "OEMID", 6, Physical) );
  470. dprintf(" OEMTableID: %s\n", ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "OEMTableID", 8, Physical) );
  471. dprintf(" OEMRevision: 0x%08lx\n", ReadField(OEMRevision) );
  472. dprintf(" CreatorID: %s\n", ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "CreatorID", 4, Physical) );
  473. dprintf(" CreatorRev: 0x%08lx\n", ReadField(CreatorRev) );
  474. } else {
  475. dprintf(
  476. " %s @(%016I64x) Rev: %#03x Len: %#08lx",
  477. ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "Signature", sizeof(ULONG64), Physical),
  478. Address,
  479. (UCHAR) ReadField(Revision),
  480. (ULONG) ReadField(Length)
  481. );
  482. dprintf(" TableID: %s\n", ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "OEMTableID", 8, Physical) );
  483. }
  484. return;
  485. }
  486. VOID
  487. dumpRSDT(
  488. IN ULONG64 Address,
  489. IN BOOLEAN Physical
  490. )
  491. /*++
  492. Routine Description:
  493. This search the dumps the RSDT table
  494. Arguments:
  495. Pointer to the table
  496. Return Value:
  497. NONE
  498. --*/
  499. {
  500. BOOL status;
  501. ULONG64 index;
  502. ULONG64 numEntries;
  503. ULONG addr;
  504. ULONG returnLength = 0;
  505. ULONG64 a;
  506. dprintf("RSDT - ");
  507. if (Physical) { // The following do NOT have their status read as a bug in the return value would give us errors when none exist. The signature check would catch them, anyway.
  508. InitTypeReadPhysical( Address, hal!_DESCRIPTION_HEADER);
  509. } else {
  510. InitTypeRead( Address, hal!_DESCRIPTION_HEADER);
  511. }
  512. if (ReadField(Signature) != RSDT_SIGNATURE) {
  513. dprintf(
  514. "dumpRSDT: Invalid Signature 0x%08lx != RSDT_SIGNATURE\n",
  515. ReadField(Signature)
  516. );
  517. dumpHeader( Address, TRUE, Physical );
  518. return;
  519. }
  520. dumpHeader( Address, TRUE, Physical );
  521. dprintf("RSDT - BODY - %016I64x\n", Address + GetTypeSize("hal!_DESCRIPTION_HEADER") );
  522. numEntries = ( ReadField(Length) - GetTypeSize("hal!_DESCRIPTION_HEADER") ) /
  523. sizeof(ULONG);
  524. GetFieldOffset( "hal!_RSDT_32", "Tables", &addr);
  525. for (index = 0; index < numEntries; index++) {
  526. //
  527. // Note: unless things radically change, the pointers in the
  528. // rsdt will always point to bios memory!
  529. //
  530. if (Physical) {
  531. ReadPhysical(Address + index + (ULONG64) addr, &a, 4, &returnLength);
  532. } else {
  533. ReadPointer(Address + index + (ULONG64) addr, &a);
  534. }
  535. dumpHeader( a, FALSE, TRUE );
  536. }
  537. return;
  538. }
  539. VOID
  540. dumpFADT(
  541. IN ULONG64 Address
  542. )
  543. /*++
  544. Routine Description:
  545. This dumps the FADT at the specified address
  546. Arguments:
  547. The address where the FADT is located at
  548. Return Value:
  549. NONE
  550. --*/
  551. {
  552. ULONG fadtLength;
  553. ULONG addr;
  554. ULONG flags;
  555. UCHAR Revision;
  556. UCHAR AddressSpaceID;
  557. ULONG64 reset_reg_addr;
  558. PCHAR addressSpace;
  559. BOOLEAN Physical = FALSE;
  560. //
  561. // First check to see if we find the correct things
  562. //
  563. dprintf("FADT -- %p", Address);
  564. if (Physical) {
  565. InitTypeReadPhysical( Address, hal!_DESCRIPTION_HEADER);
  566. } else {
  567. InitTypeRead( Address, hal!_DESCRIPTION_HEADER);
  568. }
  569. if (ReadField(Signature) != FADT_SIGNATURE) {
  570. dprintf(
  571. "dumpRSDT: Invalid Signature 0x%08lx != FADT_SIGNATURE\n",
  572. ReadField(Signature)
  573. );
  574. dumpHeader( Address, TRUE, Physical );
  575. return;
  576. }
  577. Revision = (UCHAR)ReadField(Revision);
  578. if (Revision == 1) {
  579. fadtLength = FADT_REV_1_SIZE;
  580. } else if (Revision == 2) {
  581. fadtLength = FADT_REV_2_SIZE;
  582. } else if (Revision == 3) {
  583. fadtLength = FADT_REV_3_SIZE;
  584. } else {
  585. dprintf("FADT revision is %d, which is not understood by this debugger\n", Revision);
  586. fadtLength = FADT_REV_3_SIZE;
  587. }
  588. //
  589. // Do we have a correctly sized data structure
  590. //
  591. if ((ULONG) ReadField(Length) < fadtLength) {
  592. dprintf(
  593. "dumpFADT: (%016I64x) Length (%#08lx) is not the size of the FADT (%#08lx)\n",
  594. Address,
  595. (ULONG) ReadField(Length),
  596. fadtLength
  597. );
  598. dumpHeader( Address, TRUE, Physical );
  599. return;
  600. }
  601. //
  602. // Dump the table
  603. //
  604. dumpHeader( Address, TRUE, Physical );
  605. if (Physical) { // Physical/Virtual should have been established above
  606. InitTypeReadPhysical( Address, hal!_FADT);
  607. } else {
  608. InitTypeRead( Address, hal!_FADT);
  609. }
  610. dprintf(
  611. "FADT - BODY - %016I64x\n"
  612. " FACS: 0x%08lx\n"
  613. " DSDT: 0x%08lx\n"
  614. " Int Model: %s\n"
  615. " SCI Vector: 0x%03x\n"
  616. " SMI Port: 0x%08lx\n"
  617. " ACPI On Value: 0x%03x\n"
  618. " ACPI Off Value: 0x%03x\n"
  619. " SMI CMD For S4 State: 0x%03x\n"
  620. " PM1A Event Block: 0x%08lx\n"
  621. " PM1B Event Block: 0x%08lx\n"
  622. " PM1 Event Length: 0x%03x\n"
  623. " PM1A Control Block: 0x%08lx\n"
  624. " PM1B Control Block: 0x%08lx\n"
  625. " PM1 Control Length: 0x%03x\n"
  626. " PM2 Control Block: 0x%08lx\n"
  627. " PM2 Control Length: 0x%03x\n"
  628. " PM Timer Block: 0x%08lx\n"
  629. " PM Timer Length: 0x%03x\n"
  630. " GP0 Block: 0x%08lx\n"
  631. " GP0 Length: 0x%03x\n"
  632. " GP1 Block: 0x%08lx\n"
  633. " GP1 Length: 0x%08lx\n"
  634. " GP1 Base: 0x%08lx\n"
  635. " C2 Latency: 0x%05lx\n"
  636. " C3 Latency: 0x%05lx\n"
  637. " Memory Flush Size: 0x%05lx\n"
  638. " Memory Flush Stride: 0x%05lx\n"
  639. " Duty Cycle Index: 0x%03x\n"
  640. " Duty Cycle Index Width: 0x%03x\n"
  641. " Day Alarm Index: 0x%03x\n"
  642. " Month Alarm Index: 0x%03x\n"
  643. " Century byte (CMOS): 0x%03x\n"
  644. " Boot Architecture: 0x%04x\n"
  645. " Flags: 0x%08lx\n",
  646. Address + GetTypeSize("hal!_DESCRIPTION_HEADER"),
  647. (ULONG) ReadField(facs),
  648. (ULONG) ReadField(dsdt),
  649. (ReadField(int_model) == 0 ? "Dual PIC" : "Multiple APIC" ),
  650. (USHORT) ReadField(sci_int_vector),
  651. (ULONG) ReadField(smi_cmd_io_port),
  652. (UCHAR) ReadField(acpi_on_value),
  653. (UCHAR) ReadField(acpi_off_value),
  654. (UCHAR) ReadField(s4bios_req),
  655. (ULONG) ReadField(pm1a_evt_blk_io_port),
  656. (ULONG) ReadField(pm1b_evt_blk_io_port),
  657. (UCHAR) ReadField(pm1_evt_len),
  658. (ULONG) ReadField(pm1a_ctrl_blk_io_port),
  659. (ULONG) ReadField(pm1b_ctrl_blk_io_port),
  660. (UCHAR) ReadField(pm1_ctrl_len),
  661. (ULONG) ReadField(pm2_ctrl_blk_io_port),
  662. (UCHAR) ReadField(pm2_ctrl_len),
  663. (ULONG) ReadField(pm_tmr_blk_io_port),
  664. (UCHAR) ReadField(pm_tmr_len),
  665. (ULONG) ReadField(gp0_blk_io_port),
  666. (UCHAR) ReadField(gp0_blk_len),
  667. (ULONG) ReadField(gp1_blk_io_port),
  668. (UCHAR) ReadField(gp1_blk_len),
  669. (UCHAR) ReadField(gp1_base),
  670. (USHORT) ReadField(lvl2_latency),
  671. (USHORT) ReadField(lvl3_latency),
  672. #ifndef _IA64_ // XXTF
  673. (USHORT) ReadField(flush_size),
  674. (USHORT) ReadField(flush_stride),
  675. (UCHAR) ReadField(duty_offset),
  676. (UCHAR) ReadField(duty_width),
  677. #endif
  678. (UCHAR) ReadField(day_alarm_index),
  679. (UCHAR) ReadField(month_alarm_index),
  680. (UCHAR) ReadField(century_alarm_index),
  681. (USHORT) ReadField(boot_arch),
  682. (ULONG) ReadField(flags)
  683. );
  684. flags = (ULONG) ReadField(flags);
  685. if (flags & WRITEBACKINVALIDATE_WORKS) {
  686. dprintf(" Write Back Invalidate is supported\n");
  687. }
  688. if (flags & WRITEBACKINVALIDATE_DOESNT_INVALIDATE) {
  689. dprintf(" Write Back Invalidate doesn't invalidate the caches\n");
  690. }
  691. if (flags & SYSTEM_SUPPORTS_C1) {
  692. dprintf(" System supports C1 Power state on all processors\n");
  693. }
  694. if (flags & P_LVL2_UP_ONLY) {
  695. dprintf(" System supports C2 in MP and UP configurations\n");
  696. }
  697. if (flags & PWR_BUTTON_GENERIC) {
  698. dprintf(" Power Button is treated as a generic feature\n");
  699. }
  700. if (flags & SLEEP_BUTTON_GENERIC) {
  701. dprintf(" Sleep Button is treated as a generic feature\n");
  702. }
  703. if (flags & RTC_WAKE_GENERIC) {
  704. dprintf(" RTC Wake is not supported in fixed register space\n");
  705. }
  706. if (flags & RTC_WAKE_FROM_S4) {
  707. dprintf(" RTC Wake can work from an S4 state\n");
  708. }
  709. if (flags & TMR_VAL_EXT) {
  710. dprintf(" TMR_VAL implemented as 32-bit value\n");
  711. }
  712. if (Revision > 1) {
  713. if (!(ReadField(boot_arch) & LEGACY_DEVICES)) {
  714. dprintf(" The machine does not contain legacy ISA devices\n");
  715. }
  716. if (!(ReadField(boot_arch) & I8042)) {
  717. dprintf(" The machine does not contain a legacy i8042\n");
  718. }
  719. if (flags & RESET_CAP) {
  720. dprintf(" The reset register is supported\n");
  721. dprintf(" Reset Val: %x\n", ReadField(reset_val));
  722. GetFieldOffset("hal!_FADT", "reset_reg", &addr);
  723. GetFieldValue(Address + (ULONG64)addr, "hal!_GEN_ADDR", "AddressSpaceID", AddressSpaceID);
  724. switch (AddressSpaceID) {
  725. case 0:
  726. addressSpace = "Memory";
  727. break;
  728. case 1:
  729. addressSpace = "I/O";
  730. break;
  731. case 2:
  732. addressSpace = "PCIConfig";
  733. break;
  734. default:
  735. addressSpace = "undefined";
  736. }
  737. GetFieldOffset("hal!_GEN_ADDR", "Address", &addr);
  738. GetFieldValue(Address + (ULONG64)addr, "hal!_LARGE_INTEGER", "QuadPart", reset_reg_addr);
  739. dprintf(" Reset register: %s - %016I64x\n",
  740. addressSpace,
  741. reset_reg_addr
  742. );
  743. }
  744. }
  745. return;
  746. }
  747. BOOL
  748. GetUlongPtr (
  749. IN PCHAR String,
  750. IN PULONG64 Address
  751. )
  752. {
  753. ULONG64 Location;
  754. Location = GetExpression( String );
  755. if (!Location) {
  756. dprintf("Sorry: Unable to get %s.\n",String);
  757. return FALSE;
  758. }
  759. return ReadPointer(Location, Address);
  760. }
  761. DECLARE_API( rsdt )
  762. {
  763. BOOLEAN Physical = FALSE;
  764. if (args != NULL) {
  765. AcpiRsdtAddress = GetExpression( args ); // Should work
  766. }
  767. if (AcpiRsdtAddress == 0) {
  768. UINT64 status; // formerly BOOL
  769. ULONG64 address;
  770. status = GetUlongPtr( "ACPI!AcpiInformation", &address );
  771. if (status == TRUE) {
  772. status = GetFieldValue(address,"ACPI!_ACPIInformation","RootSystemDescTable",AcpiRsdtAddress);
  773. }
  774. }
  775. if (AcpiRsdtAddress == 0) {
  776. if (!findRSDT( &AcpiRsdtAddress) ) {
  777. dprintf("Could not locate the RSDT pointer\n");
  778. return E_INVALIDARG;
  779. }
  780. Physical = TRUE;
  781. }
  782. dumpRSDT( AcpiRsdtAddress, Physical );
  783. return S_OK;
  784. }
  785. DECLARE_API( fadt )
  786. {
  787. if (args != NULL && *args != '\0') {
  788. AcpiFadtAddress = GetExpression( args );
  789. }
  790. if (AcpiFadtAddress == 0) {
  791. AcpiFadtAddress = GetExpression( "HAL!HalpFixedAcpiDescTable" );
  792. }
  793. if (AcpiFadtAddress == 0) {
  794. dprintf("fadt <address>\n");
  795. return E_INVALIDARG;
  796. }
  797. dumpFADT( AcpiFadtAddress );
  798. return S_OK;
  799. }
  800. VOID
  801. dumpFACS(
  802. IN ULONG64 Address
  803. )
  804. /*++
  805. Routine Description:
  806. This dumps the FADT at the specified address
  807. Arguments:
  808. The address where the FADT is located at
  809. Return Value:
  810. NONE
  811. --*/
  812. {
  813. BOOLEAN Physical = FALSE;
  814. //
  815. // Read the data
  816. //
  817. dprintf("FACS - %016I64x\n", Address);
  818. if (Physical) {
  819. InitTypeReadPhysical( Address, hal!_FACS);
  820. } else {
  821. InitTypeRead( Address, hal!_FACS);
  822. }
  823. if (ReadField(Signature) != FACS_SIGNATURE) {
  824. dprintf(
  825. "dumpFACS: Invalid Signature 0x%08lx != FACS_SIGNATURE\n",
  826. (ULONG) ReadField(Signature)
  827. );
  828. return;
  829. }
  830. //
  831. // Dump the table
  832. //
  833. dprintf(
  834. " Signature: %s\n"
  835. " Length: %#08lx\n"
  836. " Hardware Signature: %#08lx\n"
  837. " Firmware Wake Vector: %#08lx\n"
  838. " Global Lock : %#08lx\n",
  839. ReadPhysVirField(Address, "hal!_FACS", "Signature", sizeof(ULONG), Physical),
  840. ReadField(Length),
  841. ReadField(HardwareSignature),
  842. ReadField(pFirmwareWakingVector),
  843. ReadField(GlobalLock)
  844. );
  845. if ( (ReadField(GlobalLock) & GL_PENDING) ) {
  846. dprintf(" Request for Ownership Pending\n");
  847. }
  848. if ( (ReadField(GlobalLock) & GL_OWNER) ) {
  849. dprintf(" Global Lock is Owned\n");
  850. }
  851. dprintf(" Flags: %#08lx\n", (ULONG) ReadField(Flags) );
  852. if ( (ReadField(Flags) & FACS_S4BIOS_SUPPORTED) ) {
  853. dprintf(" S4BIOS_REQ Supported\n");
  854. }
  855. return;
  856. }
  857. DECLARE_API( facs )
  858. {
  859. if (args != NULL) {
  860. AcpiFacsAddress = GetExpression( args );
  861. }
  862. if (AcpiFacsAddress == 0) {
  863. BOOL status;
  864. UINT64 address;
  865. status = GetUlongPtr( "ACPI!AcpiInformation", &address );
  866. if (status == TRUE) {
  867. status = GetFieldValue(address,"ACPI!_ACPIInformation","FirmwareACPIControlStructure",AcpiFacsAddress);
  868. }
  869. }
  870. if (AcpiFacsAddress == 0) {
  871. dprintf("facs <address>\n");
  872. return E_INVALIDARG;
  873. }
  874. dumpFACS( AcpiFacsAddress );
  875. return S_OK;
  876. }
  877. // ReturnXxx Functions - these are just a few functions I wrote that simplify
  878. // dealing with certain types of Symbols
  879. CHAR
  880. ReturnChar(
  881. IN ULONG64 Address,
  882. IN PUCHAR StructName,
  883. IN PUCHAR FieldName
  884. )
  885. /*++
  886. Routine Description:
  887. Return char using GetFieldValue
  888. --*/
  889. {
  890. char returnChar;
  891. if (GetFieldValue(Address, StructName, FieldName, returnChar)){
  892. //
  893. // Failed. try just the base symbols name before giving up
  894. //
  895. PUCHAR symName=NULL;
  896. ULONG i;
  897. for(i=strlen(StructName); i > 0 && StructName[i] != '!'; i--);
  898. i++;
  899. symName = StructName + i;
  900. //
  901. // Try again
  902. //
  903. GetFieldValue(Address, symName, FieldName, returnChar);
  904. }
  905. return returnChar;
  906. }
  907. ULONG
  908. ReturnUSHORT(
  909. IN ULONG64 Address,
  910. IN PUCHAR StructName,
  911. IN PUCHAR FieldName
  912. )
  913. /*++
  914. Routine Description:
  915. Return USHORT using GetFieldValue
  916. --*/
  917. {
  918. USHORT returnUSHORT;
  919. if (GetFieldValue(Address, StructName, FieldName, returnUSHORT)){
  920. //
  921. // Failed. try just the base symbols name before giving up
  922. //
  923. PUCHAR symName=NULL;
  924. ULONG i;
  925. for(i=strlen(StructName); i > 0 && StructName[i] != '!'; i--);
  926. i++;
  927. symName = StructName + i;
  928. //
  929. // Try again
  930. //
  931. GetFieldValue(Address, symName, FieldName, returnUSHORT);
  932. }
  933. return returnUSHORT;
  934. }
  935. ULONG
  936. ReturnULONG(
  937. IN ULONG64 Address,
  938. IN PUCHAR StructName,
  939. IN PUCHAR FieldName
  940. )
  941. /*++
  942. Routine Description:
  943. Return ULONG using GetFieldValue
  944. --*/
  945. {
  946. ULONG returnULONG;
  947. if (GetFieldValue(Address, StructName, FieldName, returnULONG)){
  948. //
  949. // Failed. try just the base symbols name before giving up
  950. //
  951. PUCHAR symName=NULL;
  952. ULONG i;
  953. for(i=strlen(StructName); i > 0 && StructName[i] != '!'; i--);
  954. i++;
  955. symName = StructName + i;
  956. //
  957. // Try again
  958. //
  959. GetFieldValue(Address, symName, FieldName, returnULONG);
  960. }
  961. return returnULONG;
  962. }
  963. ULONG64
  964. ReturnULONG64(
  965. IN ULONG64 Address,
  966. IN PUCHAR StructName,
  967. IN PUCHAR FieldName
  968. )
  969. /*++
  970. Routine Description:
  971. Return ULONG64 using GetFieldValue
  972. --*/
  973. {
  974. ULONG64 returnULONG64;
  975. if (GetFieldValue(Address, StructName, FieldName, returnULONG64)){
  976. //
  977. // Failed. try just the base symbols name before giving up
  978. //
  979. PUCHAR symName=NULL;
  980. ULONG i;
  981. for(i=strlen(StructName); i > 0 && StructName[i] != '!'; i--);
  982. i++;
  983. symName = StructName + i;
  984. //
  985. // Try again
  986. //
  987. GetFieldValue(Address, symName, FieldName, returnULONG64);
  988. }
  989. return returnULONG64;
  990. }
  991. VOID
  992. dumpMAPIC(
  993. IN ULONG64 Address
  994. )
  995. /*++
  996. Routine Description:
  997. This dumps the multiple apic table
  998. Arguments:
  999. Address of the table
  1000. Return Value:
  1001. None
  1002. --*/
  1003. {
  1004. BOOL hasMPSFlags;
  1005. BOOL status;
  1006. BOOL virtualMemory;
  1007. ULONG mapicLength;
  1008. ULONG64 iso; // interruptSourceOverride
  1009. USHORT isoFlags;
  1010. ULONG64 buffer;
  1011. ULONG64 limit;
  1012. ULONG index;
  1013. ULONG returnLength;
  1014. ULONG flags;
  1015. ULONG get_value;
  1016. BOOLEAN Physical = FALSE;
  1017. //
  1018. // First check to see if we find the correct things
  1019. //
  1020. dprintf("MAPIC - ");
  1021. if (Physical) {
  1022. InitTypeReadPhysical( Address, hal!_DESCRIPTION_HEADER);
  1023. } else {
  1024. InitTypeRead( Address, hal!_DESCRIPTION_HEADER);
  1025. }
  1026. if (ReadField(Signature) != APIC_SIGNATURE) {
  1027. dprintf(
  1028. "dumpFACS: Invalid Signature 0x%08lx != APIC_SIGNATURE (%x)\n",
  1029. (ULONG) ReadField(Signature),
  1030. APIC_SIGNATURE
  1031. );
  1032. return;
  1033. }
  1034. mapicLength = (ULONG)ReadField(Length);
  1035. dumpHeader( Address, TRUE, FALSE );
  1036. dprintf("MAPIC - BODY - %016I64x\n", Address + GetTypeSize("hal!_DESCRIPTION_HEADER") );
  1037. dprintf(" Local APIC Address: %#08lx\n", ReturnULONG(Address, "hal!_MAPIC","LocalAPICAddress"));
  1038. GetFieldValue(Address,"hal!_MAPIC","Flags",get_value);
  1039. dprintf(" Flags: %#08lx\n", get_value );
  1040. if (get_value & PCAT_COMPAT) { // Check the flags
  1041. dprintf(" PC-AT dual 8259 compatible setup\n");
  1042. }
  1043. //gsig2
  1044. GetFieldOffset( "hal!_MAPIC", "APICTables", &get_value);
  1045. buffer = Address + get_value;
  1046. limit = ( Address + ReadField(Length) );
  1047. while (buffer < limit) {
  1048. if (CheckControlC()) {
  1049. break;
  1050. }
  1051. //
  1052. // Assume that no flags are set
  1053. //
  1054. hasMPSFlags = FALSE;
  1055. //
  1056. // Lets see what kind of table we have?
  1057. //
  1058. iso = (ULONG64) buffer;
  1059. //
  1060. // Is it a localApic?
  1061. //
  1062. if (ReturnChar(iso, "acpi!_PROCLOCALAPIC", "Type") == PROCESSOR_LOCAL_APIC) {
  1063. buffer += ReturnChar(iso, "acpi!_PROCLOCALAPIC", "Length");
  1064. dprintf(
  1065. " Processor Local Apic\n"
  1066. " ACPI Processor ID: 0x%02x\n"
  1067. " APIC ID: 0x%02x\n"
  1068. " Flags: 0x%08lx\n",
  1069. ReturnChar(iso, "acpi!_PROCLOCALAPIC", "ACPIProcessorID"),
  1070. ReturnChar(iso, "acpi!_PROCLOCALAPIC", "APICID"),
  1071. ReturnULONG(iso, "acpi!_PROCLOCALAPIC", "Flags")
  1072. );
  1073. if (ReturnULONG(iso, "acpi!_PROCLOCALAPIC", "Flags") & PLAF_ENABLED) {
  1074. dprintf(" Processor is Enabled\n");
  1075. }
  1076. if (ReturnChar(iso, "acpi!_PROCLOCALAPIC", "Length") != PROCESSOR_LOCAL_APIC_LENGTH) {
  1077. dprintf(
  1078. " Local Apic has length 0x%x instead of 0x%x\n",
  1079. ReturnChar(iso, "acpi!_PROCLOCALAPIC", "Length"),
  1080. PROCESSOR_LOCAL_APIC_LENGTH
  1081. );
  1082. break;
  1083. }
  1084. } else if (ReturnChar(iso, "hal!_IOAPIC", "Type") == IO_APIC) {
  1085. buffer += ReturnChar(iso, "hal!_IOAPIC", "Length");
  1086. dprintf(
  1087. " IO Apic\n"
  1088. " IO APIC ID: 0x%02x\n"
  1089. " IO APIC ADDRESS: 0x%08lx\n"
  1090. " System Vector Base: 0x%08lx\n",
  1091. ReturnChar(iso, "hal!_IOAPIC", "IOAPICID"),
  1092. ReturnULONG(iso, "hal!_IOAPIC", "IOAPICAddress"),
  1093. ReturnULONG(iso, "hal!_IOAPIC", "SystemVectorBase")
  1094. );
  1095. if (ReturnChar(iso, "hal!_IOAPIC", "Length") != IO_APIC_LENGTH) {
  1096. dprintf(
  1097. " IO Apic has length 0x%x instead of 0x%x\n",
  1098. ReturnChar(iso, "hal!_IOAPIC", "Length"),
  1099. IO_APIC_LENGTH
  1100. );
  1101. break;
  1102. }
  1103. } else if (ReturnChar(iso,"hal!_ISA_VECTOR","Type") == ISA_VECTOR_OVERRIDE) {
  1104. buffer += ReturnChar(iso, "hal!_ISA_VECTOR", "Length");
  1105. GetFieldValue(iso, "hal!_ISA_VECTOR", "Flags", isoFlags);
  1106. dprintf(
  1107. " Interrupt Source Override\n"
  1108. " Bus: 0x%02x\n"
  1109. " Source: 0x%02x\n"
  1110. " Global Interrupt: 0x%08lx\n"
  1111. " Flags: 0x%04x\n",
  1112. ReturnChar(iso, "hal!_ISA_VECTOR", "Bus"),
  1113. ReturnChar(iso, "hal!_ISA_VECTOR", "Source"),
  1114. ReturnULONG(iso, "hal!_ISA_VECTOR", "GlobalSystemInterruptVector"),
  1115. isoFlags
  1116. );
  1117. if (ReturnChar(iso,"hal!_ISA_VECTOR","Length") != ISA_VECTOR_OVERRIDE_LENGTH) {
  1118. dprintf(
  1119. " Interrupt Source Override has length 0x%x instead of 0x%x\n",
  1120. ReturnChar(iso, "hal!_ISA_VECTOR", "Length"),
  1121. ISA_VECTOR_OVERRIDE_LENGTH
  1122. );
  1123. break;
  1124. }
  1125. hasMPSFlags = TRUE;
  1126. flags = isoFlags;
  1127. } else if (ReturnChar(iso,"acpi!_IO_NMISOURCE","Type") == IO_NMI_SOURCE) {
  1128. buffer += ReturnChar(iso, "acpi!_IO_NMISOURCE", "Length");
  1129. GetFieldValue(iso, "acpi!_IO_NMISOURCE", "Flags", isoFlags);
  1130. dprintf(
  1131. " Non Maskable Interrupt Source - on I/O APIC\n"
  1132. " Flags: 0x%02x\n"
  1133. " Global Interrupt: 0x%08lx\n",
  1134. isoFlags,
  1135. ReturnULONG(iso, "acpi!_IO_NMISOURCE", "GlobalSystemInterruptVector")
  1136. );
  1137. if (ReturnChar(iso,"acpi!_IO_NMISOURCE","Length") != IO_NMI_SOURCE_LENGTH) {
  1138. dprintf(
  1139. " Non Maskable Interrupt source has length 0x%x instead of 0x%x\n",
  1140. ReturnChar(iso, "acpi!_IO_NMISOURCE", "Length"),
  1141. IO_NMI_SOURCE_LENGTH
  1142. );
  1143. break;
  1144. }
  1145. hasMPSFlags = TRUE;
  1146. flags = isoFlags;
  1147. } else if (ReturnChar(iso,"hal!_LOCAL_NMISOURCE","Type") == LOCAL_NMI_SOURCE) {
  1148. buffer += ReturnChar(iso, "hal!_LOCAL_NMISOURCE", "Length");
  1149. GetFieldValue(iso, "hal!_LOCAL_NMISOURCE", "Flags", isoFlags);
  1150. dprintf(
  1151. " Non Maskable Interrupt Source - local to processor\n"
  1152. " Flags: 0x%04x\n"
  1153. " Processor: 0x%02x %s\n"
  1154. " LINTIN: 0x%02x\n",
  1155. isoFlags,
  1156. ReturnChar(iso, "hal!_LOCAL_NMISOURCE", "ProcessorID"),
  1157. ReturnChar(iso,"hal!_LOCAL_NMISOURCE","ProcessorID") == 0xff ? "(all)" : "",
  1158. ReturnChar(iso, "hal!_LOCAL_NMISOURCE", "LINTIN")
  1159. );
  1160. if (ReturnChar(iso,"hal!_LOCAL_NMISOURCE","Length") != LOCAL_NMI_SOURCE_LENGTH) {
  1161. dprintf(
  1162. " Non Maskable Interrupt source has length 0x%x instead of 0x%x\n",
  1163. ReturnChar(iso, "hal!_LOCAL_NMISOURCE", "Length"),
  1164. IO_NMI_SOURCE_LENGTH
  1165. );
  1166. break;
  1167. }
  1168. hasMPSFlags = TRUE;
  1169. flags = isoFlags;
  1170. } else if (ReturnChar(iso, "hal!_PROCLOCALSAPIC", "Type") == LOCAL_SAPIC) {
  1171. buffer += ReturnChar(iso, "hal!_PROCLOCALSAPIC", "Length");
  1172. dprintf(
  1173. " Processor Local SAPIC\n"
  1174. " ACPI Processor ID: 0x%02x\n"
  1175. " APIC ID: 0x%02x\n"
  1176. " APIC EID: 0x%02x\n"
  1177. " Flags: 0x%08lx\n",
  1178. ReturnChar(iso, "hal!_PROCLOCALSAPIC", "ACPIProcessorID"),
  1179. ReturnChar(iso, "hal!_PROCLOCALSAPIC", "APICID"),
  1180. ReturnChar(iso, "hal!_PROCLOCALSAPIC", "APICEID"),
  1181. ReturnULONG(iso, "hal!_PROCLOCALSAPIC", "Flags")
  1182. );
  1183. if (ReturnChar(iso, "hal!_PROCLOCALSAPIC", "Length") != PROCESSOR_LOCAL_SAPIC_LENGTH) {
  1184. dprintf(
  1185. " Processor Local SAPIC has length 0x%x instead of 0x%x\n",
  1186. ReturnChar(iso, "hal!_PROCLOCALSAPIC", "Length"),
  1187. PROCESSOR_LOCAL_SAPIC_LENGTH
  1188. );
  1189. break;
  1190. }
  1191. } else if (ReturnChar(iso, "hal!_IOSAPIC", "Type") == IO_SAPIC) {
  1192. buffer += ReturnChar(iso, "hal!_IOSAPIC", "Length");
  1193. dprintf(
  1194. " IO SApic\n"
  1195. " IO SAPIC ADDRESS: 0x%016I64x\n"
  1196. " System Vector Base: 0x%08lx\n",
  1197. ReturnULONG64(iso, "hal!_IOSAPIC", "IOSAPICAddress"),
  1198. ReturnULONG(iso, "hal!_IOSAPIC", "SystemVectorBase")
  1199. );
  1200. if (ReturnChar(iso, "hal!_IOSAPIC", "Length") != IO_SAPIC_LENGTH) {
  1201. dprintf(
  1202. " IO SApic has length 0x%x instead of 0x%x\n",
  1203. ReturnChar(iso, "hal!_IOSAPIC", "Length"),
  1204. IO_SAPIC_LENGTH
  1205. );
  1206. break;
  1207. }
  1208. } else if (ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "Type") == PLATFORM_INTERRUPT_SOURCE) {
  1209. UCHAR InterruptType = ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "InterruptType");
  1210. buffer += ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "Length");
  1211. dprintf(
  1212. " Platform Interrupt Source\n"
  1213. " Flags: 0x%04x\n"
  1214. " Interrupt Type: %s\n"
  1215. " APICID: 0x%02x\n"
  1216. " APICEID: 0x%02x\n"
  1217. " IOSAPICVector: 0x%02x\n"
  1218. " GlobalVector: 0x%08x\n",
  1219. ReturnUSHORT(iso, "hal!_PLATFORM_INTERRUPT", "Flags"),
  1220. InterruptType == PLATFORM_INT_PMI ? "PMI" :
  1221. (InterruptType == PLATFORM_INT_INIT ? "INIT" :
  1222. (InterruptType == PLATFORM_INT_CPE ? "CPE" : "UNKNOWN")),
  1223. ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "APICID"),
  1224. ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "APICEID"),
  1225. ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "IOSAPICVector"),
  1226. ReturnULONG(iso, "hal!_PLATFORM_INTERRUPT", "GlobalVector")
  1227. );
  1228. if (ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "Length") != PLATFORM_INTERRUPT_SOURCE_LENGTH) {
  1229. dprintf(
  1230. " Platform Interrupt Source has length 0x%x instead of 0x%x\n",
  1231. ReturnChar(iso, "hal!_PLATFORM_INTERRUPT", "Length"),
  1232. PLATFORM_INTERRUPT_SOURCE_LENGTH
  1233. );
  1234. break;
  1235. }
  1236. } else {
  1237. dprintf(" UNKNOWN RECORD (%p)\n", iso);
  1238. dprintf(" Type: 0x%08x\n", ReturnChar(iso,"hal!_IOAPIC","Type"));
  1239. dprintf(" Length: 0x%08x\n", ReturnChar(iso,"hal!_IOAPIC","Length"));
  1240. //
  1241. // Dont spin forever if we encounter an known with zero length
  1242. //
  1243. if ((ReturnChar(iso,"hal!_IOAPIC","Length")) == 0) {
  1244. break;
  1245. }
  1246. buffer += ReturnChar(iso,"hal!_IOAPIC","Length");
  1247. }
  1248. //
  1249. // Do we have any flags to dump out?
  1250. //
  1251. if (hasMPSFlags) {
  1252. switch (flags & PO_BITS) {
  1253. case POLARITY_HIGH:
  1254. dprintf(" POLARITY_HIGH\n");
  1255. break;
  1256. case POLARITY_LOW:
  1257. dprintf(" POLARITY_LOW\n");
  1258. break;
  1259. case POLARITY_CONFORMS_WITH_BUS:
  1260. dprintf(" POLARITY_CONFORMS_WITH_BUS\n");
  1261. break;
  1262. default:
  1263. dprintf(" POLARITY_UNKNOWN\n");
  1264. break;
  1265. }
  1266. switch (flags & EL_BITS) {
  1267. case EL_EDGE_TRIGGERED:
  1268. dprintf(" EL_EDGE_TRIGGERED\n");
  1269. break;
  1270. case EL_LEVEL_TRIGGERED:
  1271. dprintf(" EL_LEVEL_TRIGGERED\n");
  1272. break;
  1273. case EL_CONFORMS_WITH_BUS:
  1274. dprintf(" EL_CONFORMS_WITH_BUS\n");
  1275. break;
  1276. default:
  1277. dprintf(" EL_UNKNOWN\n");
  1278. break;
  1279. }
  1280. }
  1281. }
  1282. return;
  1283. }
  1284. DECLARE_API( mapic )
  1285. {
  1286. if (args != NULL) {
  1287. AcpiMapicAddress = GetExpression( args );
  1288. }
  1289. if (AcpiMapicAddress == 0) {
  1290. BOOL status;
  1291. ULONG64 address;
  1292. status = GetUlongPtr( "ACPI!AcpiInformation", &address );
  1293. if (status == TRUE) {
  1294. status = GetFieldValue(address,"ACPI!_ACPIInformation","MultipleApicTable",AcpiMapicAddress);
  1295. }
  1296. }
  1297. if (AcpiMapicAddress == 0) {
  1298. dprintf("mapic <address>\n");
  1299. return E_INVALIDARG;
  1300. }
  1301. dumpMAPIC( AcpiMapicAddress );
  1302. return S_OK;
  1303. }
  1304. VOID
  1305. dumpGBLEntry(
  1306. IN ULONG64 Address,
  1307. IN ULONG Verbose
  1308. )
  1309. /*++
  1310. Routine Description:
  1311. This routine actually prints the rule for the table at the
  1312. specified address
  1313. Arguments:
  1314. Address - where the table is located
  1315. Return Value:
  1316. None
  1317. --*/
  1318. {
  1319. BOOL status;
  1320. UCHAR tableId[7];
  1321. UCHAR entryId[20];
  1322. //
  1323. // Read the header for the table
  1324. //
  1325. InitTypeRead( Address, hal!_DESCRIPTION_HEADER);
  1326. //
  1327. // Don't print out a table unless its the FACP or we are being verbose
  1328. //
  1329. if (!(Verbose & VERBOSE_2) && ReadField(Signature) != FADT_SIGNATURE) {
  1330. return;
  1331. }
  1332. //
  1333. // Initialize the table id field
  1334. //
  1335. memset( tableId, 0, 7 );
  1336. tableId[0] = '\"';
  1337. memcpy( &tableId[1], ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "Signature", sizeof(ULONG), FALSE), sizeof(ULONG) );
  1338. strcat( tableId, "\"" );
  1339. //
  1340. // Get the entry ready for the OEM Id
  1341. //
  1342. memset( entryId, 0, 20 );
  1343. entryId[0] = '\"';
  1344. memcpy( &entryId[1], ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "OEMID", 6, FALSE), 6 );
  1345. strcat( entryId, "\"");
  1346. dprintf("AcpiOemId=%s,%s\n", tableId, entryId );
  1347. //
  1348. // Get the entry ready for the OEM Table Id
  1349. //
  1350. memset( entryId, 0, 20 );
  1351. entryId[0] = '\"';
  1352. memcpy( &entryId[1], ReadPhysVirField(Address, "hal!_DESCRIPTION_HEADER", "OEMTableID", 8, FALSE), 8 );
  1353. strcat( entryId, "\"");
  1354. dprintf("AcpiOemTableId=%s,%s\n", tableId, entryId );
  1355. //
  1356. // Get the entry ready for the OEM Revision
  1357. //
  1358. dprintf("AcpiOemRevision=\">=\",%s,%x\n", tableId, (ULONG)ReadField(OEMRevision) );
  1359. //
  1360. // Get the entry ready for the ACPI revision
  1361. //
  1362. if (ReadField(Revision) != 1) {
  1363. dprintf("AcpiRevision=\">=\",%s,%x\n", tableId, (UCHAR)ReadField(Revision) );
  1364. }
  1365. //
  1366. // Get the entry ready for the ACPI Creator Revision
  1367. //
  1368. dprintf("AcpiCreatorRevision=\">=\",%s,%x\n", tableId, (ULONG)ReadField(CreatorRev) );
  1369. }
  1370. VOID
  1371. dumpGBL(
  1372. ULONG Verbose
  1373. )
  1374. /*++
  1375. Routine Description:
  1376. This routine reads in all the system tables and prints out
  1377. what the ACPI Good Bios List Entry for this machine should
  1378. be
  1379. Arguments:
  1380. None
  1381. Return Value:
  1382. None
  1383. --*/
  1384. {
  1385. BOOL status;
  1386. ULONG64 dateAddress;
  1387. PUCHAR tempPtr;
  1388. ULONG i;
  1389. ULONG numElements;
  1390. ULONG returnLength;
  1391. ULONG64 address;
  1392. ULONG64 address2;
  1393. ULONG addr;
  1394. ULONG64 addroffset;
  1395. //
  1396. // Remember where the date address is stored
  1397. //
  1398. dateAddress = 0xFFFF5;
  1399. //
  1400. // Make sure that we can read the pointer
  1401. //
  1402. address2 = GetExpression( "ACPI!RsdtInformation" );
  1403. if (!address2) {
  1404. dprintf("dumpGBL: Could not find RsdtInformation\n");
  1405. return;
  1406. }
  1407. status = ReadPointer(address2, &address);
  1408. if (status == FALSE || !address) {
  1409. dprintf("dumpGBL: No RsdtInformation present\n");
  1410. return;
  1411. }
  1412. //
  1413. // Read the ACPInformation table, so that we know where the RSDT lives
  1414. //
  1415. address2 = GetExpression( "ACPI!AcpiInformation" );
  1416. if (!address2) {
  1417. dprintf("dumpGBL: Could not find AcpiInformation\n");
  1418. return;
  1419. }
  1420. status = ReadPointer(address2, &address2);
  1421. if (status == FALSE || !address2) {
  1422. dprintf("dumpGBL: Could not read AcpiInformation\n");
  1423. return;
  1424. }
  1425. InitTypeRead( address2, ACPI!_ACPIInformation);
  1426. //
  1427. // Read in the header for the RSDT
  1428. //
  1429. address2 = ReadField(RootSystemDescTable);
  1430. //
  1431. // The number of elements in the table is the first entry
  1432. // in the structure
  1433. //
  1434. //status = ReadMemory(address, &numElements, GetTypeSize("acpi!_ULONG"), &returnLength);
  1435. status = ReadMemory(address, &numElements, sizeof(ULONG), &returnLength);
  1436. //if (status == FALSE || returnLength != GetTypeSize("acpi!_ULONG") ) {
  1437. if (status == FALSE || returnLength != sizeof(ULONG) ) {
  1438. dprintf("dumpGBL: Could not read RsdtInformation\n");
  1439. return;
  1440. }
  1441. //
  1442. // If there are no elements, then return
  1443. //
  1444. if (numElements == 0) {
  1445. dprintf("dumpGBL: No tables the RsdtInformation\n");
  1446. return;
  1447. }
  1448. //
  1449. // Dump a header so that people know what this is
  1450. //
  1451. memset( Buffer, 0, 2048 );
  1452. ReadPhysical( dateAddress, Buffer, 8, &returnLength );
  1453. dprintf("\nGood Bios List Entry --- Machine BIOS Date %s\n\n", Buffer);
  1454. memset( Buffer, 0, 2048 );
  1455. GetFieldOffset( "hal!_DESCRIPTION_HEADER", "OEMID", &addr);
  1456. ReadMemory( (address2 + (ULONG64) addr), &Buffer, 6, &returnLength);
  1457. tempPtr = Buffer;
  1458. while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
  1459. GetFieldOffset( "hal!_DESCRIPTION_HEADER", "OEMTableID", &addr);
  1460. ReadMemory( (address2 + (ULONG64) addr), tempPtr, 8, &returnLength);
  1461. while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
  1462. ReadPhysical( dateAddress, tempPtr, 8, &returnLength );
  1463. while (*tempPtr) { if (*tempPtr == ' ') { *tempPtr = '\0'; break; } tempPtr++; }
  1464. //
  1465. // This is the entry name
  1466. //
  1467. dprintf("[%s]\n", Buffer );
  1468. //
  1469. // Dump all the tables that are loaded in the RSDT table
  1470. //
  1471. GetFieldOffset( "ACPI!_RSDTINFORMATION", "Tables", &addr); // Get Tables offset
  1472. for (i = 0; i < numElements; i++) {
  1473. addroffset = address + (ULONG64)addr + (ULONG64)(GetTypeSize("ACPI!RSDTELEMENT") * i);
  1474. InitTypeRead(addroffset, ACPI!RSDTELEMENT);
  1475. if (!(ReadField(Flags) & RSDTELEMENT_MAPPED) ) {
  1476. continue;
  1477. }
  1478. dumpGBLEntry( ReadField(Address), Verbose );
  1479. }
  1480. //
  1481. // Dump the entry for the RSDT
  1482. //
  1483. dumpGBLEntry( address2, Verbose );
  1484. //
  1485. // Add some whitespace
  1486. //
  1487. dprintf("\n");
  1488. //
  1489. // Done
  1490. //
  1491. return;
  1492. }
  1493. DECLARE_API( gbl )
  1494. {
  1495. ULONG verbose = VERBOSE_1;
  1496. if (args != NULL) {
  1497. if (!strcmp(args, "-v")) {
  1498. verbose |= VERBOSE_2;
  1499. }
  1500. }
  1501. dumpGBL( verbose );
  1502. return S_OK;
  1503. }
  1504. /*************************** INF Starts Here ********************************/
  1505. ULONG
  1506. dumpFlags(
  1507. IN ULONGLONG Value,
  1508. IN PFLAG_RECORD FlagRecords,
  1509. IN ULONG FlagRecordSize,
  1510. IN ULONG IndentLevel,
  1511. IN ULONG Flags
  1512. )
  1513. /*++
  1514. Routine Description:
  1515. This routine dumps the flags specified in Value according to the
  1516. description passing into FlagRecords. The formating is affected by
  1517. the flags field
  1518. Arguments:
  1519. Value - The values
  1520. FlagRecord - What each bit in the flags means
  1521. FlagRecordSize - How many flags there are
  1522. IndentLevel - The base indent level
  1523. Flags - How we will process the flags
  1524. Return Value:
  1525. ULONG - the number of characters printed. 0 if we printed nothing
  1526. --*/
  1527. #define STATUS_PRINTED 0x00000001
  1528. #define STATUS_INDENTED 0x00000002
  1529. #define STATUS_NEED_COUNTING 0x00000004
  1530. #define STATUS_COUNTED 0x00000008
  1531. {
  1532. PCHAR string;
  1533. UCHAR indent[80];
  1534. ULONG column = IndentLevel;
  1535. ULONG currentStatus = 0;
  1536. ULONG fixedSize = 0;
  1537. ULONG stringSize;
  1538. ULONG tempCount;
  1539. ULONG totalCount = 0;
  1540. ULONG64 i, j, k;
  1541. IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
  1542. memset( indent, ' ', IndentLevel );
  1543. indent[IndentLevel] = '\0';
  1544. //
  1545. // Do we need to make a table?
  1546. //
  1547. if ( (Flags & DUMP_FLAG_TABLE) &&
  1548. !(Flags & DUMP_FLAG_SINGLE_LINE) ) {
  1549. currentStatus |= STATUS_NEED_COUNTING;
  1550. }
  1551. if ( (Flags & DUMP_FLAG_ALREADY_INDENTED) ) {
  1552. currentStatus |= STATUS_INDENTED;
  1553. }
  1554. //
  1555. // loop over all the steps that we need to do
  1556. //
  1557. while (1) {
  1558. for (i = 0; i < 32; i++) {
  1559. k = (1 << i);
  1560. for (j = 0; j < FlagRecordSize; j++) {
  1561. if (!(FlagRecords[j].Bit & Value) ) {
  1562. //
  1563. // Are we looking at the correct bit?
  1564. //
  1565. if (!(FlagRecords[j].Bit & k) ) {
  1566. continue;
  1567. }
  1568. //
  1569. // Yes, we are, so pick the not-present values
  1570. //
  1571. if ( (Flags & DUMP_FLAG_LONG_NAME && FlagRecords[j].NotLongName == NULL) ||
  1572. (Flags & DUMP_FLAG_SHORT_NAME && FlagRecords[j].NotShortName == NULL) ) {
  1573. continue;
  1574. }
  1575. if ( (Flags & DUMP_FLAG_LONG_NAME) ) {
  1576. string = FlagRecords[j].NotLongName;
  1577. } else if ( (Flags & DUMP_FLAG_SHORT_NAME) ) {
  1578. string = FlagRecords[j].NotShortName;
  1579. }
  1580. } else {
  1581. //
  1582. // Are we looking at the correct bit?
  1583. //
  1584. if (!(FlagRecords[j].Bit & k) ) {
  1585. continue;
  1586. }
  1587. //
  1588. // Yes, we are, so pick the not-present values
  1589. //
  1590. if ( (Flags & DUMP_FLAG_LONG_NAME && FlagRecords[j].LongName == NULL) ||
  1591. (Flags & DUMP_FLAG_SHORT_NAME && FlagRecords[j].ShortName == NULL) ) {
  1592. continue;
  1593. }
  1594. if ( (Flags & DUMP_FLAG_LONG_NAME) ) {
  1595. string = FlagRecords[j].LongName;
  1596. } else if ( (Flags & DUMP_FLAG_SHORT_NAME) ) {
  1597. string = FlagRecords[j].ShortName;
  1598. }
  1599. }
  1600. if (currentStatus & STATUS_NEED_COUNTING) {
  1601. stringSize = strlen( string ) + 1;
  1602. if (Flags & DUMP_FLAG_SHOW_BIT) {
  1603. stringSize += (4 + ( (ULONG) i / 4));
  1604. if ( (i % 4) != 0) {
  1605. stringSize++;
  1606. }
  1607. }
  1608. if (stringSize > fixedSize) {
  1609. fixedSize = stringSize;
  1610. }
  1611. continue;
  1612. }
  1613. if (currentStatus & STATUS_COUNTED) {
  1614. stringSize = fixedSize;
  1615. } else {
  1616. stringSize = strlen( string ) + 1;
  1617. if (Flags & DUMP_FLAG_SHOW_BIT) {
  1618. stringSize += (4 + ( (ULONG) i / 4));
  1619. if ( (i % 4) != 0) {
  1620. stringSize++;
  1621. }
  1622. }
  1623. }
  1624. if (!(Flags & DUMP_FLAG_SINGLE_LINE) ) {
  1625. if ( (stringSize + column) > 79 ) {
  1626. dprintf("\n%n", &tempCount);
  1627. currentStatus &= ~STATUS_INDENTED;
  1628. totalCount += tempCount;
  1629. column = 0;
  1630. }
  1631. }
  1632. if (!(Flags & DUMP_FLAG_NO_INDENT) ) {
  1633. if (!(currentStatus & STATUS_INDENTED) ) {
  1634. dprintf("%s%n", indent, &tempCount);
  1635. currentStatus |= STATUS_INDENTED;
  1636. totalCount += tempCount;
  1637. column += IndentLevel;
  1638. }
  1639. }
  1640. if ( (Flags & DUMP_FLAG_SHOW_BIT) ) {
  1641. dprintf("%I64x - %n", k, &tempCount);
  1642. tempCount++; // to account for the fact that we dump
  1643. // another space at the end of the string
  1644. totalCount += tempCount;
  1645. column += tempCount;
  1646. } else {
  1647. tempCount = 0;
  1648. }
  1649. //
  1650. // Actually print the string
  1651. //
  1652. dprintf( "%.*s %n", (stringSize - tempCount), string, &tempCount );
  1653. if (Flags & DUMP_FLAG_SHOW_BIT) {
  1654. dprintf(" ");
  1655. }
  1656. totalCount += tempCount;
  1657. column += tempCount;
  1658. }
  1659. }
  1660. //
  1661. // Change states
  1662. //
  1663. if (currentStatus & STATUS_NEED_COUNTING) {
  1664. currentStatus &= ~STATUS_NEED_COUNTING;
  1665. currentStatus |= STATUS_COUNTED;
  1666. continue;
  1667. }
  1668. if (!(Flags & DUMP_FLAG_NO_EOL) && totalCount != 0) {
  1669. dprintf("\n");
  1670. totalCount++;
  1671. }
  1672. //
  1673. // Done
  1674. //
  1675. break;
  1676. }
  1677. return totalCount;
  1678. }
  1679. VOID
  1680. dumpPM1ControlRegister(
  1681. IN ULONG Value,
  1682. IN ULONG IndentLevel
  1683. )
  1684. {
  1685. //
  1686. // Dump the PM1 Control Flags
  1687. //
  1688. dumpFlags(
  1689. (Value & 0xFF),
  1690. PM1ControlFlags,
  1691. sizeof(PM1ControlFlags) / sizeof(FLAG_RECORD),
  1692. IndentLevel,
  1693. (DUMP_FLAG_LONG_NAME | DUMP_FLAG_SHOW_BIT | DUMP_FLAG_TABLE)
  1694. );
  1695. }
  1696. VOID
  1697. dumpPM1StatusRegister(
  1698. IN ULONG Value,
  1699. IN ULONG IndentLevel
  1700. )
  1701. {
  1702. //
  1703. // Dump the PM1 Status Flags
  1704. //
  1705. dumpFlags(
  1706. (Value & 0xFFFF),
  1707. PM1StatusFlags,
  1708. (sizeof(PM1StatusFlags) / sizeof(FLAG_RECORD)),
  1709. IndentLevel,
  1710. (DUMP_FLAG_LONG_NAME | DUMP_FLAG_SHOW_BIT | DUMP_FLAG_TABLE)
  1711. );
  1712. //
  1713. // Switch to the PM1 Enable Flags
  1714. //
  1715. Value >>= 16;
  1716. //
  1717. // Dump the PM1 Enable Flags
  1718. //
  1719. dumpFlags(
  1720. (Value & 0xFFFF),
  1721. PM1EnableFlags,
  1722. (sizeof(PM1EnableFlags) / sizeof(FLAG_RECORD)),
  1723. IndentLevel,
  1724. (DUMP_FLAG_LONG_NAME | DUMP_FLAG_SHOW_BIT | DUMP_FLAG_TABLE)
  1725. );
  1726. }
  1727. VOID
  1728. dumpAcpiInformation(
  1729. VOID
  1730. )
  1731. {
  1732. BOOL status;
  1733. ULONG64 address;
  1734. ULONG returnLength;
  1735. ULONG size;
  1736. ULONG value;
  1737. ULONG addr;
  1738. ULONG i;
  1739. ULONG64 getValue;
  1740. ULONG64 getValue2;
  1741. status = GetUlongPtr( "ACPI!AcpiInformation", &address );
  1742. if (status == FALSE) {
  1743. dprintf("dumpAcpiInformation: Could not read ACPI!AcpiInformation\n");
  1744. return;
  1745. }
  1746. InitTypeRead(address, ACPI!_ACPIInformation);
  1747. dprintf("ACPIInformation (%p)\n", address);
  1748. dprintf(
  1749. " RSDT - %p\n",
  1750. ReadField(RootSystemDescTable)
  1751. );
  1752. dprintf(
  1753. " FADT - %p\n",
  1754. ReadField(FixedACPIDescTable)
  1755. );
  1756. dprintf(
  1757. " FACS - %p\n",
  1758. ReadField(FirmwareACPIControlStructure)
  1759. );
  1760. dprintf(
  1761. " DSDT - %p\n",
  1762. ReadField(DiffSystemDescTable)
  1763. );
  1764. dprintf(
  1765. " GlobalLock - %p\n",
  1766. ReadField(GlobalLock)
  1767. );
  1768. dprintf(
  1769. " GlobalLockQueue - F - %p B - %p\n",
  1770. ReadField(GlobalLockQueue.Flink),
  1771. ReadField(GlobalLockQueue.Blink)
  1772. );
  1773. dprintf(
  1774. " GlobalLockQueueLock - %p\n",
  1775. ReadField(GlobalLockQueueLock)
  1776. );
  1777. dprintf(
  1778. " GlobalLockOwnerContext - %p\n",
  1779. ReadField(GlobalLockOwnerContext)
  1780. );
  1781. dprintf(
  1782. " GlobalLockOwnerDepth - %p\n",
  1783. ReadField(GlobalLockOwnerDepth)
  1784. );
  1785. dprintf(
  1786. " ACPIOnly - %s\n",
  1787. (ReadField(ACPIOnly) ? "TRUE" : "FALSE" )
  1788. );
  1789. dprintf(
  1790. " PM1a_BLK - %p",
  1791. ReadField(PM1a_BLK)
  1792. );
  1793. if (ReadField(PM1a_BLK)) {
  1794. size = 4;
  1795. value = 0;
  1796. ReadIoSpace64( (ULONG) ReadField(PM1a_BLK), &value, &size );
  1797. if (size) {
  1798. dprintf(" (%04x) (%04x)\n", (value & 0xFFFF), (value >> 16) );
  1799. dumpPM1StatusRegister( value, 5 );
  1800. } else {
  1801. dprintf(" (N/A)\n" );
  1802. }
  1803. } else {
  1804. dprintf(" (N/A)\n");
  1805. }
  1806. dprintf(
  1807. " PM1b_BLK - %p",
  1808. ReadField(PM1b_BLK)
  1809. );
  1810. if (ReadField(PM1b_BLK)) {
  1811. size = 4;
  1812. value = 0;
  1813. ReadIoSpace64( (ULONG) ReadField(PM1b_BLK), &value, &size );
  1814. if (size) {
  1815. dprintf(" (%04x) (%04x)\n", (value & 0xFFFF), (value >> 16) );
  1816. dumpPM1StatusRegister( value, 5 );
  1817. } else {
  1818. dprintf(" (N/A)\n" );
  1819. }
  1820. } else {
  1821. dprintf(" (N/A)\n" );
  1822. }
  1823. dprintf(
  1824. " PM1a_CTRL_BLK - %p",
  1825. ReadField(PM1a_CTRL_BLK)
  1826. );
  1827. if (ReadField(PM1a_CTRL_BLK)) {
  1828. size = 2;
  1829. value = 0;
  1830. ReadIoSpace64( (ULONG) ReadField(PM1a_CTRL_BLK), &value, &size );
  1831. if (size) {
  1832. dprintf(" (%04x)\n", (value & 0xFFFF) );
  1833. dumpPM1ControlRegister( value, 5 );
  1834. } else {
  1835. dprintf(" (N/A)\n" );
  1836. }
  1837. } else {
  1838. dprintf(" (N/A)\n" );
  1839. }
  1840. dprintf(
  1841. " PM1b_CTRL_BLK - %p",
  1842. ReadField(PM1b_CTRL_BLK)
  1843. );
  1844. if (ReadField(PM1b_CTRL_BLK)) {
  1845. size = 2;
  1846. value = 0;
  1847. ReadIoSpace64( (ULONG) ReadField(PM1b_CTRL_BLK), &value, &size );
  1848. if (size) {
  1849. dprintf(" (%04x)\n", (value & 0xFFFF));
  1850. dumpPM1ControlRegister( value, 5 );
  1851. } else {
  1852. dprintf(" (N/A)\n" );
  1853. }
  1854. } else {
  1855. dprintf(" (N/A)\n" );
  1856. }
  1857. dprintf(
  1858. " PM2_CTRL_BLK - %p",
  1859. ReadField(PM2_CTRL_BLK)
  1860. );
  1861. if (ReadField(PM2_CTRL_BLK)) {
  1862. size = 1;
  1863. value = 0;
  1864. ReadIoSpace64( (ULONG) ReadField(PM2_CTRL_BLK), &value, &size );
  1865. if (size) {
  1866. dprintf(" (%02x)\n", (value & 0xFF) );
  1867. if (value & 0x1) {
  1868. dprintf(" 0 - ARB_DIS\n");
  1869. }
  1870. } else {
  1871. dprintf(" (N/A)\n");
  1872. }
  1873. } else {
  1874. dprintf(" (N/A)\n");
  1875. }
  1876. dprintf(
  1877. " PM_TMR - %p",
  1878. ReadField(PM_TMR)
  1879. );
  1880. if (ReadField(PM_TMR)) {
  1881. size = 4;
  1882. value = 0;
  1883. ReadIoSpace64( (ULONG) ReadField(PM_TMR), &value, &size );
  1884. if (size) {
  1885. dprintf(" (%08lx)\n", value );
  1886. } else {
  1887. dprintf(" (N/A)\n");
  1888. }
  1889. } else {
  1890. dprintf(" (N/A)\n");
  1891. }
  1892. dprintf(
  1893. " GP0_BLK - %p",
  1894. ReadField(GP0_BLK)
  1895. );
  1896. if (ReadField(GP0_BLK)) {
  1897. for(i = 0; i < ReadField(Gpe0Size); i++) {
  1898. size = 1;
  1899. value = 0;
  1900. ReadIoSpace64( (ULONG) ReadField(GP0_BLK) + i, &value, &size );
  1901. if (size) {
  1902. dprintf(" (%02x)", value );
  1903. } else {
  1904. dprintf(" (N/A)" );
  1905. }
  1906. }
  1907. dprintf("\n");
  1908. } else {
  1909. dprintf(" (N/A)\n");
  1910. }
  1911. dprintf(
  1912. " GP0_ENABLE - %p",
  1913. ReadField(GP0_ENABLE)
  1914. );
  1915. if (ReadField(GP0_ENABLE)) {
  1916. for(i = 0; i < ReadField(Gpe0Size); i++) {
  1917. size = 1;
  1918. value = 0;
  1919. ReadIoSpace64( (ULONG) ReadField(GP0_ENABLE) + i, &value, &size );
  1920. if (size) {
  1921. dprintf(" (%02x)", value );
  1922. } else {
  1923. dprintf(" (N/A)" );
  1924. }
  1925. }
  1926. dprintf("\n");
  1927. } else {
  1928. dprintf(" (N/A)\n");
  1929. }
  1930. dprintf(
  1931. " GP0_LEN - %p\n",
  1932. ReadField(GP0_LEN)
  1933. );
  1934. dprintf(
  1935. " GP0_SIZE - %p\n",
  1936. ReadField(Gpe0Size)
  1937. );
  1938. dprintf(
  1939. " GP1_BLK - %p",
  1940. ReadField(GP1_BLK)
  1941. );
  1942. if (ReadField(GP1_BLK)) {
  1943. for(i = 0; i < ReadField(Gpe0Size); i++) {
  1944. size = 1;
  1945. value = 0;
  1946. ReadIoSpace64( (ULONG) ReadField(GP1_BLK) + i, &value, &size );
  1947. if (size) {
  1948. dprintf(" (%02x)", value );
  1949. } else {
  1950. dprintf(" (N/A)" );
  1951. }
  1952. }
  1953. dprintf("\n");
  1954. } else {
  1955. dprintf(" (N/A)\n");
  1956. }
  1957. dprintf(
  1958. " GP1_ENABLE - %p",
  1959. ReadField(GP1_ENABLE)
  1960. );
  1961. if (ReadField(GP1_ENABLE)) {
  1962. for(i = 0; i < ReadField(Gpe0Size); i++) {
  1963. size = 1;
  1964. value = 0;
  1965. ReadIoSpace64( (ULONG) ReadField(GP1_ENABLE) + i, &value, &size );
  1966. if (size) {
  1967. dprintf(" (%02x)", value );
  1968. } else {
  1969. dprintf(" (N/A)" );
  1970. }
  1971. }
  1972. dprintf("\n");
  1973. } else {
  1974. dprintf(" (N/A)\n");
  1975. }
  1976. dprintf(
  1977. " GP1_LEN - %x\n",
  1978. ReadField(GP1_LEN)
  1979. );
  1980. dprintf(
  1981. " GP1_SIZE - %x\n",
  1982. ReadField(Gpe1Size)
  1983. );
  1984. dprintf(
  1985. " GP1_BASE_INDEX - %x\n",
  1986. ReadField(GP1_Base_Index)
  1987. );
  1988. dprintf(
  1989. " GPE_SIZE - %x\n",
  1990. ReadField(GpeSize)
  1991. );
  1992. dprintf(
  1993. " PM1_EN_BITS - %04x\n",
  1994. ReadField(pm1_en_bits)
  1995. );
  1996. dumpPM1StatusRegister( ( (ULONG) ReadField(pm1_en_bits) << 16), 5 );
  1997. dprintf(
  1998. " PM1_WAKE_MASK - %04x\n",
  1999. ReadField(pm1_wake_mask)
  2000. );
  2001. dumpPM1StatusRegister( ( (ULONG) ReadField(acpiInformation.pm1_wake_mask) << 16), 5 );
  2002. dprintf(
  2003. " C2_LATENCY - %x\n",
  2004. ReadField(c2_latency)
  2005. );
  2006. dprintf(
  2007. " C3_LATENCY - %x\n",
  2008. ReadField(c3_latency)
  2009. );
  2010. dprintf(
  2011. " ACPI_FLAGS - %x\n",
  2012. ReadField(ACPI_Flags)
  2013. );
  2014. if (ReadField(ACPI_Flags) & C2_SUPPORTED) {
  2015. dprintf(" %2d - C2_SUPPORTED\n", C2_SUPPORTED_BIT);
  2016. }
  2017. if (ReadField(ACPI_Flags) & C3_SUPPORTED) {
  2018. dprintf(" %2d - C3_SUPPORTED\n", C3_SUPPORTED_BIT);
  2019. }
  2020. if (ReadField(ACPI_Flags) & C3_PREFERRED) {
  2021. dprintf(" %2d - C3_PREFERRED\n", C3_PREFERRED_BIT);
  2022. }
  2023. dprintf(
  2024. " ACPI_CAPABILITIES - %x\n",
  2025. ReadField(ACPI_Capabilities)
  2026. );
  2027. if (ReadField(ACPI_Capabilities) & CSTATE_C1) {
  2028. dprintf(" %2d - CSTATE_C1\n", CSTATE_C1_BIT );
  2029. } if (ReadField(ACPI_Capabilities) & CSTATE_C2) {
  2030. dprintf(" %2d - CSTATE_C2\n", CSTATE_C2_BIT );
  2031. } if (ReadField(ACPI_Capabilities) & CSTATE_C3) {
  2032. dprintf(" %2d - CSTATE_C3\n", CSTATE_C3_BIT );
  2033. }
  2034. }
  2035. DECLARE_API( acpiinf )
  2036. {
  2037. dumpAcpiInformation( );
  2038. return S_OK;
  2039. }
  2040. VOID
  2041. dumpObject(
  2042. IN ULONG64 Object,
  2043. IN ULONG Verbose,
  2044. IN ULONG IndentLevel
  2045. )
  2046. /*++
  2047. Routine Description:
  2048. This dumps an Objdata so that it can be understand --- great for debugging some of the
  2049. AML code
  2050. Arguments:
  2051. Object - Address of OBJDATA structure
  2052. Return Value:
  2053. None
  2054. --*/
  2055. {
  2056. ULONG64 s;
  2057. NTSTATUS status;
  2058. UCHAR buffer[2048];
  2059. UCHAR indent[80];
  2060. ULONG64 max;
  2061. ULONG64 pbDataBuffoffset = 0;
  2062. ULONG64 offset = 0;
  2063. UCHAR StrBuffer[2048];
  2064. //
  2065. // Init the buffers
  2066. //
  2067. IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
  2068. memset( indent, ' ', IndentLevel );
  2069. indent[IndentLevel] = '\0';
  2070. //
  2071. // Get the offset to pbDataBuff
  2072. //
  2073. InitTypeRead (Object, acpi!_ObjData);
  2074. pbDataBuffoffset = ReadField (pbDataBuff);
  2075. dprintf("%sObject Data - %016I64x Type - ", indent, Object);
  2076. //
  2077. // First step is to read whatever the buffer points to, if it
  2078. // points to something
  2079. //
  2080. switch( ReadField (dwDataType) ) {
  2081. case OBJTYPE_INTDATA:
  2082. dprintf(
  2083. "%02I64x <Integer> Value=%016I64x\n",
  2084. ReadField (dwDataType),
  2085. ReadField (uipDataValue)
  2086. );
  2087. break;
  2088. case OBJTYPE_STRDATA:
  2089. if (ReadField (pbDataBuff) != 0) {
  2090. max = (ReadField (dwDataLen) > 2047 ? 2047 : ReadField (dwDataLen) );
  2091. }
  2092. buffer[max] = '\0';
  2093. ReadMemory (pbDataBuffoffset,
  2094. StrBuffer,
  2095. (ULONG) max,
  2096. NULL);
  2097. dprintf(
  2098. "%02I64x <String> String=%s\n",
  2099. ReadField (dwDataType),
  2100. StrBuffer
  2101. );
  2102. break;
  2103. case OBJTYPE_BUFFDATA:
  2104. dprintf(
  2105. "%02I64x <Buffer> Ptr=%016I64lx Length = %2I64x\n",
  2106. ReadField (dwDataType),
  2107. ReadField (pbDataBuff),
  2108. ReadField (dwDataLen)
  2109. );
  2110. break;
  2111. case OBJTYPE_PKGDATA: {
  2112. ULONG64 i = 0;
  2113. ULONG64 j = 0;
  2114. ULONG64 datatype = ReadField (dwDataType);
  2115. InitTypeRead (pbDataBuffoffset, acpi!_PackageObj);
  2116. j = ReadField (dwcElements);
  2117. dprintf(
  2118. "%02I64x <Package> NumElements=%016I64x\n",
  2119. datatype,
  2120. j
  2121. );
  2122. if (Verbose & VERBOSE_OBJECT) {
  2123. for (; i < j; i++) {
  2124. GetFieldOffset ("acpi!_PackageObj", "adata", (ULONG*) &offset);
  2125. offset += (GetTypeSize ("acpi!_ObjData") * i);
  2126. dumpObject(offset + pbDataBuffoffset,
  2127. Verbose,
  2128. IndentLevel+ 2
  2129. );
  2130. }
  2131. }
  2132. break;
  2133. }
  2134. case OBJTYPE_FIELDUNIT: {
  2135. dprintf(
  2136. "%02I64x <Field Unit> ",
  2137. ReadField (dwDataType)
  2138. );
  2139. InitTypeRead (pbDataBuffoffset, acpi!_FieldUnitObj);
  2140. dprintf(
  2141. "Parent=%016I64x Offset=%016I64x Start=%016I64x Num=%x Flags=%x\n",
  2142. ReadField (pnsFieldParent),
  2143. ReadField (FieldDesc.dwByteOffset),
  2144. ReadField (FieldDesc.dwStartBitPos),
  2145. ReadField (FieldDesc.dwNumBits),
  2146. ReadField (FieldDesc.dwFieldFlags)
  2147. );
  2148. break;
  2149. }
  2150. case OBJTYPE_DEVICE:
  2151. dprintf(
  2152. "%02I64x <Device>\n",
  2153. ReadField (dwDataType)
  2154. );
  2155. break;
  2156. case OBJTYPE_EVENT:
  2157. dprintf(
  2158. "%02I64x <Event> PKEvent=%016I64x\n",
  2159. ReadField (dwDataType),
  2160. ReadField (pbDataBuff)
  2161. );
  2162. break;
  2163. case OBJTYPE_METHOD: {
  2164. ULONG64 offset, size;
  2165. GetFieldOffset ("acpi!_MethodObj", "abCodeBuff", (ULONG *) &offset);
  2166. size = ReadField (dwDataLen) - GetTypeSize ("acpi!_MethodObj") + ANYSIZE_ARRAY;
  2167. dprintf(
  2168. "%02I64x <Method>",
  2169. ReadField (dwDataType)
  2170. );
  2171. InitTypeRead (pbDataBuffoffset, acpi!_MethodObj);
  2172. dprintf(
  2173. "Flags=%016I64x Start=%016I64x Len=%016I64x\n",
  2174. ReadField (bMethodFlags),
  2175. offset + pbDataBuffoffset,
  2176. size
  2177. );
  2178. break;
  2179. }
  2180. case OBJTYPE_MUTEX:
  2181. dprintf(
  2182. "%02I64x <Mutex> Mutex=%016I64x\n",
  2183. ReadField (dwDataType),
  2184. ReadField (pbDataBuff)
  2185. );
  2186. break;
  2187. case OBJTYPE_OPREGION: {
  2188. dprintf(
  2189. "%02I64x <Operational Region>",
  2190. ReadField (dwDataType)
  2191. );
  2192. InitTypeRead (pbDataBuffoffset, acpi!_OpRegionObj);
  2193. dprintf(
  2194. "RegionSpace=%02x OffSet=%016I64x Len=%016I64x\n",
  2195. ReadField(bRegionSpace),
  2196. ReadField(uipOffset),
  2197. ReadField(dwLen)
  2198. );
  2199. break;
  2200. }
  2201. case OBJTYPE_POWERRES: {
  2202. dprintf(
  2203. "%02I64x <Power Resource> ",
  2204. ReadField (dwDataType)
  2205. );
  2206. InitTypeRead (pbDataBuffoffset, acpi!_PowerResObj);
  2207. dprintf(
  2208. "SystemLevel=S%d Order=%x\n",
  2209. ReadField (bSystemLevel),
  2210. ReadField (bResOrder)
  2211. );
  2212. break;
  2213. }
  2214. case OBJTYPE_PROCESSOR: {
  2215. dprintf(
  2216. "%02I64x <Processor> ",
  2217. ReadField (dwDataType)
  2218. );
  2219. if (InitTypeRead (pbDataBuffoffset, acpi!_ProcessorObj))
  2220. {
  2221. dprintf ("Error reading acpi!_ProcessorObj\n");
  2222. return;
  2223. }
  2224. dprintf(
  2225. "AcpiID=%016I64x PBlk=%016I64x PBlkLen=%016I64x\n",
  2226. ReadField (bApicID),
  2227. ReadField (dwPBlk),
  2228. ReadField (dwPBlkLen)
  2229. );
  2230. break;
  2231. }
  2232. case OBJTYPE_THERMALZONE:
  2233. dprintf(
  2234. "%02I64x <Thermal Zone>\n",
  2235. ReadField (dwDataType)
  2236. );
  2237. break;
  2238. case OBJTYPE_BUFFFIELD: {
  2239. dprintf(
  2240. "%02I64x <Buffer Field>",
  2241. ReadField (dwDataType)
  2242. );
  2243. InitTypeRead (pbDataBuffoffset, acpi!_BuffFieldObj);
  2244. dprintf(
  2245. "Ptr=%016I64x Len=%0164I64x Offset=%0164I64x Start=%016I64x NumBits=%x Flags=%x\n",
  2246. ReadField (pbDataBuff),
  2247. ReadField (dwBuffLen),
  2248. ReadField (FieldDesc.dwByteOffset),
  2249. ReadField (FieldDesc.dwStartBitPos),
  2250. ReadField (FieldDesc.dwNumBits),
  2251. ReadField (FieldDesc.dwFieldFlags)
  2252. );
  2253. break;
  2254. }
  2255. case OBJTYPE_DDBHANDLE:
  2256. dprintf(
  2257. "%02I64x <DDB Handle> Handle=%016I64x\n",
  2258. ReadField (dwDataType),
  2259. ReadField (pbDataBuff)
  2260. );
  2261. break;
  2262. case OBJTYPE_DEBUG:
  2263. dprintf(
  2264. "%02I64x <Internal Debug>\n",
  2265. ReadField (dwDataType)
  2266. );
  2267. break;
  2268. case OBJTYPE_OBJALIAS:
  2269. dprintf(
  2270. "%02I64x <Internal Object Alias> NS Object=%016I64x\n",
  2271. ReadField (dwDataType),
  2272. ReadField (uipDataValue)
  2273. );
  2274. dumpNSObject( ReadField (uipDataValue), Verbose, IndentLevel + 2 );
  2275. break;
  2276. case OBJTYPE_DATAALIAS: {
  2277. dprintf(
  2278. "%02I64x <Internal Data Alias> Data Object=%016I64x\n",
  2279. ReadField (dwDataType),
  2280. ReadField (uipDataValue)
  2281. );
  2282. dumpObject(
  2283. ReadField (uipDataValue),
  2284. Verbose,
  2285. IndentLevel + 2
  2286. );
  2287. break;
  2288. }
  2289. case OBJTYPE_BANKFIELD:
  2290. dprintf(
  2291. "%02I64x <Internal Bank Field>\n",
  2292. ReadField (dwDataType)
  2293. );
  2294. break;
  2295. case OBJTYPE_FIELD:
  2296. dprintf(
  2297. "%02I64x <Internal Field>\n",
  2298. ReadField (dwDataType)
  2299. );
  2300. break;
  2301. case OBJTYPE_INDEXFIELD:
  2302. dprintf(
  2303. "%02I64x <Index Field>\n",
  2304. ReadField (dwDataType)
  2305. );
  2306. break;
  2307. case OBJTYPE_UNKNOWN:
  2308. default:
  2309. dprintf(
  2310. "%02I64x <Unknown>\n",
  2311. ReadField (dwDataType)
  2312. );
  2313. break;
  2314. }
  2315. }
  2316. DECLARE_API( nsobj )
  2317. {
  2318. ULONG64 address = 0;
  2319. if (!strlen(args)) {
  2320. ReadPointer(GetExpression ("acpi!gpnsnamespaceroot"), &address);
  2321. } else {
  2322. address = UtilStringToUlong64 ((UCHAR *)args);
  2323. }
  2324. if (!address) {
  2325. dprintf ("nsobj: Error parsing arguments\n");
  2326. return E_INVALIDARG;
  2327. }
  2328. dprintf ("nsobj: dumping object at %I64x\n", address);
  2329. dumpNSObject( address, 0xFFFF, 0 );
  2330. return S_OK;
  2331. }
  2332. VOID
  2333. dumpNSObject(
  2334. IN ULONG64 Address,
  2335. IN ULONG Verbose,
  2336. IN ULONG IndentLevel
  2337. )
  2338. /*++
  2339. Routine Description:
  2340. This function dumps a Name space object
  2341. Arguments:
  2342. Address - Where to find the object
  2343. Verbose - Should the object be dumped as well?
  2344. IndentLevel - How much to indent
  2345. Return Value:
  2346. None
  2347. --*/
  2348. {
  2349. ULONG64 s;
  2350. UCHAR buffer[5];
  2351. UCHAR indent[80];
  2352. ULONG offset = 0;
  2353. //
  2354. // Init the buffers
  2355. //
  2356. IndentLevel = (IndentLevel > 79 ? 79 : IndentLevel);
  2357. memset( indent, ' ', IndentLevel );
  2358. indent[IndentLevel] = '\0';
  2359. buffer[4] = '\0';
  2360. //
  2361. // First step is to read the root NS
  2362. //
  2363. s = InitTypeRead (Address, acpi!_NSObj);
  2364. if (s) {
  2365. dprintf("%sdumpNSObject: could not read %x(%I64x)\n", indent,Address,s);
  2366. return;
  2367. }
  2368. s = ReadField (dwNameSeg);
  2369. if (ReadField(dwNameSeg) != 0) {
  2370. memcpy( buffer, (UCHAR *) &s, 4 );
  2371. } else {
  2372. sprintf( buffer, " ");
  2373. }
  2374. dprintf(
  2375. "%sNameSpace Object %s (%016I64x) - Device %016I64x\n",
  2376. indent,
  2377. buffer,
  2378. Address,
  2379. ReadField (Context)
  2380. );
  2381. if (Verbose & VERBOSE_NSOBJ) {
  2382. dprintf(
  2383. "%s Flink %016I64x Blink %016I64x\n%s Parent %016I64x Child %016I64x\n",
  2384. indent,
  2385. ReadField (list.plistNext),
  2386. ReadField (list.plistPrev),
  2387. indent,
  2388. ReadField (pnsParent),
  2389. ReadField (pnsFirstChild)
  2390. );
  2391. }
  2392. dprintf(
  2393. "%s Value %016I64x Length %016I64x\n%s Buffer %016I64x Flags %016I64x\n",
  2394. indent,
  2395. ReadField (ObjData.uipDataValue),
  2396. ReadField (ObjData.dwDataLen),
  2397. indent,
  2398. ReadField (ObjData.pbDataBuff),
  2399. ReadField (ObjData.dwfData)
  2400. );
  2401. if (ReadField (ObjData.dwfData) & DATAF_BUFF_ALIAS) {
  2402. dprintf(" Alias" );
  2403. }
  2404. if (ReadField (ObjData.dwfData) & DATAF_GLOBAL_LOCK) {
  2405. dprintf(" Lock");
  2406. }
  2407. dprintf("\n");
  2408. GetFieldOffset ("acpi!_NSObj", "ObjData", (ULONG *) &offset);
  2409. dumpObject(Address + offset, Verbose, IndentLevel + 4);
  2410. }
  2411. VOID
  2412. dumpNSTree(
  2413. IN ULONG64 Address,
  2414. IN ULONG Level
  2415. )
  2416. /*++
  2417. Routine Description:
  2418. This thing dumps the NS tree
  2419. Arguments:
  2420. Address - Where to find the root node --- we start dumping at the children
  2421. Return Value:
  2422. None
  2423. --*/
  2424. {
  2425. BOOL end = FALSE;
  2426. ULONG64 s;
  2427. UCHAR buffer[5];
  2428. ULONG64 next;
  2429. ULONG back;
  2430. ULONG64 m1 = 0;
  2431. ULONG64 m2 = 0;
  2432. ULONG reason;
  2433. ULONG64 dataBuffSize;
  2434. UCHAR StrBuffer[2048];
  2435. ULONG64 r = 0;
  2436. buffer[4] = '\0';
  2437. memset( StrBuffer, '0', 2048 );
  2438. //
  2439. // Indent
  2440. //
  2441. for (m1 = 0; m1 < Level; m1 ++) {
  2442. dprintf("| ");
  2443. }
  2444. //
  2445. // First step is to read the root NS
  2446. //
  2447. InitTypeRead (Address, acpi!_NSObj);
  2448. if (ReadField (dwNameSeg) != 0) {
  2449. s = ReadField (dwNameSeg);
  2450. memcpy( buffer, (UCHAR*) &s, 4 );
  2451. dprintf("%4s ", buffer );
  2452. } else {
  2453. dprintf(" " );
  2454. }
  2455. dprintf(
  2456. "(%016I64x) - ", Address );
  2457. if (ReadField (Context) != 0) {
  2458. dprintf("Device %016I64x\n", ReadField (Context) );
  2459. } else {
  2460. //
  2461. // We need to read the pbDataBuff here
  2462. //
  2463. switch(ReadField (ObjData.dwDataType)) {
  2464. default:
  2465. case OBJTYPE_UNKNOWN: dprintf("Unknown\n"); break;
  2466. case OBJTYPE_INTDATA:
  2467. dprintf("Integer - %016I64x\n", ReadField (ObjData.uipDataValue));
  2468. break;
  2469. case OBJTYPE_STRDATA:
  2470. dataBuffSize = (ReadField (ObjData.dwDataLen) > 2047 ?
  2471. 2047 : ReadField (ObjData.dwDataLen));
  2472. //dprintf ("blah:%016I64x, %lx\n", ReadField (ObjData.pbDataBuff), dataBuffSize);
  2473. ReadMemory(
  2474. ReadField (ObjData.pbDataBuff),
  2475. StrBuffer,
  2476. (ULONG) dataBuffSize,
  2477. NULL
  2478. );
  2479. if (!s) {
  2480. dprintf(
  2481. "dumpNSTree: could not read %x\n",
  2482. ReadField (ObjData.pbDataBuff)
  2483. );
  2484. return;
  2485. }
  2486. StrBuffer[dataBuffSize+1] = '\0';
  2487. dprintf(
  2488. "String - %s\n",
  2489. StrBuffer
  2490. );
  2491. break;
  2492. case OBJTYPE_BUFFDATA:
  2493. dprintf(
  2494. "Buffer - %08lx L=%04x\n",
  2495. ReadField (ObjData.pbDataBuff),
  2496. ReadField (ObjData.dwDataLen)
  2497. );
  2498. break;
  2499. case OBJTYPE_PKGDATA: {
  2500. InitTypeRead (ReadField (ObjData.pbDataBuff), acpi!_PackageObj);
  2501. dprintf("Package - NumElements %x\n", ReadField (dwcElements));
  2502. break;
  2503. }
  2504. case OBJTYPE_FIELDUNIT:{
  2505. InitTypeRead (ReadField (ObjData.pbDataBuff), acpi!_FieldUnitObj);
  2506. dprintf(
  2507. "FieldUnit - Parent %016I64x Offset %016I64x Start %016I64x "
  2508. "Num %016I64x Flags %016I64x\n",
  2509. ReadField (pnsFieldParent),
  2510. ReadField (FieldDesc.dwByteOffset),
  2511. ReadField (FieldDesc.dwStartBitPos),
  2512. ReadField (FieldDesc.dwNumBits),
  2513. ReadField (FieldDesc.dwFieldFlags)
  2514. );
  2515. break;
  2516. }
  2517. case OBJTYPE_DEVICE:
  2518. dprintf("Device\n");
  2519. break;
  2520. case OBJTYPE_EVENT:
  2521. dprintf("Event - PKEvent %016I64x\n", ReadField (ObjData.pbDataBuff));
  2522. break;
  2523. case OBJTYPE_METHOD: {
  2524. ULONG64 size, offset, pbdatabuff;
  2525. pbdatabuff = ReadField (ObjData.pbDataBuff);
  2526. size = ReadField (ObjData.dwDataLen);
  2527. GetFieldOffset ("acpi!_MethodObj", "abCodeBuff", (ULONG*) &offset);
  2528. InitTypeRead (pbdatabuff, acpi!_MethodObj);
  2529. dprintf(
  2530. "Method - Flags %016I64x Start %016I64x Len %016I64x\n",
  2531. ReadField (bMethodFlags),
  2532. offset + pbdatabuff,
  2533. size - GetTypeSize ("acpi!_MethodObj") + ANYSIZE_ARRAY
  2534. );
  2535. break;
  2536. }
  2537. case OBJTYPE_OPREGION: {
  2538. InitTypeRead (ReadField (ObjData.pbDataBuff), acpi!_OpRegionObj);
  2539. dprintf(
  2540. "Opregion - RegionsSpace=%02x OffSet=%016I64x Len=%016I64x\n",
  2541. ReadField (bRegionSpace),
  2542. ReadField (uipOffset),
  2543. ReadField (dwLen)
  2544. );
  2545. break;
  2546. }
  2547. case OBJTYPE_BUFFFIELD: {
  2548. InitTypeRead (ReadField (ObjData.pbDataBuff), acpi!_BuffFieldObj);
  2549. dprintf(
  2550. "Buffer Field Ptr=%x Len=%x Offset=%x Start=%x"
  2551. "NumBits=%x Flgas=%x\n",
  2552. ReadField (pbDataBuff),
  2553. ReadField (dwBuffLen),
  2554. ReadField (FieldDesc.dwByteOffset),
  2555. ReadField (FieldDesc.dwStartBitPos),
  2556. ReadField (FieldDesc.dwNumBits),
  2557. ReadField (FieldDesc.dwFieldFlags)
  2558. );
  2559. break;
  2560. }
  2561. case OBJTYPE_FIELD: {
  2562. dprintf("Field\n");
  2563. break;
  2564. }
  2565. case OBJTYPE_INDEXFIELD: dprintf("Index Field\n"); break;
  2566. case OBJTYPE_MUTEX: dprintf("Mutex\n"); break;
  2567. case OBJTYPE_POWERRES: dprintf("Power Resource\n"); break;
  2568. case OBJTYPE_PROCESSOR: dprintf("Processor\n"); break;
  2569. case OBJTYPE_THERMALZONE: dprintf("Thermal Zone\n"); break;
  2570. case OBJTYPE_DDBHANDLE: dprintf("DDB Handle\n"); break;
  2571. case OBJTYPE_DEBUG: dprintf("Debug\n"); break;
  2572. case OBJTYPE_OBJALIAS: dprintf("Object Alias\n"); break;
  2573. case OBJTYPE_DATAALIAS: dprintf("Data Alias\n"); break;
  2574. case OBJTYPE_BANKFIELD: dprintf("Bank Field\n"); break;
  2575. }
  2576. }
  2577. m1 = next = ReadField (pnsFirstChild);
  2578. while (next != 0 && end == FALSE) {
  2579. if (CheckControlC()) {
  2580. break;
  2581. }
  2582. dumpNSTree( next, Level + 1);
  2583. InitTypeRead (next, acpi!_NSObj);
  2584. //
  2585. // Do the end check tests
  2586. //
  2587. if ( m2 == 0) {
  2588. m2 = ReadField (list.plistPrev);
  2589. } else if (m1 == ReadField (list.plistNext)) {
  2590. end = TRUE;
  2591. reason = 1;
  2592. } else if (m2 == next) {
  2593. end = TRUE;
  2594. reason = 2;
  2595. }
  2596. next = ReadField (list.plistNext);
  2597. }
  2598. }
  2599. DECLARE_API( nstree )
  2600. {
  2601. ULONG64 address = 0;
  2602. if (!strlen(args)) {
  2603. ReadPointer(GetExpression ("acpi!gpnsnamespaceroot"), &address);
  2604. } else {
  2605. address = UtilStringToUlong64 ((UCHAR *)args);
  2606. }
  2607. if (!address) {
  2608. dprintf ("nstree: Error parsing arguments\n");
  2609. return E_INVALIDARG;
  2610. }
  2611. dprintf ("nstree: dumping object at %I64x\n", address);
  2612. dumpNSTree( address, 0 );
  2613. return S_OK;
  2614. }
  2615. //
  2616. // Flags for interrupt vectors
  2617. //
  2618. #define VECTOR_MODE 1
  2619. #define VECTOR_LEVEL 1
  2620. #define VECTOR_EDGE 0
  2621. #define VECTOR_POLARITY 2
  2622. #define VECTOR_ACTIVE_LOW 2
  2623. #define VECTOR_ACTIVE_HIGH 0
  2624. //
  2625. // Vector Type:
  2626. //
  2627. // VECTOR_SIGNAL = standard edge-triggered or
  2628. // level-sensitive interrupt vector
  2629. //
  2630. // VECTOR_MESSAGE = an MSI (Message Signalled Interrupt) vector
  2631. //
  2632. #define VECTOR_TYPE 4
  2633. #define VECTOR_SIGNAL 0
  2634. #define VECTOR_MESSAGE 4
  2635. #define IS_LEVEL_TRIGGERED(vectorFlags) \
  2636. (vectorFlags & VECTOR_LEVEL)
  2637. #define IS_EDGE_TRIGGERED(vectorFlags) \
  2638. !(vectorFlags & VECTOR_LEVEL)
  2639. #define IS_ACTIVE_LOW(vectorFlags) \
  2640. (vectorFlags & VECTOR_ACTIVE_LOW)
  2641. #define IS_ACTIVE_HIGH(vectorFlags) \
  2642. !(vectorFlags & VECTOR_ACTIVE_LOW)
  2643. #define TOKEN_VALUE 0x57575757
  2644. #define EMPTY_BLOCK_VALUE 0x58585858
  2645. #define VECTOR_HASH_TABLE_LENGTH 0x1f
  2646. #define VECTOR_HASH_TABLE_WIDTH 2
  2647. VOID
  2648. dumpHashTableEntry(
  2649. IN ULONG64 VectorBlock
  2650. )
  2651. {
  2652. InitTypeRead (VectorBlock, acpi!_VECTOR_BLOCK);
  2653. dprintf("%04x Count/temp: %02d/%02d ",
  2654. ReadField (Entry.Vector),
  2655. ReadField (Entry.Count),
  2656. ReadField (Entry.TempCount));
  2657. dprintf("Flags: (%s %s) TempFlags(%s %s)\n",
  2658. (ReadField (Entry.Flags) & VECTOR_MODE) == VECTOR_LEVEL ?
  2659. "level" : "edge",
  2660. (ReadField (Entry.Flags) & VECTOR_POLARITY) == VECTOR_ACTIVE_LOW ?
  2661. "low" : "high",
  2662. (ReadField (Entry.TempFlags) & VECTOR_MODE) == VECTOR_LEVEL ?
  2663. "level" : "edge",
  2664. (ReadField (Entry.TempFlags) & VECTOR_POLARITY) == VECTOR_ACTIVE_LOW ?
  2665. "low" : "high");
  2666. }
  2667. VOID
  2668. dumpIrqArb(
  2669. IN ULONG64 IrqArb
  2670. )
  2671. {
  2672. ULONG64 Address;
  2673. ULONG64 Flink;
  2674. LIST_ENTRY64 ListEntry;
  2675. ULONG64 nextNode;
  2676. ULONG64 ListHead;
  2677. ULONG64 linkNode;
  2678. ULONG64 attachedDevs;
  2679. ULONG attachedDevOffset;
  2680. ULONG64 hashTable, hashTablePtr;
  2681. ULONG64 hashEntry;
  2682. ULONG hashEntrySize;
  2683. ULONG i,j;
  2684. ULONG64 retVal;
  2685. retVal = InitTypeRead (IrqArb, nt!_ARBITER_INSTANCE);
  2686. if (retVal) {
  2687. dprintf("Failed to get symbol nt!_ARBITER_INSTANCE\n");
  2688. return;
  2689. }
  2690. Address = ReadField(Extension);
  2691. dprintf("ACPI IRQ Arbiter: %016I64x Extension: %016I64x\n",
  2692. IrqArb, Address);
  2693. retVal = InitTypeRead (Address, acpi!ARBITER_EXTENSION);
  2694. if (retVal) {
  2695. dprintf("Failed to get symbol acpi!ARBITER_EXTENSION\n");
  2696. return;
  2697. }
  2698. ListHead = ReadField(LinkNodeHead);
  2699. dprintf("\nLink nodes in use: (list head at %016I64x )\n", ListHead);
  2700. ListEntry.Flink = ReadField(LinkNodeHead.Flink);
  2701. ListEntry.Blink = Address;
  2702. //dprintf("%016I64x, %016I64x\n", ListEntry.Flink, ListEntry.Blink);
  2703. if (ListHead == ListEntry.Flink) {
  2704. dprintf("\tNone.\n");
  2705. }
  2706. if (GetFieldOffset("acpi!LINK_NODE", "AttachedDevices", &attachedDevOffset)) {
  2707. dprintf("symbol lookup acpi!LINK_NODE failed\n");
  2708. return;
  2709. }
  2710. nextNode = ListEntry.Flink;
  2711. while (nextNode != ListEntry.Blink) {
  2712. //dprintf("nextNode: %016I64x\n", nextNode);
  2713. retVal = InitTypeRead (nextNode, acpi!LINK_NODE);
  2714. if (retVal) {
  2715. dprintf("Failed to get type acpi!LINK_NODE\n");
  2716. break;
  2717. }
  2718. dprintf("\n");
  2719. dumpNSObject( ReadField(NameSpaceObject), 0xFFFF, 3 );
  2720. InitTypeRead (nextNode, acpi!LINK_NODE);
  2721. dprintf("\n\tVector/temp: (%x/%x) RefCount/temp: (%d/%d) Flags: %x\n",
  2722. (ULONG)(ReadField(CurrentIrq) & 0xffffffff),
  2723. (ULONG)(ReadField(TempIrq) & 0xffffffff),
  2724. ReadField(ReferenceCount),
  2725. ReadField(TempRefCount),
  2726. ReadField(Flags));
  2727. attachedDevs = ReadField(AttachedDevices.Next);
  2728. //dprintf("attachedDevs: %p nextNode: %p attachedDevOffset: %x\n",
  2729. // attachedDevs, nextNode, attachedDevOffset);
  2730. while (attachedDevs != (nextNode + attachedDevOffset)) {
  2731. InitTypeRead(attachedDevs, acpi!LINK_NODE_ATTACHED_DEVICES);
  2732. //dprintf("\t\tAttached PDO: %016I64x\n", ReadField(Pdo));
  2733. attachedDevs = ReadField(List.Next);
  2734. if (CheckControlC()) {
  2735. break;
  2736. }
  2737. }
  2738. InitTypeRead (nextNode, acpi!LINK_NODE);
  2739. nextNode = ReadField(List.Flink);
  2740. if (CheckControlC()) {
  2741. break;
  2742. }
  2743. }
  2744. hashTablePtr = GetExpression( "acpi!irqhashtable" );
  2745. if (!hashTablePtr) {
  2746. dprintf("couldn't read symbol acpi!irqhashtable\n");
  2747. return;
  2748. }
  2749. retVal = ReadPointer(hashTablePtr, &hashTable);
  2750. if (!retVal) {
  2751. return;
  2752. }
  2753. hashEntrySize = GetTypeSize("acpi!_VECTOR_BLOCK");
  2754. dprintf("\n\nIRQ Hash Table (at %016I64x ):\n",
  2755. hashTable);
  2756. for (i = 0; i < VECTOR_HASH_TABLE_LENGTH; i++) {
  2757. hashEntry = hashTable + (i * VECTOR_HASH_TABLE_WIDTH * hashEntrySize);
  2758. DumpVectorTableStartRow:
  2759. for (j = 0; j < VECTOR_HASH_TABLE_WIDTH; j++) {
  2760. InitTypeRead(hashEntry, acpi!_VECTOR_BLOCK);
  2761. if (ReadField(Chain.Token) == TOKEN_VALUE) {
  2762. hashEntry = ReadField(Chain.Next);
  2763. dumpHashTableEntry(hashEntry);
  2764. goto DumpVectorTableStartRow;
  2765. }
  2766. if (ReadField(Entry.Vector) != EMPTY_BLOCK_VALUE) {
  2767. dumpHashTableEntry(hashEntry);
  2768. }
  2769. hashEntry += hashEntrySize;
  2770. if (CheckControlC()) {
  2771. break;
  2772. }
  2773. }
  2774. if (CheckControlC()) {
  2775. break;
  2776. }
  2777. }
  2778. }
  2779. DECLARE_API( acpiirqarb )
  2780. {
  2781. ULONG64 irqArbiter;
  2782. irqArbiter = GetExpression( "acpi!acpiarbiter" );
  2783. if (!irqArbiter) {
  2784. dprintf("failed to find address of arbiter\n");
  2785. return E_INVALIDARG;
  2786. }
  2787. dumpIrqArb(irqArbiter);
  2788. return S_OK;
  2789. }