ia64/xen-unstable

view xen/arch/x86/acpi/boot.c @ 19697:42fe00c6f8b4

Enable pci mmcfg and ATS for x86_64

This patch enables PCI MMCONFIG in xen and turns on hooks for ATS.

Signed-off-by: Allen Kay <allen.m.kay@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jun 02 11:49:34 2009 +0100 (2009-06-02)
parents d5ddc782bc49
children
line source
1 /*
2 * boot.c - Architecture-Specific Low-Level ACPI Boot Support
3 *
4 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5 * Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
6 *
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 */
26 #include <xen/config.h>
27 #include <xen/errno.h>
28 #include <xen/init.h>
29 #include <xen/acpi.h>
30 #include <xen/irq.h>
31 #include <xen/dmi.h>
32 #include <asm/fixmap.h>
33 #include <asm/page.h>
34 #include <asm/apic.h>
35 #include <asm/io_apic.h>
36 #include <asm/apic.h>
37 #include <asm/io.h>
38 #include <asm/mpspec.h>
39 #include <asm/processor.h>
40 #include <mach_apic.h>
41 #include <mach_mpparse.h>
43 int sbf_port;
44 #define CONFIG_ACPI_PCI
46 #define BAD_MADT_ENTRY(entry, end) ( \
47 (!entry) || (unsigned long)entry + sizeof(*entry) > end || \
48 ((struct acpi_subtable_header *)entry)->length != sizeof(*entry))
50 #define PREFIX "ACPI: "
52 #ifdef CONFIG_ACPI_PCI
53 int acpi_noirq __initdata; /* skip ACPI IRQ initialization */
54 int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */
55 #else
56 int acpi_noirq __initdata = 1;
57 int acpi_pci_disabled __initdata = 1;
58 #endif
59 int acpi_ht __initdata = 1; /* enable HT */
61 int acpi_lapic;
62 int acpi_ioapic;
63 int acpi_strict;
64 EXPORT_SYMBOL(acpi_strict);
66 u8 acpi_sci_flags __initdata;
67 int acpi_sci_override_gsi __initdata;
68 int acpi_skip_timer_override __initdata;
70 #ifdef CONFIG_X86_LOCAL_APIC
71 static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
72 #endif
74 u32 acpi_smi_cmd;
75 u8 acpi_enable_value, acpi_disable_value;
77 #ifndef __HAVE_ARCH_CMPXCHG
78 #warning ACPI uses CMPXCHG, i486 and later hardware
79 #endif
81 #define MAX_MADT_ENTRIES 256
82 u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
83 {[0 ... MAX_MADT_ENTRIES - 1] = 0xff };
84 EXPORT_SYMBOL(x86_acpiid_to_apicid);
86 /* --------------------------------------------------------------------------
87 Boot-time Configuration
88 -------------------------------------------------------------------------- */
90 /*
91 * The default interrupt routing model is PIC (8259). This gets
92 * overriden if IOAPICs are enumerated (below).
93 */
94 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
96 /*
97 * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
98 * to map the target physical address. The problem is that set_fixmap()
99 * provides a single page, and it is possible that the page is not
100 * sufficient.
101 * By using this area, we can map up to MAX_IO_APICS pages temporarily,
102 * i.e. until the next __va_range() call.
103 *
104 * Important Safety Note: The fixed I/O APIC page numbers are *subtracted*
105 * from the fixed base. That's why we start at FIX_IO_APIC_BASE_END and
106 * count idx down while incrementing the phys address.
107 */
108 char *__acpi_map_table(unsigned long phys, unsigned long size)
109 {
110 unsigned long base, offset, mapped_size;
111 int idx;
113 /* XEN: RAM holes above 1MB are not permanently mapped. */
114 if ((phys + size) <= (1 * 1024 * 1024))
115 return __va(phys);
117 offset = phys & (PAGE_SIZE - 1);
118 mapped_size = PAGE_SIZE - offset;
119 set_fixmap(FIX_ACPI_END, phys);
120 base = fix_to_virt(FIX_ACPI_END);
122 /*
123 * Most cases can be covered by the below.
124 */
125 idx = FIX_ACPI_END;
126 while (mapped_size < size) {
127 if (--idx < FIX_ACPI_BEGIN)
128 return NULL; /* cannot handle this */
129 phys += PAGE_SIZE;
130 set_fixmap(idx, phys);
131 mapped_size += PAGE_SIZE;
132 }
134 return ((char *) base + offset);
135 }
137 #ifdef CONFIG_X86_LOCAL_APIC
138 static int __init acpi_parse_madt(struct acpi_table_header *table)
139 {
140 struct acpi_table_madt *madt;
142 madt = (struct acpi_table_madt *)table;
144 if (madt->address) {
145 acpi_lapic_addr = (u64) madt->address;
147 printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n",
148 madt->address);
149 }
151 acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
153 return 0;
154 }
156 static int __init
157 acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long end)
158 {
159 struct acpi_table_lapic *processor = NULL;
161 processor = (struct acpi_table_lapic *)header;
163 if (BAD_MADT_ENTRY(processor, end))
164 return -EINVAL;
166 acpi_table_print_madt_entry(header);
168 /* Record local apic id only when enabled */
169 if (processor->flags.enabled)
170 x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
172 /*
173 * We need to register disabled CPU as well to permit
174 * counting disabled CPUs. This allows us to size
175 * cpus_possible_map more accurately, to permit
176 * to not preallocating memory for all NR_CPUS
177 * when we use CPU hotplug.
178 */
179 mp_register_lapic(processor->id, /* APIC ID */
180 processor->flags.enabled); /* Enabled? */
182 return 0;
183 }
185 static int __init
186 acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
187 const unsigned long end)
188 {
189 struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
191 lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header;
193 if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
194 return -EINVAL;
196 acpi_lapic_addr = lapic_addr_ovr->address;
198 return 0;
199 }
201 static int __init
202 acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const unsigned long end)
203 {
204 struct acpi_table_lapic_nmi *lapic_nmi = NULL;
206 lapic_nmi = (struct acpi_table_lapic_nmi *)header;
208 if (BAD_MADT_ENTRY(lapic_nmi, end))
209 return -EINVAL;
211 acpi_table_print_madt_entry(header);
213 if (lapic_nmi->lint != 1)
214 printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
216 return 0;
217 }
219 #endif /*CONFIG_X86_LOCAL_APIC */
221 #if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/
223 static int __init
224 acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
225 {
226 struct acpi_table_ioapic *ioapic = NULL;
228 ioapic = (struct acpi_table_ioapic *)header;
230 if (BAD_MADT_ENTRY(ioapic, end))
231 return -EINVAL;
233 acpi_table_print_madt_entry(header);
235 mp_register_ioapic(ioapic->id,
236 ioapic->address, ioapic->global_irq_base);
238 return 0;
239 }
241 static int __init
242 acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
243 const unsigned long end)
244 {
245 struct acpi_table_int_src_ovr *intsrc = NULL;
247 intsrc = (struct acpi_table_int_src_ovr *)header;
249 if (BAD_MADT_ENTRY(intsrc, end))
250 return -EINVAL;
252 acpi_table_print_madt_entry(header);
254 if (acpi_skip_timer_override &&
255 intsrc->bus_irq == 0 && intsrc->global_irq == 2) {
256 printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
257 return 0;
258 }
260 mp_override_legacy_irq(intsrc->bus_irq,
261 intsrc->flags.polarity,
262 intsrc->flags.trigger, intsrc->global_irq);
264 return 0;
265 }
267 static int __init
268 acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end)
269 {
270 struct acpi_table_nmi_src *nmi_src = NULL;
272 nmi_src = (struct acpi_table_nmi_src *)header;
274 if (BAD_MADT_ENTRY(nmi_src, end))
275 return -EINVAL;
277 acpi_table_print_madt_entry(header);
279 /* TBD: Support nimsrc entries? */
281 return 0;
282 }
284 #endif /* CONFIG_X86_IO_APIC */
286 static int __init acpi_parse_sbf(struct acpi_table_header *table)
287 {
288 struct acpi_table_boot *sb;
290 sb = (struct acpi_table_boot *)table;
291 if (!sb) {
292 printk(KERN_WARNING PREFIX "Unable to map SBF\n");
293 return -ENODEV;
294 }
296 sbf_port = sb->cmos_index; /* Save CMOS port */
298 return 0;
299 }
301 #ifdef CONFIG_HPET_TIMER
303 static int __init acpi_parse_hpet(struct acpi_table_header *table)
304 {
305 struct acpi_table_hpet *hpet_tbl = (struct acpi_table_hpet *)table;
307 if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) {
308 printk(KERN_WARNING PREFIX "HPET timers must be located in "
309 "memory.\n");
310 return -1;
311 }
313 #if 0/*def CONFIG_X86_64*/
314 vxtime.hpet_address = hpet_tbl->address.address;
316 printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
317 hpet_tbl->id, vxtime.hpet_address);
318 #else /* X86 */
319 {
320 extern unsigned long hpet_address;
322 hpet_address = hpet_tbl->address.address;
323 printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
324 hpet_tbl->id, hpet_address);
325 }
326 #endif /* X86 */
328 return 0;
329 }
330 #else
331 #define acpi_parse_hpet NULL
332 #endif
334 #ifdef CONFIG_X86_PM_TIMER
335 extern u32 pmtmr_ioport;
336 #endif
338 #ifdef CONFIG_ACPI_SLEEP
339 #define acpi_fadt_copy_address(dst, src, len) do { \
340 if (fadt->header.revision >= FADT2_REVISION_ID) \
341 acpi_sinfo.dst##_blk = fadt->x##src##_block; \
342 if (!acpi_sinfo.dst##_blk.address) { \
343 acpi_sinfo.dst##_blk.address = fadt->src##_block; \
344 acpi_sinfo.dst##_blk.space_id = ACPI_ADR_SPACE_SYSTEM_IO; \
345 acpi_sinfo.dst##_blk.bit_width = fadt->len##_length << 3; \
346 acpi_sinfo.dst##_blk.bit_offset = 0; \
347 acpi_sinfo.dst##_blk.access_width = 0; \
348 } \
349 } while (0)
351 /* Get pm1x_cnt and pm1x_evt information for ACPI sleep */
352 static void __init
353 acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt)
354 {
355 struct acpi_table_facs *facs = NULL;
356 uint64_t facs_pa;
358 acpi_fadt_copy_address(pm1a_cnt, pm1a_control, pm1_control);
359 acpi_fadt_copy_address(pm1b_cnt, pm1b_control, pm1_control);
360 acpi_fadt_copy_address(pm1a_evt, pm1a_event, pm1_event);
361 acpi_fadt_copy_address(pm1b_evt, pm1b_event, pm1_event);
363 printk(KERN_INFO PREFIX
364 "ACPI SLEEP INFO: pm1x_cnt[%"PRIx64",%"PRIx64"], "
365 "pm1x_evt[%"PRIx64",%"PRIx64"]\n",
366 acpi_sinfo.pm1a_cnt_blk.address,
367 acpi_sinfo.pm1b_cnt_blk.address,
368 acpi_sinfo.pm1a_evt_blk.address,
369 acpi_sinfo.pm1b_evt_blk.address);
371 /* Now FACS... */
372 if (fadt->header.revision >= FADT2_REVISION_ID)
373 facs_pa = fadt->Xfacs;
374 else
375 facs_pa = (uint64_t)fadt->facs;
377 facs = (struct acpi_table_facs *)
378 __acpi_map_table(facs_pa, sizeof(struct acpi_table_facs));
379 if (!facs)
380 goto bad;
382 if (strncmp(facs->signature, "FACS", 4)) {
383 printk(KERN_ERR PREFIX "Invalid FACS signature %.4s\n",
384 facs->signature);
385 goto bad;
386 }
388 if (facs->length < 24) {
389 printk(KERN_ERR PREFIX "Invalid FACS table length: 0x%x",
390 facs->length);
391 goto bad;
392 }
394 if (facs->length < 64)
395 printk(KERN_WARNING PREFIX
396 "FACS is shorter than ACPI spec allow: 0x%x",
397 facs->length);
399 acpi_sinfo.wakeup_vector = facs_pa +
400 offsetof(struct acpi_table_facs, firmware_waking_vector);
401 acpi_sinfo.vector_width = 32;
403 printk(KERN_INFO PREFIX
404 " wakeup_vec[%"PRIx64"], vec_size[%x]\n",
405 acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width);
406 return;
407 bad:
408 memset(&acpi_sinfo, 0, sizeof(acpi_sinfo));
409 }
410 #endif
412 static int __init acpi_parse_fadt(struct acpi_table_header *table)
413 {
414 struct acpi_table_fadt *fadt = (struct acpi_table_fadt *)table;
416 #ifdef CONFIG_ACPI_INTERPRETER
417 /* initialize sci_int early for INT_SRC_OVR MADT parsing */
418 acpi_fadt.sci_int = fadt->sci_int;
420 /* initialize rev and apic_phys_dest_mode for x86_64 genapic */
421 acpi_fadt.revision = fadt->revision;
422 acpi_fadt.force_apic_physical_destination_mode =
423 fadt->force_apic_physical_destination_mode;
424 #endif
426 #ifdef CONFIG_X86_PM_TIMER
427 /* detect the location of the ACPI PM Timer */
428 if (fadt->header.revision >= FADT2_REVISION_ID) {
429 /* FADT rev. 2 */
430 if (fadt->xpm_timer_block.space_id ==
431 ACPI_ADR_SPACE_SYSTEM_IO)
432 pmtmr_ioport = fadt->xpm_timer_block.address;
433 /*
434 * "X" fields are optional extensions to the original V1.0
435 * fields, so we must selectively expand V1.0 fields if the
436 * corresponding X field is zero.
437 */
438 if (!pmtmr_ioport)
439 pmtmr_ioport = fadt->pm_timer_block;
440 } else {
441 /* FADT rev. 1 */
442 pmtmr_ioport = fadt->pm_timer_block;
443 }
444 if (pmtmr_ioport)
445 printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n",
446 pmtmr_ioport);
447 #endif
449 acpi_smi_cmd = fadt->smi_command;
450 acpi_enable_value = fadt->acpi_enable;
451 acpi_disable_value = fadt->acpi_disable;
453 #ifdef CONFIG_ACPI_SLEEP
454 acpi_fadt_parse_sleep_info(fadt);
455 #endif
457 return 0;
458 }
460 #ifdef CONFIG_X86_LOCAL_APIC
461 /*
462 * Parse LAPIC entries in MADT
463 * returns 0 on success, < 0 on error
464 */
465 static int __init acpi_parse_madt_lapic_entries(void)
466 {
467 int count;
469 if (!cpu_has_apic)
470 return -ENODEV;
472 /*
473 * Note that the LAPIC address is obtained from the MADT (32-bit value)
474 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
475 */
477 count =
478 acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
479 acpi_parse_lapic_addr_ovr, 0);
480 if (count < 0) {
481 printk(KERN_ERR PREFIX
482 "Error parsing LAPIC address override entry\n");
483 return count;
484 }
486 mp_register_lapic_address(acpi_lapic_addr);
488 count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
489 MAX_APICS);
490 if (!count) {
491 printk(KERN_ERR PREFIX "No LAPIC entries present\n");
492 /* TBD: Cleanup to allow fallback to MPS */
493 return -ENODEV;
494 } else if (count < 0) {
495 printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
496 /* TBD: Cleanup to allow fallback to MPS */
497 return count;
498 }
500 count =
501 acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
502 if (count < 0) {
503 printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
504 /* TBD: Cleanup to allow fallback to MPS */
505 return count;
506 }
507 return 0;
508 }
509 #endif /* CONFIG_X86_LOCAL_APIC */
511 #if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/
512 /*
513 * Parse IOAPIC related entries in MADT
514 * returns 0 on success, < 0 on error
515 */
516 static int __init acpi_parse_madt_ioapic_entries(void)
517 {
518 int count;
520 /*
521 * ACPI interpreter is required to complete interrupt setup,
522 * so if it is off, don't enumerate the io-apics with ACPI.
523 * If MPS is present, it will handle them,
524 * otherwise the system will stay in PIC mode
525 */
526 if (acpi_disabled || acpi_noirq) {
527 return -ENODEV;
528 }
530 if (!cpu_has_apic)
531 return -ENODEV;
533 /*
534 * if "noapic" boot option, don't look for IO-APICs
535 */
536 if (skip_ioapic_setup) {
537 printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
538 "due to 'noapic' option.\n");
539 return -ENODEV;
540 }
542 count =
543 acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic,
544 MAX_IO_APICS);
545 if (!count) {
546 printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
547 return -ENODEV;
548 } else if (count < 0) {
549 printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
550 return count;
551 }
553 count =
554 acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr,
555 MAX_IRQ_SOURCES);
556 if (count < 0) {
557 printk(KERN_ERR PREFIX
558 "Error parsing interrupt source overrides entry\n");
559 /* TBD: Cleanup to allow fallback to MPS */
560 return count;
561 }
563 #ifdef CONFIG_ACPI_INTERPRETER
564 /*
565 * If BIOS did not supply an INT_SRC_OVR for the SCI
566 * pretend we got one so we can set the SCI flags.
567 */
568 if (!acpi_sci_override_gsi)
569 acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0);
570 #endif
572 /* Fill in identity legacy mapings where no override */
573 mp_config_acpi_legacy_irqs();
575 count =
576 acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
577 MAX_IRQ_SOURCES);
578 if (count < 0) {
579 printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
580 /* TBD: Cleanup to allow fallback to MPS */
581 return count;
582 }
584 return 0;
585 }
586 #else
587 static inline int acpi_parse_madt_ioapic_entries(void)
588 {
589 return -1;
590 }
591 #endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */
594 static void __init acpi_process_madt(void)
595 {
596 #ifdef CONFIG_X86_LOCAL_APIC
597 int error;
599 if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
601 /*
602 * Parse MADT LAPIC entries
603 */
604 error = acpi_parse_madt_lapic_entries();
605 if (!error) {
606 acpi_lapic = 1;
607 generic_bigsmp_probe();
609 /*
610 * Parse MADT IO-APIC entries
611 */
612 error = acpi_parse_madt_ioapic_entries();
613 if (!error) {
614 acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
615 acpi_irq_balance_set(NULL);
616 acpi_ioapic = 1;
618 smp_found_config = 1;
619 clustered_apic_check();
620 }
621 }
622 if (error == -EINVAL) {
623 /*
624 * Dell Precision Workstation 410, 610 come here.
625 */
626 printk(KERN_ERR PREFIX
627 "Invalid BIOS MADT, disabling ACPI\n");
628 disable_acpi();
629 }
630 }
631 #endif
632 return;
633 }
635 extern int acpi_force;
637 #ifdef __i386__
639 static int __init disable_acpi_irq(struct dmi_system_id *d)
640 {
641 if (!acpi_force) {
642 printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
643 d->ident);
644 acpi_noirq_set();
645 }
646 return 0;
647 }
649 static int __init disable_acpi_pci(struct dmi_system_id *d)
650 {
651 if (!acpi_force) {
652 printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
653 d->ident);
654 /*acpi_disable_pci();*/
655 }
656 return 0;
657 }
659 static int __init dmi_disable_acpi(struct dmi_system_id *d)
660 {
661 if (!acpi_force) {
662 printk(KERN_NOTICE "%s detected: acpi off\n", d->ident);
663 disable_acpi();
664 } else {
665 printk(KERN_NOTICE
666 "Warning: DMI blacklist says broken, but acpi forced\n");
667 }
668 return 0;
669 }
671 /*
672 * Limit ACPI to CPU enumeration for HT
673 */
674 static int __init force_acpi_ht(struct dmi_system_id *d)
675 {
676 if (!acpi_force) {
677 printk(KERN_NOTICE "%s detected: force use of acpi=ht\n",
678 d->ident);
679 disable_acpi();
680 acpi_ht = 1;
681 } else {
682 printk(KERN_NOTICE
683 "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
684 }
685 return 0;
686 }
688 /*
689 * If your system is blacklisted here, but you find that acpi=force
690 * works for you, please contact acpi-devel@sourceforge.net
691 */
692 static struct dmi_system_id __initdata acpi_dmi_table[] = {
693 /*
694 * Boxes that need ACPI disabled
695 */
696 {
697 .callback = dmi_disable_acpi,
698 .ident = "IBM Thinkpad",
699 .matches = {
700 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
701 DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
702 },
703 },
705 /*
706 * Boxes that need acpi=ht
707 */
708 {
709 .callback = force_acpi_ht,
710 .ident = "FSC Primergy T850",
711 .matches = {
712 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
713 DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
714 },
715 },
716 {
717 .callback = force_acpi_ht,
718 .ident = "DELL GX240",
719 .matches = {
720 DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
721 DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
722 },
723 },
724 {
725 .callback = force_acpi_ht,
726 .ident = "HP VISUALIZE NT Workstation",
727 .matches = {
728 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
729 DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
730 },
731 },
732 {
733 .callback = force_acpi_ht,
734 .ident = "Compaq Workstation W8000",
735 .matches = {
736 DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
737 DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
738 },
739 },
740 {
741 .callback = force_acpi_ht,
742 .ident = "ASUS P4B266",
743 .matches = {
744 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
745 DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
746 },
747 },
748 {
749 .callback = force_acpi_ht,
750 .ident = "ASUS P2B-DS",
751 .matches = {
752 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
753 DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
754 },
755 },
756 {
757 .callback = force_acpi_ht,
758 .ident = "ASUS CUR-DLS",
759 .matches = {
760 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
761 DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
762 },
763 },
764 {
765 .callback = force_acpi_ht,
766 .ident = "ABIT i440BX-W83977",
767 .matches = {
768 DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
769 DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
770 },
771 },
772 {
773 .callback = force_acpi_ht,
774 .ident = "IBM Bladecenter",
775 .matches = {
776 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
777 DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
778 },
779 },
780 {
781 .callback = force_acpi_ht,
782 .ident = "IBM eServer xSeries 360",
783 .matches = {
784 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
785 DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
786 },
787 },
788 {
789 .callback = force_acpi_ht,
790 .ident = "IBM eserver xSeries 330",
791 .matches = {
792 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
793 DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
794 },
795 },
796 {
797 .callback = force_acpi_ht,
798 .ident = "IBM eserver xSeries 440",
799 .matches = {
800 DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
801 DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
802 },
803 },
805 /*
806 * Boxes that need ACPI PCI IRQ routing disabled
807 */
808 {
809 .callback = disable_acpi_irq,
810 .ident = "ASUS A7V",
811 .matches = {
812 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
813 DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
814 /* newer BIOS, Revision 1011, does work */
815 DMI_MATCH(DMI_BIOS_VERSION,
816 "ASUS A7V ACPI BIOS Revision 1007"),
817 },
818 },
820 /*
821 * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
822 */
823 { /* _BBN 0 bug */
824 .callback = disable_acpi_pci,
825 .ident = "ASUS PR-DLS",
826 .matches = {
827 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
828 DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
829 DMI_MATCH(DMI_BIOS_VERSION,
830 "ASUS PR-DLS ACPI BIOS Revision 1010"),
831 DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
832 },
833 },
834 {
835 .callback = disable_acpi_pci,
836 .ident = "Acer TravelMate 36x Laptop",
837 .matches = {
838 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
839 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
840 },
841 },
842 {}
843 };
845 #endif /* __i386__ */
847 /*
848 * acpi_boot_table_init() and acpi_boot_init()
849 * called from setup_arch(), always.
850 * 1. checksums all tables
851 * 2. enumerates lapics
852 * 3. enumerates io-apics
853 *
854 * acpi_table_init() is separate to allow reading SRAT without
855 * other side effects.
856 *
857 * side effects of acpi_boot_init:
858 * acpi_lapic = 1 if LAPIC found
859 * acpi_ioapic = 1 if IOAPIC found
860 * if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
861 * if acpi_blacklisted() acpi_disabled = 1;
862 * acpi_irq_model=...
863 * ...
864 *
865 * return value: (currently ignored)
866 * 0: success
867 * !0: failure
868 */
870 int __init acpi_boot_table_init(void)
871 {
872 int error;
874 #ifdef __i386__
875 dmi_check_system(acpi_dmi_table);
876 #endif
878 /*
879 * If acpi_disabled, bail out
880 * One exception: acpi=ht continues far enough to enumerate LAPICs
881 */
882 if (acpi_disabled && !acpi_ht)
883 return 1;
885 /*
886 * Initialize the ACPI boot-time table parser.
887 */
888 error = acpi_table_init();
889 if (error) {
890 disable_acpi();
891 return error;
892 }
894 acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
896 /*
897 * blacklist may disable ACPI entirely
898 */
899 error = acpi_blacklisted();
900 if (error) {
901 extern int acpi_force;
903 if (acpi_force) {
904 printk(KERN_WARNING PREFIX "acpi=force override\n");
905 } else {
906 printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
907 disable_acpi();
908 return error;
909 }
910 }
912 return 0;
913 }
915 int __init acpi_boot_init(void)
916 {
917 /*
918 * If acpi_disabled, bail out
919 * One exception: acpi=ht continues far enough to enumerate LAPICs
920 */
921 if (acpi_disabled && !acpi_ht)
922 return 1;
924 acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
926 /*
927 * set sci_int and PM timer address
928 */
929 acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
931 /*
932 * Process the Multiple APIC Description Table (MADT), if present
933 */
934 acpi_process_madt();
936 acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
938 acpi_dmar_init();
940 acpi_mmcfg_init();
942 return 0;
943 }
945 unsigned int acpi_get_processor_id(unsigned int cpu)
946 {
947 unsigned int acpiid, apicid;
949 if ((apicid = x86_cpu_to_apicid[cpu]) == 0xff)
950 return 0xff;
952 for (acpiid = 0; acpiid < ARRAY_SIZE(x86_acpiid_to_apicid); acpiid++)
953 if (x86_acpiid_to_apicid[acpiid] == apicid)
954 return acpiid;
956 return 0xff;
957 }