cfeb729c4b5d43ff77c51dd8eab1f02105f29e50
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / kernel / acpi.c
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-kochi@bq.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/module.h>
36 #include <linux/init.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/smp.h>
40 #include <linux/string.h>
41 #include <linux/types.h>
42 #include <linux/irq.h>
43 #include <linux/acpi.h>
44 #include <linux/efi.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 void (*pm_idle) (void);
57 EXPORT_SYMBOL(pm_idle);
58 void (*pm_power_off) (void);
59
60 unsigned char acpi_kbd_controller_present = 1;
61 unsigned char acpi_legacy_devices;
62
63 int acpi_disabled;      /* XXX this shouldn't be needed---we can't boot without ACPI! */
64
65 const char *
66 acpi_get_sysname (void)
67 {
68 #ifdef CONFIG_IA64_GENERIC
69         unsigned long rsdp_phys;
70         struct acpi20_table_rsdp *rsdp;
71         struct acpi_table_xsdt *xsdt;
72         struct acpi_table_header *hdr;
73
74         rsdp_phys = acpi_find_rsdp();
75         if (!rsdp_phys) {
76                 printk(KERN_ERR "ACPI 2.0 RSDP not found, default to \"dig\"\n");
77                 return "dig";
78         }
79
80         rsdp = (struct acpi20_table_rsdp *) __va(rsdp_phys);
81         if (strncmp(rsdp->signature, RSDP_SIG, sizeof(RSDP_SIG) - 1)) {
82                 printk(KERN_ERR "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
83                 return "dig";
84         }
85
86         xsdt = (struct acpi_table_xsdt *) __va(rsdp->xsdt_address);
87         hdr = &xsdt->header;
88         if (strncmp(hdr->signature, XSDT_SIG, sizeof(XSDT_SIG) - 1)) {
89                 printk(KERN_ERR "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
90                 return "dig";
91         }
92
93         if (!strcmp(hdr->oem_id, "HP")) {
94                 return "hpzx1";
95         }
96         else if (!strcmp(hdr->oem_id, "SGI")) {
97                 return "sn2";
98         }
99
100         return "dig";
101 #else
102 # if defined (CONFIG_IA64_HP_SIM)
103         return "hpsim";
104 # elif defined (CONFIG_IA64_HP_ZX1)
105         return "hpzx1";
106 # elif defined (CONFIG_IA64_SGI_SN2)
107         return "sn2";
108 # elif defined (CONFIG_IA64_DIG)
109         return "dig";
110 # else
111 #       error Unknown platform.  Fix acpi.c.
112 # endif
113 #endif
114 }
115
116 #ifdef CONFIG_ACPI_BOOT
117
118 #define ACPI_MAX_PLATFORM_INTERRUPTS    256
119
120 /* Array to record platform interrupt vectors for generic interrupt routing. */
121 int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = {
122         [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1
123 };
124
125 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
126
127 /*
128  * Interrupt routing API for device drivers.  Provides interrupt vector for
129  * a generic platform event.  Currently only CPEI is implemented.
130  */
131 int
132 acpi_request_vector (u32 int_type)
133 {
134         int vector = -1;
135
136         if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
137                 /* corrected platform error interrupt */
138                 vector = platform_intr_list[int_type];
139         } else
140                 printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
141         return vector;
142 }
143
144 char *
145 __acpi_map_table (unsigned long phys_addr, unsigned long size)
146 {
147         return __va(phys_addr);
148 }
149
150 /* --------------------------------------------------------------------------
151                             Boot-time Table Parsing
152    -------------------------------------------------------------------------- */
153
154 static int                      total_cpus __initdata;
155 static int                      available_cpus __initdata;
156 struct acpi_table_madt *        acpi_madt __initdata;
157 static u8                       has_8259;
158
159
160 static int __init
161 acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header)
162 {
163         struct acpi_table_lapic_addr_ovr *lapic;
164
165         lapic = (struct acpi_table_lapic_addr_ovr *) header;
166         if (!lapic)
167                 return -EINVAL;
168
169         acpi_table_print_madt_entry(header);
170
171         if (lapic->address) {
172                 iounmap((void *) ipi_base_addr);
173                 ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
174         }
175         return 0;
176 }
177
178
179 static int __init
180 acpi_parse_lsapic (acpi_table_entry_header *header)
181 {
182         struct acpi_table_lsapic *lsapic;
183
184         lsapic = (struct acpi_table_lsapic *) header;
185         if (!lsapic)
186                 return -EINVAL;
187
188         acpi_table_print_madt_entry(header);
189
190         printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
191
192         if (!lsapic->flags.enabled)
193                 printk(" disabled");
194         else {
195                 printk(" enabled");
196 #ifdef CONFIG_SMP
197                 smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
198                 if (hard_smp_processor_id()
199                     == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
200                         printk(" (BSP)");
201 #endif
202                 ++available_cpus;
203         }
204
205         printk("\n");
206
207         total_cpus++;
208         return 0;
209 }
210
211
212 static int __init
213 acpi_parse_lapic_nmi (acpi_table_entry_header *header)
214 {
215         struct acpi_table_lapic_nmi *lacpi_nmi;
216
217         lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
218         if (!lacpi_nmi)
219                 return -EINVAL;
220
221         acpi_table_print_madt_entry(header);
222
223         /* TBD: Support lapic_nmi entries */
224         return 0;
225 }
226
227
228 static int __init
229 acpi_parse_iosapic (acpi_table_entry_header *header)
230 {
231         struct acpi_table_iosapic *iosapic;
232
233         iosapic = (struct acpi_table_iosapic *) header;
234         if (!iosapic)
235                 return -EINVAL;
236
237         acpi_table_print_madt_entry(header);
238
239         iosapic_init(iosapic->address, iosapic->global_irq_base);
240
241         return 0;
242 }
243
244
245 static int __init
246 acpi_parse_plat_int_src (acpi_table_entry_header *header)
247 {
248         struct acpi_table_plat_int_src *plintsrc;
249         int vector;
250
251         plintsrc = (struct acpi_table_plat_int_src *) header;
252         if (!plintsrc)
253                 return -EINVAL;
254
255         acpi_table_print_madt_entry(header);
256
257         /*
258          * Get vector assignment for this interrupt, set attributes,
259          * and program the IOSAPIC routing table.
260          */
261         vector = iosapic_register_platform_intr(plintsrc->type,
262                                                 plintsrc->global_irq,
263                                                 plintsrc->iosapic_vector,
264                                                 plintsrc->eid,
265                                                 plintsrc->id,
266                                                 (plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
267                                                 (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
268
269         platform_intr_list[plintsrc->type] = vector;
270         return 0;
271 }
272
273
274 static int __init
275 acpi_parse_int_src_ovr (acpi_table_entry_header *header)
276 {
277         struct acpi_table_int_src_ovr *p;
278
279         p = (struct acpi_table_int_src_ovr *) header;
280         if (!p)
281                 return -EINVAL;
282
283         acpi_table_print_madt_entry(header);
284
285         iosapic_override_isa_irq(p->bus_irq, p->global_irq,
286                                  (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
287                                  (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
288         return 0;
289 }
290
291
292 static int __init
293 acpi_parse_nmi_src (acpi_table_entry_header *header)
294 {
295         struct acpi_table_nmi_src *nmi_src;
296
297         nmi_src = (struct acpi_table_nmi_src*) header;
298         if (!nmi_src)
299                 return -EINVAL;
300
301         acpi_table_print_madt_entry(header);
302
303         /* TBD: Support nimsrc entries */
304         return 0;
305 }
306
307
308 static int __init
309 acpi_parse_madt (unsigned long phys_addr, unsigned long size)
310 {
311         if (!phys_addr || !size)
312                 return -EINVAL;
313
314         acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
315
316         /* remember the value for reference after free_initmem() */
317 #ifdef CONFIG_ITANIUM
318         has_8259 = 1; /* Firmware on old Itanium systems is broken */
319 #else
320         has_8259 = acpi_madt->flags.pcat_compat;
321 #endif
322         iosapic_system_init(has_8259);
323
324         /* Get base address of IPI Message Block */
325
326         if (acpi_madt->lapic_address)
327                 ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
328
329         printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);
330         return 0;
331 }
332
333
334 #ifdef CONFIG_ACPI_NUMA
335
336 #undef SLIT_DEBUG
337
338 #define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
339 #define PXM_MAGIC       (255)
340
341 static int __initdata srat_num_cpus;                    /* number of cpus */
342 static u32 __initdata pxm_flag[PXM_FLAG_LEN];
343 static u32 __initdata mpxm_flag[PXM_FLAG_LEN];
344 #define pxm_bit_set(bit)        (set_bit(bit,(void *)pxm_flag))
345 #define pxm_bit_clear(bit)      (clear_bit(bit, (void *)pxm_flag))
346 #define pxm_bit_test(bit)       (test_bit(bit,(void *)pxm_flag))
347 #define mpxm_bit_set(bit)       (set_bit(bit, (void *) mpxm_flag))
348 #define mpxm_bit_test(bit)      (test_bit(bit, (void *) mpxm_flag))
349 /* maps to convert between proximity domain and logical node ID */
350 int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
351 int __initdata nid_to_pxm_map[MAX_NUMNODES];
352 static struct acpi_table_slit __initdata *slit_table;
353
354 /*
355  * ACPI 2.0 SLIT (System Locality Information Table)
356  * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
357  */
358 void __init
359 acpi_numa_slit_init (struct acpi_table_slit *slit)
360 {
361         u32 len;
362
363         len = sizeof(struct acpi_table_header) + 8
364                 + slit->localities * slit->localities;
365         if (slit->header.length != len) {
366                 printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
367                        len, slit->header.length);
368                 memset(numa_slit, 10, sizeof(numa_slit));
369                 return;
370         }
371         slit_table = slit;
372 }
373
374 void __init
375 acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa)
376 {
377         /* record this node in proximity bitmap */
378         pxm_bit_set(pa->proximity_domain);
379
380         node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid);
381         /* nid should be overridden as logical node id later */
382         node_cpuid[srat_num_cpus].nid = pa->proximity_domain;
383         srat_num_cpus++;
384 }
385
386 void __init
387 acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
388 {
389         unsigned long paddr, size;
390         u8 pxm;
391         struct node_memblk_s *p, *q, *pend;
392
393         pxm = ma->proximity_domain;
394
395         /* fill node memory chunk structure */
396         paddr = ma->base_addr_hi;
397         paddr = (paddr << 32) | ma->base_addr_lo;
398         size = ma->length_hi;
399         size = (size << 32) | ma->length_lo;
400
401         /* Ignore disabled entries */
402         if (!ma->flags.enabled)
403                 return;
404
405         /* record this node in proximity bitmap */
406         pxm_bit_set(pxm);
407
408         /* Insertion sort based on base address */
409         pend = &node_memblk[num_node_memblks];
410         for (p = &node_memblk[0]; p < pend; p++) {
411                 if (paddr < p->start_paddr)
412                         break;
413         }
414         if (p < pend) {
415                 for (q = pend - 1; q >= p; q--)
416                         *(q + 1) = *q;
417         }
418         p->start_paddr = paddr;
419         p->size = size;
420         p->nid = pxm;
421         num_node_memblks++;
422 }
423
424 static void __init
425 acpi_pxm_magic_slit_fix(void)
426 {
427         u8              distance, x;
428         int             i, j, nid;
429 #define SLIT_IDENTITY   10
430
431
432         if (!pxm_bit_test(PXM_MAGIC) || slit_table->localities >= PXM_MAGIC)
433                 return;
434
435         nid = pxm_to_nid_map[PXM_MAGIC];
436
437         for (distance = SLIT_IDENTITY*2, i = 0; i < slit_table->localities; i++) {
438                 if (!pxm_bit_test(i))
439                         continue;
440                 for (j = 0; j < slit_table->localities; j++) {
441                         if (!pxm_bit_test(j) || (i == j))
442                                 continue;
443
444                         x = (slit_table->entry[i*slit_table->localities + j] + SLIT_IDENTITY) / 2;
445                         distance = min(x, distance);
446                 }
447         }
448
449         /*
450          * Fill in distances for PXM magic.
451          */
452
453         for (i = 0; i < numnodes;  i++) 
454                 node_distance(i, nid) = distance;
455
456         for (i = 0; i < (numnodes - 1); i++)
457                 node_distance(nid, i) = distance;
458
459         node_distance(nid, nid) = SLIT_IDENTITY;
460
461
462         return;
463 }
464
465 static void __init
466 acpi_pxm_magic_fix(void)
467 {
468         struct node_memblk_s    *p;
469         int                     i, nnode, nid, cpu, pxm;
470
471
472         /*
473          * If every nid has memory then we are done.
474          */
475
476         for (nnode = 0, p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++) 
477                 if (!mpxm_bit_test(p->nid)) {
478                         mpxm_bit_set(p->nid);
479                         nnode++;
480                 }
481         
482         /*
483          * All nids with memory.
484          */
485
486         if (nnode == numnodes) 
487                 return;
488
489         /*
490          * Change logical node id for nids without memory.
491          * If we are removing a nid without memory, then
492          * move that nid's cpus to nnode-1 which will become
493          * the magic PXM's logical node id.  The node_cpu[X].nid
494          * is the PXM but will change later to logical node
495          * id.
496          */
497
498         for (nid = 0, i = 0; i < numnodes; i++) 
499                 if (mpxm_bit_test(i)) {
500                         if (i == nid) {
501                                 nid++;
502                                 continue;
503                         }
504
505                         for (p = &node_memblk[0]; p < &node_memblk[num_node_memblks]; p++)
506                                 if (p->nid == i)
507                                         p->nid = nid;
508
509                         pxm = nid_to_pxm_map[i];
510                         pxm_to_nid_map[pxm] = nid;
511                         nid_to_pxm_map[nid] = pxm;
512                         nid++;
513                 }
514                 else {
515                         for (cpu = 0; cpu < srat_num_cpus; cpu++)
516                                 if (node_cpuid[cpu].nid == nid_to_pxm_map[i])
517                                         node_cpuid[cpu].nid = PXM_MAGIC;
518
519                         pxm_to_nid_map[i] = nnode - 1;
520                         pxm_bit_clear(nid_to_pxm_map[i]);
521                 }
522
523         numnodes = nnode;
524
525         return;
526 }
527
528 void __init
529 acpi_numa_arch_fixup (void)
530 {
531         int i, j, node_from, node_to;
532
533         /* If there's no SRAT, fix the phys_id */
534         if (srat_num_cpus == 0) {
535                 node_cpuid[0].phys_id = hard_smp_processor_id();
536                 return;
537         }
538
539         /* calculate total number of nodes in system from PXM bitmap */
540         numnodes = 0;           /* init total nodes in system */
541
542         memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map));
543         memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map));
544         for (i = 0; i < MAX_PXM_DOMAINS; i++) {
545                 if (pxm_bit_test(i)) {
546                         pxm_to_nid_map[i] = numnodes;
547                         nid_to_pxm_map[numnodes++] = i;
548                 }
549         }
550
551         /* set logical node id in memory chunk structure */
552         for (i = 0; i < num_node_memblks; i++)
553                 node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid];
554
555         acpi_pxm_magic_fix();
556
557         /* assign memory bank numbers for each chunk on each node */
558         for (i = 0; i < numnodes; i++) {
559                 int bank;
560
561                 bank = 0;
562                 for (j = 0; j < num_node_memblks; j++)
563                         if (node_memblk[j].nid == i)
564                                 node_memblk[j].bank = bank++;
565         }
566
567         /* set logical node id in cpu structure */
568         for (i = 0; i < srat_num_cpus; i++)
569                 node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
570
571         printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes);
572         printk(KERN_INFO "Number of memory chunks in system = %d\n", num_node_memblks);
573
574         if (!slit_table) 
575                 return;
576
577         memset(numa_slit, -1, sizeof(numa_slit));
578
579         acpi_pxm_magic_slit_fix();
580
581         for (i=0; i<slit_table->localities; i++) {
582                 if (!pxm_bit_test(i))
583                         continue;
584                 node_from = pxm_to_nid_map[i];
585                 for (j=0; j<slit_table->localities; j++) {
586                         if (!pxm_bit_test(j))
587                                 continue;
588                         node_to = pxm_to_nid_map[j];
589                         node_distance(node_from, node_to) =
590                                 slit_table->entry[i*slit_table->localities + j];
591                 }
592         }
593
594 #ifdef SLIT_DEBUG
595         printk("ACPI 2.0 SLIT locality table:\n");
596         for (i = 0; i < numnodes; i++) {
597                 for (j = 0; j < numnodes; j++)
598                         printk("%03d ", node_distance(i,j));
599                 printk("\n");
600         }
601 #endif
602 }
603 #endif /* CONFIG_ACPI_NUMA */
604
605 static int __init
606 acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
607 {
608         struct acpi_table_header *fadt_header;
609         struct fadt_descriptor_rev2 *fadt;
610
611         if (!phys_addr || !size)
612                 return -EINVAL;
613
614         fadt_header = (struct acpi_table_header *) __va(phys_addr);
615         if (fadt_header->revision != 3)
616                 return -ENODEV;         /* Only deal with ACPI 2.0 FADT */
617
618         fadt = (struct fadt_descriptor_rev2 *) fadt_header;
619
620         if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
621                 acpi_kbd_controller_present = 0;
622
623         if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES)
624                 acpi_legacy_devices = 1;
625
626         acpi_register_irq(fadt->sci_int, ACPI_ACTIVE_LOW, ACPI_LEVEL_SENSITIVE);
627         return 0;
628 }
629
630
631 unsigned long __init
632 acpi_find_rsdp (void)
633 {
634         unsigned long rsdp_phys = 0;
635
636         if (efi.acpi20)
637                 rsdp_phys = __pa(efi.acpi20);
638         else if (efi.acpi)
639                 printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
640         return rsdp_phys;
641 }
642
643
644 int __init
645 acpi_boot_init (void)
646 {
647
648         /*
649          * MADT
650          * ----
651          * Parse the Multiple APIC Description Table (MADT), if exists.
652          * Note that this table provides platform SMP configuration
653          * information -- the successor to MPS tables.
654          */
655
656         if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {
657                 printk(KERN_ERR PREFIX "Can't find MADT\n");
658                 goto skip_madt;
659         }
660
661         /* Local APIC */
662
663         if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0)
664                 printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
665
666         if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1)
667                 printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
668
669         if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0)
670                 printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
671
672         /* I/O APIC */
673
674         if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
675                 printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
676
677         /* System-Level Interrupt Routing */
678
679         if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0)
680                 printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
681
682         if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0)
683                 printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
684
685         if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, 0) < 0)
686                 printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
687   skip_madt:
688
689         /*
690          * FADT says whether a legacy keyboard controller is present.
691          * The FADT also contains an SCI_INT line, by which the system
692          * gets interrupts such as power and sleep buttons.  If it's not
693          * on a Legacy interrupt, it needs to be setup.
694          */
695         if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1)
696                 printk(KERN_ERR PREFIX "Can't find FADT\n");
697
698 #ifdef CONFIG_SMP
699         if (available_cpus == 0) {
700                 printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
701                 printk(KERN_INFO "CPU 0 (0x%04x)", hard_smp_processor_id());
702                 smp_boot_data.cpu_phys_id[available_cpus] = hard_smp_processor_id();
703                 available_cpus = 1; /* We've got at least one of these, no? */
704         }
705         smp_boot_data.cpu_count = available_cpus;
706
707         smp_build_cpu_map();
708 # ifdef CONFIG_ACPI_NUMA
709         if (srat_num_cpus == 0) {
710                 int cpu, i = 1;
711                 for (cpu = 0; cpu < smp_boot_data.cpu_count; cpu++)
712                         if (smp_boot_data.cpu_phys_id[cpu] != hard_smp_processor_id())
713                                 node_cpuid[i++].phys_id = smp_boot_data.cpu_phys_id[cpu];
714         }
715         build_cpu_to_node_map();
716 # endif
717 #endif
718         /* Make boot-up look pretty */
719         printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
720         return 0;
721 }
722
723 int
724 acpi_irq_to_vector (u32 gsi)
725 {
726         if (has_8259 && gsi < 16)
727                 return isa_irq_to_vector(gsi);
728
729         return gsi_to_vector(gsi);
730 }
731
732 int
733 acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
734 {
735         if (has_8259 && gsi < 16)
736                 return isa_irq_to_vector(gsi);
737
738         return iosapic_register_intr(gsi,
739                         (polarity == ACPI_ACTIVE_HIGH) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
740                         (trigger == ACPI_EDGE_SENSITIVE) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
741 }
742 EXPORT_SYMBOL(acpi_register_irq);
743
744 #endif /* CONFIG_ACPI_BOOT */