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-2003 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 * Copyright (C) 2001 Jenna Hall <jenna.s.hall@intel.com> 12 * Copyright (C) 2001 Takayoshi Kochi <t-kouchi@cq.jp.nec.com> 13 * Copyright (C) 2002 Erich Focht <efocht@ess.nec.de> 14 * 15 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 * 17 * This program is free software; you can redistribute it and/or modify 18 * it under the terms of the GNU General Public License as published by 19 * the Free Software Foundation; either version 2 of the License, or 20 * (at your option) any later version. 21 * 22 * This program is distributed in the hope that it will be useful, 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * GNU General Public License for more details. 26 * 27 * You should have received a copy of the GNU General Public License 28 * along with this program; if not, write to the Free Software 29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 30 * 31 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 */ 33 34 #include <linux/config.h> 35 #include <linux/init.h> 36 #include <linux/kernel.h> 37 #include <linux/sched.h> 38 #include <linux/smp.h> 39 #include <linux/string.h> 40 #include <linux/types.h> 41 #include <linux/irq.h> 42 #include <linux/acpi.h> 43 #include <linux/efi.h> 44 #include <linux/mm.h> 45 #include <linux/mmzone.h> 46 #include <asm/io.h> 47 #include <asm/iosapic.h> 48 #include <asm/machvec.h> 49 #include <asm/page.h> 50 #include <asm/system.h> 51 #include <asm/numa.h> 52 53 54 #define PREFIX "ACPI: " 55 56 asm (".weak iosapic_register_intr"); 57 asm (".weak iosapic_override_isa_irq"); 58 asm (".weak iosapic_register_platform_intr"); 59 asm (".weak iosapic_init"); 60 asm (".weak iosapic_system_init"); 61 asm (".weak iosapic_version"); 62 63 void (*pm_idle) (void); 64 void (*pm_power_off) (void); 65 66 unsigned char acpi_kbd_controller_present = 1; 67 68 const char * 69 acpi_get_sysname (void) 70 { 71 #ifdef CONFIG_IA64_GENERIC 72 unsigned long rsdp_phys; 73 struct acpi20_table_rsdp *rsdp; 74 struct acpi_table_xsdt *xsdt; 75 struct acpi_table_header *hdr; 76 77 rsdp_phys = acpi_find_rsdp(); 78 if (!rsdp_phys) { 79 printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n"); 80 return "dig"; 81 } 82 83 rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys); 84 if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) { 85 printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n"); 86 return "dig"; 87 } 88 89 xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address); 90 hdr = &xsdt->header; 91 if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) { 92 printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n"); 93 return "dig"; 94 } 95 96 if (!strcmp(hdr->oem_id, "HP")) { 97 return "hp"; 98 } 99 else if (!strcmp(hdr->oem_id, "SGI")) { 100 return "sn2"; 101 } 102 103 return "dig"; 104 #else 105 # if defined (CONFIG_IA64_HP_SIM) 106 return "hpsim"; 107 # elif defined (CONFIG_IA64_HP_ZX1) 108 return "hp"; 109 # elif defined (CONFIG_IA64_SGI_SN2) 110 return "sn2"; 111 # elif defined (CONFIG_IA64_DIG) 112 return "dig"; 113 # else 114 # error Unknown platform. Fix acpi.c. 115 # endif 116 #endif 117 } 118 119 #ifdef CONFIG_ACPI 120 121 struct acpi_vendor_descriptor { 122 u8 guid_id; 123 efi_guid_t guid; 124 }; 125 126 struct acpi_vendor_info { 127 struct acpi_vendor_descriptor *descriptor; 128 u8 *data; 129 u32 length; 130 }; 131 132 acpi_status 133 acpi_vendor_resource_match (struct acpi_resource *resource, void *context) 134 { 135 struct acpi_vendor_info *info = (struct acpi_vendor_info *) context; 136 struct acpi_resource_vendor *vendor; 137 struct acpi_vendor_descriptor *descriptor; 138 u32 length; 139 140 if (resource->id != ACPI_RSTYPE_VENDOR) 141 return AE_OK; 142 143 vendor = (struct acpi_resource_vendor *) &resource->data; 144 descriptor = (struct acpi_vendor_descriptor *) vendor->reserved; 145 if (vendor->length <= sizeof(*info->descriptor) || 146 descriptor->guid_id != info->descriptor->guid_id || 147 efi_guidcmp(descriptor->guid, info->descriptor->guid)) 148 return AE_OK; 149 150 length = vendor->length - sizeof(struct acpi_vendor_descriptor); 151 info->data = acpi_os_allocate(length); 152 if (!info->data) 153 return AE_NO_MEMORY; 154 155 memcpy(info->data, vendor->reserved + sizeof(struct acpi_vendor_descriptor), length); 156 info->length = length; 157 return AE_CTRL_TERMINATE; 158 } 159 160 acpi_status 161 acpi_find_vendor_resource (acpi_handle obj, struct acpi_vendor_descriptor *id, 162 u8 **data, u32 *length) 163 { 164 struct acpi_vendor_info info; 165 166 info.descriptor = id; 167 info.data = 0; 168 169 acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, &info); 170 if (!info.data) 171 return AE_NOT_FOUND; 172 173 *data = info.data; 174 *length = info.length; 175 return AE_OK; 176 } 177 178 struct acpi_vendor_descriptor hp_ccsr_descriptor = { 179 .guid_id = 2, 180 .guid = EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad) 181 }; 182 183 acpi_status 184 acpi_hp_csr_space (acpi_handle obj, u64 *csr_base, u64 *csr_length) 185 { 186 acpi_status status; 187 u8 *data; 188 u32 length; 189 190 status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); 191 192 if (ACPI_FAILURE(status) || length != 16) 193 return AE_NOT_FOUND; 194 195 memcpy(csr_base, data, sizeof(*csr_base)); 196 memcpy(csr_length, data + 8, sizeof(*csr_length)); 197 acpi_os_free(data); 198 199 return AE_OK; 200 } 201 202 #endif /* CONFIG_ACPI */ 203 204 #ifdef CONFIG_ACPI_BOOT 205 206 #define ACPI_MAX_PLATFORM_INTERRUPTS 256 207 208 /* Array to record platform interrupt vectors for generic interrupt routing. */ 209 int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = { 210 [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1 211 }; 212 213 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC; 214 215 /* 216 * Interrupt routing API for device drivers. Provides interrupt vector for 217 * a generic platform event. Currently only CPEI is implemented. 218 */ 219 int 220 acpi_request_vector (u32 int_type) 221 { 222 int vector = -1; 223 224 if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) { 225 /* corrected platform error interrupt */ 226 vector = platform_intr_list[int_type]; 227 } else 228 printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n"); 229 return vector; 230 } 231 232 char * 233 __acpi_map_table (unsigned long phys_addr, unsigned long size) 234 { 235 return __va(phys_addr); 236 } 237 238 /* -------------------------------------------------------------------------- 239 Boot-time Table Parsing 240 -------------------------------------------------------------------------- */ 241 242 static int total_cpus __initdata; 243 static int available_cpus __initdata; 244 struct acpi_table_madt * acpi_madt __initdata; 245 static u8 has_8259; 246 247 248 static int __init 249 acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header) 250 { 251 struct acpi_table_lapic_addr_ovr *lapic; 252 253 lapic = (struct acpi_table_lapic_addr_ovr *) header; 254 if (!lapic) 255 return -EINVAL; 256 257 acpi_table_print_madt_entry(header); 258 259 if (lapic->address) { 260 iounmap((void *) ipi_base_addr); 261 ipi_base_addr = (unsigned long) ioremap(lapic->address, 0); 262 } 263 return 0; 264 } 265 266 267 static int __init 268 acpi_parse_lsapic (acpi_table_entry_header *header) 269 { 270 struct acpi_table_lsapic *lsapic; 271 272 lsapic = (struct acpi_table_lsapic *) header; 273 if (!lsapic) 274 return -EINVAL; 275 276 acpi_table_print_madt_entry(header); 277 278 printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid); 279 280 if (!lsapic->flags.enabled) 281 printk(" disabled"); 282 else if (available_cpus >= NR_CPUS) 283 printk(" ignored (increase NR_CPUS)"); 284 else { 285 printk(" enabled"); 286 #ifdef CONFIG_SMP 287 smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid; 288 if (hard_smp_processor_id() 289 == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus]) 290 printk(" (BSP)"); 291 #endif 292 ++available_cpus; 293 } 294 295 printk("\n"); 296 297 total_cpus++; 298 return 0; 299 } 300 301 302 static int __init 303 acpi_parse_lapic_nmi (acpi_table_entry_header *header) 304 { 305 struct acpi_table_lapic_nmi *lacpi_nmi; 306 307 lacpi_nmi = (struct acpi_table_lapic_nmi*) header; 308 if (!lacpi_nmi) 309 return -EINVAL; 310 311 acpi_table_print_madt_entry(header); 312 313 /* TBD: Support lapic_nmi entries */ 314 return 0; 315 } 316 317 318 static int __init 319 acpi_parse_iosapic (acpi_table_entry_header *header) 320 { 321 struct acpi_table_iosapic *iosapic; 322 323 iosapic = (struct acpi_table_iosapic *) header; 324 if (!iosapic) 325 return -EINVAL; 326 327 acpi_table_print_madt_entry(header); 328 329 if (iosapic_init) 330 iosapic_init(iosapic->address, iosapic->global_irq_base); 331 332 return 0; 333 } 334 335 336 static int __init 337 acpi_parse_plat_int_src (acpi_table_entry_header *header) 338 { 339 struct acpi_table_plat_int_src *plintsrc; 340 int vector; 341 342 plintsrc = (struct acpi_table_plat_int_src *) header; 343 if (!plintsrc) 344 return -EINVAL; 345 346 acpi_table_print_madt_entry(header); 347 348 if (!iosapic_register_platform_intr) { 349 printk(KERN_WARNING PREFIX "No ACPI platform interrupt support\n"); 350 return -ENODEV; 351 } 352 353 /* 354 * Get vector assignment for this interrupt, set attributes, 355 * and program the IOSAPIC routing table. 356 */ 357 vector = iosapic_register_platform_intr(plintsrc->type, 358 plintsrc->global_irq, 359 plintsrc->iosapic_vector, 360 plintsrc->eid, 361 plintsrc->id, 362 (plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, 363 (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); 364 365 platform_intr_list[plintsrc->type] = vector; 366 return 0; 367 } 368 369 370 static int __init 371 acpi_parse_int_src_ovr (acpi_table_entry_header *header) 372 { 373 struct acpi_table_int_src_ovr *p; 374 375 p = (struct acpi_table_int_src_ovr *) header; 376 if (!p) 377 return -EINVAL; 378 379 acpi_table_print_madt_entry(header); 380 381 /* Ignore if the platform doesn't support overrides */ 382 if (!iosapic_override_isa_irq) 383 return 0; 384 385 iosapic_override_isa_irq(p->bus_irq, p->global_irq, 386 (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, 387 (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); 388 return 0; 389 } 390 391 392 static int __init 393 acpi_parse_nmi_src (acpi_table_entry_header *header) 394 { 395 struct acpi_table_nmi_src *nmi_src; 396 397 nmi_src = (struct acpi_table_nmi_src*) header; 398 if (!nmi_src) 399 return -EINVAL; 400 401 acpi_table_print_madt_entry(header); 402 403 /* TBD: Support nimsrc entries */ 404 return 0; 405 } 406 407 408 static int __init 409 acpi_parse_madt (unsigned long phys_addr, unsigned long size) 410 { 411 if (!phys_addr || !size) 412 return -EINVAL; 413 414 acpi_madt = (struct acpi_table_madt *) __va(phys_addr); 415 416 /* remember the value for reference after free_initmem() */ 417 #ifdef CONFIG_ITANIUM 418 has_8259 = 1; /* Firmware on old Itanium systems is broken */ 419 #else 420 has_8259 = acpi_madt->flags.pcat_compat; 421 #endif 422 if (iosapic_system_init) 423 iosapic_system_init(has_8259); 424 425 /* Get base address of IPI Message Block */ 426 427 if (acpi_madt->lapic_address) 428 ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0); 429 430 printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr); 431 return 0; 432 } 433 434 435 #ifdef CONFIG_ACPI_NUMA 436 437 #define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32) 438 439 static int __initdata srat_num_cpus; /* number of cpus */ 440 static u32 __initdata pxm_flag[PXM_FLAG_LEN]; 441 #define pxm_bit_set(bit) (set_bit(bit,(void *)pxm_flag)) 442 #define pxm_bit_test(bit) (test_bit(bit,(void *)pxm_flag)) 443 /* maps to convert between proximity domain and logical node ID */ 444 int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS]; 445 int __initdata nid_to_pxm_map[NR_NODES]; 446 struct acpi_table_slit __initdata *slit_table; 447 448 /* 449 * ACPI 2.0 SLIT (System Locality Information Table) 450 * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf 451 */ 452 void __init 453 acpi_numa_slit_init (struct acpi_table_slit *slit) 454 { 455 u32 len; 456 457 len = sizeof(struct acpi_table_header) + 8 458 + slit->localities * slit->localities; 459 if (slit->header.length != len) { 460 printk("KERN_INFO ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", 461 len, slit->header.length); 462 memset(numa_slit, 10, sizeof(numa_slit)); 463 return; 464 } 465 slit_table = slit; 466 } 467 468 void __init 469 acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa) 470 { 471 /* record this node in proximity bitmap */ 472 pxm_bit_set(pa->proximity_domain); 473 474 node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid); 475 /* nid should be overridden as logical node id later */ 476 node_cpuid[srat_num_cpus].nid = pa->proximity_domain; 477 srat_num_cpus++; 478 } 479 480 void __init 481 acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma) 482 { 483 unsigned long paddr, size, hole_size, min_hole_size; 484 u8 pxm; 485 struct node_memblk_s *p, *q, *pend; 486 487 pxm = ma->proximity_domain; 488 489 /* fill node memory chunk structure */ 490 paddr = ma->base_addr_hi; 491 paddr = (paddr << 32) | ma->base_addr_lo; 492 size = ma->length_hi; 493 size = (size << 32) | ma->length_lo; 494 495 if (num_memblks >= NR_MEMBLKS) { 496 printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n", 497 size/(1024*1024), paddr); 498 return; 499 } 500 501 /* Ignore disabled entries */ 502 if (!ma->flags.enabled) 503 return; 504 505 /* 506 * When the chunk is not the first one in the node, check distance 507 * from the other chunks. When the hole is too huge ignore the chunk. 508 * This restriction should be removed when multiple chunks per node 509 * is supported. 510 */ 511 pend = &node_memblk[num_memblks]; 512 min_hole_size = 0; 513 for (p = &node_memblk[0]; p < pend; p++) { 514 if (p->nid != pxm) 515 continue; 516 if (p->start_paddr < paddr) 517 hole_size = paddr - (p->start_paddr + p->size); 518 else 519 hole_size = p->start_paddr - (paddr + size); 520 521 if (!min_hole_size || hole_size < min_hole_size) 522 min_hole_size = hole_size; 523 } 524 525 #if 0 /* test */ 526 if (min_hole_size) { 527 if (min_hole_size > size) { 528 printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n", 529 size/(1024*1024), paddr); 530 return; 531 } 532 } 533 #endif 534 535 /* record this node in proximity bitmap */ 536 pxm_bit_set(pxm); 537 538 /* Insertion sort based on base address */ 539 pend = &node_memblk[num_memblks]; 540 for (p = &node_memblk[0]; p < pend; p++) { 541 if (paddr < p->start_paddr) 542 break; 543 } 544 if (p < pend) { 545 for (q = pend; q >= p; q--) 546 *(q + 1) = *q; 547 } 548 p->start_paddr = paddr; 549 p->size = size; 550 p->nid = pxm; 551 num_memblks++; 552 } 553 554 void __init 555 acpi_numa_arch_fixup(void) 556 { 557 int i, j, node_from, node_to; 558 559 if (srat_num_cpus == 0) { 560 node_cpuid[0].phys_id = hard_smp_processor_id(); 561 return; 562 } 563 564 /* calculate total number of nodes in system from PXM bitmap */ 565 numnodes = 0; /* init total nodes in system */ 566 567 memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map)); 568 memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map)); 569 for (i = 0; i < MAX_PXM_DOMAINS; i++) { 570 if (pxm_bit_test(i)) { 571 pxm_to_nid_map[i] = numnodes; 572 nid_to_pxm_map[numnodes++] = i; 573 } 574 } 575 576 /* set logical node id in memory chunk structure */ 577 for (i = 0; i < num_memblks; i++) 578 node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid]; 579 580 /* assign memory bank numbers for each chunk on each node */ 581 for (i = 0; i < numnodes; i++) { 582 int bank; 583 584 bank = 0; 585 for (j = 0; j < num_memblks; j++) 586 if (node_memblk[j].nid == i) 587 node_memblk[j].bank = bank++; 588 } 589 590 /* set logical node id in cpu structure */ 591 for (i = 0; i < srat_num_cpus; i++) 592 node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid]; 593 594 printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes); 595 printk(KERN_INFO "Number of memory chunks in system = %d\n", num_memblks); 596 597 if (!slit_table) return; 598 memset(numa_slit, -1, sizeof(numa_slit)); 599 for (i=0; i<slit_table->localities; i++) { 600 if (!pxm_bit_test(i)) 601 continue; 602 node_from = pxm_to_nid_map[i]; 603 for (j=0; j<slit_table->localities; j++) { 604 if (!pxm_bit_test(j)) 605 continue; 606 node_to = pxm_to_nid_map[j]; 607 node_distance(node_from, node_to) = 608 slit_table->entry[i*slit_table->localities + j]; 609 } 610 } 611 612 #ifdef SLIT_DEBUG 613 printk(KERN_DEBUG "ACPI 2.0 SLIT locality table:\n"); 614 for (i = 0; i < numnodes; i++) { 615 for (j = 0; j < numnodes; j++) 616 printk(KERN_DEBUG "%03d ", node_distance(i,j)); 617 printk("\n"); 618 } 619 #endif 620 } 621 #endif /* CONFIG_ACPI_NUMA */ 622 623 static int __init 624 acpi_parse_fadt (unsigned long phys_addr, unsigned long size) 625 { 626 struct acpi_table_header *fadt_header; 627 struct fadt_descriptor_rev2 *fadt; 628 u32 sci_irq; 629 630 if (!phys_addr || !size) 631 return -EINVAL; 632 633 fadt_header = (struct acpi_table_header *) __va(phys_addr); 634 if (fadt_header->revision != 3) 635 return -ENODEV; /* Only deal with ACPI 2.0 FADT */ 636 637 fadt = (struct fadt_descriptor_rev2 *) fadt_header; 638 639 if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) 640 acpi_kbd_controller_present = 0; 641 642 sci_irq = fadt->sci_int; 643 644 if (has_8259 && sci_irq < 16) 645 return 0; /* legacy, no setup required */ 646 647 if (!iosapic_register_intr) 648 return -ENODEV; 649 650 iosapic_register_intr(sci_irq, IOSAPIC_POL_LOW, IOSAPIC_LEVEL); 651 return 0; 652 } 653 654 655 unsigned long __init 656 acpi_find_rsdp (void) 657 { 658 unsigned long rsdp_phys = 0; 659 660 if (efi.acpi20) 661 rsdp_phys = __pa(efi.acpi20); 662 else if (efi.acpi) 663 printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n"); 664 return rsdp_phys; 665 } 666 667 668 int __init 669 acpi_boot_init (void) 670 { 671 672 /* 673 * MADT 674 * ---- 675 * Parse the Multiple APIC Description Table (MADT), if exists. 676 * Note that this table provides platform SMP configuration 677 * information -- the successor to MPS tables. 678 */ 679 680 if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) { 681 printk(KERN_ERR PREFIX "Can't find MADT\n"); 682 goto skip_madt; 683 } 684 685 /* Local APIC */ 686 687 if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0) 688 printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n"); 689 690 if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1) 691 printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n"); 692 693 if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0) 694 printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n"); 695 696 /* I/O APIC */ 697 698 if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1) 699 printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n"); 700 701 /* System-Level Interrupt Routing */ 702 703 if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0) 704 printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n"); 705 706 if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0) 707 printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n"); 708 709 if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0) 710 printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n"); 711 skip_madt: 712 713 /* 714 * FADT says whether a legacy keyboard controller is present. 715 * The FADT also contains an SCI_INT line, by which the system 716 * gets interrupts such as power and sleep buttons. If it's not 717 * on a Legacy interrupt, it needs to be setup. 718 */ 719 if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1) 720 printk(KERN_ERR PREFIX "Can't find FADT\n"); 721 722 #ifdef CONFIG_SMP 723 if (available_cpus == 0) { 724 printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n"); 725 printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id()); 726 smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id(); 727 available_cpus = 1; /* We've got at least one of these, no? */ 728 } 729 smp_boot_data.cpu_count = available_cpus; 730 731 smp_build_cpu_map(); 732 # ifdef CONFIG_NUMA 733 /* If the platform did not have an SRAT table, initialize the 734 * node_cpuid table from the smp_boot_data array. All cpus 735 * will be on node 0. 736 */ 737 if (srat_num_cpus == 0) { 738 int cpu, i=1; 739 for (cpu=0; cpu<smp_boot_data.cpu_count; cpu++) 740 if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id()) 741 node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu]; 742 } 743 build_cpu_to_node_map(); 744 # endif 745 746 #endif 747 /* Make boot-up look pretty */ 748 printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus); 749 return 0; 750 } 751 752 /* 753 * PCI Interrupt Routing 754 */ 755 756 #ifdef CONFIG_PCI 757 int __init 758 acpi_get_prt (struct pci_vector_struct **vectors, int *count) 759 { 760 struct pci_vector_struct *vector; 761 struct list_head *node; 762 struct acpi_prt_entry *entry; 763 int i = 0; 764 765 if (!vectors || !count) 766 return -EINVAL; 767 768 *vectors = NULL; 769 *count = 0; 770 771 if (acpi_prt.count < 0) { 772 printk(KERN_ERR PREFIX "No PCI interrupt routing entries\n"); 773 return -ENODEV; 774 } 775 776 /* Allocate vectors */ 777 778 *vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL); 779 if (!(*vectors)) 780 return -ENOMEM; 781 782 /* Convert PRT entries to IOSAPIC PCI vectors */ 783 784 vector = *vectors; 785 786 list_for_each(node, &acpi_prt.entries) { 787 entry = (struct acpi_prt_entry *)node; 788 vector[i].segment = entry->id.segment; 789 vector[i].bus = entry->id.bus; 790 vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff; 791 vector[i].pin = entry->pin; 792 vector[i].irq = entry->link.index; 793 i++; 794 } 795 *count = acpi_prt.count; 796 return 0; 797 } 798 #endif /* CONFIG_PCI */ 799 800 /* Assume IA64 always use I/O SAPIC */ 801 802 int __init 803 acpi_get_interrupt_model (int *type) 804 { 805 if (!type) 806 return -EINVAL; 807 808 *type = ACPI_IRQ_MODEL_IOSAPIC; 809 return 0; 810 } 811 812 int 813 acpi_irq_to_vector (u32 irq) 814 { 815 if (has_8259 && irq < 16) 816 return isa_irq_to_vector(irq); 817 818 return gsi_to_vector(irq); 819 } 820 821 int 822 acpi_register_irq (u32 gsi, u32 polarity, u32 trigger) 823 { 824 int vector = 0; 825 826 if (has_8259 && gsi < 16) 827 return isa_irq_to_vector(gsi); 828 829 if (!iosapic_register_intr) 830 return 0; 831 832 /* Turn it on */ 833 vector = iosapic_register_intr(gsi, 834 (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW, 835 (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL); 836 return vector; 837 } 838 839 #endif /* CONFIG_ACPI_BOOT */ 840
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.