~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/ia64/kernel/acpi.c

Version: ~ [ linux-6.2-rc3 ] ~ [ linux-6.1.5 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.87 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.162 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.228 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.269 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.302 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp