added some suse-specific patches to the kernel.
[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/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 <asm/io.h>
45 #include <asm/iosapic.h>
46 #include <asm/machvec.h>
47 #include <asm/page.h>
48 #include <asm/system.h>
49 #include <asm/numa.h>
50
51
52 #define PREFIX                  "ACPI: "
53
54 asm (".weak iosapic_register_intr");
55 asm (".weak iosapic_override_isa_irq");
56 asm (".weak iosapic_register_platform_intr");
57 asm (".weak iosapic_init");
58 asm (".weak iosapic_system_init");
59 asm (".weak iosapic_version");
60
61 void (*pm_idle) (void);
62 void (*pm_power_off) (void);
63
64 unsigned char acpi_kbd_controller_present = 1;
65
66 int acpi_disabled __initdata;   /* XXX this shouldn't be needed---we can't boot without ACPI! */
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 "hpzx1";
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_SN1)
107         return "sn1";
108 # elif defined (CONFIG_IA64_SGI_SN2)
109         return "sn2";
110 # elif defined (CONFIG_IA64_DIG)
111         return "dig";
112 # else
113 #       error Unknown platform.  Fix acpi.c.
114 # endif
115 #endif
116 }
117
118 #ifdef CONFIG_ACPI
119
120 /**
121  * acpi_get_crs - Return the current resource settings for a device
122  * obj: A handle for this device
123  * buf: A buffer to be populated by this call.
124  *
125  * Pass a valid handle, typically obtained by walking the namespace and a
126  * pointer to an allocated buffer, and this function will fill in the buffer
127  * with a list of acpi_resource structures.
128  */
129 acpi_status
130 acpi_get_crs (acpi_handle obj, struct acpi_buffer *buf)
131 {
132         acpi_status result;
133         buf->length = 0;
134         buf->pointer = NULL;
135
136         result = acpi_get_current_resources(obj, buf);
137         if (result != AE_BUFFER_OVERFLOW)
138                 return result;
139         buf->pointer = kmalloc(buf->length, GFP_KERNEL);
140         if (!buf->pointer)
141                 return -ENOMEM;
142
143         return acpi_get_current_resources(obj, buf);
144 }
145
146 struct acpi_resource *
147 acpi_get_crs_next (struct acpi_buffer *buf, int *offset)
148 {
149         struct acpi_resource *res;
150
151         if (*offset >= buf->length)
152                 return NULL;
153
154         res = buf->pointer + *offset;
155         *offset += res->length;
156         return res;
157 }
158
159 union acpi_resource_data *
160 acpi_get_crs_type (struct acpi_buffer *buf, int *offset, int type)
161 {
162         for (;;) {
163                 struct acpi_resource *res = acpi_get_crs_next(buf, offset);
164                 if (!res)
165                         return NULL;
166                 if (res->id == type)
167                         return &res->data;
168         }
169 }
170
171 void
172 acpi_dispose_crs (struct acpi_buffer *buf)
173 {
174         kfree(buf->pointer);
175 }
176
177 void
178 acpi_get_crs_addr (struct acpi_buffer *buf, int type, u64 *base, u64 *size, u64 *tra)
179 {
180         int offset = 0;
181         struct acpi_resource_address16 *addr16;
182         struct acpi_resource_address32 *addr32;
183         struct acpi_resource_address64 *addr64;
184
185         for (;;) {
186                 struct acpi_resource *res = acpi_get_crs_next(buf, &offset);
187                 if (!res)
188                         return;
189                 switch (res->id) {
190                         case ACPI_RSTYPE_ADDRESS16:
191                                 addr16 = (struct acpi_resource_address16 *) &res->data;
192
193                                 if (type == addr16->resource_type) {
194                                         *base = addr16->min_address_range;
195                                         *size = addr16->address_length;
196                                         *tra = addr16->address_translation_offset;
197                                         return;
198                                 }
199                                 break;
200                         case ACPI_RSTYPE_ADDRESS32:
201                                 addr32 = (struct acpi_resource_address32 *) &res->data;
202                                 if (type == addr32->resource_type) {
203                                         *base = addr32->min_address_range;
204                                         *size = addr32->address_length;
205                                         *tra = addr32->address_translation_offset;
206                                         return;
207                                 }
208                                 break;
209                         case ACPI_RSTYPE_ADDRESS64:
210                                 addr64 = (struct acpi_resource_address64 *) &res->data;
211                                 if (type == addr64->resource_type) {
212                                         *base = addr64->min_address_range;
213                                         *size = addr64->address_length;
214                                         *tra = addr64->address_translation_offset;
215                                         return;
216                                 }
217                                 break;
218                 }
219         }
220 }
221
222 int
223 acpi_get_addr_space(void *obj, u8 type, u64 *base, u64 *length, u64 *tra)
224 {
225         acpi_status status;
226         struct acpi_buffer buf;
227
228         *base = 0;
229         *length = 0;
230         *tra = 0;
231
232         status = acpi_get_crs((acpi_handle)obj, &buf);
233         if (ACPI_FAILURE(status)) {
234                 printk(KERN_ERR PREFIX "Unable to get _CRS data on object\n");
235                 return status;
236         }
237
238         acpi_get_crs_addr(&buf, type, base, length, tra);
239
240         acpi_dispose_crs(&buf);
241
242         return AE_OK;
243 }
244 #endif /* CONFIG_ACPI */
245
246 #ifdef CONFIG_ACPI_BOOT
247
248 #define ACPI_MAX_PLATFORM_INTERRUPTS    256
249
250 /* Array to record platform interrupt vectors for generic interrupt routing. */
251 int platform_intr_list[ACPI_MAX_PLATFORM_INTERRUPTS] = {
252         [0 ... ACPI_MAX_PLATFORM_INTERRUPTS - 1] = -1
253 };
254
255 enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_IOSAPIC;
256
257 /*
258  * Interrupt routing API for device drivers.  Provides interrupt vector for
259  * a generic platform event.  Currently only CPEI is implemented.
260  */
261 int
262 acpi_request_vector (u32 int_type)
263 {
264         int vector = -1;
265
266         if (int_type < ACPI_MAX_PLATFORM_INTERRUPTS) {
267                 /* correctable platform error interrupt */
268                 vector = platform_intr_list[int_type];
269         } else
270                 printk(KERN_ERR "acpi_request_vector(): invalid interrupt type\n");
271         return vector;
272 }
273
274 char *
275 __acpi_map_table (unsigned long phys_addr, unsigned long size)
276 {
277         return __va(phys_addr);
278 }
279
280 /* --------------------------------------------------------------------------
281                             Boot-time Table Parsing
282    -------------------------------------------------------------------------- */
283
284 static int                      total_cpus __initdata;
285 static int                      available_cpus __initdata;
286 struct acpi_table_madt *        acpi_madt __initdata;
287 static u8                       has_8259;
288
289
290 static int __init
291 acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header)
292 {
293         struct acpi_table_lapic_addr_ovr *lapic;
294
295         lapic = (struct acpi_table_lapic_addr_ovr *) header;
296         if (!lapic)
297                 return -EINVAL;
298
299         acpi_table_print_madt_entry(header);
300
301         if (lapic->address) {
302                 iounmap((void *) ipi_base_addr);
303                 ipi_base_addr = (unsigned long) ioremap(lapic->address, 0);
304         }
305         return 0;
306 }
307
308
309 static int __init
310 acpi_parse_lsapic (acpi_table_entry_header *header)
311 {
312         struct acpi_table_lsapic *lsapic;
313
314         lsapic = (struct acpi_table_lsapic *) header;
315         if (!lsapic)
316                 return -EINVAL;
317
318         acpi_table_print_madt_entry(header);
319
320         printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
321
322         if (lsapic->flags.enabled) {
323                 available_cpus++;
324                 printk(" enabled");
325 #ifdef CONFIG_SMP
326                 smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
327                 if (hard_smp_processor_id() == smp_boot_data.cpu_phys_id[total_cpus])
328                         printk(" (BSP)");
329 #endif
330         }
331         else {
332                 printk(" disabled");
333 #ifdef CONFIG_SMP
334                 smp_boot_data.cpu_phys_id[total_cpus] = -1;
335 #endif
336         }
337
338         printk("\n");
339
340         total_cpus++;
341         return 0;
342 }
343
344
345 static int __init
346 acpi_parse_lapic_nmi (acpi_table_entry_header *header)
347 {
348         struct acpi_table_lapic_nmi *lacpi_nmi;
349
350         lacpi_nmi = (struct acpi_table_lapic_nmi*) header;
351         if (!lacpi_nmi)
352                 return -EINVAL;
353
354         acpi_table_print_madt_entry(header);
355
356         /* TBD: Support lapic_nmi entries */
357         return 0;
358 }
359
360
361 static int __init
362 acpi_parse_iosapic (acpi_table_entry_header *header)
363 {
364         struct acpi_table_iosapic *iosapic;
365
366         iosapic = (struct acpi_table_iosapic *) header;
367         if (!iosapic)
368                 return -EINVAL;
369
370         acpi_table_print_madt_entry(header);
371
372         if (iosapic_init)
373                 iosapic_init(iosapic->address, iosapic->global_irq_base);
374
375         return 0;
376 }
377
378
379 static int __init
380 acpi_parse_plat_int_src (acpi_table_entry_header *header)
381 {
382         struct acpi_table_plat_int_src *plintsrc;
383         int vector;
384
385         plintsrc = (struct acpi_table_plat_int_src *) header;
386         if (!plintsrc)
387                 return -EINVAL;
388
389         acpi_table_print_madt_entry(header);
390
391         if (!iosapic_register_platform_intr) {
392                 printk(KERN_WARNING PREFIX "No ACPI platform interrupt support\n");
393                 return -ENODEV;
394         }
395
396         /*
397          * Get vector assignment for this interrupt, set attributes,
398          * and program the IOSAPIC routing table.
399          */
400         vector = iosapic_register_platform_intr(plintsrc->type,
401                                                 plintsrc->global_irq,
402                                                 plintsrc->iosapic_vector,
403                                                 plintsrc->eid,
404                                                 plintsrc->id,
405                                                 (plintsrc->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
406                                                 (plintsrc->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
407
408         platform_intr_list[plintsrc->type] = vector;
409         return 0;
410 }
411
412
413 static int __init
414 acpi_parse_int_src_ovr (acpi_table_entry_header *header)
415 {
416         struct acpi_table_int_src_ovr *p;
417
418         p = (struct acpi_table_int_src_ovr *) header;
419         if (!p)
420                 return -EINVAL;
421
422         acpi_table_print_madt_entry(header);
423
424         /* Ignore if the platform doesn't support overrides */
425         if (!iosapic_override_isa_irq)
426                 return 0;
427
428         iosapic_override_isa_irq(p->bus_irq, p->global_irq,
429                                  (p->flags.polarity == 1) ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
430                                  (p->flags.trigger == 1) ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
431         return 0;
432 }
433
434
435 static int __init
436 acpi_parse_nmi_src (acpi_table_entry_header *header)
437 {
438         struct acpi_table_nmi_src *nmi_src;
439
440         nmi_src = (struct acpi_table_nmi_src*) header;
441         if (!nmi_src)
442                 return -EINVAL;
443
444         acpi_table_print_madt_entry(header);
445
446         /* TBD: Support nimsrc entries */
447         return 0;
448 }
449
450
451 static int __init
452 acpi_parse_madt (unsigned long phys_addr, unsigned long size)
453 {
454         if (!phys_addr || !size)
455                 return -EINVAL;
456
457         acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
458
459         /* remember the value for reference after free_initmem() */
460 #ifdef CONFIG_ITANIUM
461         has_8259 = 1; /* Firmware on old Itanium systems is broken */
462 #else
463         has_8259 = acpi_madt->flags.pcat_compat;
464 #endif
465         if (iosapic_system_init)
466                 iosapic_system_init(has_8259);
467
468         /* Get base address of IPI Message Block */
469
470         if (acpi_madt->lapic_address)
471                 ipi_base_addr = (unsigned long) ioremap(acpi_madt->lapic_address, 0);
472
473         printk(KERN_INFO PREFIX "Local APIC address 0x%lx\n", ipi_base_addr);
474         return 0;
475 }
476
477
478 #ifdef CONFIG_ACPI_NUMA
479
480 #define SLIT_DEBUG
481
482 #define PXM_FLAG_LEN ((MAX_PXM_DOMAINS + 1)/32)
483
484 static int __initdata srat_num_cpus;                    /* number of cpus */
485 static u32 __initdata pxm_flag[PXM_FLAG_LEN];
486 #define pxm_bit_set(bit)        (set_bit(bit,(void *)pxm_flag))
487 #define pxm_bit_test(bit)       (test_bit(bit,(void *)pxm_flag))
488 /* maps to convert between proximity domain and logical node ID */
489 int __initdata pxm_to_nid_map[MAX_PXM_DOMAINS];
490 int __initdata nid_to_pxm_map[NR_NODES];
491 static struct acpi_table_slit __initdata *slit_table;
492
493 /*
494  * ACPI 2.0 SLIT (System Locality Information Table)
495  * http://devresource.hp.com/devresource/Docs/TechPapers/IA64/slit.pdf
496  */
497 void __init
498 acpi_numa_slit_init (struct acpi_table_slit *slit)
499 {
500         u32 len;
501
502         len = sizeof(struct acpi_table_header) + 8
503                 + slit->localities * slit->localities;
504         if (slit->header.length != len) {
505                 printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n",
506                        len, slit->header.length);
507                 memset(numa_slit, 10, sizeof(numa_slit));
508                 return;
509         }
510         slit_table = slit;
511 }
512
513 void __init
514 acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa)
515 {
516         /* record this node in proximity bitmap */
517         pxm_bit_set(pa->proximity_domain);
518
519         node_cpuid[srat_num_cpus].phys_id = (pa->apic_id << 8) | (pa->lsapic_eid);
520         /* nid should be overridden as logical node id later */
521         node_cpuid[srat_num_cpus].nid = pa->proximity_domain;
522         srat_num_cpus++;
523 }
524
525 void __init
526 acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
527 {
528         unsigned long paddr, size, hole_size, min_hole_size;
529         u8 pxm;
530         struct node_memblk_s *p, *q, *pend;
531
532         pxm = ma->proximity_domain;
533
534         /* fill node memory chunk structure */
535         paddr = ma->base_addr_hi;
536         paddr = (paddr << 32) | ma->base_addr_lo;
537         size = ma->length_hi;
538         size = (size << 32) | ma->length_lo;
539
540         if (num_memblks >= NR_MEMBLKS) {
541                 printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n",
542                        size/(1024*1024), paddr);
543                 return;
544         }
545
546         /* Ignore disabled entries */
547         if (!ma->flags.enabled)
548                 return;
549
550         /*
551          * When the chunk is not the first one in the node, check distance
552          * from the other chunks. When the hole is too huge ignore the chunk.
553          * This restriction should be removed when multiple chunks per node
554          * is supported.
555          */
556         pend = &node_memblk[num_memblks];
557         min_hole_size = 0;
558         for (p = &node_memblk[0]; p < pend; p++) {
559                 if (p->nid != pxm)
560                         continue;
561                 if (p->start_paddr < paddr)
562                         hole_size = paddr - (p->start_paddr + p->size);
563                 else
564                         hole_size = p->start_paddr - (paddr + size);
565
566                 if (!min_hole_size || hole_size < min_hole_size)
567                         min_hole_size = hole_size;
568         }
569
570         if (min_hole_size) {
571                 if (min_hole_size > size) {
572                         printk(KERN_ERR "Too huge memory hole. Ignoring %ld MBytes at %lx\n",
573                                size/(1024*1024), paddr);
574                         return;
575                 }
576         }
577
578         /* record this node in proximity bitmap */
579         pxm_bit_set(pxm);
580
581         /* Insertion sort based on base address */
582         pend = &node_memblk[num_memblks];
583         for (p = &node_memblk[0]; p < pend; p++) {
584                 if (paddr < p->start_paddr)
585                         break;
586         }
587         if (p < pend) {
588                 for (q = pend; q >= p; q--)
589                         *(q + 1) = *q;
590         }
591         p->start_paddr = paddr;
592         p->size = size;
593         p->nid = pxm;
594         num_memblks++;
595 }
596
597 void __init
598 acpi_numa_arch_fixup (void)
599 {
600         int i, j, node_from, node_to;
601
602         /* calculate total number of nodes in system from PXM bitmap */
603         numnodes = 0;           /* init total nodes in system */
604
605         memset(pxm_to_nid_map, -1, sizeof(pxm_to_nid_map));
606         memset(nid_to_pxm_map, -1, sizeof(nid_to_pxm_map));
607         for (i = 0; i < MAX_PXM_DOMAINS; i++) {
608                 if (pxm_bit_test(i)) {
609                         pxm_to_nid_map[i] = numnodes;
610                         nid_to_pxm_map[numnodes++] = i;
611                 }
612         }
613
614         /* set logical node id in memory chunk structure */
615         for (i = 0; i < num_memblks; i++)
616                 node_memblk[i].nid = pxm_to_nid_map[node_memblk[i].nid];
617
618         /* assign memory bank numbers for each chunk on each node */
619         for (i = 0; i < numnodes; i++) {
620                 int bank;
621
622                 bank = 0;
623                 for (j = 0; j < num_memblks; j++)
624                         if (node_memblk[j].nid == i)
625                                 node_memblk[j].bank = bank++;
626         }
627
628         /* set logical node id in cpu structure */
629         for (i = 0; i < srat_num_cpus; i++)
630                 node_cpuid[i].nid = pxm_to_nid_map[node_cpuid[i].nid];
631
632         printk(KERN_INFO "Number of logical nodes in system = %d\n", numnodes);
633         printk(KERN_INFO "Number of memory chunks in system = %d\n", num_memblks);
634
635         if (!slit_table) return;
636         memset(numa_slit, -1, sizeof(numa_slit));
637         for (i=0; i<slit_table->localities; i++) {
638                 if (!pxm_bit_test(i))
639                         continue;
640                 node_from = pxm_to_nid_map[i];
641                 for (j=0; j<slit_table->localities; j++) {
642                         if (!pxm_bit_test(j))
643                                 continue;
644                         node_to = pxm_to_nid_map[j];
645                         node_distance(node_from, node_to) =
646                                 slit_table->entry[i*slit_table->localities + j];
647                 }
648         }
649
650 #ifdef SLIT_DEBUG
651         printk("ACPI 2.0 SLIT locality table:\n");
652         for (i = 0; i < numnodes; i++) {
653                 for (j = 0; j < numnodes; j++)
654                         printk("%03d ", node_distance(i,j));
655                 printk("\n");
656         }
657 #endif
658 }
659 #endif /* CONFIG_ACPI_NUMA */
660
661 static int __init
662 acpi_parse_fadt (unsigned long phys_addr, unsigned long size)
663 {
664         struct acpi_table_header *fadt_header;
665         struct fadt_descriptor_rev2 *fadt;
666         u32 sci_irq;
667
668         if (!phys_addr || !size)
669                 return -EINVAL;
670
671         fadt_header = (struct acpi_table_header *) __va(phys_addr);
672         if (fadt_header->revision != 3)
673                 return -ENODEV;         /* Only deal with ACPI 2.0 FADT */
674
675         fadt = (struct fadt_descriptor_rev2 *) fadt_header;
676
677         if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER))
678                 acpi_kbd_controller_present = 0;
679
680         if (!iosapic_register_intr)
681                 return 0;       /* just ignore the rest */
682
683         sci_irq = fadt->sci_int;
684
685         if (has_8259 && sci_irq < 16)
686                 return 0;       /* legacy, no setup required */
687
688         iosapic_register_intr(sci_irq, IOSAPIC_POL_LOW, IOSAPIC_LEVEL);
689         return 0;
690 }
691
692
693 unsigned long __init
694 acpi_find_rsdp (void)
695 {
696         unsigned long rsdp_phys = 0;
697
698         if (efi.acpi20)
699                 rsdp_phys = __pa(efi.acpi20);
700         else if (efi.acpi)
701                 printk(KERN_WARNING PREFIX "v1.0/r0.71 tables no longer supported\n");
702         return rsdp_phys;
703 }
704
705
706 #ifdef CONFIG_SERIAL_8250_ACPI
707
708 #include <linux/acpi_serial.h>
709
710 static int __init
711 acpi_parse_spcr (unsigned long phys_addr, unsigned long size)
712 {
713         acpi_ser_t *spcr;
714         unsigned int gsi;
715
716         if (!phys_addr || !size)
717                 return -EINVAL;
718
719         if (!iosapic_register_intr)
720                 return -ENODEV;
721
722         /*
723          * ACPI is able to describe serial ports that live at non-standard
724          * memory addresses and use non-standard interrupts, either via
725          * direct SAPIC mappings or via PCI interrupts.  We handle interrupt
726          * routing for SAPIC-based (non-PCI) devices here.  Interrupt routing
727          * for PCI devices will be handled when processing the PCI Interrupt
728          * Routing Table (PRT).
729          */
730
731         spcr = (acpi_ser_t *) __va(phys_addr);
732
733         setup_serial_acpi(spcr);
734
735         if (spcr->length < sizeof(acpi_ser_t))
736                 /* Table not long enough for full info, thus no interrupt */
737                 return -ENODEV;
738
739         if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) &&
740             (spcr->int_type == ACPI_SERIAL_INT_SAPIC))
741         {
742                 int vector;
743
744                 /* We have a UART in memory space with an SAPIC interrupt */
745
746                 gsi = (  (spcr->global_int[3] << 24) |
747                          (spcr->global_int[2] << 16) |
748                          (spcr->global_int[1] << 8)  |
749                          (spcr->global_int[0])  );
750
751                 vector = iosapic_register_intr(gsi, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
752         }
753         return 0;
754 }
755
756 #endif /* CONFIG_SERIAL_8250_ACPI */
757
758
759 int __init
760 acpi_boot_init (void)
761 {
762
763         /*
764          * MADT
765          * ----
766          * Parse the Multiple APIC Description Table (MADT), if exists.
767          * Note that this table provides platform SMP configuration
768          * information -- the successor to MPS tables.
769          */
770
771         if (acpi_table_parse(ACPI_APIC, acpi_parse_madt) < 1) {
772                 printk(KERN_ERR PREFIX "Can't find MADT\n");
773                 goto skip_madt;
774         }
775
776         /* Local APIC */
777
778         if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0)
779                 printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
780
781         if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1)
782                 printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
783
784         if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0)
785                 printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
786
787         /* I/O APIC */
788
789         if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1)
790                 printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
791
792         /* System-Level Interrupt Routing */
793
794         if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0)
795                 printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
796
797         if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0)
798                 printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
799
800         if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0)
801                 printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
802   skip_madt:
803
804         /*
805          * FADT says whether a legacy keyboard controller is present.
806          * The FADT also contains an SCI_INT line, by which the system
807          * gets interrupts such as power and sleep buttons.  If it's not
808          * on a Legacy interrupt, it needs to be setup.
809          */
810         if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1)
811                 printk(KERN_ERR PREFIX "Can't find FADT\n");
812
813 #ifdef CONFIG_SERIAL_8250_ACPI
814         /*
815          * TBD: Need phased approach to table parsing (only do those absolutely
816          *      required during boot-up).  Recommend expanding concept of fix-
817          *      feature devices (LDM) to include table-based devices such as
818          *      serial ports, EC, SMBus, etc.
819          */
820         acpi_table_parse(ACPI_SPCR, acpi_parse_spcr);
821 #endif
822
823 #ifdef CONFIG_SMP
824         if (available_cpus == 0) {
825                 printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
826                 available_cpus = 1; /* We've got at least one of these, no? */
827         }
828         smp_boot_data.cpu_count = total_cpus;
829
830         smp_build_cpu_map();
831 # ifdef CONFIG_NUMA
832         build_cpu_to_node_map();
833 # endif
834 #endif
835         /* Make boot-up look pretty */
836         printk(KERN_INFO "%d CPUs available, %d CPUs total\n", available_cpus, total_cpus);
837         return 0;
838 }
839
840 /*
841  * PCI Interrupt Routing
842  */
843
844 #ifdef CONFIG_PCI
845 int __init
846 acpi_get_prt (struct pci_vector_struct **vectors, int *count)
847 {
848         struct pci_vector_struct *vector;
849         struct list_head *node;
850         struct acpi_prt_entry *entry;
851         int i = 0;
852
853         if (!vectors || !count)
854                 return -EINVAL;
855
856         *vectors = NULL;
857         *count = 0;
858
859         if (acpi_prt.count < 0) {
860                 printk(KERN_ERR PREFIX "No PCI interrupt routing entries\n");
861                 return -ENODEV;
862         }
863
864         /* Allocate vectors */
865
866         *vectors = kmalloc(sizeof(struct pci_vector_struct) * acpi_prt.count, GFP_KERNEL);
867         if (!(*vectors))
868                 return -ENOMEM;
869
870         /* Convert PRT entries to IOSAPIC PCI vectors */
871
872         vector = *vectors;
873
874         list_for_each(node, &acpi_prt.entries) {
875                 entry = (struct acpi_prt_entry *)node;
876                 vector[i].segment = entry->id.segment;
877                 vector[i].bus    = entry->id.bus;
878                 vector[i].pci_id = ((u32) entry->id.device << 16) | 0xffff;
879                 vector[i].pin    = entry->pin;
880                 vector[i].irq    = entry->link.index;
881                 i++;
882         }
883         *count = acpi_prt.count;
884         return 0;
885 }
886 #endif /* CONFIG_PCI */
887
888 /* Assume IA64 always use I/O SAPIC */
889
890 int __init
891 acpi_get_interrupt_model (int *type)
892 {
893         if (!type)
894                 return -EINVAL;
895
896         *type = ACPI_IRQ_MODEL_IOSAPIC;
897         return 0;
898 }
899
900 int
901 acpi_irq_to_vector (u32 irq)
902 {
903         if (has_8259 && irq < 16)
904                 return isa_irq_to_vector(irq);
905
906         return gsi_to_vector(irq);
907 }
908
909 int
910 acpi_register_irq (u32 gsi, u32 polarity, u32 trigger)
911 {
912         int vector = 0;
913
914         if (acpi_madt->flags.pcat_compat && (gsi < 16))
915                 return isa_irq_to_vector(gsi);
916
917         if (!iosapic_register_intr)
918                 return 0;
919
920         /* Turn it on */
921         vector = iosapic_register_intr (gsi, polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
922                         trigger ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
923         return vector;
924 }
925
926 #endif /* CONFIG_ACPI_BOOT */