]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ppc64: SMT processor support and logical cpu numbering, from Dave Engebretsen
authorAndrew Morton <akpm@osdl.org>
Mon, 19 Jan 2004 02:18:04 +0000 (18:18 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 19 Jan 2004 02:18:04 +0000 (18:18 -0800)
From: Anton Blanchard <anton@samba.org>

And SMT processor support & move back to a logical cpu numbering
in support of DLPAR work.

arch/ppc64/kernel/open_pic.c
arch/ppc64/kernel/prom.c
arch/ppc64/kernel/setup.c
arch/ppc64/kernel/smp.c
arch/ppc64/kernel/xics.c
include/asm-ppc64/paca.h
include/asm-ppc64/processor.h
include/asm-ppc64/smp.h

index 0480e67352c984f3e64d0489d0a0102773300423..d93e71b88356afead133543a91da4fd78073a1aa 100644 (file)
@@ -85,10 +85,10 @@ unsigned int openpic_vec_spurious;
  */
 #ifdef CONFIG_SMP
 #define THIS_CPU               Processor[cpu]
-#define DECL_THIS_CPU          int cpu = smp_processor_id()
+#define DECL_THIS_CPU          int cpu = hard_smp_processor_id()
 #define CHECK_THIS_CPU         check_arg_cpu(cpu)
 #else
-#define THIS_CPU               Processor[smp_processor_id()]
+#define THIS_CPU               Processor[hard_smp_processor_id()]
 #define DECL_THIS_CPU
 #define CHECK_THIS_CPU
 #endif /* CONFIG_SMP */
@@ -355,7 +355,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
        /* SIOint (8259 cascade) is special */
        if (offset) {
                openpic_initirq(0, 8, offset, 1, 1);
-               openpic_mapirq(0, 1 << boot_cpuid);
+               openpic_mapirq(0, 1 << get_hard_smp_processor_id(boot_cpuid));
        }
 
        /* Init all external sources */
@@ -373,7 +373,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
                /* Enabled, Priority 8 or 9 */
                openpic_initirq(i, pri, i+offset, !sense, sense);
                /* Processor 0 */
-               openpic_mapirq(i, 1 << boot_cpuid);
+               openpic_mapirq(i, 1 << get_hard_smp_processor_id(boot_cpuid));
        }
 
        /* Init descriptors */
@@ -514,10 +514,23 @@ static void openpic_set_spurious(u_int vec)
                           vec);
 }
 
+/*
+ * Convert a cpu mask from logical to physical cpu numbers.
+ */
+static inline u32 physmask(u32 cpumask)
+{
+       int i;
+       u32 mask = 0;
+
+       for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
+               mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
+       return mask;
+}
+
 void openpic_init_processor(u_int cpumask)
 {
        openpic_write(&OpenPIC->Global.Processor_Initialization,
-                     cpumask & cpus_coerce(cpu_online_map));
+                     physmask(cpumask & cpus_coerce(cpu_online_map)));
 }
 
 #ifdef CONFIG_SMP
@@ -551,7 +564,7 @@ void openpic_cause_IPI(u_int ipi, u_int cpumask)
        CHECK_THIS_CPU;
        check_arg_ipi(ipi);
        openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
-                     cpumask & cpus_coerce(cpu_online_map));
+                     physmask(cpumask & cpus_coerce(cpu_online_map)));
 }
 
 void openpic_request_IPIs(void)
@@ -592,7 +605,7 @@ void __devinit do_openpic_setup_cpu(void)
 {
 #ifdef CONFIG_IRQ_ALL_CPUS
        int i;
-       u32 msk = 1 << smp_processor_id();
+       u32 msk = 1 << hard_smp_processor_id();
 #endif
 
        spin_lock(&openpic_setup_lock);
@@ -637,7 +650,7 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask)
 {
        check_arg_timer(timer);
        openpic_write(&OpenPIC->Global.Timer[timer].Destination,
-                     cpumask & cpus_coerce(cpu_online_map));
+                     physmask(cpumask & cpus_coerce(cpu_online_map)));
 }
 
 
@@ -763,7 +776,7 @@ static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask)
        cpumask_t tmp;
 
        cpus_and(tmp, cpumask, cpu_online_map);
