Commit 09a0a191 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[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.
parent b015de48
...@@ -85,10 +85,10 @@ unsigned int openpic_vec_spurious; ...@@ -85,10 +85,10 @@ unsigned int openpic_vec_spurious;
*/ */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
#define THIS_CPU Processor[cpu] #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) #define CHECK_THIS_CPU check_arg_cpu(cpu)
#else #else
#define THIS_CPU Processor[smp_processor_id()] #define THIS_CPU Processor[hard_smp_processor_id()]
#define DECL_THIS_CPU #define DECL_THIS_CPU
#define CHECK_THIS_CPU #define CHECK_THIS_CPU
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
...@@ -355,7 +355,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -355,7 +355,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
/* SIOint (8259 cascade) is special */ /* SIOint (8259 cascade) is special */
if (offset) { if (offset) {
openpic_initirq(0, 8, offset, 1, 1); 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 */ /* Init all external sources */
...@@ -373,7 +373,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, ...@@ -373,7 +373,7 @@ void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack,
/* Enabled, Priority 8 or 9 */ /* Enabled, Priority 8 or 9 */
openpic_initirq(i, pri, i+offset, !sense, sense); openpic_initirq(i, pri, i+offset, !sense, sense);
/* Processor 0 */ /* Processor 0 */
openpic_mapirq(i, 1 << boot_cpuid); openpic_mapirq(i, 1 << get_hard_smp_processor_id(boot_cpuid));
} }
/* Init descriptors */ /* Init descriptors */
...@@ -514,10 +514,23 @@ static void openpic_set_spurious(u_int vec) ...@@ -514,10 +514,23 @@ static void openpic_set_spurious(u_int vec)
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) void openpic_init_processor(u_int cpumask)
{ {
openpic_write(&OpenPIC->Global.Processor_Initialization, openpic_write(&OpenPIC->Global.Processor_Initialization,
cpumask & cpus_coerce(cpu_online_map)); physmask(cpumask & cpus_coerce(cpu_online_map)));
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -551,7 +564,7 @@ void openpic_cause_IPI(u_int ipi, u_int cpumask) ...@@ -551,7 +564,7 @@ void openpic_cause_IPI(u_int ipi, u_int cpumask)
CHECK_THIS_CPU; CHECK_THIS_CPU;
check_arg_ipi(ipi); check_arg_ipi(ipi);
openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(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) void openpic_request_IPIs(void)
...@@ -592,7 +605,7 @@ void __devinit do_openpic_setup_cpu(void) ...@@ -592,7 +605,7 @@ void __devinit do_openpic_setup_cpu(void)
{ {
#ifdef CONFIG_IRQ_ALL_CPUS #ifdef CONFIG_IRQ_ALL_CPUS
int i; int i;
u32 msk = 1 << smp_processor_id(); u32 msk = 1 << hard_smp_processor_id();
#endif #endif
spin_lock(&openpic_setup_lock); spin_lock(&openpic_setup_lock);
...@@ -637,7 +650,7 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask) ...@@ -637,7 +650,7 @@ static void __init openpic_maptimer(u_int timer, u_int cpumask)
{ {
check_arg_timer(timer); check_arg_timer(timer);
openpic_write(&OpenPIC->Global.Timer[timer].Destination, 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) ...@@ -763,7 +776,7 @@ static void openpic_set_affinity(unsigned int irq_nr, cpumask_t cpumask)
cpumask_t tmp; cpumask_t tmp;
cpus_and(tmp, cpumask, cpu_online_map); 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 #ifdef CONFIG_SMP
......
...@@ -149,6 +149,7 @@ char *bootpath = 0; ...@@ -149,6 +149,7 @@ char *bootpath = 0;
char *bootdevice = 0; char *bootdevice = 0;
int boot_cpuid = 0; int boot_cpuid = 0;
#define MAX_CPU_THREADS 2
struct device_node *allnodes = 0; struct device_node *allnodes = 0;
/* use when traversing tree through the allnext, child, sibling, /* use when traversing tree through the allnext, child, sibling,
...@@ -898,16 +899,21 @@ static void ...@@ -898,16 +899,21 @@ static void
prom_hold_cpus(unsigned long mem) prom_hold_cpus(unsigned long mem)
{ {
unsigned long i; unsigned long i;
unsigned int cpuid; unsigned int reg;
phandle node; phandle node;
unsigned long offset = reloc_offset(); unsigned long offset = reloc_offset();
char type[64], *path; 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 void __secondary_hold(void);
extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_spinloop;
extern unsigned long __secondary_hold_acknowledge; extern unsigned long __secondary_hold_acknowledge;
unsigned long *spinloop = __v2a(&__secondary_hold_spinloop); unsigned long *spinloop = __v2a(&__secondary_hold_spinloop);
unsigned long *acknowledge = __v2a(&__secondary_hold_acknowledge); unsigned long *acknowledge = __v2a(&__secondary_hold_acknowledge);
unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold)); unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold));
struct naca_struct *_naca = RELOC(naca);
struct systemcfg *_systemcfg = RELOC(systemcfg); struct systemcfg *_systemcfg = RELOC(systemcfg);
struct paca_struct *_xPaca = PTRRELOC(&paca[0]); struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
struct prom_t *_prom = PTRRELOC(&prom); struct prom_t *_prom = PTRRELOC(&prom);
...@@ -960,13 +966,9 @@ prom_hold_cpus(unsigned long mem) ...@@ -960,13 +966,9 @@ prom_hold_cpus(unsigned long mem)
if (strcmp(type, RELOC("okay")) != 0) if (strcmp(type, RELOC("okay")) != 0)
continue; continue;
cpuid = -1; reg = -1;
call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"),
&cpuid, sizeof(cpuid)); &reg, sizeof(reg));
/* Only need to start secondary procs, not ourself. */
if ( cpuid == _prom->cpu )
continue;
path = (char *) mem; path = (char *) mem;
memset(path, 0, 256); memset(path, 0, 256);
...@@ -976,12 +978,14 @@ prom_hold_cpus(unsigned long mem) ...@@ -976,12 +978,14 @@ prom_hold_cpus(unsigned long mem)
#ifdef DEBUG_PROM #ifdef DEBUG_PROM
prom_print_nl(); prom_print_nl();
prom_print(RELOC("cpu hw idx = 0x")); prom_print(RELOC("cpuid = 0x"));
prom_print_hex(cpuid); prom_print_hex(cpuid);
prom_print_nl(); prom_print_nl();
prom_print(RELOC("cpu hw idx = 0x"));
prom_print_hex(reg);
prom_print_nl();
#endif #endif
prom_print(RELOC("starting cpu ")); _xPaca[cpuid].xHwProcNum = reg;
prom_print(path);
/* Init the acknowledge var which will be reset by /* Init the acknowledge var which will be reset by
* the secondary cpu when it awakens from its OF * the secondary cpu when it awakens from its OF
...@@ -989,45 +993,80 @@ prom_hold_cpus(unsigned long mem) ...@@ -989,45 +993,80 @@ prom_hold_cpus(unsigned long mem)
*/ */
*acknowledge = (unsigned long)-1; *acknowledge = (unsigned long)-1;
#ifdef DEBUG_PROM propsize = call_prom(RELOC("getprop"), 4, 1, node,
prom_print(RELOC(" 3) spinloop = 0x")); RELOC("ibm,ppc-interrupt-server#s"),
prom_print_hex(spinloop); &interrupt_server,
prom_print_nl(); sizeof(interrupt_server));
prom_print(RELOC(" 3) *spinloop = 0x")); if (propsize < 0) {
prom_print_hex(*spinloop); /* no property. old hardware has no SMT */
prom_print_nl(); cpu_threads = 1;
prom_print(RELOC(" 3) acknowledge = 0x")); interrupt_server[0] = reg; /* fake it with phys id */
prom_print_hex(acknowledge); } else {
prom_print_nl(); /* We have a threaded processor */
prom_print(RELOC(" 3) *acknowledge = 0x")); cpu_threads = propsize / sizeof(u32);
prom_print_hex(*acknowledge); if (cpu_threads > MAX_CPU_THREADS) {
prom_print_nl(); prom_print(RELOC("SMT: too many threads!\nSMT: found "));
prom_print(RELOC(" 3) secondary_hold = 0x")); prom_print_hex(cpu_threads);
prom_print_hex(secondary_hold); prom_print(RELOC(", max is "));
prom_print_hex(MAX_CPU_THREADS);
prom_print_nl(); prom_print_nl();
#endif cpu_threads = 1; /* ToDo: panic? */
call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid); }
}
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("...")); prom_print(RELOC("..."));
call_prom(RELOC("start-cpu"), 3, 0, node,
secondary_hold, cpuid);
for ( i = 0 ; (i < 100000000) && for ( i = 0 ; (i < 100000000) &&
(*acknowledge == ((unsigned long)-1)); i++ ) ; (*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) { if (*acknowledge == cpuid) {
prom_print(RELOC("ok\n")); prom_print(RELOC("ok\n"));
/* Set the number of active processors. */ /* Set the number of active processors. */
_systemcfg->processorCount++; _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 { } else {
prom_print(RELOC("failed: ")); prom_print(RELOC("failed: "));
prom_print_hex(*acknowledge); prom_print_hex(*acknowledge);
prom_print_nl(); 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 #ifdef CONFIG_HMT
/* Only enable HMT on processors that provide support. */ /* Only enable HMT on processors that provide support. */
...@@ -1037,10 +1076,10 @@ prom_hold_cpus(unsigned long mem) ...@@ -1037,10 +1076,10 @@ prom_hold_cpus(unsigned long mem)
prom_print(RELOC(" starting secondary threads\n")); prom_print(RELOC(" starting secondary threads\n"));
for (i = 0; i < NR_CPUS; i += 2) { for (i = 0; i < NR_CPUS; i += 2) {
if (!_xPaca[i].active) if (!cpu_online(i))
continue; continue;
if (i == boot_cpuid) { if (i == 0) {
unsigned long pir = _get_PIR(); unsigned long pir = _get_PIR();
if (__is_processor(PV_PULSAR)) { if (__is_processor(PV_PULSAR)) {
RELOC(hmt_thread_data)[i].pir = RELOC(hmt_thread_data)[i].pir =
...@@ -1050,7 +1089,8 @@ prom_hold_cpus(unsigned long mem) ...@@ -1050,7 +1089,8 @@ prom_hold_cpus(unsigned long mem)
pir & 0x3ff; 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; _systemcfg->processorCount *= 2;
} else { } else {
...@@ -1063,6 +1103,105 @@ prom_hold_cpus(unsigned long mem) ...@@ -1063,6 +1103,105 @@ prom_hold_cpus(unsigned long mem)
#endif #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 * 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, ...@@ -1145,11 +1284,9 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
cpu_pkg, RELOC("reg"), cpu_pkg, RELOC("reg"),
&getprop_rval, sizeof(getprop_rval)); &getprop_rval, sizeof(getprop_rval));
_prom->cpu = (int)(unsigned long)getprop_rval; _prom->cpu = (int)(unsigned long)getprop_rval;
_xPaca[_prom->cpu].active = 1; _xPaca[0].xHwProcNum = _prom->cpu;
#ifdef CONFIG_SMP
cpu_set(_prom->cpu, RELOC(cpu_online_map)); RELOC(boot_cpuid) = 0;
#endif
RELOC(boot_cpuid) = _prom->cpu;
#ifdef DEBUG_PROM #ifdef DEBUG_PROM
prom_print(RELOC("Booting CPU hw index = 0x")); prom_print(RELOC("Booting CPU hw index = 0x"));
...@@ -1183,11 +1320,12 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, ...@@ -1183,11 +1320,12 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
/* Initialize some system info into the Naca early... */ /* Initialize some system info into the Naca early... */
mem = prom_initialize_naca(mem); mem = prom_initialize_naca(mem);
smt_setup();
/* If we are on an SMP machine, then we *MUST* do the /* If we are on an SMP machine, then we *MUST* do the
* following, regardless of whether we have an SMP * following, regardless of whether we have an SMP
* kernel or not. * kernel or not.
*/ */
if (_systemcfg->processorCount > 1)
prom_hold_cpus(mem); prom_hold_cpus(mem);
#ifdef DEBUG_PROM #ifdef DEBUG_PROM
......
...@@ -58,6 +58,8 @@ extern void iSeries_init_early( void ); ...@@ -58,6 +58,8 @@ extern void iSeries_init_early( void );
extern void pSeries_init_early( void ); extern void pSeries_init_early( void );
extern void pSeriesLP_init_early(void); extern void pSeriesLP_init_early(void);
extern void mm_init_ppc64( 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); extern void vpa_init(int cpu);
unsigned long decr_overclock = 1; unsigned long decr_overclock = 1;
...@@ -144,6 +146,8 @@ void __init disable_early_printk(void) ...@@ -144,6 +146,8 @@ void __init disable_early_printk(void)
void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7) unsigned long r6, unsigned long r7)
{ {
unsigned int ret, i;
#ifdef CONFIG_XMON_DEFAULT #ifdef CONFIG_XMON_DEFAULT
debugger = xmon; debugger = xmon;
debugger_bpt = xmon_bpt; debugger_bpt = xmon_bpt;
...@@ -187,6 +191,21 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -187,6 +191,21 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
if (systemcfg->platform & PLATFORM_PSERIES) { if (systemcfg->platform & PLATFORM_PSERIES) {
early_console_initialized = 1; early_console_initialized = 1;
register_console(&udbg_console); 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); printk("Starting Linux PPC64 %s\n", UTS_RELEASE);
...@@ -205,11 +224,6 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, ...@@ -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("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs);
printk("-----------------------------------------------------\n"); printk("-----------------------------------------------------\n");
if (systemcfg->platform & PLATFORM_PSERIES) {
finish_device_tree();
chrp_init(r3, r4, r5, r6, r7);
}
mm_init_ppc64(); mm_init_ppc64();
if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
......
...@@ -53,8 +53,11 @@ ...@@ -53,8 +53,11 @@
int smp_threads_ready; int smp_threads_ready;
unsigned long cache_decay_ticks; 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_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); EXPORT_SYMBOL(cpu_online_map);
...@@ -67,6 +70,8 @@ extern unsigned char stab_array[]; ...@@ -67,6 +70,8 @@ extern unsigned char stab_array[];
extern int cpu_idle(void *unused); extern int cpu_idle(void *unused);
void smp_call_function_interrupt(void); void smp_call_function_interrupt(void);
void smp_message_pass(int target, int msg, unsigned long data, int wait); 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)) #define smp_message_pass(t,m,d,w) smp_ops->message_pass((t),(m),(d),(w))
......
...@@ -202,7 +202,7 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value) ...@@ -202,7 +202,7 @@ static void pSeriesLP_qirr_info(int n_cpu , u8 value)
{ {
unsigned long lpar_rc; 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) if (lpar_rc != H_Success)
panic("bad return code qirr - rc = %lx\n", lpar_rc); panic("bad return code qirr - rc = %lx\n", lpar_rc);
} }
...@@ -441,7 +441,7 @@ void xics_init_IRQ(void) ...@@ -441,7 +441,7 @@ void xics_init_IRQ(void)
np; np;
np = of_find_node_by_type(np, "cpu")) { np = of_find_node_by_type(np, "cpu")) {
ireg = (uint *)get_property(np, "reg", &ilen); 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); ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
i = ilen / sizeof(int); i = ilen / sizeof(int);
if (ireg && i > 0) { if (ireg && i > 0) {
...@@ -478,8 +478,8 @@ void xics_init_IRQ(void) ...@@ -478,8 +478,8 @@ void xics_init_IRQ(void)
for (i = 0; i < NR_CPUS; ++i) { for (i = 0; i < NR_CPUS; ++i) {
if (!cpu_possible(i)) if (!cpu_possible(i))
continue; continue;
xics_per_cpu[i] = __ioremap((ulong)inodes[i].addr, xics_per_cpu[i] = __ioremap((ulong)inodes[get_hard_smp_processor_id(i)].addr,
(ulong)inodes[i].size, (ulong)inodes[get_hard_smp_processor_id(i)].size,
_PAGE_NO_CACHE); _PAGE_NO_CACHE);
} }
#else #else
...@@ -570,7 +570,7 @@ void xics_set_affinity(unsigned int virq, cpumask_t cpumask) ...@@ -570,7 +570,7 @@ void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
cpus_and(tmp, cpu_online_map, cpumask); cpus_and(tmp, cpu_online_map, cpumask);
if (cpus_empty(tmp)) if (cpus_empty(tmp))
goto out; goto out;
newmask = first_cpu(cpumask); newmask = get_hard_smp_processor_id(first_cpu(cpumask));
} }
status = rtas_call(ibm_set_xive, 3, 1, NULL, status = rtas_call(ibm_set_xive, 3, 1, NULL,
......
...@@ -61,7 +61,7 @@ struct paca_struct { ...@@ -61,7 +61,7 @@ struct paca_struct {
struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC 0x08 */ struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC 0x08 */
u64 xCurrent; /* Pointer to current 0x10 */ u64 xCurrent; /* Pointer to current 0x10 */
u16 xPacaIndex; /* Logical processor number 0x18 */ 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 */ u32 default_decr; /* Default decrementer value 0x1c */
u64 unused1; u64 unused1;
u64 xKsave; /* Saved Kernel stack addr or zero 0x28 */ u64 xKsave; /* Saved Kernel stack addr or zero 0x28 */
......
...@@ -371,6 +371,7 @@ ...@@ -371,6 +371,7 @@
#define PV_ICESTAR 0x0036 #define PV_ICESTAR 0x0036
#define PV_SSTAR 0x0037 #define PV_SSTAR 0x0037
#define PV_POWER4p 0x0038 #define PV_POWER4p 0x0038
#define PV_POWER5 0x003A
#define PV_630 0x0040 #define PV_630 0x0040
#define PV_630p 0x0041 #define PV_630p 0x0041
......
...@@ -34,9 +34,28 @@ extern void smp_send_xmon_break(int cpu); ...@@ -34,9 +34,28 @@ extern void smp_send_xmon_break(int cpu);
struct pt_regs; struct pt_regs;
extern void smp_message_recv(int, 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 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. /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
* *
...@@ -52,5 +71,7 @@ void smp_init_pSeries(void); ...@@ -52,5 +71,7 @@ void smp_init_pSeries(void);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* !(CONFIG_SMP) */ #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 /* !(_PPC64_SMP_H) */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment