diff options
author | Christian Krafft <krafft@de.ibm.com> | 2007-04-23 15:35:39 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@klappe.arndb.de> | 2007-04-23 15:44:38 -0400 |
commit | 91a69c9646a5b709381d99a171890e77377b1b9c (patch) | |
tree | 3827389a195eecd0e010e53d926318328edab25f /arch | |
parent | 390cbb56a731546edc0f35fbc4c5045676467581 (diff) |
[POWERPC] cell: add cbe_node_to_cpu function
This patch adds code to deal with conversion of
logical cpu to cbe nodes. It removes code that
assummed there were two logical CPUs per CBE.
Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/oprofile/op_model_cell.c | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/cbe_regs.c | 53 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/cbe_regs.h | 5 |
3 files changed, 45 insertions, 14 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 | ||
45 | static cpumask_t cbe_local_mask[MAX_CBE] = { [0 ... MAX_CBE-1] = CPU_MASK_NONE }; | ||
46 | static cpumask_t cbe_first_online_cpu = CPU_MASK_NONE; | ||
47 | |||
43 | static struct cbe_regs_map *cbe_find_map(struct device_node *np) | 48 | static 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 | } |
131 | EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs); | 136 | EXPORT_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 | */ | ||
140 | u32 cbe_get_hw_thread_id(int cpu) | 138 | u32 cbe_get_hw_thread_id(int cpu) |
141 | { | 139 | { |
142 | return (cpu & 1); | 140 | return cbe_thread_map[cpu].thread_id; |
143 | } | 141 | } |
144 | EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id); | 142 | EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id); |
145 | 143 | ||
144 | u32 cbe_cpu_to_node(int cpu) | ||
145 | { | ||
146 | return cbe_thread_map[cpu].cbe_id; | ||
147 | } | ||
148 | EXPORT_SYMBOL_GPL(cbe_cpu_to_node); | ||
149 | |||
150 | u32 cbe_node_to_cpu(int node) | ||
151 | { | ||
152 | return find_first_bit( (unsigned long *) &cbe_local_mask[node], sizeof(cpumask_t)); | ||
153 | } | ||
154 | EXPORT_SYMBOL_GPL(cbe_node_to_cpu); | ||
155 | |||
146 | void __init cbe_regs_init(void) | 156 | void __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 { | |||
255 | extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np); | 255 | extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np); |
256 | extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu); | 256 | extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu); |
257 | 257 | ||
258 | /* some utility functions to deal with SMT */ | ||
259 | extern u32 cbe_get_hw_thread_id(int cpu); | ||
260 | extern u32 cbe_cpu_to_node(int cpu); | ||
261 | extern u32 cbe_node_to_cpu(int node); | ||
262 | |||
258 | /* Init this module early */ | 263 | /* Init this module early */ |
259 | extern void cbe_regs_init(void); | 264 | extern void cbe_regs_init(void); |
260 | 265 | ||