vserver 2.0 rc7
[linux-2.6.git] / arch / ia64 / kernel / setup.c
index 29684bf..d14692e 100644 (file)
@@ -4,10 +4,15 @@
  * Copyright (C) 1998-2001, 2003-2004 Hewlett-Packard Co
  *     David Mosberger-Tang <davidm@hpl.hp.com>
  *     Stephane Eranian <eranian@hpl.hp.com>
- * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
+ * Copyright (C) 2000, 2004 Intel Corp
+ *     Rohit Seth <rohit.seth@intel.com>
+ *     Suresh Siddha <suresh.b.siddha@intel.com>
+ *     Gordon Jin <gordon.jin@intel.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  *
+ * 12/26/04 S.Siddha, G.Jin, R.Seth
+ *                     Add multi-threading and multi-core detection
  * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo().
  * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map
  * 03/31/00 R.Seth     cpu_initialized and current->processor fixes
@@ -75,8 +80,6 @@ struct io_space io_space[MAX_IO_SPACES];
 EXPORT_SYMBOL(io_space);
 unsigned int num_io_spaces;
 
-unsigned char aux_device_present = 0xaa;        /* XXX remove this when legacy I/O is gone */
-
 /*
  * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
  * mask specifies a mask of address bits that must be 0 in order for two buffers to be
@@ -298,6 +301,34 @@ mark_bsp_online (void)
 #endif
 }
 
+#ifdef CONFIG_SMP
+static void
+check_for_logical_procs (void)
+{
+       pal_logical_to_physical_t info;
+       s64 status;
+
+       status = ia64_pal_logical_to_phys(0, &info);
+       if (status == -1) {
+               printk(KERN_INFO "No logical to physical processor mapping "
+                      "available\n");
+               return;
+       }
+       if (status) {
+               printk(KERN_ERR "ia64_pal_logical_to_phys failed with %ld\n",
+                      status);
+               return;
+       }
+       /*
+        * Total number of siblings that BSP has.  Though not all of them 
+        * may have booted successfully. The correct number of siblings 
+        * booted is in info.overview_num_log.
+        */
+       smp_num_siblings = info.overview_tpc;
+       smp_num_cpucores = info.overview_cpp;
+}
+#endif
+
 void __init
 setup_arch (char **cmdline_p)
 {
@@ -358,6 +389,19 @@ setup_arch (char **cmdline_p)
 
 #ifdef CONFIG_SMP
        cpu_physical_id(0) = hard_smp_processor_id();
+
+       cpu_set(0, cpu_sibling_map[0]);
+       cpu_set(0, cpu_core_map[0]);
+
+       check_for_logical_procs();
+       if (smp_num_cpucores > 1)
+               printk(KERN_INFO
+                      "cpu package is Multi-Core capable: number of cores=%d\n",
+                      smp_num_cpucores);
+       if (smp_num_siblings > 1)
+               printk(KERN_INFO
+                      "cpu package is Multi-Threading capable: number of siblings=%d\n",
+                      smp_num_siblings);
 #endif
 
        cpu_init();     /* initialize the bootstrap CPU */
@@ -461,12 +505,23 @@ show_cpuinfo (struct seq_file *m, void *v)
                   "cpu regs   : %u\n"
                   "cpu MHz    : %lu.%06lu\n"
                   "itc MHz    : %lu.%06lu\n"
-                  "BogoMIPS   : %lu.%02lu\n\n",
+                  "BogoMIPS   : %lu.%02lu\n",
                   cpunum, c->vendor, family, c->model, c->revision, c->archrev,
                   features, c->ppn, c->number,
                   c->proc_freq / 1000000, c->proc_freq % 1000000,
                   c->itc_freq / 1000000, c->itc_freq % 1000000,
                   lpj*HZ/500000, (lpj*HZ/5000) % 100);
+#ifdef CONFIG_SMP
+       seq_printf(m, "siblings   : %u\n", c->num_log);
+       if (c->threads_per_core > 1 || c->cores_per_socket > 1)
+               seq_printf(m,
+                          "physical id: %u\n"
+                          "core id    : %u\n"
+                          "thread id  : %u\n",
+                          c->socket_id, c->core_id, c->thread_id);
+#endif
+       seq_printf(m,"\n");
+
        return 0;
 }
 
@@ -535,6 +590,14 @@ identify_cpu (struct cpuinfo_ia64 *c)
        memcpy(c->vendor, cpuid.field.vendor, 16);
 #ifdef CONFIG_SMP
        c->cpu = smp_processor_id();
+
+       /* below default values will be overwritten  by identify_siblings() 
+        * for Multi-Threading/Multi-Core capable cpu's
+        */
+       c->threads_per_core = c->cores_per_socket = c->num_log = 1;
+       c->socket_id = -1;
+
+       identify_siblings(c);
 #endif
        c->ppn = cpuid.field.ppn;
        c->number = cpuid.field.number;
@@ -648,7 +711,17 @@ cpu_init (void)
        ia64_set_kr(IA64_KR_FPU_OWNER, 0);
 
        /*
-        * Initialize default control register to defer all speculative faults.  The
+        * Initialize the page-table base register to a global
+        * directory with all zeroes.  This ensure that we can handle
+        * TLB-misses to user address-space even before we created the
+        * first user address-space.  This may happen, e.g., due to
+        * aggressive use of lfetch.fault.
+        */
+       ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page)));
+
+       /*
+        * Initialize default control register to defer speculative faults except
+        * for those arising from TLB misses, which are not deferred.  The
         * kernel MUST NOT depend on a particular setting of these bits (in other words,
         * the kernel must have recovery code for all speculative accesses).  Turn on
         * dcr.lc as per recommendation by the architecture team.  Most IA-32 apps