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.

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