-       openpic_mapirq(irq_nr - open_pic_irq_offset, cpus_coerce(tmp));
+       openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_coerce(tmp)));
 }
 
 #ifdef CONFIG_SMP
index 0d6d237b66d2ab33805d59bdbe88df087a82ddc0..0b368a00168a16c46c87e3623ca24e660c9bfbc9 100644 (file)
@@ -149,6 +149,7 @@ char *bootpath = 0;
 char *bootdevice = 0;
 
 int boot_cpuid = 0;
+#define MAX_CPU_THREADS 2
 
 struct device_node *allnodes = 0;
 /* use when traversing tree through the allnext, child, sibling,
@@ -898,16 +899,21 @@ static void
 prom_hold_cpus(unsigned long mem)
 {
        unsigned long i;
-       unsigned int cpuid;
+       unsigned int reg;
        phandle node;
        unsigned long offset = reloc_offset();
        char type[64], *path;
+       int cpuid = 0;
+       unsigned int interrupt_server[MAX_CPU_THREADS];
+       unsigned int cpu_threads, hw_cpu_num;
+       int propsize;
        extern void __secondary_hold(void);
         extern unsigned long __secondary_hold_spinloop;
         extern unsigned long __secondary_hold_acknowledge;
         unsigned long *spinloop     = __v2a(&__secondary_hold_spinloop);
         unsigned long *acknowledge  = __v2a(&__secondary_hold_acknowledge);
         unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
+        struct naca_struct *_naca = RELOC(naca);
         struct systemcfg *_systemcfg = RELOC(systemcfg);
        struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
        struct prom_t *_prom = PTRRELOC(&prom);
@@ -960,13 +966,9 @@ prom_hold_cpus(unsigned long mem)
                if (strcmp(type, RELOC("okay")) != 0)
                        continue;
 
-                cpuid = -1;
+                reg = -1;
                call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
-                         &cpuid, sizeof(cpuid));
-
-               /* Only need to start secondary procs, not ourself. */
-               if ( cpuid == _prom->cpu )
-                       continue;
+                         &reg, sizeof(reg));
 
                path = (char *) mem;
                memset(path, 0, 256);
@@ -976,12 +978,14 @@ prom_hold_cpus(unsigned long mem)
 
 #ifdef DEBUG_PROM
                prom_print_nl();
-               prom_print(RELOC("cpu hw idx   = 0x"));
+               prom_print(RELOC("cpuid        = 0x"));
                prom_print_hex(cpuid);
                prom_print_nl();
+               prom_print(RELOC("cpu hw idx   = 0x"));
+               prom_print_hex(reg);
+               prom_print_nl();
 #endif
-               prom_print(RELOC("starting cpu "));
-               prom_print(path);
+               _xPaca[cpuid].xHwProcNum = reg;
 
                /* Init the acknowledge var which will be reset by
                 * the secondary cpu when it awakens from its OF
@@ -989,45 +993,80 @@ prom_hold_cpus(unsigned long mem)
                 */
                *acknowledge = (unsigned long)-1;
 
