Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1149 lines
30 KiB

  1. /*** tables.c - Dump various ACPI tables
  2. *
  3. * This module provides the functions to dump various ACPI tables.
  4. *
  5. * Copyright (c) 1999 Microsoft Corporation
  6. * Author: Michael Tsang (MikeTs)
  7. * Created 04/08/99
  8. *
  9. * MODIFICATION HISTORY
  10. */
  11. #ifdef __UNASM
  12. #pragma warning (disable: 4201 4214 4514)
  13. typedef unsigned __int64 ULONGLONG;
  14. #define LOCAL __cdecl
  15. #define EXPORT __cdecl
  16. #include <stdarg.h>
  17. //#define _X86_
  18. #include <windef.h>
  19. #include <winbase.h>
  20. #include <winreg.h>
  21. #define ULONG_PTR ULONG
  22. #define EXCL_BASEDEF
  23. #include "pch.h"
  24. #include "fmtdata.h"
  25. #define BYTEOF(d,i) (((BYTE *)&(d))[i])
  26. /***LP IsWinNT - check if OS is NT
  27. *
  28. * ENTRY
  29. * None
  30. *
  31. * EXIT-SUCCESS
  32. * returns TRUE - OS is NT
  33. * EXIT-FAILURE
  34. * returns FALSE - OS is not NT
  35. */
  36. BOOL LOCAL IsWinNT(VOID)
  37. {
  38. BOOL rc = FALSE;
  39. OSVERSIONINFO osinfo;
  40. ENTER((2, "IsWinNT()\n"));
  41. osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  42. if (GetVersionEx(&osinfo) && (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT))
  43. {
  44. rc = TRUE;
  45. }
  46. EXIT((2, "IsWinNT=%x\n", rc));
  47. return rc;
  48. } //IsWinNT
  49. #ifndef WINNT
  50. /***LP OpenVxD - Open ACPITAB.VXD
  51. *
  52. * ENTRY
  53. * None
  54. *
  55. * EXIT-SUCCESS
  56. * returns VxD handle
  57. * EXIT-FAILURE
  58. * returns NULL
  59. */
  60. HANDLE LOCAL OpenVxD(VOID)
  61. {
  62. HANDLE hVxD;
  63. DWORD dwVersion;
  64. ENTER((2, "OpenVxD()\n"));
  65. if ((hVxD = CreateFile(ACPITAB_VXD_NAME, 0, 0, NULL, 0,
  66. FILE_FLAG_DELETE_ON_CLOSE, NULL)) ==
  67. INVALID_HANDLE_VALUE)
  68. {
  69. ERROR(("OpenVxD: failed to open VxD %s (rc=%x)",
  70. ACPITAB_VXD_NAME, GetLastError()));
  71. hVxD = NULL;
  72. }
  73. else if (!DeviceIoControl(hVxD, ACPITAB_DIOC_GETVERSION, NULL, 0,
  74. &dwVersion, sizeof(dwVersion), NULL, NULL))
  75. {
  76. ERROR(("OpenVxD: failed to get VxD version. (rc=%x)", GetLastError()));
  77. CloseVxD(hVxD);
  78. hVxD = NULL;
  79. }
  80. else if (dwVersion != ((ACPITAB_MAJOR_VER << 8) | ACPITAB_MINOR_VER))
  81. {
  82. ERROR(("OpenVxD: version error (Ver=%x)", dwVersion));
  83. CloseVxD(hVxD);
  84. hVxD = NULL;
  85. }
  86. EXIT((2, "OpenVxD=%x\n", hVxD));
  87. return hVxD;
  88. } //OpenVxD
  89. /***LP CloseVxD - Close the VxD
  90. *
  91. * ENTRY
  92. * hVxD - VxD handle
  93. *
  94. * EXIT
  95. * None
  96. */
  97. VOID LOCAL CloseVxD(HANDLE hVxD)
  98. {
  99. ENTER((2, "CloseVxD(hVxD=%x)\n", hVxD));
  100. CloseHandle(hVxD);
  101. EXIT((2, "CloseVxD!\n"));
  102. } //CloseVxD
  103. /***LP VxDGetTableBySig - Get table by its signature
  104. *
  105. * ENTRY
  106. * dwTabSig - table signature
  107. * pdwTableAddr -> to hold physical address of table (can be NULL)
  108. *
  109. * EXIT-SUCCESS
  110. * returns pointer to table
  111. * EXIT-FAILURE
  112. * returns NULL
  113. */
  114. PBYTE LOCAL VxDGetTableBySig(DWORD dwTabSig, PDWORD pdwTableAddr)
  115. {
  116. PBYTE pb = NULL;
  117. TABINFO TabInfo;
  118. ENTER((2, "VxDGetTableBySig(TabSig=%x,pdwAddr=%p)\n",
  119. dwTabSig, pdwTableAddr));
  120. TabInfo.dwTabSig = dwTabSig;
  121. if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABINFO, NULL, 0, &TabInfo,
  122. sizeof(TabInfo), NULL, NULL))
  123. {
  124. if (dwTabSig == SIG_RSDP)
  125. {
  126. //
  127. // We are getting RSD PTR
  128. //
  129. if ((pb = MEMALLOC(sizeof(RSDP))) != NULL)
  130. {
  131. memcpy(pb, &TabInfo.rsdp, sizeof(RSDP));
  132. if (pdwTableAddr != NULL)
  133. {
  134. *pdwTableAddr = TabInfo.dwPhyAddr;
  135. }
  136. }
  137. else
  138. {
  139. ERROR(("VxDGetTableBySig: failed to allocate RSDP buffer"));
  140. }
  141. }
  142. else if (dwTabSig == FACS_SIGNATURE)
  143. {
  144. if ((pb = MEMALLOC(sizeof(FACS))) != NULL)
  145. {
  146. memcpy(pb, &TabInfo.facs, sizeof(FACS));
  147. if (pdwTableAddr != NULL)
  148. {
  149. *pdwTableAddr = TabInfo.dwPhyAddr;
  150. }
  151. }
  152. else
  153. {
  154. ERROR(("VxDGetTableBySig: failed to allocate FACS buffer"));
  155. }
  156. }
  157. else if ((pb = MEMALLOC(TabInfo.dh.Length)) != NULL)
  158. {
  159. if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE,
  160. (PVOID)TabInfo.dwPhyAddr, 0, pb,
  161. TabInfo.dh.Length, NULL, NULL) == 0)
  162. {
  163. ERROR(("VxDGetTableBySig: failed to get table %s. (rc=%x)",
  164. GetTableSigStr(dwTabSig), GetLastError()));
  165. MEMFREE(pb);
  166. pb = NULL;
  167. }
  168. else
  169. {
  170. if (pdwTableAddr != NULL)
  171. {
  172. *pdwTableAddr = TabInfo.dwPhyAddr;
  173. }
  174. ValidateTable(pb, TabInfo.dh.Length);
  175. }
  176. }
  177. else
  178. {
  179. ERROR(("VxDGetTableBySig: failed to allocate table buffer (len=%d)",
  180. TabInfo.dh.Length));
  181. }
  182. }
  183. else
  184. {
  185. ERROR(("VxDGetTableBySig: failed to get table info %s. (rc=%x)",
  186. GetTableSigStr(dwTabSig), GetLastError()));
  187. }
  188. EXIT((2, "VxDGetTableBySig=%x\n", pb));
  189. return pb;
  190. } //VxDGetTableBySig
  191. /***LP VxDGetTableByAddr - Get table by its physical address
  192. *
  193. * ENTRY
  194. * dwTableAddr - physical address of table
  195. * pdwTableSig -> to hold signature of table (can be NULL)
  196. *
  197. * EXIT-SUCCESS
  198. * returns pointer to table
  199. * EXIT-FAILURE
  200. * returns NULL
  201. */
  202. PBYTE LOCAL VxDGetTableByAddr(DWORD dwTableAddr, PDWORD pdwTableSig)
  203. {
  204. PBYTE pb = NULL;
  205. DESCRIPTION_HEADER dh;
  206. ENTER((2, "VxDGetTableByAddr(TabAddr=%x,pdwSig=%p)\n",
  207. dwTableAddr, pdwTableSig));
  208. if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE, (PVOID)dwTableAddr, 0,
  209. &dh, sizeof(dh), NULL, NULL))
  210. {
  211. DWORD dwLen = (dh.Signature == SIG_LOW_RSDP)? sizeof(RSDP): dh.Length;
  212. if ((pb = MEMALLOC(dwLen)) != NULL)
  213. {
  214. if (DeviceIoControl(ghVxD, ACPITAB_DIOC_GETTABLE,
  215. (PVOID)dwTableAddr, 0, pb, dwLen, NULL, NULL)
  216. == 0)
  217. {
  218. ERROR(("VxDGetTableByAddr: failed to get table %s at %x. (rc=%x)",
  219. GetTableSigStr(dh.Signature), dwTableAddr,
  220. GetLastError()));
  221. MEMFREE(pb);
  222. pb = NULL;
  223. }
  224. else if (pdwTableSig != NULL)
  225. {
  226. if (pdwTableSig != NULL)
  227. {
  228. *pdwTableSig = (dh.Signature == SIG_LOW_RSDP)?
  229. SIG_RSDP: dh.Signature;
  230. }
  231. ValidateTable(pb, dwLen);
  232. }
  233. }
  234. else
  235. {
  236. ERROR(("VxDGetTableByAddr: failed to allocate table buffer (len=%d)",
  237. dh.Length));
  238. }
  239. }
  240. else
  241. {
  242. ERROR(("VxDGetTableByAddr: failed to get table %s header (rc=%x)",
  243. GetTableSigStr(dh.Signature), GetLastError()));
  244. }
  245. EXIT((2, "VxDGetTableByAddr=%x\n", pb));
  246. return pb;
  247. } //VxDGetTableByAddr
  248. #endif //ifndef WINNT
  249. /***LP EnumSubKey - enumerate subkey
  250. *
  251. * ENTRY
  252. * hkey - key to enumerate
  253. * dwIndex - subkey index
  254. *
  255. * EXIT-SUCCESS
  256. * returns subkey
  257. * EXIT-FAILURE
  258. * returns NULL
  259. */
  260. HKEY LOCAL EnumSubKey(HKEY hkey, DWORD dwIndex)
  261. {
  262. HKEY hkeySub = NULL;
  263. char szSubKey[32];
  264. DWORD dwSubKeySize = sizeof(szSubKey);
  265. ENTER((2, "EnumSubKey(hkey=%x,Index=%d)\n", hkey, dwIndex));
  266. if ((RegEnumKeyEx(hkey, dwIndex, szSubKey, &dwSubKeySize, NULL, NULL, NULL,
  267. NULL) == ERROR_SUCCESS) &&
  268. (RegOpenKeyEx(hkey, szSubKey, 0, KEY_READ, &hkeySub) != ERROR_SUCCESS))
  269. {
  270. hkeySub = NULL;
  271. }
  272. EXIT((2, "EnumSubKey=%x\n", hkeySub));
  273. return hkeySub;
  274. } //EnumSubKey
  275. /***LP OpenNTTable - Open ACPI table in NT registry
  276. *
  277. * ENTRY
  278. * dwTabSig - table signature
  279. *
  280. * EXIT-SUCCESS
  281. * returns table registry handle
  282. * EXIT-FAILURE
  283. * returns NULL
  284. */
  285. HKEY LOCAL OpenNTTable(DWORD dwTabSig)
  286. {
  287. HKEY hkeyTab = NULL, hkey1 = NULL, hkey2 = NULL;
  288. static char szTabKey[] = "Hardware\\ACPI\\xxxx";
  289. ENTER((2, "OpenNTTable(TabSig=%s)\n", GetTableSigStr(dwTabSig)));
  290. if (dwTabSig == FADT_SIGNATURE)
  291. {
  292. memcpy(&szTabKey[strlen(szTabKey) - 4], "FADT", sizeof(ULONG));
  293. }
  294. else
  295. {
  296. memcpy(&szTabKey[strlen(szTabKey) - 4], &dwTabSig, sizeof(ULONG));
  297. }
  298. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTabKey, 0, KEY_READ, &hkey1) ==
  299. ERROR_SUCCESS)
  300. {
  301. //
  302. // hkey1 is now "Hardware\ACPI\<TabSig>"
  303. //
  304. if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL)
  305. {
  306. //
  307. // hkey2 is now "Hardware\ACPI\<TabSig>\<OEMID>"
  308. //
  309. RegCloseKey(hkey1);
  310. if ((hkey1 = EnumSubKey(hkey2, 0)) != NULL)
  311. {
  312. //
  313. // hkey1 is now "Hardware\ACPI\<TabSig>\<OEMID>\<OEMTabID>"
  314. //
  315. RegCloseKey(hkey2);
  316. if ((hkey2 = EnumSubKey(hkey1, 0)) != NULL)
  317. {
  318. //
  319. // hkey2 is now
  320. // "Hardware\ACPI\<TabSig>\<OEMID>\<OEMTabID>\<OEMRev>"
  321. //
  322. hkeyTab = hkey2;
  323. }
  324. }
  325. }
  326. }
  327. if (hkey1 != NULL)
  328. {
  329. RegCloseKey(hkey1);
  330. }
  331. if ((hkey2 != NULL) && (hkeyTab != hkey2))
  332. {
  333. RegCloseKey(hkey2);
  334. }
  335. EXIT((2, "OpenNTTable=%x\n", hkeyTab));
  336. return hkeyTab;
  337. } //OpenNTTable
  338. /***LP GetNTTable - Get ACPI table from NT registry
  339. *
  340. * ENTRY
  341. * dwTabSig - table signature
  342. *
  343. * EXIT-SUCCESS
  344. * returns pointer to table
  345. * EXIT-FAILURE
  346. * returns NULL
  347. */
  348. PBYTE LOCAL GetNTTable(DWORD dwTabSig)
  349. {
  350. PBYTE pb = NULL;
  351. HKEY hkeyTab;
  352. ENTER((2, "GetNTTable(TabSig=%s)\n", GetTableSigStr(dwTabSig)));
  353. if ((hkeyTab = OpenNTTable(dwTabSig)) != NULL)
  354. {
  355. DWORD dwLen = 0;
  356. PSZ pszTabKey = "00000000";
  357. if (RegQueryValueEx(hkeyTab, pszTabKey, NULL, NULL, NULL, &dwLen) ==
  358. ERROR_SUCCESS)
  359. {
  360. if ((pb = MEMALLOC(dwLen)) != NULL)
  361. {
  362. if (RegQueryValueEx(hkeyTab, pszTabKey, NULL, NULL, pb, &dwLen)
  363. != ERROR_SUCCESS)
  364. {
  365. ERROR(("GetNTTable: failed to read table"));
  366. }
  367. }
  368. else
  369. {
  370. ERROR(("GetNTTable: failed to allocate table buffer"));
  371. }
  372. }
  373. else
  374. {
  375. ERROR(("GetNTTable: failed to read table key"));
  376. }
  377. RegCloseKey(hkeyTab);
  378. }
  379. else
  380. {
  381. ERROR(("GetNTTable: failed to get table %s", GetTableSigStr(dwTabSig)));
  382. }
  383. EXIT((2, "GetNTTable=%x\n", pb));
  384. return pb;
  385. } //GetNTTable
  386. /***LP GetTableBySig - Get table by its signature
  387. *
  388. * ENTRY
  389. * dwTabSig - table signature
  390. * pdwTableAddr -> to hold physical address of table (can be NULL)
  391. *
  392. * EXIT-SUCCESS
  393. * returns pointer to table
  394. * EXIT-FAILURE
  395. * returns NULL
  396. */
  397. PBYTE LOCAL GetTableBySig(DWORD dwTabSig, PDWORD pdwTableAddr)
  398. {
  399. PBYTE pb = NULL;
  400. ENTER((2, "GetTableBySig(TabSig=%x,pdwAddr=%p)\n", dwTabSig, pdwTableAddr));
  401. if (gdwfASL & ASLF_NT)
  402. {
  403. if (((pb = GetNTTable(dwTabSig)) != NULL) && (pdwTableAddr != NULL))
  404. {
  405. *pdwTableAddr = 0;
  406. }
  407. }
  408. #ifndef WINNT
  409. else
  410. {
  411. pb = VxDGetTableBySig(dwTabSig, pdwTableAddr);
  412. }
  413. #endif
  414. EXIT((2, "GetTableBySig=%x\n", pb));
  415. return pb;
  416. } //GetTableBySig
  417. /***LP GetTableByAddr - Get table by its physical address
  418. *
  419. * ENTRY
  420. * dwTableAddr - physical address of table
  421. * pdwTableSig -> to hold signature of table (can be NULL)
  422. *
  423. * EXIT-SUCCESS
  424. * returns pointer to table
  425. * EXIT-FAILURE
  426. * returns NULL
  427. */
  428. PBYTE LOCAL GetTableByAddr(DWORD dwTableAddr, PDWORD pdwTableSig)
  429. {
  430. PBYTE pb = NULL;
  431. ENTER((2, "GetTableByAddr(TabAddr=%x,pdwSig=%p)\n",
  432. dwTableAddr, pdwTableSig));
  433. if (gdwfASL & ASLF_NT)
  434. {
  435. ERROR(("GetTableByAddr: not supported by NT"));
  436. }
  437. #ifndef WINNT
  438. else
  439. {
  440. pb = VxDGetTableByAddr(dwTableAddr, pdwTableSig);
  441. }
  442. #endif
  443. EXIT((2, "GetTableByAddr=%x\n", pb));
  444. return pb;
  445. } //GetTableByAddr
  446. /***LP DumpAllTables - Dump all ACPI tables
  447. *
  448. * ENTRY
  449. * pfileOut -> output file
  450. *
  451. * EXIT-SUCCESS
  452. * returns ASLERR_NONE
  453. * EXIT-FAILURE
  454. * returns negative error code
  455. */
  456. int LOCAL DumpAllTables(FILE *pfileOut)
  457. {
  458. int rc = ASLERR_NONE;
  459. PBYTE pb;
  460. DWORD dwAddr;
  461. ENTER((1, "DumpAllTables(pfileOut=%p)\n", pfileOut));
  462. if (gdwfASL & ASLF_NT)
  463. {
  464. DumpTableBySig(pfileOut, RSDT_SIGNATURE);
  465. DumpTableBySig(pfileOut, FADT_SIGNATURE);
  466. DumpTableBySig(pfileOut, FACS_SIGNATURE);
  467. DumpTableBySig(pfileOut, SBST_SIGNATURE);
  468. DumpTableBySig(pfileOut, APIC_SIGNATURE);
  469. DumpTableBySig(pfileOut, SIG_BOOT);
  470. DumpTableBySig(pfileOut, SIG_DBGP);
  471. DumpTableBySig(pfileOut, DSDT_SIGNATURE);
  472. DumpTableBySig(pfileOut, SSDT_SIGNATURE);
  473. DumpTableBySig(pfileOut, PSDT_SIGNATURE);
  474. }
  475. else if ((pb = GetTableBySig(SIG_RSDP, &dwAddr)) != NULL)
  476. {
  477. if ((rc = DumpRSDP(pfileOut, pb, dwAddr)) == ASLERR_NONE)
  478. {
  479. DWORD dwRSDTAddr = ((PRSDP)pb)->RsdtAddress;
  480. DWORD dwTableSig;
  481. MEMFREE(pb);
  482. if ((pb = GetTableByAddr(dwRSDTAddr, &dwTableSig)) != NULL)
  483. {
  484. if ((rc = DumpTable(pfileOut, pb, dwRSDTAddr, dwTableSig)) ==
  485. ASLERR_NONE)
  486. {
  487. PRSDT pRSDT = (PRSDT)pb;
  488. DWORD i, dwcEntries;
  489. dwcEntries = (pRSDT->Header.Length -
  490. sizeof(DESCRIPTION_HEADER))/sizeof(ULONG);
  491. for (i = 0; i < dwcEntries; ++i)
  492. {
  493. if ((rc = DumpTableByAddr(pfileOut, pRSDT->Tables[i]))
  494. != ASLERR_NONE)
  495. {
  496. break;
  497. }
  498. }
  499. }
  500. if ((rc == ASLERR_NONE) &&
  501. ((rc = DumpTableBySig(pfileOut, FACS_SIGNATURE)) ==
  502. ASLERR_NONE))
  503. {
  504. rc = DumpTableBySig(pfileOut, DSDT_SIGNATURE);
  505. }
  506. }
  507. else
  508. {
  509. rc = ASLERR_GET_TABLE;
  510. }
  511. }
  512. if (pb != NULL)
  513. {
  514. MEMFREE(pb);
  515. }
  516. }
  517. else
  518. {
  519. rc = ASLERR_GET_TABLE;
  520. }
  521. EXIT((1, "DumpAllTables=%d\n", rc));
  522. return rc;
  523. } //DumpAllTables
  524. /***LP DumpTableBySig - Dump an ACPI table by its Table Signature
  525. *
  526. * ENTRY
  527. * pfileOut -> output file
  528. * dwTableSig - table signature
  529. *
  530. * EXIT-SUCCESS
  531. * returns ASLERR_NONE
  532. * EXIT-FAILURE
  533. * returns negative error code
  534. */
  535. int LOCAL DumpTableBySig(FILE *pfileOut, DWORD dwTableSig)
  536. {
  537. int rc = ASLERR_NONE;
  538. PBYTE pb;
  539. DWORD dwTableAddr;
  540. ENTER((1, "DumpTableBySig(pfileOut=%p,TableSig=%s)\n",
  541. pfileOut, GetTableSigStr(dwTableSig)));
  542. if (((PSZ)&dwTableSig)[0] == '*')
  543. {
  544. rc = DumpAllTables(pfileOut);
  545. }
  546. else if ((pb = GetTableBySig(dwTableSig, &dwTableAddr)) != NULL)
  547. {
  548. rc = DumpTable(pfileOut, pb, dwTableAddr, dwTableSig);
  549. MEMFREE(pb);
  550. }
  551. else
  552. {
  553. rc = ASLERR_GET_TABLE;
  554. }
  555. EXIT((1, "DumpTableBySig=%d\n", rc));
  556. return rc;
  557. } //DumpTableBySig
  558. /***LP DumpTableByAddr - Dump an ACPI table by its address
  559. *
  560. * ENTRY
  561. * pfileOut -> output file
  562. * dwTableAddr - physical address of the table
  563. *
  564. * EXIT-SUCCESS
  565. * returns ASLERR_NONE
  566. * EXIT-FAILURE
  567. * returns negative error code
  568. */
  569. int LOCAL DumpTableByAddr(FILE *pfileOut, DWORD dwTableAddr)
  570. {
  571. int rc = ASLERR_NONE;
  572. PBYTE pb;
  573. DWORD dwTableSig;
  574. ENTER((1, "DumpTableByAddr(pfileOut=%p,TableAddr=%x)\n",
  575. pfileOut, dwTableAddr));
  576. if ((pb = GetTableByAddr(dwTableAddr, &dwTableSig)) != NULL)
  577. {
  578. rc = DumpTable(pfileOut, pb, dwTableAddr, dwTableSig);
  579. MEMFREE(pb);
  580. }
  581. else
  582. {
  583. rc = ASLERR_GET_TABLE;
  584. }
  585. EXIT((1, "DumpTableByAddr=%d\n", rc));
  586. return rc;
  587. } //DumpTableByAddr
  588. /***LP DumpRSDP - Dump the RSD PTR table
  589. *
  590. * ENTRY
  591. * pfileOut -> output file
  592. * pb -> RSDP structure
  593. * dwAddr - physical address of RSDP
  594. *
  595. * EXIT-SUCCESS
  596. * returns ASLERR_NONE
  597. * EXIT-FAILURE
  598. * returns negative error code
  599. */
  600. int LOCAL DumpRSDP(FILE *pfileOut, PBYTE pb, DWORD dwAddr)
  601. {
  602. int rc = ASLERR_NONE;
  603. ENTER((1, "DumpRSDP(pfileOut=%p,Addr=%x,pRSDP=%p)\n",
  604. pfileOut, dwAddr, pb));
  605. if (pfileOut != NULL)
  606. {
  607. DWORD dwOffset = 0;
  608. fprintf(pfileOut, szSectFmt, dwAddr, "RSD PTR");
  609. if (BinFPrintf(pfileOut, NULL, afmtRSDPTR, pb, &dwOffset, szOffsetFmt)
  610. != FERR_NONE)
  611. {
  612. ERROR(("DumpRSDP: failed to dump RSD PTR structure"));
  613. rc = ASLERR_INTERNAL_ERROR;
  614. }
  615. }
  616. else
  617. {
  618. rc = DumpTableBin(SIG_RSDP, dwAddr, pb, sizeof(RSDP));
  619. }
  620. EXIT((1, "DumpRSDP=%d\n", rc));
  621. return rc;
  622. } //DumpRSDP
  623. /***LP DumpTable - Dump an ACPI table
  624. *
  625. * ENTRY
  626. * pfileOut -> output file
  627. * pb -> ACPI table
  628. * dwTableAddr - physical address of table
  629. * dwTableSig - signature of table
  630. *
  631. * EXIT-SUCCESS
  632. * returns ASLERR_NONE
  633. * EXIT-FAILURE
  634. * returns negative error code
  635. */
  636. int LOCAL DumpTable(FILE *pfileOut, PBYTE pb, DWORD dwTableAddr,
  637. DWORD dwTableSig)
  638. {
  639. int rc = ASLERR_NONE;
  640. ENTER((1, "DumpTable(pfileOut=%p,pb=%p,TableAddr=%x,TableSig=%s)\n",
  641. pfileOut, pb, dwTableAddr, GetTableSigStr(dwTableSig)));
  642. if (dwTableSig == SIG_RSDP)
  643. {
  644. rc = DumpRSDP(pfileOut, pb, dwTableAddr);
  645. }
  646. else if (pfileOut != NULL)
  647. {
  648. rc = DumpTableTxt(pfileOut, pb, dwTableAddr, dwTableSig);
  649. }
  650. else
  651. {
  652. rc = DumpTableBin(dwTableSig, dwTableAddr, pb,
  653. (dwTableSig == FACS_SIGNATURE)?
  654. sizeof(FACS):
  655. ((PDESCRIPTION_HEADER)pb)->Length);
  656. }
  657. EXIT((1, "DumpTable=%d\n", rc));
  658. return rc;
  659. } //DumpTable
  660. /***LP DumpTableTxt - Dump an ACPI table to a text file
  661. *
  662. * ENTRY
  663. * pfileOut -> output file
  664. * pb -> ACPI table
  665. * dwTableAddr - physical address of table
  666. * dwTableSig - signature of table
  667. *
  668. * EXIT-SUCCESS
  669. * returns ASLERR_NONE
  670. * EXIT-FAILURE
  671. * returns negative error code
  672. */
  673. int LOCAL DumpTableTxt(FILE *pfileOut, PBYTE pb, DWORD dwTableAddr,
  674. DWORD dwTableSig)
  675. {
  676. int rc = ASLERR_NONE;
  677. PFMT pfmt;
  678. DWORD dwFlags;
  679. ENTER((1, "DumpTableTxt(pfileOut=%p,pb=%p,TableAddr=%x,TableSig=%s)\n",
  680. pfileOut, pb, dwTableAddr, GetTableSigStr(dwTableSig)));
  681. if ((rc = FindTableFmt(dwTableSig, &pfmt, &dwFlags)) ==
  682. ASLERR_SIG_NOT_FOUND)
  683. {
  684. rc = ASLERR_NONE;
  685. }
  686. if (rc == ASLERR_NONE)
  687. {
  688. DWORD dwOffset = 0;
  689. fprintf(pfileOut, szSectFmt, dwTableAddr, GetTableSigStr(dwTableSig));
  690. if (!(dwFlags & TF_NOHDR) &&
  691. (BinFPrintf(pfileOut, NULL, afmtTableHdr, pb, &dwOffset,
  692. szOffsetFmt) != FERR_NONE))
  693. {
  694. ERROR(("DumpTableTxt: failed to dump %s structure header",
  695. GetTableSigStr(dwTableSig)));
  696. rc = ASLERR_INTERNAL_ERROR;
  697. }
  698. else if (pfmt != NULL)
  699. {
  700. if (BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset, szOffsetFmt) !=
  701. FERR_NONE)
  702. {
  703. ERROR(("DumpTableTxt: failed to dump %s structure",
  704. GetTableSigStr(dwTableSig)));
  705. rc = ASLERR_INTERNAL_ERROR;
  706. }
  707. else if ((dwTableSig == FADT_SIGNATURE) &&
  708. (((PDESCRIPTION_HEADER)pb)->Revision > 1))
  709. {
  710. /*
  711. pfmt = (((PGRAS)pb)->id == REGSPACE_PCICFG)? afmtGRASPCICS:
  712. afmtGRASRegAddr;*/
  713. fprintf(pfileOut, "; Reset Register\n");
  714. if ((BinFPrintf(pfileOut, NULL, afmtGRASCommon, pb, &dwOffset,
  715. szOffsetFmt) != FERR_NONE) ||
  716. (BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset,
  717. szOffsetFmt) != FERR_NONE) ||
  718. (BinFPrintf(pfileOut, NULL, afmtFACP2, pb, &dwOffset,
  719. szOffsetFmt) != FERR_NONE))
  720. {
  721. ERROR(("DumpTableTxt: failed to dump extended %s structure",
  722. GetTableSigStr(dwTableSig)));
  723. rc = ASLERR_INTERNAL_ERROR;
  724. }
  725. }
  726. else if (dwTableSig == SIG_DBGP)
  727. {
  728. /*
  729. pfmt = (((PGRAS)pb)->id == REGSPACE_PCICFG)? afmtGRASPCICS:
  730. afmtGRASRegAddr;*/
  731. fprintf(pfileOut, "; Debug Port Base Address\n");
  732. if ((BinFPrintf(pfileOut, NULL, afmtGRASCommon, pb, &dwOffset,
  733. szOffsetFmt) != FERR_NONE) ||
  734. (BinFPrintf(pfileOut, NULL, pfmt, pb, &dwOffset,
  735. szOffsetFmt) != FERR_NONE))
  736. {
  737. ERROR(("DumpTableTxt: failed to dump extended %s structure",
  738. GetTableSigStr(dwTableSig)));
  739. rc = ASLERR_INTERNAL_ERROR;
  740. }
  741. }
  742. }
  743. else
  744. {
  745. #define NUM_COLS 16
  746. PRSDT pRSDT;
  747. DWORD i, dwcEntries;
  748. PBYTE pbEnd;
  749. char szAMLName[_MAX_FNAME];
  750. char szBytes[NUM_COLS + 1];
  751. switch (dwTableSig)
  752. {
  753. case RSDT_SIGNATURE:
  754. pRSDT = (PRSDT)pb;
  755. dwcEntries = (pRSDT->Header.Length -
  756. sizeof(DESCRIPTION_HEADER))/sizeof(ULONG);
  757. for (i = 0; i < dwcEntries; ++i)
  758. {
  759. fprintf(pfileOut, szOffsetFmt, dwOffset);
  760. fprintf(pfileOut, "[%02d] %08lx\n",
  761. i, pRSDT->Tables[i]);
  762. dwOffset += sizeof(ULONG);
  763. }
  764. break;
  765. case DSDT_SIGNATURE:
  766. case SSDT_SIGNATURE:
  767. case PSDT_SIGNATURE:
  768. strncpy(szAMLName, (PSZ)&dwTableSig, sizeof(DWORD));
  769. strcpy(&szAMLName[sizeof(DWORD)], ".AML");
  770. rc = UnAsmAML(szAMLName, dwTableAddr, pb,
  771. (PFNPRINT)fprintf, pfileOut);
  772. break;
  773. default:
  774. //
  775. // Don't return error because we want to continue.
  776. //
  777. WARN(("DumpTableTxt: unexpected table signature %s",
  778. GetTableSigStr(dwTableSig)));
  779. pbEnd = pb + ((PDESCRIPTION_HEADER)pb)->Length;
  780. pb += sizeof(DESCRIPTION_HEADER);
  781. i = 0;
  782. while (pb < pbEnd)
  783. {
  784. szBytes[i] = (char)(isprint(*pb)? *pb: '.');
  785. if (i == 0)
  786. {
  787. fprintf(pfileOut, szOffsetFmt, dwOffset);
  788. fprintf(pfileOut, "%02x", *pb);
  789. }
  790. else if (i == NUM_COLS/2)
  791. {
  792. fprintf(pfileOut, "-%02x", *pb);
  793. }
  794. else
  795. {
  796. fprintf(pfileOut, ",%02x", *pb);
  797. }
  798. i++;
  799. if (i == NUM_COLS)
  800. {
  801. szBytes[i] = '\0';
  802. fprintf(pfileOut, " ;%s\n", szBytes);
  803. i = 0;
  804. }
  805. dwOffset += sizeof(BYTE);
  806. pb += sizeof(BYTE);
  807. }
  808. if (i < NUM_COLS)
  809. {
  810. szBytes[i] = '\0';
  811. while (i < NUM_COLS)
  812. {
  813. fprintf(pfileOut, " ");
  814. i++;
  815. }
  816. fprintf(pfileOut, " ;%s\n", szBytes);
  817. }
  818. }
  819. }
  820. }
  821. EXIT((1, "DumpTableTxt=%d\n", rc));
  822. return rc;
  823. } //DumpTableTxt
  824. /***LP DumpTableBin - Dump an ACPI table to a binary file
  825. *
  826. * ENTRY
  827. * dwTableSig - table signature
  828. * dwAddr - physical address of table
  829. * pb -> ACPI table
  830. * dwLen - length of table
  831. *
  832. * EXIT-SUCCESS
  833. * returns ASLERR_NONE
  834. * EXIT-FAILURE
  835. * returns negative error code
  836. */
  837. int LOCAL DumpTableBin(DWORD dwTableSig, DWORD dwAddr, PBYTE pb, DWORD dwLen)
  838. {
  839. int rc = ASLERR_NONE;
  840. char szBinFile[_MAX_FNAME];
  841. FILE *pfile;
  842. ENTER((1, "DumpTableBin(TableSig=%s,Addr=%x,pb=%p,Len=%d)\n",
  843. GetTableSigStr(dwTableSig), dwAddr, pb, dwLen));
  844. strncpy(szBinFile, (PSZ)&dwTableSig, sizeof(DWORD));
  845. sprintf(&szBinFile[sizeof(DWORD)], "%04x", (WORD)dwAddr);
  846. strcpy(&szBinFile[sizeof(DWORD) + 4], ".BIN");
  847. if ((pfile = fopen(szBinFile, "wb")) == NULL)
  848. {
  849. ERROR(("DumpTableBin: failed to create file %s", szBinFile));
  850. rc = ASLERR_CREATE_FILE;
  851. }
  852. else
  853. {
  854. if (fwrite(pb, dwLen, 1, pfile) != 1)
  855. {
  856. ERROR(("DumpTableBin: failed to write to file %s", szBinFile));
  857. rc = ASLERR_WRITE_FILE;
  858. }
  859. fclose(pfile);
  860. }
  861. EXIT((1, "DumpTableBin=%d\n", rc));
  862. return rc;
  863. } //DumpTableBin
  864. /***LP FindTableFmt - Find the appropriate table format structure
  865. *
  866. * ENTRY
  867. * dwTableSig - table signature
  868. * ppfmt -> to hold pfmt found
  869. * pdwFlags -> to hold table flags
  870. *
  871. * EXIT-SUCCESS
  872. * returns ASLERR_NONE
  873. * EXIT-FAILURE
  874. * returns negative error code
  875. */
  876. int LOCAL FindTableFmt(DWORD dwTableSig, PFMT *ppfmt, PDWORD pdwFlags)
  877. {
  878. int rc = ASLERR_NONE;
  879. int i;
  880. ENTER((1, "FindTableFmt(TableSig=%s,ppfmt=%p,pdwFlags=%p)\n",
  881. GetTableSigStr(dwTableSig), ppfmt, pdwFlags));
  882. for (i = 0; FmtTable[i].dwTableSig != 0; ++i)
  883. {
  884. if (dwTableSig == FmtTable[i].dwTableSig)
  885. {
  886. *ppfmt = FmtTable[i].pfmt;
  887. *pdwFlags = FmtTable[i].dwFlags;
  888. break;
  889. }
  890. }
  891. if (FmtTable[i].dwTableSig == 0)
  892. {
  893. *ppfmt = NULL;
  894. *pdwFlags = 0;
  895. rc = ASLERR_SIG_NOT_FOUND;
  896. }
  897. EXIT((1, "FindTableFmt=%d (pfmt=%p,Flags=%x)\n", rc, *ppfmt, *pdwFlags));
  898. return rc;
  899. } //FindTableFmt
  900. /***LP GetTableSigStr - Get table signature string
  901. *
  902. * ENTRY
  903. * dwTableSig - table signature
  904. *
  905. * EXIT
  906. * returns the table signature string
  907. */
  908. PSZ LOCAL GetTableSigStr(DWORD dwTableSig)
  909. {
  910. static char szTableSig[5] = {0};
  911. ENTER((2, "GetTableSigStr(TableSig=%08x)\n", dwTableSig));
  912. strncpy(szTableSig, (PSZ)&dwTableSig, sizeof(DWORD));
  913. EXIT((2, "GetTableSigStr=%s\n", szTableSig));
  914. return szTableSig;
  915. } //GetTableSigStr
  916. /***LP ValidateTable - Validate the given table
  917. *
  918. * ENTRY
  919. * pbTable -> Table
  920. * dwLen - Table length
  921. *
  922. * EXIT-SUCCESS
  923. * returns TRUE
  924. * EXIT-FAILURE
  925. * returns FALSE
  926. */
  927. BOOL LOCAL ValidateTable(PBYTE pbTable, DWORD dwLen)
  928. {
  929. BOOL rc = TRUE;
  930. DWORD dwTableSig, dwTableLen = 0;
  931. BOOL fNeedChkSum = FALSE;
  932. ENTER((2, "ValidateTable(pbTable=%x,Len=%d)\n", pbTable, dwLen));
  933. dwTableSig = ((PDESCRIPTION_HEADER)pbTable)->Signature;
  934. switch (dwTableSig)
  935. {
  936. case SIG_LOW_RSDP:
  937. dwTableLen = sizeof(RSDP);
  938. fNeedChkSum = TRUE;
  939. break;
  940. case RSDT_SIGNATURE:
  941. case FADT_SIGNATURE:
  942. case DSDT_SIGNATURE:
  943. case SSDT_SIGNATURE:
  944. case PSDT_SIGNATURE:
  945. case APIC_SIGNATURE:
  946. case SBST_SIGNATURE:
  947. case SIG_BOOT:
  948. case SIG_DBGP:
  949. dwTableLen = ((PDESCRIPTION_HEADER)pbTable)->Length;
  950. fNeedChkSum = TRUE;
  951. break;
  952. case FACS_SIGNATURE:
  953. dwTableLen = ((PFACS)pbTable)->Length;
  954. break;
  955. default:
  956. if (IsALikelySig(dwTableSig) &&
  957. (((PDESCRIPTION_HEADER)pbTable)->Length < 256))
  958. {
  959. dwTableLen = ((PDESCRIPTION_HEADER)pbTable)->Length;
  960. fNeedChkSum = TRUE;
  961. }
  962. else
  963. {
  964. WARN(("ValidateTable: invalid table signature %s",
  965. GetTableSigStr(dwTableSig)));
  966. rc = FALSE;
  967. }
  968. }
  969. if (dwTableLen > dwLen)
  970. {
  971. WARN(("ValidateTable: invalid length %d in table %s",
  972. dwTableLen, GetTableSigStr(dwTableSig)));
  973. rc = FALSE;
  974. }
  975. if ((rc == TRUE) && fNeedChkSum &&
  976. (ComputeDataChkSum(pbTable, dwTableLen) != 0))
  977. {
  978. WARN(("ValidateTable: invalid checksum in table %s",
  979. GetTableSigStr(dwTableSig)));
  980. rc = FALSE;
  981. }
  982. EXIT((2, "ValidateTable=%x\n", rc));
  983. return rc;
  984. } //ValidateTable
  985. /***LP IsALikelySig - Check if a table signature is possibly valid
  986. *
  987. * ENTRY
  988. * dwTableSig - table signature
  989. *
  990. * EXIT-SUCCESS
  991. * returns TRUE
  992. * EXIT-FAILURE
  993. * returns FALSE
  994. */
  995. BOOL LOCAL IsALikelySig(DWORD dwTableSig)
  996. {
  997. BOOL rc = TRUE;
  998. int i, ch;
  999. ENTER((2, "IsALikelySig(dwTableSig=%x)\n", dwTableSig));
  1000. for (i = 0; i < sizeof(DWORD); ++i)
  1001. {
  1002. ch = BYTEOF(dwTableSig, i);
  1003. if ((ch < 'A') || (ch > 'Z'))
  1004. {
  1005. rc = FALSE;
  1006. break;
  1007. }
  1008. }
  1009. EXIT((2, "IsALikelySig=%x\n", rc));
  1010. return rc;
  1011. } //IsALikelySig
  1012. #endif //ifdef __UNASM