Commit 91a69c9646a5b709381d99a171890e77377b1b9c
Committed by
Arnd Bergmann
1 parent
390cbb56a7
Exists in
master
and in
7 other branches
[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>
Showing 4 changed files with 45 additions and 19 deletions Side-by-side Diff
arch/powerpc/oprofile/op_model_cell.c
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | #include <asm/system.h> |
38 | 38 | |
39 | 39 | #include "../platforms/cell/interrupt.h" |
40 | +#include "../platforms/cell/cbe_regs.h" | |
40 | 41 | |
41 | 42 | #define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */ |
42 | 43 | #define PPU_CYCLES_GRP_NUM 1 /* special group number for identifying |
arch/powerpc/platforms/cell/cbe_regs.c
... | ... | @@ -38,8 +38,13 @@ |
38 | 38 | { |
39 | 39 | struct device_node *cpu_node; |
40 | 40 | struct cbe_regs_map *regs; |
41 | + unsigned int thread_id; | |
42 | + unsigned int cbe_id; | |
41 | 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 | 48 | static struct cbe_regs_map *cbe_find_map(struct device_node *np) |
44 | 49 | { |
45 | 50 | int i; |
46 | 51 | |
47 | 52 | |
48 | 53 | |
49 | 54 | |
50 | 55 | |
... | ... | @@ -130,31 +135,40 @@ |
130 | 135 | } |
131 | 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 | 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 | 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 | 156 | void __init cbe_regs_init(void) |
147 | 157 | { |
148 | 158 | int i; |
159 | + unsigned int thread_id; | |
149 | 160 | struct device_node *cpu; |
150 | 161 | |
151 | 162 | /* Build local fast map of CPUs */ |
152 | - for_each_possible_cpu(i) | |
153 | - cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL); | |
163 | + for_each_possible_cpu(i) { | |
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 | 168 | /* Find maps for each device tree CPU */ |
156 | 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 | 173 | /* That hack must die die die ! */ |
160 | 174 | const struct address_prop { |
... | ... | @@ -162,6 +176,8 @@ |
162 | 176 | unsigned int len; |
163 | 177 | } __attribute__((packed)) *prop; |
164 | 178 | |
179 | + cbe_id = cbe_regs_map_count++; | |
180 | + map = &cbe_regs_maps[cbe_id]; | |
165 | 181 | |
166 | 182 | if (cbe_regs_map_count > MAX_CBE) { |
167 | 183 | printk(KERN_ERR "cbe_regs: More BE chips than supported" |
... | ... | @@ -170,9 +186,18 @@ |
170 | 186 | return; |
171 | 187 | } |
172 | 188 | map->cpu_node = cpu; |
173 | - for_each_possible_cpu(i) | |
174 | - if (cbe_thread_map[i].cpu_node == cpu) | |
175 | - cbe_thread_map[i].regs = map; | |
189 | + | |
190 | + for_each_possible_cpu(i) { | |
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 | 202 | prop = of_get_property(cpu, "pervasive", NULL); |
178 | 203 | if (prop != NULL) |
arch/powerpc/platforms/cell/cbe_regs.h
... | ... | @@ -255,6 +255,11 @@ |
255 | 255 | extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np); |
256 | 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 | 263 | /* Init this module early */ |
259 | 264 | extern void cbe_regs_init(void); |
260 | 265 |
include/asm-powerpc/cell-pmu.h
... | ... | @@ -97,11 +97,6 @@ |
97 | 97 | extern u32 cbe_get_and_clear_pm_interrupts(u32 cpu); |
98 | 98 | extern void cbe_sync_irq(int node); |
99 | 99 | |
100 | -/* Utility functions, macros */ | |
101 | -extern u32 cbe_get_hw_thread_id(int cpu); | |
102 | - | |
103 | -#define cbe_cpu_to_node(cpu) ((cpu) >> 1) | |
104 | - | |
105 | 100 | #define CBE_COUNT_SUPERVISOR_MODE 0 |
106 | 101 | #define CBE_COUNT_HYPERVISOR_MODE 1 |
107 | 102 | #define CBE_COUNT_PROBLEM_MODE 2 |