-#ifdef DEBUG_PROM
-               prom_print(RELOC("    3) spinloop       = 0x"));
-               prom_print_hex(spinloop);
-               prom_print_nl();
-               prom_print(RELOC("    3) *spinloop      = 0x"));
-               prom_print_hex(*spinloop);
-               prom_print_nl();
-               prom_print(RELOC("    3) acknowledge    = 0x"));
-               prom_print_hex(acknowledge);
-               prom_print_nl();
-               prom_print(RELOC("    3) *acknowledge   = 0x"));
-               prom_print_hex(*acknowledge);
-               prom_print_nl();
-               prom_print(RELOC("    3) secondary_hold = 0x"));
-               prom_print_hex(secondary_hold);
+               propsize = call_prom(RELOC("getprop"), 4, 1, node,
+                                    RELOC("ibm,ppc-interrupt-server#s"), 
+                                    &interrupt_server, 
+                                    sizeof(interrupt_server));
+               if (propsize < 0) {
+                       /* no property.  old hardware has no SMT */
+                       cpu_threads = 1;
+                       interrupt_server[0] = reg; /* fake it with phys id */
+               } else {
+                       /* We have a threaded processor */
+                       cpu_threads = propsize / sizeof(u32);
+                       if (cpu_threads > MAX_CPU_THREADS) {
+                               prom_print(RELOC("SMT: too many threads!\nSMT: found "));
+                               prom_print_hex(cpu_threads);
+                               prom_print(RELOC(", max is "));
+                               prom_print_hex(MAX_CPU_THREADS);
                prom_print_nl();
-#endif
-               call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid);
+                               cpu_threads = 1; /* ToDo: panic? */
+                       }
+               }
+
+               hw_cpu_num = interrupt_server[0];
+               if (hw_cpu_num != _prom->cpu) {
+                       /* Primary Thread of non-boot cpu */
+                       prom_print_hex(cpuid);
+                       prom_print(RELOC(" : starting cpu "));
+                       prom_print(path);
                prom_print(RELOC("..."));
+                       call_prom(RELOC("start-cpu"), 3, 0, node, 
+                                 secondary_hold, cpuid);
+
                for ( i = 0 ; (i < 100000000) && 
                              (*acknowledge == ((unsigned long)-1)); i++ ) ;
-#ifdef DEBUG_PROM
-               {
-                       unsigned long *p = 0x0;
-                       prom_print(RELOC("    4) 0x0 = 0x"));
-                       prom_print_hex(*p);
-                       prom_print_nl();
-               }
-#endif
+
                if (*acknowledge == cpuid) {
                        prom_print(RELOC("ok\n"));
                        /* Set the number of active processors. */
                        _systemcfg->processorCount++;
-                       _xPaca[cpuid].active = 1;
+                               cpu_set(cpuid, RELOC(cpu_available_map));
+                               cpu_set(cpuid, RELOC(cpu_possible_map));
+                               cpu_set(cpuid, RELOC(cpu_present_at_boot));
                } else {
                        prom_print(RELOC("failed: "));
                        prom_print_hex(*acknowledge);
                        prom_print_nl();
+                               /* prom_panic(RELOC("cpu failed to start")); */
                }
+               } else {
+                       prom_print_hex(cpuid);
+                       prom_print(RELOC(" : booting  cpu "));
+                       prom_print(path);
+                       prom_print_nl();
+                       cpu_set(cpuid, RELOC(cpu_available_map));
+                       cpu_set(cpuid, RELOC(cpu_possible_map));
+                       cpu_set(cpuid, RELOC(cpu_online_map));
+                       cpu_set(cpuid, RELOC(cpu_present_at_boot));
+               }
+
+               /* Init paca for secondary threads.   They start later. */
+               for (i=1; i < cpu_threads; i++) {
+                       cpuid++;
+                       _xPaca[cpuid].xHwProcNum = interrupt_server[i];
+                       prom_print_hex(interrupt_server[i]);
+                       prom_print(RELOC(" : preparing thread ... "));
+                       if (_naca->smt_state) {
+                               cpu_set(cpuid, RELOC(cpu_available_map));
+                               cpu_set(cpuid, RELOC(cpu_present_at_boot));
+                               prom_print(RELOC("available"));
+                       } else {
+                               prom_print(RELOC("not available"));
+                       }
+                       prom_print_nl();
+               }
+               cpuid++;
        }
 #ifdef CONFIG_HMT
        /* Only enable HMT on processors that provide support. */
@@ -1037,10 +1076,10 @@ prom_hold_cpus(unsigned long mem)
                prom_print(RELOC("    starting secondary threads\n"));
 
                for (i = 0; i < NR_CPUS; i += 2) {
-                       if (!_xPaca[i].active)
+                       if (!cpu_online(i))
                                continue;
 
-                       if (i == boot_cpuid) {
+                       if (i == 0) {
                                unsigned long pir = _get_PIR();
                                if (__is_processor(PV_PULSAR)) {
                                        RELOC(hmt_thread_data)[i].pir = 
@@ -1050,7 +1089,8 @@ prom_hold_cpus(unsigned long mem)
                                                pir & 0x3ff;
                                }
                        }
-                       _xPaca[i+1].active = 1;
+/*                     cpu_set(i+1, cpu_online_map); */
+                       cpu_set(i+1, RELOC(cpu_possible_map));
                }
                _systemcfg->processorCount *= 2;
        } else {
@@ -1063,6 +1103,105 @@ prom_hold_cpus(unsigned long mem)
 #endif
 }
 
