source: trunk/packages/xen-3.1/xen-3.1/xen/arch/x86/acpi/boot.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 21.8 KB
Line 
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 */
25
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 <mach_apic.h>
40#include <mach_mpparse.h>
41
42int sbf_port;
43#define CONFIG_ACPI_PCI
44
45#define BAD_MADT_ENTRY(entry, end) (                                        \
46                (!entry) || (unsigned long)entry + sizeof(*entry) > end ||  \
47                ((acpi_table_entry_header *)entry)->length != sizeof(*entry))
48
49#define PREFIX                  "ACPI: "
50
51#ifdef CONFIG_ACPI_PCI
52int acpi_noirq __initdata;      /* skip ACPI IRQ initialization */
53int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */
54#else
55int acpi_noirq __initdata = 1;
56int acpi_pci_disabled __initdata = 1;
57#endif
58int acpi_ht __initdata = 1;     /* enable HT */
59
60int acpi_lapic;
61int acpi_ioapic;
62int acpi_strict;
63EXPORT_SYMBOL(acpi_strict);
64
65acpi_interrupt_flags acpi_sci_flags __initdata;
66int acpi_sci_override_gsi __initdata;
67int acpi_skip_timer_override __initdata;
68
69#ifdef CONFIG_X86_LOCAL_APIC
70static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
71#endif
72
73#ifndef __HAVE_ARCH_CMPXCHG
74#warning ACPI uses CMPXCHG, i486 and later hardware
75#endif
76
77#define MAX_MADT_ENTRIES        256
78u8 x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
79    {[0 ... MAX_MADT_ENTRIES - 1] = 0xff };
80EXPORT_SYMBOL(x86_acpiid_to_apicid);
81
82/* --------------------------------------------------------------------------
83                              Boot-time Configuration
84   -------------------------------------------------------------------------- */
85
86/*
87 * The default interrupt routing model is PIC (8259).  This gets
88 * overriden if IOAPICs are enumerated (below).
89 */
90enum acpi_irq_model_id          acpi_irq_model = ACPI_IRQ_MODEL_PIC;
91
92/*
93 * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
94 * to map the target physical address. The problem is that set_fixmap()
95 * provides a single page, and it is possible that the page is not
96 * sufficient.
97 * By using this area, we can map up to MAX_IO_APICS pages temporarily,
98 * i.e. until the next __va_range() call.
99 *
100 * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
101 * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
102 * count idx down while incrementing the phys address.
103 */
104char *__acpi_map_table(unsigned long phys, unsigned long size)
105{
106        unsigned long base, offset, mapped_size;
107        int idx;
108
109        if (phys + size < 8 * 1024 * 1024)
110                return __va(phys);
111
112        offset = phys & (PAGE_SIZE - 1);
113        mapped_size = PAGE_SIZE - offset;
114        set_fixmap(FIX_ACPI_END, phys);
115        base = fix_to_virt(FIX_ACPI_END);
116
117        /*
118         * Most cases can be covered by the below.
119         */
120        idx = FIX_ACPI_END;
121        while (mapped_size < size) {
122                if (--idx < FIX_ACPI_BEGIN)
123                        return NULL;    /* cannot handle this */
124                phys += PAGE_SIZE;
125                set_fixmap(idx, phys);
126                mapped_size += PAGE_SIZE;
127        }
128
129        return ((char *) base + offset);
130}
131
132#ifdef CONFIG_X86_LOCAL_APIC
133static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size)
134{
135        struct acpi_table_madt *madt = NULL;
136
137        if (!phys_addr || !size)
138                return -EINVAL;
139
140        madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size);
141        if (!madt) {
142                printk(KERN_WARNING PREFIX "Unable to map MADT\n");
143                return -ENODEV;
144        }
145
146        if (madt->lapic_address) {
147                acpi_lapic_addr = (u64) madt->lapic_address;
148
149                printk(KERN_DEBUG PREFIX "Local APIC address 0x%08x\n",
150                       madt->lapic_address);
151        }
152
153        acpi_madt_oem_check(madt->header.oem_id, madt->header.oem_table_id);
154
155        return 0;
156}
157
158static int __init
159acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end)
160{
161        struct acpi_table_lapic *processor = NULL;
162
163        processor = (struct acpi_table_lapic *)header;
164
165        if (BAD_MADT_ENTRY(processor, end))
166                return -EINVAL;
167
168        acpi_table_print_madt_entry(header);
169
170        /* Record local apic id only when enabled */
171        if (processor->flags.enabled)
172                x86_acpiid_to_apicid[processor->acpi_id] = processor->id;
173
174        /*
175         * We need to register disabled CPU as well to permit
176         * counting disabled CPUs. This allows us to size
177         * cpus_possible_map more accurately, to permit
178         * to not preallocating memory for all NR_CPUS
179         * when we use CPU hotplug.
180         */
181        mp_register_lapic(processor->id,        /* APIC ID */
182                          processor->flags.enabled);    /* Enabled? */
183
184        return 0;
185}
186
187static int __init
188acpi_parse_lapic_addr_ovr(acpi_table_entry_header * header,
189                          const unsigned long end)
190{
191        struct acpi_table_lapic_addr_ovr *lapic_addr_ovr = NULL;
192
193        lapic_addr_ovr = (struct acpi_table_lapic_addr_ovr *)header;
194
195        if (BAD_MADT_ENTRY(lapic_addr_ovr, end))
196                return -EINVAL;
197
198        acpi_lapic_addr = lapic_addr_ovr->address;
199
200        return 0;
201}
202
203static int __init
204acpi_parse_lapic_nmi(acpi_table_entry_header * header, const unsigned long end)
205{
206        struct acpi_table_lapic_nmi *lapic_nmi = NULL;
207
208        lapic_nmi = (struct acpi_table_lapic_nmi *)header;
209
210        if (BAD_MADT_ENTRY(lapic_nmi, end))
211                return -EINVAL;
212
213        acpi_table_print_madt_entry(header);
214
215        if (lapic_nmi->lint != 1)
216                printk(KERN_WARNING PREFIX "NMI not connected to LINT 1!\n");
217
218        return 0;
219}
220
221#endif                          /*CONFIG_X86_LOCAL_APIC */
222
223#if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/
224
225static int __init
226acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end)
227{
228        struct acpi_table_ioapic *ioapic = NULL;
229
230        ioapic = (struct acpi_table_ioapic *)header;
231
232        if (BAD_MADT_ENTRY(ioapic, end))
233                return -EINVAL;
234
235        acpi_table_print_madt_entry(header);
236
237        mp_register_ioapic(ioapic->id,
238                           ioapic->address, ioapic->global_irq_base);
239
240        return 0;
241}
242
243static int __init
244acpi_parse_int_src_ovr(acpi_table_entry_header * header,
245                       const unsigned long end)
246{
247        struct acpi_table_int_src_ovr *intsrc = NULL;
248
249        intsrc = (struct acpi_table_int_src_ovr *)header;
250
251        if (BAD_MADT_ENTRY(intsrc, end))
252                return -EINVAL;
253
254        acpi_table_print_madt_entry(header);
255
256        if (acpi_skip_timer_override &&
257                intsrc->bus_irq == 0 && intsrc->global_irq == 2) {
258                        printk(PREFIX "BIOS IRQ0 pin2 override ignored.\n");
259                        return 0;
260        }
261
262        mp_override_legacy_irq(intsrc->bus_irq,
263                               intsrc->flags.polarity,
264                               intsrc->flags.trigger, intsrc->global_irq);
265
266        return 0;
267}
268
269static int __init
270acpi_parse_nmi_src(acpi_table_entry_header * header, const unsigned long end)
271{
272        struct acpi_table_nmi_src *nmi_src = NULL;
273
274        nmi_src = (struct acpi_table_nmi_src *)header;
275
276        if (BAD_MADT_ENTRY(nmi_src, end))
277                return -EINVAL;
278
279        acpi_table_print_madt_entry(header);
280
281        /* TBD: Support nimsrc entries? */
282
283        return 0;
284}
285
286#endif /* CONFIG_X86_IO_APIC */
287
288static unsigned long __init
289acpi_scan_rsdp(unsigned long start, unsigned long length)
290{
291        unsigned long offset = 0;
292        unsigned long sig_len = sizeof("RSD PTR ") - 1;
293
294        /*
295         * Scan all 16-byte boundaries of the physical memory region for the
296         * RSDP signature.
297         */
298        for (offset = 0; offset < length; offset += 16) {
299                if (strncmp((char *)(start + offset), "RSD PTR ", sig_len))
300                        continue;
301                return (start + offset);
302        }
303
304        return 0;
305}
306
307static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size)
308{
309        struct acpi_table_sbf *sb;
310
311        if (!phys_addr || !size)
312                return -EINVAL;
313
314        sb = (struct acpi_table_sbf *)__acpi_map_table(phys_addr, size);
315        if (!sb) {
316                printk(KERN_WARNING PREFIX "Unable to map SBF\n");
317                return -ENODEV;
318        }
319
320        sbf_port = sb->sbf_cmos;        /* Save CMOS port */
321
322        return 0;
323}
324
325#ifdef CONFIG_HPET_TIMER
326
327static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
328{
329        struct acpi_table_hpet *hpet_tbl;
330
331        if (!phys || !size)
332                return -EINVAL;
333
334        hpet_tbl = (struct acpi_table_hpet *)__acpi_map_table(phys, size);
335        if (!hpet_tbl) {
336                printk(KERN_WARNING PREFIX "Unable to map HPET\n");
337                return -ENODEV;
338        }
339
340        if (hpet_tbl->addr.space_id != ACPI_SPACE_MEM) {
341                printk(KERN_WARNING PREFIX "HPET timers must be located in "
342                       "memory.\n");
343                return -1;
344        }
345
346#if 0/*def      CONFIG_X86_64*/
347        vxtime.hpet_address = hpet_tbl->addr.addrl |
348                ((long) hpet_tbl->addr.addrh << 32);
349
350        printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
351               hpet_tbl->id, vxtime.hpet_address);
352#else   /* X86 */
353        {
354                extern unsigned long hpet_address;
355
356                hpet_address = hpet_tbl->addr.addrl;
357                printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
358                       hpet_tbl->id, hpet_address);
359        }
360#endif  /* X86 */
361
362        return 0;
363}
364#else
365#define acpi_parse_hpet NULL
366#endif
367
368#ifdef CONFIG_X86_PM_TIMER
369extern u32 pmtmr_ioport;
370#endif
371
372static int __init acpi_parse_fadt(unsigned long phys, unsigned long size)
373{
374        struct fadt_descriptor_rev2 *fadt = NULL;
375
376        fadt = (struct fadt_descriptor_rev2 *)__acpi_map_table(phys, size);
377        if (!fadt) {
378                printk(KERN_WARNING PREFIX "Unable to map FADT\n");
379                return 0;
380        }
381
382#ifdef  CONFIG_ACPI_INTERPRETER
383        /* initialize sci_int early for INT_SRC_OVR MADT parsing */
384        acpi_fadt.sci_int = fadt->sci_int;
385
386        /* initialize rev and apic_phys_dest_mode for x86_64 genapic */
387        acpi_fadt.revision = fadt->revision;
388        acpi_fadt.force_apic_physical_destination_mode =
389            fadt->force_apic_physical_destination_mode;
390#endif
391
392#ifdef CONFIG_X86_PM_TIMER
393        /* detect the location of the ACPI PM Timer */
394        if (fadt->revision >= FADT2_REVISION_ID) {
395                /* FADT rev. 2 */
396                if (fadt->xpm_tmr_blk.address_space_id !=
397                    ACPI_ADR_SPACE_SYSTEM_IO)
398                        return 0;
399
400                pmtmr_ioport = fadt->xpm_tmr_blk.address;
401                /*
402                 * "X" fields are optional extensions to the original V1.0
403                 * fields, so we must selectively expand V1.0 fields if the
404                 * corresponding X field is zero.
405                 */
406                if (!pmtmr_ioport)
407                        pmtmr_ioport = fadt->V1_pm_tmr_blk;
408        } else {
409                /* FADT rev. 1 */
410                pmtmr_ioport = fadt->V1_pm_tmr_blk;
411        }
412        if (pmtmr_ioport)
413                printk(KERN_INFO PREFIX "PM-Timer IO Port: %#x\n",
414                       pmtmr_ioport);
415#endif
416        return 0;
417}
418
419unsigned long __init acpi_find_rsdp(void)
420{
421        unsigned long rsdp_phys = 0;
422
423#if 0
424        if (efi_enabled) {
425                if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
426                        return efi.acpi20;
427                else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
428                        return efi.acpi;
429        }
430#endif
431        /*
432         * Scan memory looking for the RSDP signature. First search EBDA (low
433         * memory) paragraphs and then search upper memory (E0000-FFFFF).
434         */
435        rsdp_phys = acpi_scan_rsdp(0, 0x400);
436        if (!rsdp_phys)
437                rsdp_phys = acpi_scan_rsdp(0xE0000, 0x20000);
438
439        return rsdp_phys;
440}
441
442#ifdef  CONFIG_X86_LOCAL_APIC
443/*
444 * Parse LAPIC entries in MADT
445 * returns 0 on success, < 0 on error
446 */
447static int __init acpi_parse_madt_lapic_entries(void)
448{
449        int count;
450
451        if (!cpu_has_apic)
452                return -ENODEV;
453
454        /*
455         * Note that the LAPIC address is obtained from the MADT (32-bit value)
456         * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
457         */
458
459        count =
460            acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR,
461                                  acpi_parse_lapic_addr_ovr, 0);
462        if (count < 0) {
463                printk(KERN_ERR PREFIX
464                       "Error parsing LAPIC address override entry\n");
465                return count;
466        }
467
468        mp_register_lapic_address(acpi_lapic_addr);
469
470        count = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
471                                      MAX_APICS);
472        if (!count) {
473                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
474                /* TBD: Cleanup to allow fallback to MPS */
475                return -ENODEV;
476        } else if (count < 0) {
477                printk(KERN_ERR PREFIX "Error parsing LAPIC entry\n");
478                /* TBD: Cleanup to allow fallback to MPS */
479                return count;
480        }
481
482        count =
483            acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
484        if (count < 0) {
485                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
486                /* TBD: Cleanup to allow fallback to MPS */
487                return count;
488        }
489        return 0;
490}
491#endif /* CONFIG_X86_LOCAL_APIC */
492
493#if defined(CONFIG_X86_IO_APIC) /*&& defined(CONFIG_ACPI_INTERPRETER)*/
494/*
495 * Parse IOAPIC related entries in MADT
496 * returns 0 on success, < 0 on error
497 */
498static int __init acpi_parse_madt_ioapic_entries(void)
499{
500        int count;
501
502        /*
503         * ACPI interpreter is required to complete interrupt setup,
504         * so if it is off, don't enumerate the io-apics with ACPI.
505         * If MPS is present, it will handle them,
506         * otherwise the system will stay in PIC mode
507         */
508        if (acpi_disabled || acpi_noirq) {
509                return -ENODEV;
510        }
511
512        if (!cpu_has_apic)
513                return -ENODEV;
514
515        /*
516         * if "noapic" boot option, don't look for IO-APICs
517         */
518        if (skip_ioapic_setup) {
519                printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
520                       "due to 'noapic' option.\n");
521                return -ENODEV;
522        }
523
524        count =
525            acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic,
526                                  MAX_IO_APICS);
527        if (!count) {
528                printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
529                return -ENODEV;
530        } else if (count < 0) {
531                printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
532                return count;
533        }
534
535        count =
536            acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr,
537                                  NR_IRQ_VECTORS);
538        if (count < 0) {
539                printk(KERN_ERR PREFIX
540                       "Error parsing interrupt source overrides entry\n");
541                /* TBD: Cleanup to allow fallback to MPS */
542                return count;
543        }
544
545#ifdef CONFIG_ACPI_INTERPRETER
546        /*
547         * If BIOS did not supply an INT_SRC_OVR for the SCI
548         * pretend we got one so we can set the SCI flags.
549         */
550        if (!acpi_sci_override_gsi)
551                acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0);
552#endif
553
554        /* Fill in identity legacy mapings where no override */
555        mp_config_acpi_legacy_irqs();
556
557        count =
558            acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
559                                  NR_IRQ_VECTORS);
560        if (count < 0) {
561                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
562                /* TBD: Cleanup to allow fallback to MPS */
563                return count;
564        }
565
566        return 0;
567}
568#else
569static inline int acpi_parse_madt_ioapic_entries(void)
570{
571        return -1;
572}
573#endif /* !(CONFIG_X86_IO_APIC && CONFIG_ACPI_INTERPRETER) */
574
575
576static void __init acpi_process_madt(void)
577{
578#ifdef CONFIG_X86_LOCAL_APIC
579        int count, error;
580
581        count = acpi_table_parse(ACPI_APIC, acpi_parse_madt);
582        if (count >= 1) {
583
584                /*
585                 * Parse MADT LAPIC entries
586                 */
587                error = acpi_parse_madt_lapic_entries();
588                if (!error) {
589                        acpi_lapic = 1;
590                        generic_bigsmp_probe();
591 
592                        /*
593                         * Parse MADT IO-APIC entries
594                         */
595                        error = acpi_parse_madt_ioapic_entries();
596                        if (!error) {
597                                acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
598                                acpi_irq_balance_set(NULL);
599                                acpi_ioapic = 1;
600
601                                smp_found_config = 1;
602                                clustered_apic_check();
603                        }
604                }
605                if (error == -EINVAL) {
606                        /*
607                         * Dell Precision Workstation 410, 610 come here.
608                         */
609                        printk(KERN_ERR PREFIX
610                               "Invalid BIOS MADT, disabling ACPI\n");
611                        disable_acpi();
612                }
613        }
614#endif
615        return;
616}
617
618extern int acpi_force;
619
620#ifdef __i386__
621
622static int __init disable_acpi_irq(struct dmi_system_id *d)
623{
624        if (!acpi_force) {
625                printk(KERN_NOTICE "%s detected: force use of acpi=noirq\n",
626                       d->ident);
627                acpi_noirq_set();
628        }
629        return 0;
630}
631
632static int __init disable_acpi_pci(struct dmi_system_id *d)
633{
634        if (!acpi_force) {
635                printk(KERN_NOTICE "%s detected: force use of pci=noacpi\n",
636                       d->ident);
637                /*acpi_disable_pci();*/
638        }
639        return 0;
640}
641
642static int __init dmi_disable_acpi(struct dmi_system_id *d)
643{
644        if (!acpi_force) {
645                printk(KERN_NOTICE "%s detected: acpi off\n", d->ident);
646                disable_acpi();
647        } else {
648                printk(KERN_NOTICE
649                       "Warning: DMI blacklist says broken, but acpi forced\n");
650        }
651        return 0;
652}
653
654/*
655 * Limit ACPI to CPU enumeration for HT
656 */
657static int __init force_acpi_ht(struct dmi_system_id *d)
658{
659        if (!acpi_force) {
660                printk(KERN_NOTICE "%s detected: force use of acpi=ht\n",
661                       d->ident);
662                disable_acpi();
663                acpi_ht = 1;
664        } else {
665                printk(KERN_NOTICE
666                       "Warning: acpi=force overrules DMI blacklist: acpi=ht\n");
667        }
668        return 0;
669}
670
671/*
672 * If your system is blacklisted here, but you find that acpi=force
673 * works for you, please contact acpi-devel@sourceforge.net
674 */
675static struct dmi_system_id __initdata acpi_dmi_table[] = {
676        /*
677         * Boxes that need ACPI disabled
678         */
679        {
680         .callback = dmi_disable_acpi,
681         .ident = "IBM Thinkpad",
682         .matches = {
683                     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
684                     DMI_MATCH(DMI_BOARD_NAME, "2629H1G"),
685                     },
686         },
687
688        /*
689         * Boxes that need acpi=ht
690         */
691        {
692         .callback = force_acpi_ht,
693         .ident = "FSC Primergy T850",
694         .matches = {
695                     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
696                     DMI_MATCH(DMI_PRODUCT_NAME, "PRIMERGY T850"),
697                     },
698         },
699        {
700         .callback = force_acpi_ht,
701         .ident = "DELL GX240",
702         .matches = {
703                     DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
704                     DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
705                     },
706         },
707        {
708         .callback = force_acpi_ht,
709         .ident = "HP VISUALIZE NT Workstation",
710         .matches = {
711                     DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
712                     DMI_MATCH(DMI_PRODUCT_NAME, "HP VISUALIZE NT Workstation"),
713                     },
714         },
715        {
716         .callback = force_acpi_ht,
717         .ident = "Compaq Workstation W8000",
718         .matches = {
719                     DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
720                     DMI_MATCH(DMI_PRODUCT_NAME, "Workstation W8000"),
721                     },
722         },
723        {
724         .callback = force_acpi_ht,
725         .ident = "ASUS P4B266",
726         .matches = {
727                     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
728                     DMI_MATCH(DMI_BOARD_NAME, "P4B266"),
729                     },
730         },
731        {
732         .callback = force_acpi_ht,
733         .ident = "ASUS P2B-DS",
734         .matches = {
735                     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
736                     DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
737                     },
738         },
739        {
740         .callback = force_acpi_ht,
741         .ident = "ASUS CUR-DLS",
742         .matches = {
743                     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
744                     DMI_MATCH(DMI_BOARD_NAME, "CUR-DLS"),
745                     },
746         },
747        {
748         .callback = force_acpi_ht,
749         .ident = "ABIT i440BX-W83977",
750         .matches = {
751                     DMI_MATCH(DMI_BOARD_VENDOR, "ABIT <http://www.abit.com>"),
752                     DMI_MATCH(DMI_BOARD_NAME, "i440BX-W83977 (BP6)"),
753                     },
754         },
755        {
756         .callback = force_acpi_ht,
757         .ident = "IBM Bladecenter",
758         .matches = {
759                     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
760                     DMI_MATCH(DMI_BOARD_NAME, "IBM eServer BladeCenter HS20"),
761                     },
762         },
763        {
764         .callback = force_acpi_ht,
765         .ident = "IBM eServer xSeries 360",
766         .matches = {
767                     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
768                     DMI_MATCH(DMI_BOARD_NAME, "eServer xSeries 360"),
769                     },
770         },
771        {
772         .callback = force_acpi_ht,
773         .ident = "IBM eserver xSeries 330",
774         .matches = {
775                     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
776                     DMI_MATCH(DMI_BOARD_NAME, "eserver xSeries 330"),
777                     },
778         },
779        {
780         .callback = force_acpi_ht,
781         .ident = "IBM eserver xSeries 440",
782         .matches = {
783                     DMI_MATCH(DMI_BOARD_VENDOR, "IBM"),
784                     DMI_MATCH(DMI_PRODUCT_NAME, "eserver xSeries 440"),
785                     },
786         },
787
788        /*
789         * Boxes that need ACPI PCI IRQ routing disabled
790         */
791        {
792         .callback = disable_acpi_irq,
793         .ident = "ASUS A7V",
794         .matches = {
795                     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC"),
796                     DMI_MATCH(DMI_BOARD_NAME, "<A7V>"),
797                     /* newer BIOS, Revision 1011, does work */
798                     DMI_MATCH(DMI_BIOS_VERSION,
799                               "ASUS A7V ACPI BIOS Revision 1007"),
800                     },
801         },
802
803        /*
804         * Boxes that need ACPI PCI IRQ routing and PCI scan disabled
805         */
806        {                       /* _BBN 0 bug */
807         .callback = disable_acpi_pci,
808         .ident = "ASUS PR-DLS",
809         .matches = {
810                     DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
811                     DMI_MATCH(DMI_BOARD_NAME, "PR-DLS"),
812                     DMI_MATCH(DMI_BIOS_VERSION,
813                               "ASUS PR-DLS ACPI BIOS Revision 1010"),
814                     DMI_MATCH(DMI_BIOS_DATE, "03/21/2003")
815                     },
816         },
817        {
818         .callback = disable_acpi_pci,
819         .ident = "Acer TravelMate 36x Laptop",
820         .matches = {
821                     DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
822                     DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
823                     },
824         },
825        {}
826};
827
828#endif                          /* __i386__ */
829
830/*
831 * acpi_boot_table_init() and acpi_boot_init()
832 *  called from setup_arch(), always.
833 *      1. checksums all tables
834 *      2. enumerates lapics
835 *      3. enumerates io-apics
836 *
837 * acpi_table_init() is separate to allow reading SRAT without
838 * other side effects.
839 *
840 * side effects of acpi_boot_init:
841 *      acpi_lapic = 1 if LAPIC found
842 *      acpi_ioapic = 1 if IOAPIC found
843 *      if (acpi_lapic && acpi_ioapic) smp_found_config = 1;
844 *      if acpi_blacklisted() acpi_disabled = 1;
845 *      acpi_irq_model=...
846 *      ...
847 *
848 * return value: (currently ignored)
849 *      0: success
850 *      !0: failure
851 */
852
853int __init acpi_boot_table_init(void)
854{
855        int error;
856
857#ifdef __i386__
858        dmi_check_system(acpi_dmi_table);
859#endif
860
861        /*
862         * If acpi_disabled, bail out
863         * One exception: acpi=ht continues far enough to enumerate LAPICs
864         */
865        if (acpi_disabled && !acpi_ht)
866                return 1;
867
868        /*
869         * Initialize the ACPI boot-time table parser.
870         */
871        error = acpi_table_init();
872        if (error) {
873                disable_acpi();
874                return error;
875        }
876
877        acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
878
879        /*
880         * blacklist may disable ACPI entirely
881         */
882        error = acpi_blacklisted();
883        if (error) {
884                extern int acpi_force;
885
886                if (acpi_force) {
887                        printk(KERN_WARNING PREFIX "acpi=force override\n");
888                } else {
889                        printk(KERN_WARNING PREFIX "Disabling ACPI support\n");
890                        disable_acpi();
891                        return error;
892                }
893        }
894
895        return 0;
896}
897
898int __init acpi_boot_init(void)
899{
900        /*
901         * If acpi_disabled, bail out
902         * One exception: acpi=ht continues far enough to enumerate LAPICs
903         */
904        if (acpi_disabled && !acpi_ht)
905                return 1;
906
907        acpi_table_parse(ACPI_BOOT, acpi_parse_sbf);
908
909        /*
910         * set sci_int and PM timer address
911         */
912        acpi_table_parse(ACPI_FADT, acpi_parse_fadt);
913
914        /*
915         * Process the Multiple APIC Description Table (MADT), if present
916         */
917        acpi_process_madt();
918
919        acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
920
921        return 0;
922}
Note: See TracBrowser for help on using the repository browser.