tables.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /*
  2. * acpi_tables.c - ACPI Boot-Time Table Parsing
  3. *
  4. * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  5. *
  6. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  23. *
  24. */
  25. #include <linux/config.h>
  26. #include <linux/init.h>
  27. #include <linux/kernel.h>
  28. #include <linux/sched.h>
  29. #include <linux/smp.h>
  30. #include <linux/string.h>
  31. #include <linux/types.h>
  32. #include <linux/irq.h>
  33. #include <linux/errno.h>
  34. #include <linux/acpi.h>
  35. #include <linux/bootmem.h>
  36. #define PREFIX "ACPI: "
  37. #define ACPI_MAX_TABLES 256
  38. static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
  39. [ACPI_TABLE_UNKNOWN] = "????",
  40. [ACPI_APIC] = "APIC",
  41. [ACPI_BOOT] = "BOOT",
  42. [ACPI_DBGP] = "DBGP",
  43. [ACPI_DSDT] = "DSDT",
  44. [ACPI_ECDT] = "ECDT",
  45. [ACPI_ETDT] = "ETDT",
  46. [ACPI_FADT] = "FACP",
  47. [ACPI_FACS] = "FACS",
  48. [ACPI_OEMX] = "OEM",
  49. [ACPI_PSDT] = "PSDT",
  50. [ACPI_SBST] = "SBST",
  51. [ACPI_SLIT] = "SLIT",
  52. [ACPI_SPCR] = "SPCR",
  53. [ACPI_SRAT] = "SRAT",
  54. [ACPI_SSDT] = "SSDT",
  55. [ACPI_SPMI] = "SPMI",
  56. [ACPI_HPET] = "HPET",
  57. [ACPI_MCFG] = "MCFG",
  58. };
  59. static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
  60. static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
  61. /* System Description Table (RSDT/XSDT) */
  62. struct acpi_table_sdt {
  63. unsigned long pa;
  64. enum acpi_table_id id;
  65. unsigned long size;
  66. } __attribute__ ((packed));
  67. static unsigned long sdt_pa; /* Physical Address */
  68. static unsigned long sdt_count; /* Table count */
  69. static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES];
  70. void
  71. acpi_table_print (
  72. struct acpi_table_header *header,
  73. unsigned long phys_addr)
  74. {
  75. char *name = NULL;
  76. if (!header)
  77. return;
  78. /* Some table signatures aren't good table names */
  79. if (!strncmp((char *) &header->signature,
  80. acpi_table_signatures[ACPI_APIC],
  81. sizeof(header->signature))) {
  82. name = "MADT";
  83. }
  84. else if (!strncmp((char *) &header->signature,
  85. acpi_table_signatures[ACPI_FADT],
  86. sizeof(header->signature))) {
  87. name = "FADT";
  88. }
  89. else
  90. name = header->signature;
  91. printk(KERN_DEBUG PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n",
  92. name, header->revision, header->oem_id,
  93. header->oem_table_id, header->oem_revision,
  94. header->asl_compiler_id, header->asl_compiler_revision,
  95. (void *) phys_addr);
  96. }
  97. void
  98. acpi_table_print_madt_entry (
  99. acpi_table_entry_header *header)
  100. {
  101. if (!header)
  102. return;
  103. switch (header->type) {
  104. case ACPI_MADT_LAPIC:
  105. {
  106. struct acpi_table_lapic *p =
  107. (struct acpi_table_lapic*) header;
  108. printk(KERN_INFO PREFIX "LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
  109. p->acpi_id, p->id, p->flags.enabled?"enabled":"disabled");
  110. }
  111. break;
  112. case ACPI_MADT_IOAPIC:
  113. {
  114. struct acpi_table_ioapic *p =
  115. (struct acpi_table_ioapic*) header;
  116. printk(KERN_INFO PREFIX "IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
  117. p->id, p->address, p->global_irq_base);
  118. }
  119. break;
  120. case ACPI_MADT_INT_SRC_OVR:
  121. {
  122. struct acpi_table_int_src_ovr *p =
  123. (struct acpi_table_int_src_ovr*) header;
  124. printk(KERN_INFO PREFIX "INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
  125. p->bus, p->bus_irq, p->global_irq,
  126. mps_inti_flags_polarity[p->flags.polarity],
  127. mps_inti_flags_trigger[p->flags.trigger]);
  128. if(p->flags.reserved)
  129. printk(KERN_INFO PREFIX "INT_SRC_OVR unexpected reserved flags: 0x%x\n",
  130. p->flags.reserved);
  131. }
  132. break;
  133. case ACPI_MADT_NMI_SRC:
  134. {
  135. struct acpi_table_nmi_src *p =
  136. (struct acpi_table_nmi_src*) header;
  137. printk(KERN_INFO PREFIX "NMI_SRC (%s %s global_irq %d)\n",
  138. mps_inti_flags_polarity[p->flags.polarity],
  139. mps_inti_flags_trigger[p->flags.trigger], p->global_irq);
  140. }
  141. break;
  142. case ACPI_MADT_LAPIC_NMI:
  143. {
  144. struct acpi_table_lapic_nmi *p =
  145. (struct acpi_table_lapic_nmi*) header;
  146. printk(KERN_INFO PREFIX "LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
  147. p->acpi_id,
  148. mps_inti_flags_polarity[p->flags.polarity],
  149. mps_inti_flags_trigger[p->flags.trigger], p->lint);
  150. }
  151. break;
  152. case ACPI_MADT_LAPIC_ADDR_OVR:
  153. {
  154. struct acpi_table_lapic_addr_ovr *p =
  155. (struct acpi_table_lapic_addr_ovr*) header;
  156. printk(KERN_INFO PREFIX "LAPIC_ADDR_OVR (address[%p])\n",
  157. (void *) (unsigned long) p->address);
  158. }
  159. break;
  160. case ACPI_MADT_IOSAPIC:
  161. {
  162. struct acpi_table_iosapic *p =
  163. (struct acpi_table_iosapic*) header;
  164. printk(KERN_INFO PREFIX "IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
  165. p->id, (void *) (unsigned long) p->address, p->global_irq_base);
  166. }
  167. break;
  168. case ACPI_MADT_LSAPIC:
  169. {
  170. struct acpi_table_lsapic *p =
  171. (struct acpi_table_lsapic*) header;
  172. printk(KERN_INFO PREFIX "LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
  173. p->acpi_id, p->id, p->eid, p->flags.enabled?"enabled":"disabled");
  174. }
  175. break;
  176. case ACPI_MADT_PLAT_INT_SRC:
  177. {
  178. struct acpi_table_plat_int_src *p =
  179. (struct acpi_table_plat_int_src*) header;
  180. printk(KERN_INFO PREFIX "PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
  181. mps_inti_flags_polarity[p->flags.polarity],
  182. mps_inti_flags_trigger[p->flags.trigger],
  183. p->type, p->id, p->eid, p->iosapic_vector, p->global_irq);
  184. }
  185. break;
  186. default:
  187. printk(KERN_WARNING PREFIX "Found unsupported MADT entry (type = 0x%x)\n",
  188. header->type);
  189. break;
  190. }
  191. }
  192. static int
  193. acpi_table_compute_checksum (
  194. void *table_pointer,
  195. unsigned long length)
  196. {
  197. u8 *p = (u8 *) table_pointer;
  198. unsigned long remains = length;
  199. unsigned long sum = 0;
  200. if (!p || !length)
  201. return -EINVAL;
  202. while (remains--)
  203. sum += *p++;
  204. return (sum & 0xFF);
  205. }
  206. /*
  207. * acpi_get_table_header_early()
  208. * for acpi_blacklisted(), acpi_table_get_sdt()
  209. */
  210. int __init
  211. acpi_get_table_header_early (
  212. enum acpi_table_id id,
  213. struct acpi_table_header **header)
  214. {
  215. unsigned int i;
  216. enum acpi_table_id temp_id;
  217. /* DSDT is different from the rest */
  218. if (id == ACPI_DSDT)
  219. temp_id = ACPI_FADT;
  220. else
  221. temp_id = id;
  222. /* Locate the table. */
  223. for (i = 0; i < sdt_count; i++) {
  224. if (sdt_entry[i].id != temp_id)
  225. continue;
  226. *header = (void *)
  227. __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
  228. if (!*header) {
  229. printk(KERN_WARNING PREFIX "Unable to map %s\n",
  230. acpi_table_signatures[temp_id]);
  231. return -ENODEV;
  232. }
  233. break;
  234. }
  235. if (!*header) {
  236. printk(KERN_WARNING PREFIX "%s not present\n",
  237. acpi_table_signatures[id]);
  238. return -ENODEV;
  239. }
  240. /* Map the DSDT header via the pointer in the FADT */
  241. if (id == ACPI_DSDT) {
  242. struct fadt_descriptor_rev2 *fadt = (struct fadt_descriptor_rev2 *) *header;
  243. if (fadt->revision == 3 && fadt->Xdsdt) {
  244. *header = (void *) __acpi_map_table(fadt->Xdsdt,
  245. sizeof(struct acpi_table_header));
  246. } else if (fadt->V1_dsdt) {
  247. *header = (void *) __acpi_map_table(fadt->V1_dsdt,
  248. sizeof(struct acpi_table_header));
  249. } else
  250. *header = NULL;
  251. if (!*header) {
  252. printk(KERN_WARNING PREFIX "Unable to map DSDT\n");
  253. return -ENODEV;
  254. }
  255. }
  256. return 0;
  257. }
  258. int __init
  259. acpi_table_parse_madt_family (
  260. enum acpi_table_id id,
  261. unsigned long madt_size,
  262. int entry_id,
  263. acpi_madt_entry_handler handler,
  264. unsigned int max_entries)
  265. {
  266. void *madt = NULL;
  267. acpi_table_entry_header *entry;
  268. unsigned int count = 0;
  269. unsigned long madt_end;
  270. unsigned int i;
  271. if (!handler)
  272. return -EINVAL;
  273. /* Locate the MADT (if exists). There should only be one. */
  274. for (i = 0; i < sdt_count; i++) {
  275. if (sdt_entry[i].id != id)
  276. continue;
  277. madt = (void *)
  278. __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
  279. if (!madt) {
  280. printk(KERN_WARNING PREFIX "Unable to map %s\n",
  281. acpi_table_signatures[id]);
  282. return -ENODEV;
  283. }
  284. break;
  285. }
  286. if (!madt) {
  287. printk(KERN_WARNING PREFIX "%s not present\n",
  288. acpi_table_signatures[id]);
  289. return -ENODEV;
  290. }
  291. madt_end = (unsigned long) madt + sdt_entry[i].size;
  292. /* Parse all entries looking for a match. */
  293. entry = (acpi_table_entry_header *)
  294. ((unsigned long) madt + madt_size);
  295. while (((unsigned long) entry) + sizeof(acpi_table_entry_header) < madt_end) {
  296. if (entry->type == entry_id &&
  297. (!max_entries || count++ < max_entries))
  298. if (handler(entry, madt_end))
  299. return -EINVAL;
  300. entry = (acpi_table_entry_header *)
  301. ((unsigned long) entry + entry->length);
  302. }
  303. if (max_entries && count > max_entries) {
  304. printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of "
  305. "%i found\n", acpi_table_signatures[id], entry_id,
  306. count - max_entries, count);
  307. }
  308. return count;
  309. }
  310. int __init
  311. acpi_table_parse_madt (
  312. enum acpi_madt_entry_id id,
  313. acpi_madt_entry_handler handler,
  314. unsigned int max_entries)
  315. {
  316. return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt),
  317. id, handler, max_entries);
  318. }
  319. int __init
  320. acpi_table_parse (
  321. enum acpi_table_id id,
  322. acpi_table_handler handler)
  323. {
  324. int count = 0;
  325. unsigned int i = 0;
  326. if (!handler)
  327. return -EINVAL;
  328. for (i = 0; i < sdt_count; i++) {
  329. if (sdt_entry[i].id != id)
  330. continue;
  331. count++;
  332. if (count == 1)
  333. handler(sdt_entry[i].pa, sdt_entry[i].size);
  334. else
  335. printk(KERN_WARNING PREFIX "%d duplicate %s table ignored.\n",
  336. count, acpi_table_signatures[id]);
  337. }
  338. return count;
  339. }
  340. static int __init
  341. acpi_table_get_sdt (
  342. struct acpi_table_rsdp *rsdp)
  343. {
  344. struct acpi_table_header *header = NULL;
  345. unsigned int i, id = 0;
  346. if (!rsdp)
  347. return -EINVAL;
  348. /* First check XSDT (but only on ACPI 2.0-compatible systems) */
  349. if ((rsdp->revision >= 2) &&
  350. (((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) {
  351. struct acpi_table_xsdt *mapped_xsdt = NULL;
  352. sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address;
  353. /* map in just the header */
  354. header = (struct acpi_table_header *)
  355. __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
  356. if (!header) {
  357. printk(KERN_WARNING PREFIX "Unable to map XSDT header\n");
  358. return -ENODEV;
  359. }
  360. /* remap in the entire table before processing */
  361. mapped_xsdt = (struct acpi_table_xsdt *)
  362. __acpi_map_table(sdt_pa, header->length);
  363. if (!mapped_xsdt) {
  364. printk(KERN_WARNING PREFIX "Unable to map XSDT\n");
  365. return -ENODEV;
  366. }
  367. header = &mapped_xsdt->header;
  368. if (strncmp(header->signature, "XSDT", 4)) {
  369. printk(KERN_WARNING PREFIX "XSDT signature incorrect\n");
  370. return -ENODEV;
  371. }
  372. if (acpi_table_compute_checksum(header, header->length)) {
  373. printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n");
  374. return -ENODEV;
  375. }
  376. sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3;
  377. if (sdt_count > ACPI_MAX_TABLES) {
  378. printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n",
  379. (sdt_count - ACPI_MAX_TABLES));
  380. sdt_count = ACPI_MAX_TABLES;
  381. }
  382. for (i = 0; i < sdt_count; i++)
  383. sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i];
  384. }
  385. /* Then check RSDT */
  386. else if (rsdp->rsdt_address) {
  387. struct acpi_table_rsdt *mapped_rsdt = NULL;
  388. sdt_pa = rsdp->rsdt_address;
  389. /* map in just the header */
  390. header = (struct acpi_table_header *)
  391. __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header));
  392. if (!header) {
  393. printk(KERN_WARNING PREFIX "Unable to map RSDT header\n");
  394. return -ENODEV;
  395. }
  396. /* remap in the entire table before processing */
  397. mapped_rsdt = (struct acpi_table_rsdt *)
  398. __acpi_map_table(sdt_pa, header->length);
  399. if (!mapped_rsdt) {
  400. printk(KERN_WARNING PREFIX "Unable to map RSDT\n");
  401. return -ENODEV;
  402. }
  403. header = &mapped_rsdt->header;
  404. if (strncmp(header->signature, "RSDT", 4)) {
  405. printk(KERN_WARNING PREFIX "RSDT signature incorrect\n");
  406. return -ENODEV;
  407. }
  408. if (acpi_table_compute_checksum(header, header->length)) {
  409. printk(KERN_WARNING PREFIX "Invalid RSDT checksum\n");
  410. return -ENODEV;
  411. }
  412. sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 2;
  413. if (sdt_count > ACPI_MAX_TABLES) {
  414. printk(KERN_WARNING PREFIX "Truncated %lu RSDT entries\n",
  415. (sdt_count - ACPI_MAX_TABLES));
  416. sdt_count = ACPI_MAX_TABLES;
  417. }
  418. for (i = 0; i < sdt_count; i++)
  419. sdt_entry[i].pa = (unsigned long) mapped_rsdt->entry[i];
  420. }
  421. else {
  422. printk(KERN_WARNING PREFIX "No System Description Table (RSDT/XSDT) specified in RSDP\n");
  423. return -ENODEV;
  424. }
  425. acpi_table_print(header, sdt_pa);
  426. for (i = 0; i < sdt_count; i++) {
  427. /* map in just the header */
  428. header = (struct acpi_table_header *)
  429. __acpi_map_table(sdt_entry[i].pa,
  430. sizeof(struct acpi_table_header));
  431. if (!header)
  432. continue;
  433. /* remap in the entire table before processing */
  434. header = (struct acpi_table_header *)
  435. __acpi_map_table(sdt_entry[i].pa,
  436. header->length);
  437. if (!header)
  438. continue;
  439. acpi_table_print(header, sdt_entry[i].pa);
  440. if (acpi_table_compute_checksum(header, header->length)) {
  441. printk(KERN_WARNING " >>> ERROR: Invalid checksum\n");
  442. continue;
  443. }
  444. sdt_entry[i].size = header->length;
  445. for (id = 0; id < ACPI_TABLE_COUNT; id++) {
  446. if (!strncmp((char *) &header->signature,
  447. acpi_table_signatures[id],
  448. sizeof(header->signature))) {
  449. sdt_entry[i].id = id;
  450. }
  451. }
  452. }
  453. /*
  454. * The DSDT is *not* in the RSDT (why not? no idea.) but we want
  455. * to print its info, because this is what people usually blacklist
  456. * against. Unfortunately, we don't know the phys_addr, so just
  457. * print 0. Maybe no one will notice.
  458. */
  459. if(!acpi_get_table_header_early(ACPI_DSDT, &header))
  460. acpi_table_print(header, 0);
  461. return 0;
  462. }
  463. /*
  464. * acpi_table_init()
  465. *
  466. * find RSDP, find and checksum SDT/XSDT.
  467. * checksum all tables, print SDT/XSDT
  468. *
  469. * result: sdt_entry[] is initialized
  470. */
  471. int __init
  472. acpi_table_init (void)
  473. {
  474. struct acpi_table_rsdp *rsdp = NULL;
  475. unsigned long rsdp_phys = 0;
  476. int result = 0;
  477. /* Locate and map the Root System Description Table (RSDP) */
  478. rsdp_phys = acpi_find_rsdp();
  479. if (!rsdp_phys) {
  480. printk(KERN_ERR PREFIX "Unable to locate RSDP\n");
  481. return -ENODEV;
  482. }
  483. rsdp = (struct acpi_table_rsdp *) __va(rsdp_phys);
  484. if (!rsdp) {
  485. printk(KERN_WARNING PREFIX "Unable to map RSDP\n");
  486. return -ENODEV;
  487. }
  488. printk(KERN_DEBUG PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
  489. rsdp->revision, rsdp->oem_id, (void *) rsdp_phys);
  490. if (rsdp->revision < 2)
  491. result = acpi_table_compute_checksum(rsdp, sizeof(struct acpi_table_rsdp));
  492. else
  493. result = acpi_table_compute_checksum(rsdp, ((struct acpi20_table_rsdp *)rsdp)->length);
  494. if (result) {
  495. printk(KERN_WARNING " >>> ERROR: Invalid checksum\n");
  496. return -ENODEV;
  497. }
  498. /* Locate and map the System Description table (RSDT/XSDT) */
  499. if (acpi_table_get_sdt(rsdp))
  500. return -ENODEV;
  501. return 0;
  502. }