+static void
+smt_setup(void)
+{
+       char *p, *q;
+       char my_smt_enabled = SMT_DYNAMIC;
+       unsigned long my_smt_snooze_delay; 
+       ihandle prom_options = NULL;
+       char option[9];
+       unsigned long offset = reloc_offset();
+        struct naca_struct *_naca = RELOC(naca);
+       char found = 0;
+
+       if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) {
+               for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) {
+                       q = p + 12;
+                       if (p > RELOC(cmd_line) && p[-1] != ' ')
+                               continue;
+                       found = 1;
+                       if (q[0] == 'o' && q[1] == 'f' && 
+                           q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) {
+                               my_smt_enabled = SMT_OFF;
+                       } else if (q[0]=='o' && q[1] == 'n' && 
+                                  (q[2] == ' ' || q[2] == '\0')) {
+                               my_smt_enabled = SMT_ON;
+                       } else {
+                               my_smt_enabled = SMT_DYNAMIC;
+                       } 
+               }
+       }
+       if (!found) {
+               prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options"));
+               if (prom_options != (ihandle) -1) {
+                       call_prom(RELOC("getprop"), 
+                               4, 1, prom_options,
+                               RELOC("ibm,smt-enabled"), 
+                               option, 
+                               sizeof(option));
+                       if (option[0] != 0) {
+                               found = 1;
+                               if (!strcmp(option, "off"))     
+                                       my_smt_enabled = SMT_OFF;
+                               else if (!strcmp(option, "on")) 
+                                       my_smt_enabled = SMT_ON;
+                               else
+                                       my_smt_enabled = SMT_DYNAMIC;
+                       }
+               }
+       }
+
+       if (!found )
+               my_smt_enabled = SMT_DYNAMIC; /* default to on */
+
+       found = 0;
+       if (my_smt_enabled) {
+               if (strstr(RELOC(cmd_line), RELOC("smt-snooze-delay="))) {
+                       for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-snooze-delay="))) != 0; ) {
+                               q = p + 17;
+                               if (p > RELOC(cmd_line) && p[-1] != ' ')
+                                       continue;
+                               found = 1;
+                               /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */
+                               my_smt_snooze_delay = 0;
+                               while (*q >= '0' && *q <= '9') {
+                                       my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0';
+                                       q++;
+                               }
+                       }
+               }
+
+               if (!found) {
+                       prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options"));
+                       if (prom_options != (ihandle) -1) {
+                               call_prom(RELOC("getprop"), 
+                                       4, 1, prom_options,
+                                       RELOC("ibm,smt-snooze-delay"), 
+                                       option, 
+                                       sizeof(option));
+                               if (option[0] != 0) {
+                                       found = 1;
+                                       /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */
+                                       my_smt_snooze_delay = 0;
+                                       q = option;
+                                       while (*q >= '0' && *q <= '9') {
+                                               my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0';
+                                               q++;
+                                       }
+                               }
+                       }
+               }
+
+               if (!found) {
+                       my_smt_snooze_delay = 30000; /* default value */
+               }
+       } else {
+               my_smt_snooze_delay = 0; /* default value */
+       }
+       _naca->smt_snooze_delay = my_smt_snooze_delay;
+       _naca->smt_state = my_smt_enabled;
+}
 
 /*
  * We enter here early on, when the Open Firmware prom is still
@@ -1145,11 +1284,9 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
                cpu_pkg, RELOC("reg"),
                &getprop_rval, sizeof(getprop_rval));
        _prom->cpu = (int)(unsigned long)getprop_rval;
-       _xPaca[_prom->cpu].active = 1;
-#ifdef CONFIG_SMP
-       cpu_set(_prom->cpu, RELOC(cpu_online_map));
-#endif
-       RELOC(boot_cpuid) = _prom->cpu;
+       _xPaca[0].xHwProcNum = _prom->cpu;
+
+       RELOC(boot_cpuid) = 0;
 
 #ifdef DEBUG_PROM
        prom_print(RELOC("Booting CPU hw index = 0x"));
@@ -1183,11 +1320,12 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
         /* Initialize some system info into the Naca early... */
         mem = prom_initialize_naca(mem);
 
+       smt_setup();
+       
         /* If we are on an SMP machine, then we *MUST* do the
          * following, regardless of whether we have an SMP
          * kernel or not.
          */
-        if (_systemcfg->processorCount > 1)
                prom_hold_cpus(mem);
 
 #ifdef DEBUG_PROM
index 346a6bfec5f816eb889a36f3c7b46dd8803f9417..9f8c5f1f1e402e280a4f7fb55e60451cbac0b252 100644 (file)
@@ -58,6 +58,8 @@ extern void iSeries_init_early( void );
 extern void pSeries_init_early( void );
 extern void pSeriesLP_init_early(void);
 extern void mm_init_ppc64( void ); 
+extern void pseries_secondary_smp_init(unsigned long); 
+extern int  idle_setup(void);
 extern void vpa_init(int cpu);
 
 unsigned long decr_overclock = 1;
@@ -144,6 +146,8 @@ void __init disable_early_printk(void)
 void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
                  unsigned long r6, unsigned long r7)
 {
+        unsigned int ret, i;
+
 #ifdef CONFIG_XMON_DEFAULT
        debugger = xmon;
        debugger_bpt = xmon_bpt;
@@ -187,6 +191,21 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
        if (systemcfg->platform & PLATFORM_PSERIES) {
                early_console_initialized = 1;
                register_console(&udbg_console);
+               finish_device_tree();
+               chrp_init(r3, r4, r5, r6, r7);
+
+               /* Start secondary threads on SMT systems */
+               for (i = 0; i < NR_CPUS; i++) {
+                       if(cpu_available(i)  && !cpu_possible(i)) {
+                               printk("%16.16x : starting thread\n", i);
+                               rtas_call(rtas_token("start-cpu"), 3, 1, 
+                                         (void *)&ret,
+                                         get_hard_smp_processor_id(i), 
+                                         *((unsigned long *)pseries_secondary_smp_init), i);
+                               cpu_set(i, cpu_possible_map);
+                               systemcfg->processorCount++;
+                       }
+               }
        }
 
        printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
@@ -205,11 +224,6 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
        printk("htab_data.num_ptegs           = 0x%lx\n", htab_data.htab_num_ptegs);
        printk("-----------------------------------------------------\n");
 
-       if (systemcfg->platform & PLATFORM_PSERIES) {
-               finish_device_tree();
-               chrp_init(r3, r4, r5, r6, r7);
-       }
-
        mm_init_ppc64();
 
        if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
index ef60b1ccec69fcdf581225a4e30ca835f682c56e..1b7f1ebf88c3c934d011c3ac7f3c2a36aaac6d03 100644 (file)
 int smp_threads_ready;
 unsigned long cache_decay_ticks;
 
-/* initialised so it doesn't end up in bss */
+/* Initialised so it doesn't end up in bss */
+cpumask_t cpu_possible_map    = CPU_MASK_NONE;
 cpumask_t cpu_online_map = CPU_MASK_NONE;
+cpumask_t cpu_available_map   = CPU_MASK_NONE;
+cpumask_t cpu_present_at_boot = CPU_MASK_NONE;
 
 EXPORT_SYMBOL(cpu_online_map);
 
@@ -67,6 +70,8 @@ extern unsigned char stab_array[];
 extern int cpu_idle(void *unused);
 void smp_call_function_interrupt(void);
 void smp_message_pass(int target, int msg, unsigned long data, int wait);
+extern long register_vpa(unsigned long flags, unsigned long proc,
+                        unsigned long vpa);
 
 #define smp_message_pass(t,m,d,w) smp_ops->message_pass((t),(m),(d),(w))
 
index c5e9ad8f3702415461c1cbcd3894b211567628b3..05ca227ace39cb98b78b8819325e2338b40d56a7 100644 (file)
@@ -202,7 +202,7 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value)
 {
        unsigned long lpar_rc;
 
-       lpar_rc = plpar_ipi(n_cpu, value);
+       lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value);
        if (lpar_rc != H_Success)
                panic("bad return code qirr - rc = %lx\n", lpar_rc); 
 }
