acpi.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:20k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  acpi.c - Architecture-Specific Low-Level ACPI Support
  3.  *
  4.  *  Copyright (C) 1999 VA Linux Systems
  5.  *  Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
  6.  *  Copyright (C) 2000, 2002 Hewlett-Packard Co.
  7.  * David Mosberger-Tang <davidm@hpl.hp.com>
  8.  *  Copyright (C) 2000 Intel Corp.
  9.  *  Copyright (C) 2000,2001 J.I. Lee <jung-ik.lee@intel.com>
  10.  *  Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
  11.  *
  12.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  13.  *
  14.  *  This program is free software; you can redistribute it and/or modify
  15.  *  it under the terms of the GNU General Public License as published by
  16.  *  the Free Software Foundation; either version 2 of the License, or
  17.  *  (at your option) any later version.
  18.  *
  19.  *  This program is distributed in the hope that it will be useful,
  20.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  *  GNU General Public License for more details.
  23.  *
  24.  *  You should have received a copy of the GNU General Public License
  25.  *  along with this program; if not, write to the Free Software
  26.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27.  *
  28.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  29.  */
  30. #include <linux/config.h>
  31. #include <linux/init.h>
  32. #include <linux/kernel.h>
  33. #include <linux/sched.h>
  34. #include <linux/smp.h>
  35. #include <linux/string.h>
  36. #include <linux/types.h>
  37. #include <linux/irq.h>
  38. #include <linux/acpi.h>
  39. #include <linux/efi.h>
  40. #include <asm/io.h>
  41. #include <asm/iosapic.h>
  42. #include <asm/machvec.h>
  43. #include <asm/page.h>
  44. #include <asm/system.h>
  45. #define PREFIX "ACPI: "
  46. asm (".weak iosapic_register_intr");
  47. asm (".weak iosapic_override_isa_irq");
  48. asm (".weak iosapic_register_platform_intr");
  49. asm (".weak iosapic_init");
  50. asm (".weak iosapic_version");
  51. void (*pm_idle) (void);
  52. void (*pm_power_off) (void);
  53. unsigned char acpi_kbd_controller_present = 1;
  54. const char *
  55. acpi_get_sysname (void)
  56. {
  57. #ifdef CONFIG_IA64_GENERIC
  58. unsigned long rsdp_phys;
  59. struct acpi20_table_rsdp *rsdp;
  60. struct acpi_table_xsdt *xsdt;
  61. struct acpi_table_header *hdr;
  62. rsdp_phys = acpi_find_rsdp();
  63. if (!rsdp_phys) {
  64. printk("ACPI 2.0 RSDP not found, default to "dig"n");
  65. return "dig";
  66. }
  67. rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
  68. if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
  69. printk("ACPI 2.0 RSDP signature incorrect, default to "dig"n");
  70. return "dig";
  71. }
  72. xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
  73. hdr = &xsdt->header;
  74. if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
  75. printk("ACPI 2.0 XSDT signature incorrect, default to "dig"n");
  76. return "dig";
  77. }
  78. if (!strcmp(hdr->oem_id, "HP")) {
  79. return "hpzx1";
  80. }
  81. return "dig";
  82. #else
  83. # if defined (CONFIG_IA64_HP_SIM)
  84. return "hpsim";
  85. # elif defined (CONFIG_IA64_HP_ZX1)
  86. return "hpzx1";
  87. # elif defined (CONFIG_IA64_SGI_SN1)
  88. return "sn1";
  89. # elif defined (CONFIG_IA64_SGI_SN2)
  90. return "sn2";
  91. # elif defined (CONFIG_IA64_DIG)
  92. return "dig";
  93. # elif defined (CONFIG_IA64_HP_ZX1)
  94. return "hpzx1";
  95. # else
  96. # error Unknown platform.  Fix acpi.c.
  97. # endif
  98. #endif
  99. }
  100. #ifdef CONFIG_ACPI
  101. /**
  102.  * acpi_get_crs - Return the current resource settings for a device
  103.  * obj: A handle for this device
  104.  * buf: A buffer to be populated by this call.
  105.  *
  106.  * Pass a valid handle, typically obtained by walking the namespace and a
  107.  * pointer to an allocated buffer, and this function will fill in the buffer
  108.  * with a list of acpi_resource structures.
  109.  */
  110. acpi_status
  111. acpi_get_crs (acpi_handle obj, acpi_buffer *buf)
  112. {
  113. acpi_status result;
  114. buf->length = 0;
  115. buf->pointer = NULL;
  116. result = acpi_get_current_resources(obj, buf);
  117. if (result != AE_BUFFER_OVERFLOW)
  118. return result;
  119. buf->pointer = kmalloc(buf->length, GFP_KERNEL);
  120. if (!buf->pointer)
  121. return -ENOMEM;
  122. return acpi_get_current_resources(obj, buf);
  123. }
  124. acpi_resource *
  125. acpi_get_crs_next (acpi_buffer *buf, int *offset)
  126. {
  127. acpi_resource *res;
  128. if (*offset >= buf->length)
  129. return NULL;
  130. res = buf->pointer + *offset;
  131. *offset += res->length;
  132. return res;
  133. }
  134. acpi_resource_data *
  135. acpi_get_crs_type (acpi_buffer *buf, int *offset, int type)
  136. {
  137. for (;;) {
  138. acpi_resource *res = acpi_get_crs_next(buf, offset);
  139. if (!res)
  140. return NULL;
  141. if (res->id == type)
  142. return &res->data;
  143. }
  144. }
  145. void
  146. acpi_dispose_crs (acpi_buffer *buf)
  147. {
  148. kfree(buf->pointer);
  149. }
  150. static void
  151. acpi_get_crs_addr (acpi_buffer *buf, int type, u64 *base, u64 *length, u64 *tra)
  152. {
  153. int offset = 0;
  154. acpi_resource_address16 *addr16;
  155. acpi_resource_address32 *addr32;
  156. acpi_resource_address64 *addr64;
  157. for (;;) {
  158. acpi_resource *res = acpi_get_crs_next(buf, &offset);
  159. if (!res)
  160. return;
  161. switch (res->id) {
  162. case ACPI_RSTYPE_ADDRESS16:
  163. addr16 = (acpi_resource_address16 *) &res->data;
  164. if (type == addr16->resource_type) {
  165. *base = addr16->min_address_range;
  166. *length = addr16->address_length;
  167. *tra = addr16->address_translation_offset;
  168. return;
  169. }
  170. break;
  171. case ACPI_RSTYPE_ADDRESS32:
  172. addr32 = (acpi_resource_address32 *) &res->data;
  173. if (type == addr32->resource_type) {
  174. *base = addr32->min_address_range;
  175. *length = addr32->address_length;
  176. *tra = addr32->address_translation_offset;
  177. return;
  178. }
  179. break;
  180. case ACPI_RSTYPE_ADDRESS64:
  181. addr64 = (acpi_resource_address64 *) &res->data;
  182. if (type == addr64->resource_type) {
  183. *base = addr64->min_address_range;
  184. *length = addr64->address_length;
  185. *tra = addr64->address_translation_offset;
  186. return;
  187. }
  188. break;
  189. }
  190. }
  191. }
  192. acpi_status
  193. acpi_get_addr_space(acpi_handle obj, u8 type, u64 *base, u64 *length, u64 *tra)
  194. {
  195. acpi_status status;
  196. acpi_buffer buf;
  197. *base = 0;
  198. *length = 0;
  199. *tra = 0;
  200. status = acpi_get_crs(obj, &buf);
  201. if (ACPI_FAILURE(status)) {
  202. printk(KERN_ERR PREFIX "Unable to get _CRS data on objectn");
  203. return status;
  204. }
  205. acpi_get_crs_addr(&buf, type, base, length, tra);
  206. acpi_dispose_crs(&buf);
  207. return AE_OK;
  208. }
  209. typedef struct {
  210. u8 guid_id;
  211. u8 guid[16];
  212. u8 csr_base[8];
  213. u8 csr_length[8];
  214. } acpi_hp_vendor_long;
  215. #define HP_CCSR_LENGTH 0x21
  216. #define HP_CCSR_TYPE 0x2
  217. #define HP_CCSR_GUID EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 
  218.       0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad)
  219. acpi_status
  220. acpi_hp_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
  221. {
  222. int i, offset = 0;
  223. acpi_status status;
  224. acpi_buffer buf;
  225. acpi_resource_vendor *res;
  226. acpi_hp_vendor_long *hp_res;
  227. efi_guid_t vendor_guid;
  228. *csr_base = 0;
  229. *csr_length = 0;
  230. status = acpi_get_crs(obj, &buf);
  231. if (ACPI_FAILURE(status)) {
  232. printk(KERN_ERR PREFIX "Unable to get _CRS data on objectn");
  233. return status;
  234. }
  235. res = (acpi_resource_vendor *)acpi_get_crs_type(&buf, &offset, ACPI_RSTYPE_VENDOR);
  236. if (!res) {
  237. printk(KERN_ERR PREFIX "Failed to find config space for devicen");
  238. acpi_dispose_crs(&buf);
  239. return AE_NOT_FOUND;
  240. }
  241. hp_res = (acpi_hp_vendor_long *)(res->reserved);
  242. if (res->length != HP_CCSR_LENGTH || hp_res->guid_id != HP_CCSR_TYPE) {
  243. printk(KERN_ERR PREFIX "Unknown Vendor datan");
  244. acpi_dispose_crs(&buf);
  245. return AE_TYPE; /* Revisit error? */
  246. }
  247. memcpy(&vendor_guid, hp_res->guid, sizeof(efi_guid_t));
  248. if (efi_guidcmp(vendor_guid, HP_CCSR_GUID) != 0) {
  249. printk(KERN_ERR PREFIX "Vendor GUID does not matchn");
  250. acpi_dispose_crs(&buf);
  251. return AE_TYPE; /* Revisit error? */
  252. }
  253. for (i = 0 ; i < 8 ; i++) {
  254. *csr_base |= ((u64)(hp_res->csr_base[i]) << (i * 8));
  255. *csr_length |= ((u64)(hp_res->csr_length[i]) << (i * 8));
  256. }
  257. acpi_dispose_crs(&buf);
  258. return AE_OK;
  259. }
  260. #endif /* CONFIG_ACPI */
  261. #ifdef CONFIG_ACPI_BOOT
  262. #define ACPI_MAX_PLATFORM_INTERRUPTS 256
  263. /* Array to record platform interrupt vectors for generic interrupt routing. */
  264. int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 };
  265. enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
  266. /*
  267.  * Interrupt routing API for device drivers.  Provides interrupt vector for
  268.  * a generic platform event.  Currently only CPEI is implemented.
  269.  */
  270. int
  271. acpi_request_vector (u32 int_type)
  272. {
  273. int vector = -1;
  274. if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
  275. /* correctable platform error interrupt */
  276. vector = platform_intr_list[int_type];
  277. } else
  278. printk("acpi_request_vector(): invalid interrupt typen");
  279. return vector;
  280. }
  281. char *
  282. __acpi_map_table (unsigned long phys_addr, unsigned long size)
  283. {
  284. return __va(phys_addr);
  285. }
  286. /* --------------------------------------------------------------------------
  287.                             Boot-time Table Parsing
  288.    -------------------------------------------------------------------------- */
  289. static int total_cpus __initdata;
  290. static int available_cpus __initdata;
  291. struct acpi_table_madt * acpi_madt __initdata;
  292. static u8 has_8259;
  293. static int __init
  294. acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header)
  295. {
  296. struct acpi_table_lapic_addr_ovr *lapic;
  297. lapic = (struct acpi_table_lapic_addr_ovr *) header;
  298. if (!lapic)
  299. return -EINVAL;
  300. acpi_table_print_madt_entry(header);
  301. if (lapic->address) {
  302. iounmap((void *) ipi_base_addr);
  303. ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
  304. }
  305. return 0;
  306. }
  307. static int __init
  308. acpi_parse_lsapic (acpi_table_entry_header *header)
  309. {
  310. struct acpi_table_lsapic *lsapic;
  311. lsapic = (struct acpi_table_lsapic *) header;
  312. if (!lsapic)
  313. return -EINVAL;
  314. acpi_table_print_madt_entry(header);
  315. printk("CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
  316. if (lsapic->flags.enabled) {
  317. available_cpus++;
  318. printk(" enabled");
  319. #ifdef CONFIG_SMP
  320. smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
  321. if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus])
  322. printk(" (BSP)");
  323. #endif
  324. }
  325. else {
  326. printk(" disabled");
  327. #ifdef CONFIG_SMP
  328. smp_boot_data.cpu_phys_id[total_cpus] = -1;
  329. #endif
  330. }
  331. printk("n");
  332. total_cpus++;
  333. return 0;
  334. }
  335. static int __init
  336. acpi_parse_lapic_nmi (acpi_table_entry_header *header)
  337. {
  338. struct acpi_table_lapic_nmi *lacpi_nmi;
  339. lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
  340. if (!lacpi_nmi)
  341. return -EINVAL;
  342. acpi_table_print_madt_entry(header);
  343. /* TBD: Support lapic_nmi entries */
  344. return 0;
  345. }
  346. static int __init
  347. acpi_find_iosapic (unsigned int gsi, u32 *gsi_base, char **iosapic_address)
  348. {
  349. struct acpi_table_iosapic *iosapic;
  350. int ver;
  351. int max_pin;
  352. char *p;
  353. char *end;
  354. if (!gsi_base || !iosapic_address)
  355. return -ENODEV;
  356. p = (char *) (acpi_madt + 1);
  357. end = p + (acpi_madt->header.length - sizeof(struct acpi_table_madt));
  358. while (p < end) {
  359. if (*p == ACPI_MADT_IOSAPIC) {
  360. iosapic = (struct acpi_table_iosapic *) p;
  361. *gsi_base = iosapic->global_irq_base;
  362. *iosapic_address = ioremap(iosapic->address, 0);
  363. ver = iosapic_version(*iosapic_address);
  364. max_pin = (ver >> 16) & 0xff;
  365. if ((gsi - *gsi_base) <= max_pin)
  366. return 0; /* Found it! */
  367. }
  368. p += p[1];
  369. }
  370. return -ENODEV;
  371. }
  372. static int __init
  373. acpi_parse_iosapic (acpi_table_entry_header *header)
  374. {
  375. struct acpi_table_iosapic *iosapic;
  376. iosapic = (struct acpi_table_iosapic *) header;
  377. if (!iosapic)
  378. return -EINVAL;
  379. acpi_table_print_madt_entry(header);
  380. if (iosapic_init) {
  381. #ifndef CONFIG_ITANIUM
  382. /* PCAT_COMPAT flag indicates dual-8259 setup */
  383. iosapic_init(iosapic->address, iosapic->global_irq_base,
  384.      acpi_madt->flags.pcat_compat);
  385. #else
  386. /* Firmware on old Itanium systems is broken */
  387. iosapic_init(iosapic->address, iosapic->global_irq_base, 1);
  388. #endif
  389. }
  390. return 0;
  391. }
  392. static int __init
  393. acpi_parse_plat_int_src (acpi_table_entry_header *header)
  394. {
  395. struct acpi_table_plat_int_src *plintsrc;
  396. int vector;
  397. u32 gsi_base;
  398. char *iosapic_address;
  399. plintsrc = (struct acpi_table_plat_int_src *) header;
  400. if (!plintsrc)
  401. return -EINVAL;
  402. acpi_table_print_madt_entry(header);
  403. if (!iosapic_register_platform_intr) {
  404. printk(KERN_WARNING PREFIX "No ACPI platform interrupt supportn");
  405. return -ENODEV;
  406. }
  407. if (acpi_find_iosapic(plintsrc->global_irq, &gsi_base, &iosapic_address)) {
  408. printk(KERN_WARNING PREFIX "IOSAPIC not foundn");
  409. return -ENODEV;
  410. }
  411. /*
  412.  * Get vector assignment for this interrupt, set attributes,
  413.  * and program the IOSAPIC routing table.
  414.  */
  415. vector = iosapic_register_platform_intr(plintsrc->type,
  416. plintsrc->global_irq,
  417. plintsrc->iosapic_vector,
  418. plintsrc->eid,
  419. plintsrc->id,
  420. (plintsrc->flags.polarity == 1) ? 1 : 0,
  421. (plintsrc->flags.trigger == 1) ? 1 : 0,
  422. gsi_base,
  423. iosapic_address);
  424. platform_intr_list[plintsrc->type] = vector;
  425. return 0;
  426. }
  427. static int __init
  428. acpi_parse_int_src_ovr (acpi_table_entry_header *header)
  429. {
  430. struct acpi_table_int_src_ovr *p;
  431. p = (struct acpi_table_int_src_ovr *) header;
  432. if (!p)
  433. return -EINVAL;
  434. acpi_table_print_madt_entry(header);
  435. /* Ignore if the platform doesn't support overrides */
  436. if (!iosapic_override_isa_irq)
  437. return 0;
  438. iosapic_override_isa_irq(p->bus_irq, p->global_irq,
  439.  (p->flags.polarity == 1) ? 1 : 0,
  440.  (p->flags.trigger == 1) ? 1 : 0);
  441. return 0;
  442. }
  443. static int __init
  444. acpi_parse_nmi_src (acpi_table_entry_header *header)
  445. {
  446. struct acpi_table_nmi_src *nmi_src;
  447. nmi_src = (struct acpi_table_nmi_src*) header;
  448. if (!nmi_src)
  449. return -EINVAL;
  450. acpi_table_print_madt_entry(header);
  451. /* TBD: Support nimsrc entries */
  452. return 0;
  453. }
  454. static int __init
  455. acpi_parse_madt (unsigned long phys_addr, unsigned long size)
  456. {
  457. if (!phys_addr || !size)
  458. return -EINVAL;
  459. acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
  460. /* remember the value for reference after free_initmem() */
  461. has_8259 = acpi_madt->flags.pcat_compat;
  462. /* Get base address of IPI Message Block */
  463. if (acpi_madt->lapic_address)
  464. ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
  465. printk(KERN_INFO PREFIX "Local APIC address 0x%lxn", ipi_base_addr);
  466. return 0;
  467. }
  468. static int __init
  469. acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
  470. {
  471. struct acpi_table_header *fadt_header;
  472. fadt_descriptor_rev2 *fadt;
  473. u32 sci_irq, gsi_base;
  474. char *iosapic_address;
  475. if (!phys_addr || !size)
  476. return -EINVAL;
  477. fadt_header = (struct acpi_table_header *) __va(phys_addr);
  478. if (fadt_header->revision != 3)
  479. return -ENODEV; /* Only deal with ACPI 2.0 FADT */
  480. fadt = (fadt_descriptor_rev2 *) fadt_header;
  481. if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
  482. acpi_kbd_controller_present = 0;
  483. sci_irq = fadt->sci_int;
  484. if (has_8259 && sci_irq < 16)
  485. return 0; /* legacy, no setup required */
  486. if (!iosapic_register_intr)
  487. return -ENODEV;
  488. if (!acpi_find_iosapic(sci_irq, &gsi_base, &iosapic_address))
  489. iosapic_register_intr(sci_irq, 0, 0, gsi_base, iosapic_address);
  490. return 0;
  491. }
  492. #ifdef CONFIG_SERIAL_ACPI
  493. #include <linux/acpi_serial.h>
  494. static int __init
  495. acpi_parse_spcr (unsigned long phys_addr, unsigned long size)
  496. {
  497. acpi_ser_t *spcr;
  498. u32 gsi, gsi_base;
  499. char *iosapic_address;
  500. if (!phys_addr || !size)
  501. return -EINVAL;
  502. if (!iosapic_register_intr)
  503. return -ENODEV;
  504. /*
  505.  * ACPI is able to describe serial ports that live at non-standard
  506.  * memory addresses and use non-standard interrupts, either via
  507.  * direct SAPIC mappings or via PCI interrupts.  We handle interrupt
  508.  * routing for SAPIC-based (non-PCI) devices here.  Interrupt routing
  509.  * for PCI devices will be handled when processing the PCI Interrupt
  510.  * Routing Table (PRT).
  511.  */
  512. spcr = (acpi_ser_t *) __va(phys_addr);
  513. setup_serial_acpi(spcr);
  514. if (spcr->length < sizeof(acpi_ser_t))
  515. /* Table not long enough for full info, thus no interrupt */
  516. return -ENODEV;
  517. if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) &&
  518.     (spcr->int_type == ACPI_SERIAL_INT_SAPIC)) {
  519. /* We have a UART in memory space with an SAPIC interrupt */
  520. gsi = (spcr->global_int[3] << 24) |
  521.       (spcr->global_int[2] << 16) |
  522.       (spcr->global_int[1] << 8)  |
  523.       (spcr->global_int[0]);
  524. if (!acpi_find_iosapic(gsi, &gsi_base, &iosapic_address))
  525. iosapic_register_intr(gsi, 1, 1,
  526.       gsi_base, iosapic_address);
  527. }
  528. return 0;
  529. }
  530. #endif /*CONFIG_SERIAL_ACPI*/
  531. unsigned long __init
  532. acpi_find_rsdp (void)
  533. {
  534. unsigned long rsdp_phys = 0;
  535. if (efi.acpi20)
  536. rsdp_phys = __pa(efi.acpi20);
  537. else if (efi.acpi)
  538. printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supportedn");
  539. return rsdp_phys;
  540. }
  541. int __init
  542. acpi_boot_init (char *cmdline)
  543. {
  544. int result;
  545. /* Initialize the ACPI boot-time table parser */
  546. result = acpi_table_init(cmdline);
  547. if (result)
  548. return result;
  549. /*
  550.  * MADT
  551.  * ----
  552.  * Parse the Multiple APIC Description Table (MADT), if exists.
  553.  * Note that this table provides platform SMP configuration
  554.  * information -- the successor to MPS tables.
  555.  */
  556. if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {
  557. printk(KERN_ERR PREFIX "Can't find MADTn");
  558. goto skip_madt;
  559. }
  560. /* Local APIC */
  561. if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
  562.   acpi_parse_lapic_addr_ovr) < 0)
  563. printk(KERN_ERR PREFIX "Error parsing LAPIC address override entryn");
  564. if (acpi_table_parse_madt(ACPI_MADT_LSAPIC,
  565.   acpi_parse_lsapic) < 1)
  566. printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entriesn");
  567. if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI,
  568.   acpi_parse_lapic_nmi) < 0)
  569. printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entryn");
  570. /* I/O APIC */
  571. if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC,
  572.   acpi_parse_iosapic) < 1)
  573. printk(KERN_ERR PREFIX "Error parsing MADT - no IOAPIC entriesn");
  574. /* System-Level Interrupt Routing */
  575. if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,
  576.   acpi_parse_plat_int_src) < 0)
  577. printk(KERN_ERR PREFIX "Error parsing platform interrupt source entryn");
  578. if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR,
  579.   acpi_parse_int_src_ovr) < 0)
  580. printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entryn");
  581. if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC,
  582.   acpi_parse_nmi_src) < 0)
  583. printk(KERN_ERR PREFIX "Error parsing NMI SRC entryn");
  584. skip_madt:
  585. /*
  586.  * The FADT table contains an SCI_INT line, by which the system
  587.  * gets interrupts such as power and sleep buttons.  If it's not
  588.  * on a Legacy interrupt, it needs to be setup.
  589.  */
  590. if (acpi_table_parse(ACPI_FACP, acpi_parse_fadt) < 1)
  591. printk(KERN_ERR PREFIX "Can't find FADTn");
  592. #ifdef CONFIG_SERIAL_ACPI
  593. acpi_table_parse(ACPI_SPCR, acpi_parse_spcr);
  594. #endif
  595. #ifdef CONFIG_SMP
  596. if (available_cpus == 0) {
  597. printk("ACPI: Found 0 CPUS; assuming 1n");
  598. available_cpus = 1; /* We've got at least one of these, no? */
  599. }
  600. smp_boot_data.cpu_count = total_cpus;
  601. #endif
  602. /* Make boot-up look pretty */
  603. printk("%d CPUs available, %d CPUs totaln", available_cpus, total_cpus);
  604. return 0;
  605. }
  606. /* --------------------------------------------------------------------------
  607.                              PCI Interrupt Routing
  608.    -------------------------------------------------------------------------- */
  609. int __init
  610. acpi_get_prt (struct pci_vector_struct **vectors, int *count)
  611. {
  612. struct pci_vector_struct *vector;
  613. struct list_head *node;
  614. struct acpi_prt_entry *entry;
  615. int i = 0;
  616. if (!vectors || !count)
  617. return -EINVAL;
  618. *vectors = NULL;
  619. *count = 0;
  620. if (acpi_prt.count < 0) {
  621. printk(KERN_ERR PREFIX "No PCI interrupt routing entriesn");
  622. return -ENODEV;
  623. }
  624. /* Allocate vectors */
  625. *vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL);
  626. if (!(*vectors))
  627. return -ENOMEM;
  628. /* Convert PRT entries to IOSAPIC PCI vectors */
  629. vector = *vectors;
  630. list_for_each(node, &acpi_prt.entries) {
  631. entry = (struct acpi_prt_entry *)node;
  632. vector[i].segment = entry->id.segment;
  633. vector[i].bus    = entry->id.bus;
  634. vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff;
  635. vector[i].pin    = entry->pin;
  636. vector[i].irq    = entry->link.index;
  637. i++;
  638. }
  639. *count = acpi_prt.count;
  640. return 0;
  641. }
  642. /* Assume IA64 always use I/O SAPIC */
  643. int __init
  644. acpi_get_interrupt_model (int *type)
  645. {
  646.         if (!type)
  647.                 return -EINVAL;
  648. *type = ACPI_IRQ_MODEL_IOSAPIC;
  649.         return 0;
  650. }
  651. int
  652. acpi_irq_to_vector (u32 irq)
  653. {
  654. if (has_8259 && irq < 16)
  655. return isa_irq_to_vector(irq);
  656. return gsi_to_vector(irq);
  657. }
  658. #endif /* CONFIG_ACPI_BOOT */