summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDietmar Eggemann <dietmar.eggemann@arm.com>2012-03-15 12:09:41 +0000
committerDietmar Eggemann <dietmar.eggemann@arm.com>2012-05-22 10:43:46 +0100
commit1e79620987334875f4386f5761d1a75edd0c8ad3 (patch)
tree6639364d97612e302a251e4d2bdc4f5c97e63091
parent079394921557233a01d429011432ed5e9044e384 (diff)
downloadswitcher-1e79620987334875f4386f5761d1a75edd0c8ad3.tar.gz
Hotplug: Add a cpu mask argument to event functions.
To be able to cluster switch with cpus in hotplug, the event mechanism must be able to inform only cpus which are online when the cluster switch occurs. Thus the event functions need the online cpu mask as an argument. Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
-rw-r--r--big-little/include/events.h5
-rw-r--r--big-little/lib/virt_events.c54
2 files changed, 34 insertions, 25 deletions
diff --git a/big-little/include/events.h b/big-little/include/events.h
index 629404f..abebaa9 100644
--- a/big-little/include/events.h
+++ b/big-little/include/events.h
@@ -68,11 +68,12 @@
#define FLUSH_L2 2
#define SETUP_RST 3
+
extern void set_event(unsigned, unsigned);
-extern void set_events(unsigned);
+extern void set_events(unsigned, unsigned);
extern unsigned get_event(unsigned, unsigned);
extern void reset_event(unsigned, unsigned);
extern void wait_for_event(unsigned, unsigned);
-extern void wait_for_events(unsigned);
+extern void wait_for_events(unsigned, unsigned);
#endif /* __EVENTS_H__ */
diff --git a/big-little/lib/virt_events.c b/big-little/lib/virt_events.c
index 33e9d3b..ec5c468 100644
--- a/big-little/lib/virt_events.c
+++ b/big-little/lib/virt_events.c
@@ -66,6 +66,15 @@ void wait_for_event(unsigned event_id, unsigned cpu_id)
return;
}
+static unsigned count_set_bits(unsigned mask)
+{
+ unsigned i;
+ for (i = 0; mask; i++)
+ mask &= mask - 1;
+
+ return i;
+}
+
/*
* Wait for events from each core. Its a little trickier than
* waiting for a single event. The event register as per the
@@ -74,26 +83,29 @@ void wait_for_event(unsigned event_id, unsigned cpu_id)
* the time we enter wfe() then each flag variable should be
* checked.
*/
-void wait_for_events(unsigned event_id)
+void wait_for_events(unsigned event_id, unsigned cpu_mask)
{
- unsigned ctr, event_count = 0, num_cpus = 0;
+ unsigned mask = 0, event_count = 0, cpu_count = 0;
+ int cpu_id = 0;
- if (switcher) {
- num_cpus = num_secondaries() + 1;
- } else {
- num_cpus = CLUSTER_CPU_COUNT(host_cluster)
- + CLUSTER_CPU_COUNT(!host_cluster);
- }
+ cpu_count = count_set_bits(cpu_mask);
do {
- for (ctr = 0; ctr < num_cpus; ctr++) {
- if (TRUE == get_event(event_id, ctr)) {
+ for (mask = cpu_mask; mask;) {
+
+ /* Find the first set msb */
+ cpu_id = bitindex(mask);
+
+ /* Unset the recorded bit */
+ mask &= ~(1 << cpu_id);
+
+ if (TRUE == get_event(event_id, cpu_id)) {
event_count++;
- reset_event(event_id, ctr);
+ reset_event(event_id, cpu_id);
}
}
- if (event_count != num_cpus)
+ if (event_count != cpu_count)
wfe();
else
break;
@@ -102,19 +114,15 @@ void wait_for_events(unsigned event_id)
return;
}
-void set_events(unsigned event_id)
+void set_events(unsigned event_id, unsigned cpu_mask)
{
- unsigned ctr, num_cpus = 0;
+ unsigned cpu_id = 0;
- if (switcher) {
- num_cpus = num_secondaries() + 1;
- } else {
- num_cpus = CLUSTER_CPU_COUNT(host_cluster)
- + CLUSTER_CPU_COUNT(!host_cluster);
- }
+ while (cpu_mask) {
+ cpu_id = bitindex(cpu_mask);
+ set_event(event_id, cpu_id);
+ cpu_mask &= ~(1 << cpu_id);
+ };
- for (ctr = 0; ctr < num_cpus; ctr++) {
- set_event(event_id, ctr);
- }
return;
}