@@ -441,7 +441,7 @@ nextnode:
             np;
             np = of_find_node_by_type(np, "cpu")) {
                ireg = (uint *)get_property(np, "reg", &ilen);
-               if (ireg && ireg[0] == smp_processor_id()) {
+               if (ireg && ireg[0] == hard_smp_processor_id()) {
                        ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
                        i = ilen / sizeof(int);
                        if (ireg && i > 0) {
@@ -478,8 +478,8 @@ nextnode:
                for (i = 0; i < NR_CPUS; ++i) {
                        if (!cpu_possible(i))
                                continue;
-                       xics_per_cpu[i] = __ioremap((ulong)inodes[i].addr, 
-                                                   (ulong)inodes[i].size,
+                       xics_per_cpu[i] = __ioremap((ulong)inodes[get_hard_smp_processor_id(i)].addr, 
+                                                   (ulong)inodes[get_hard_smp_processor_id(i)].size,
                                                    _PAGE_NO_CACHE);
                }
 #else
@@ -570,7 +570,7 @@ void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
                cpus_and(tmp, cpu_online_map, cpumask);
                if (cpus_empty(tmp))
                        goto out;
-               newmask = first_cpu(cpumask);
+               newmask = get_hard_smp_processor_id(first_cpu(cpumask));
        }
 
        status = rtas_call(ibm_set_xive, 3, 1, NULL,
index 7eb25cffdd3e6ac82e7a4e6f355faea86fcdd3ed..d41818ab9a835c546646e2c94773e6dbbfd0466d 100644 (file)
@@ -61,7 +61,7 @@ struct paca_struct {
        struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC     0x08 */
        u64 xCurrent;                   /* Pointer to current                   0x10 */
        u16 xPacaIndex;                 /* Logical processor number             0x18 */
-       u16 active;                     /* Is this cpu active?                  0x1a */
+        u16 xHwProcNum;                 /* Physical processor number            0x1A */
        u32 default_decr;               /* Default decrementer value            0x1c */ 
        u64 unused1;
        u64 xKsave;                     /* Saved Kernel stack addr or zero      0x28 */
index c5344d5c0f9402235c47373a6de58340783917fa..03cbc221b5553a907c3e1ab741847672d7e9abf3 100644 (file)
 #define        PV_ICESTAR      0x0036
 #define        PV_SSTAR        0x0037
 #define        PV_POWER4p      0x0038
+#define        PV_POWER5       0x003A
 #define        PV_630          0x0040
 #define        PV_630p         0x0041
 
index 467e8cfc42b656142a7b7fd65f34f49d60023e4b..32db8c4751dbe17da2d825510004e45439fa73c9 100644 (file)
@@ -34,9 +34,28 @@ extern void smp_send_xmon_break(int cpu);
 struct pt_regs;
 extern void smp_message_recv(int, struct pt_regs *);
 
-#define cpu_possible(cpu)      paca[cpu].active
 
 #define smp_processor_id() (get_paca()->xPacaIndex)
+#define hard_smp_processor_id() (get_paca()->xHwProcNum)
+
+/*
+ * Retrieve the state of a CPU:
+ * online:          CPU is in a normal run state
+ * possible:        CPU is a candidate to be made online
+ * available:       CPU is candidate for the 'possible' pool
+ *                  Used to get SMT threads started at boot time.
+ * present_at_boot: CPU was available at boot time.  Used in DLPAR
+ *                  code to handle special cases for processor start up.
+ */
+extern cpumask_t cpu_present_at_boot;
+extern cpumask_t cpu_online_map;
+extern cpumask_t cpu_possible_map;
+extern cpumask_t cpu_available_map;
+
+#define cpu_present_at_boot(cpu) cpu_isset(cpu, cpu_present_at_boot)
+#define cpu_online(cpu)          cpu_isset(cpu, cpu_online_map) 
+#define cpu_possible(cpu)        cpu_isset(cpu, cpu_possible_map) 
+#define cpu_available(cpu)       cpu_isset(cpu, cpu_available_map) 
 
 /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
  *
@@ -52,5 +71,7 @@ void smp_init_pSeries(void);
 
 #endif /* __ASSEMBLY__ */
 #endif /* !(CONFIG_SMP) */
+#define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum)
+#define set_hard_smp_processor_id(CPU, VAL) do { (paca[(CPU)].xHwProcNum = VAL); } while (0)
 #endif /* !(_PPC64_SMP_H) */
 #endif /* __KERNEL__ */