aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c1
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.c53
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.h5
-rw-r--r--include/asm-powerpc/cell-pmu.h5
4 files changed, 45 insertions, 19 deletions
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index e08e1d7b3dc5..fb999e3e9f21 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -37,6 +37,7 @@
37#include <asm/system.h> 37#include <asm/system.h>
38 38
39#include "../platforms/cell/interrupt.h" 39#include "../platforms/cell/interrupt.h"
40#include "../platforms/cell/cbe_regs.h"
40 41
41#define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */ 42#define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */
42#define PPU_CYCLES_GRP_NUM 1 /* special group number for identifying 43#define PPU_CYCLES_GRP_NUM 1 /* special group number for identifying
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
index 7c94af4ac439..dca39c0af7ea 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -38,8 +38,13 @@ static struct cbe_thread_map
38{ 38{
39 struct device_node *cpu_node; 39 struct device_node *cpu_node;
40 struct cbe_regs_map *regs; 40 struct cbe_regs_map *regs;
41 unsigned int thread_id;
42 unsigned int cbe_id;
41} cbe_thread_map[NR_CPUS]; 43} cbe_thread_map[NR_CPUS];
42 44
45static cpumask_t cbe_local_mask[MAX_CBE] = { [0 ... MAX_CBE-1] = CPU_MASK_NONE };
46static cpumask_t cbe_first_online_cpu = CPU_MASK_NONE;
47
43static struct cbe_regs_map *cbe_find_map(struct device_node *np) 48static struct cbe_regs_map *cbe_find_map(struct device_node *np)
44{ 49{
45 int i; 50 int i;
@@ -130,31 +135,40 @@ struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu)
130} 135}
131EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs); 136EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs);
132 137
133/* FIXME
134 * This is little more than a stub at the moment. It should be
135 * fleshed out so that it works for both SMT and non-SMT, no
136 * matter if the passed cpu is odd or even.
137 * For SMT enabled, returns 0 for even-numbered cpu; otherwise 1.
138 * For SMT disabled, returns 0 for all cpus.
139 */
140u32 cbe_get_hw_thread_id(int cpu) 138u32 cbe_get_hw_thread_id(int cpu)
141{ 139{
142 return (cpu & 1); 140 return cbe_thread_map[cpu].thread_id;
143} 141}
144EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id); 142EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id);
145 143
144u32 cbe_cpu_to_node(int cpu)
145{
146 return cbe_thread_map[cpu].cbe_id;
147}
148EXPORT_SYMBOL_GPL(cbe_cpu_to_node);
149
150u32 cbe_node_to_cpu(int node)
151{
152 return find_first_bit( (unsigned long *) &cbe_local_mask[node], sizeof(cpumask_t));
153}
154EXPORT_SYMBOL_GPL(cbe_node_to_cpu);
155
146void __init cbe_regs_init(void) 156void __init cbe_regs_init(void)
147{ 157{
148 int i; 158 int i;
159 unsigned int thread_id;
149 struct device_node *cpu; 160 struct device_node *cpu;
150 161
151 /* Build local fast map of CPUs */ 162 /* Build local fast map of CPUs */
152 for_each_possible_cpu(i) 163 for_each_possible_cpu(i) {
153 cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL); 164 cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id);
165 cbe_thread_map[i].thread_id = thread_id;
166 }
154 167
155 /* Find maps for each device tree CPU */ 168 /* Find maps for each device tree CPU */
156 for_each_node_by_type(cpu, "cpu") { 169 for_each_node_by_type(cpu, "cpu") {
157 struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++]; 170 struct cbe_regs_map *map;
171 unsigned int cbe_id;
158 172
159 /* That hack must die die die ! */ 173 /* That hack must die die die ! */
160 const struct address_prop { 174 const struct address_prop {
@@ -162,6 +176,8 @@ void __init cbe_regs_init(void)
162 unsigned int len; 176 unsigned int len;
163 } __attribute__((packed)) *prop; 177 } __attribute__((packed)) *prop;
164 178
179 cbe_id = cbe_regs_map_count++;
180 map = &cbe_regs_maps[cbe_id];
165 181
166 if (cbe_regs_map_count > MAX_CBE) { 182 if (cbe_regs_map_count > MAX_CBE) {
167 printk(KERN_ERR "cbe_regs: More BE chips than supported" 183 printk(KERN_ERR "cbe_regs: More BE chips than supported"
@@ -170,9 +186,18 @@ void __init cbe_regs_init(void)
170 return; 186 return;
171 } 187 }
172 map->cpu_node = cpu; 188 map->cpu_node = cpu;
173 for_each_possible_cpu(i) 189
174 if (cbe_thread_map[i].cpu_node == cpu) 190 for_each_possible_cpu(i) {
175 cbe_thread_map[i].regs = map; 191 struct cbe_thread_map *thread = &cbe_thread_map[i];
192
193 if (thread->cpu_node == cpu) {
194 thread->regs = map;
195 thread->cbe_id = cbe_id;
196 cpu_set(i, cbe_local_mask[cbe_id]);
197 if(thread->thread_id == 0)
198 cpu_set(i, cbe_first_online_cpu);
199 }
200 }
176 201
177 prop = of_get_property(cpu, "pervasive", NULL); 202 prop = of_get_property(cpu, "pervasive", NULL);
178 if (prop != NULL) 203 if (prop != NULL)
diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h
index 440a7ecc66ea..17d597144877 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.h
+++ b/arch/powerpc/platforms/cell/cbe_regs.h
@@ -255,6 +255,11 @@ struct cbe_mic_tm_regs {
255extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np); 255extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np);
256extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu); 256extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
257 257
258/* some utility functions to deal with SMT */
259extern u32 cbe_get_hw_thread_id(int cpu);
260extern u32 cbe_cpu_to_node(int cpu);
261extern u32 cbe_node_to_cpu(int node);
262
258/* Init this module early */ 263/* Init this module early */
259extern void cbe_regs_init(void); 264extern void cbe_regs_init(void);
260 265
diff --git a/include/asm-powerpc/cell-pmu.h b/include/asm-powerpc/cell-pmu.h
index 35b95773746c..8066eede3a0c 100644
--- a/include/asm-powerpc/cell-pmu.h
+++ b/include/asm-powerpc/cell-pmu.h
@@ -97,11 +97,6 @@ extern void cbe_disable_pm_interrupts(u32 cpu);
97extern u32 cbe_get_and_clear_pm_interrupts(u32 cpu); 97extern u32 cbe_get_and_clear_pm_interrupts(u32 cpu);
98extern void cbe_sync_irq(int node); 98extern void cbe_sync_irq(int node);
99 99
100/* Utility functions, macros */
101extern u32 cbe_get_hw_thread_id(int cpu);
102
103#define cbe_cpu_to_node(cpu) ((cpu) >> 1)
104
105#define CBE_COUNT_SUPERVISOR_MODE 0 100#define CBE_COUNT_SUPERVISOR_MODE 0
106#define CBE_COUNT_HYPERVISOR_MODE 1 101#define CBE_COUNT_HYPERVISOR_MODE 1
107#define CBE_COUNT_PROBLEM_MODE 2 102#define CBE_COUNT_PROBLEM_MODE 2