summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-01-18 18:18:04 -0800
committerLinus Torvalds <torvalds@home.osdl.org>2004-01-18 18:18:04 -0800
commit09a0a191e17e4c4ee7603ef085ae8d97a1c2e282 (patch)
tree8a117a2ceacfc78fe45129c83ed1c2c30fa96855
parentb015de4810ae2a8824591a9c673fdb5b05591abc (diff)
[PATCH] ppc64: SMT processor support and logical cpu numbering, from Dave Engebretsen
From: Anton Blanchard <anton@samba.org> And SMT processor support & move back to a logical cpu numbering in support of DLPAR work.
-rw-r--r--arch/ppc64/kernel/open_pic.c31
-rw-r--r--arch/ppc64/kernel/prom.c228
-rw-r--r--arch/ppc64/kernel/setup.c24
-rw-r--r--arch/ppc64/kernel/smp.c7
-rw-r--r--arch/ppc64/kernel/xics.c10
-rw-r--r--include/asm-ppc64/paca.h2
-rw-r--r--include/asm-ppc64/processor.h1
-rw-r--r--include/asm-ppc64/smp.h23
8 files changed, 259 insertions, 67 deletions
diff --git a/arch/ppc64/kernel/open_pic.c b/arch/ppc64/kernel/open_pic.c
index 0480e67352c9..d93e71b88356 100644
--- a/arch/ppc64/kernel/open_pic.c
+++ b/arch/ppc64/kernel/open_pic.c
@@ -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
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c
index 0d6d237b66d2..0b368a00168a 100644
--- a/arch/ppc64/kernel/prom.c
+++ b/arch/ppc64/kernel/prom.c
@@ -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
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c
index 346a6bfec5f8..9f8c5f1f1e40 100644
--- a/arch/ppc64/kernel/setup.c
+++ b/arch/ppc64/kernel/setup.c
@@ -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) {
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index ef60b1ccec69..1b7f1ebf88c3 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -53,8 +53,11 @@
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))
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
index c5e9ad8f3702..05ca227ace39 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -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,
diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h
index 7eb25cffdd3e..d41818ab9a83 100644
--- a/include/asm-ppc64/paca.h
+++ b/include/asm-ppc64/paca.h
@@ -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 */
diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h
index c5344d5c0f94..03cbc221b555 100644
--- a/include/asm-ppc64/processor.h
+++ b/include/asm-ppc64/processor.h
@@ -371,6 +371,7 @@
#define PV_ICESTAR 0x0036
#define PV_SSTAR 0x0037
#define PV_POWER4p 0x0038
+#define PV_POWER5 0x003A
#define PV_630 0x0040
#define PV_630p 0x0041
diff --git a/include/asm-ppc64/smp.h b/include/asm-ppc64/smp.h
index 467e8cfc42b6..32db8c4751db 100644
--- a/include/asm-ppc64/smp.h
+++ b/include/asm-ppc64/smp.h
@@ -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__ */