linux/arch/i386/mach-generic/probe.c
<<
>>
Prefs
   1/* Copyright 2003 Andi Kleen, SuSE Labs. 
   2 * Subject to the GNU Public License, v.2 
   3 * 
   4 * Generic x86 APIC driver probe layer.
   5 */  
   6#include <linux/threads.h>
   7#include <linux/cpumask.h>
   8#include <linux/string.h>
   9#include <linux/kernel.h>
  10#include <linux/ctype.h>
  11#include <linux/init.h>
  12#include <linux/errno.h>
  13#include <asm/fixmap.h>
  14#include <asm/mpspec.h>
  15#include <asm/apicdef.h>
  16#include <asm/genapic.h>
  17
  18extern struct genapic apic_summit;
  19extern struct genapic apic_bigsmp;
  20extern struct genapic apic_es7000;
  21extern struct genapic apic_default;
  22
  23struct genapic *genapic = &apic_default;
  24
  25struct genapic *apic_probe[] __initdata = { 
  26        &apic_summit,
  27        &apic_bigsmp, 
  28        &apic_es7000,
  29        &apic_default,  /* must be last */
  30        NULL,
  31};
  32
  33static int cmdline_apic __initdata;
  34static int __init parse_apic(char *arg)
  35{
  36        int i;
  37
  38        if (!arg)
  39                return -EINVAL;
  40
  41        for (i = 0; apic_probe[i]; i++) {
  42                if (!strcmp(apic_probe[i]->name, arg)) {
  43                        genapic = apic_probe[i];
  44                        cmdline_apic = 1;
  45                        return 0;
  46                }
  47        }
  48
  49        /* Parsed again by __setup for debug/verbose */
  50        return 0;
  51}
  52early_param("apic", parse_apic);
  53
  54void __init generic_bigsmp_probe(void)
  55{
  56        /*
  57         * This routine is used to switch to bigsmp mode when
  58         * - There is no apic= option specified by the user
  59         * - generic_apic_probe() has choosen apic_default as the sub_arch
  60         * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
  61         */
  62
  63        if (!cmdline_apic && genapic == &apic_default)
  64                if (apic_bigsmp.probe()) {
  65                        genapic = &apic_bigsmp;
  66                        printk(KERN_INFO "Overriding APIC driver with %s\n",
  67                               genapic->name);
  68                }
  69}
  70
  71void __init generic_apic_probe(void)
  72{ 
  73        if (!cmdline_apic) {
  74                int i;
  75                for (i = 0; apic_probe[i]; i++) {
  76                        if (apic_probe[i]->probe()) {
  77                                genapic = apic_probe[i];
  78                                break;
  79                        }
  80                }
  81                /* Not visible without early console */
  82                if (!apic_probe[i])
  83                        panic("Didn't find an APIC driver");
  84        }
  85        printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
  86} 
  87
  88/* These functions can switch the APIC even after the initial ->probe() */
  89
  90int __init mps_oem_check(struct mp_config_table *mpc, char *oem, char *productid)
  91{ 
  92        int i;
  93        for (i = 0; apic_probe[i]; ++i) { 
  94                if (apic_probe[i]->mps_oem_check(mpc,oem,productid)) { 
  95                        if (!cmdline_apic) {
  96                                genapic = apic_probe[i];
  97                                printk(KERN_INFO "Switched to APIC driver `%s'.\n",
  98                                       genapic->name);
  99                        }
 100                        return 1;
 101                } 
 102        } 
 103        return 0;
 104} 
 105
 106int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 107{
 108        int i;
 109        for (i = 0; apic_probe[i]; ++i) { 
 110                if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) { 
 111                        if (!cmdline_apic) {
 112                                genapic = apic_probe[i];
 113                                printk(KERN_INFO "Switched to APIC driver `%s'.\n",
 114                                       genapic->name);
 115                        }
 116                        return 1;
 117                } 
 118        } 
 119        return 0;       
 120}
 121
 122int hard_smp_processor_id(void)
 123{
 124        return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID));
 125}
 126
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.