summaryrefslogtreecommitdiff
path: root/big-little/lib/virt_events.c
diff options
context:
space:
mode:
authorDave Martin <dave.martin@linaro.org>2011-12-16 11:41:59 +0000
committerDave Martin <dave.martin@linaro.org>2011-12-16 11:41:59 +0000
commit9945995974f51e86ff8a5e3162c47e1019ce9a08 (patch)
tree254d310b4a81e31f5ea2ab914b3cb9e643bf64a6 /big-little/lib/virt_events.c
arm-virtualizer: Initial import of v2.1 releasearm_v2.1
From Release_Notes.txt: ARM Virtualizer software release v2.1 This software release is a v2.1 snapshot of the ARM Virtualizer software. The ARM Virtualizer software is example code that demonstrates cluster context switching capability on a coherent dual cluster system composed of a Cortex-A7 cluster and a Cortex-A15 cluster. The intent behind this delivery is to allow inspection of the software architecture and to demonstrate existing functionality. It is possible to execute the ARM Virtualizer software on a Kingfisher Real-Time System Model (RTSM VE Cortex-A15 KF CCI version 6.2 Beta).
Diffstat (limited to 'big-little/lib/virt_events.c')
-rw-r--r--big-little/lib/virt_events.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/big-little/lib/virt_events.c b/big-little/lib/virt_events.c
new file mode 100644
index 0000000..b842324
--- /dev/null
+++ b/big-little/lib/virt_events.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2011, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with
+ * or without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior written
+ * permission.
+ */
+
+#include "events.h"
+#include "misc.h"
+#include "virt_helpers.h"
+
+/*
+ * cpu ids are used as is when "switcher" is true. In the
+ * "always on" case absolute cpu ids are used i.e 0-7 for
+ * an MPx4+MPx4 configuration.
+ */
+/*
+ * Pick up the event definition from the world that wants
+ * to use them.
+ */
+extern unsigned event[][MAX_EVENTS];
+
+/*
+ * Set the specified event for that cpu.
+ */
+void set_event(unsigned event_id, unsigned cpu_id)
+{
+ event[cpu_id][event_id] = TRUE;
+ dsb();
+ sev();
+ return;
+}
+
+inline unsigned get_event(unsigned event_id, unsigned cpu_id)
+{
+ return event[cpu_id][event_id];
+}
+
+void reset_event(unsigned event_id, unsigned cpu_id)
+{
+ event[cpu_id][event_id] = FALSE;
+ return;
+}
+
+void wait_for_event(unsigned event_id, unsigned cpu_id)
+{
+ while (FALSE == get_event(event_id, cpu_id)) {
+ wfe();
+ }
+
+ return;
+}
+
+/*
+ * Wait for events from each core. Its a little trickier than
+ * waiting for a single event. The event register as per the
+ * architecture is just a single bit to flag an event rather
+ * than the number of events. If multiple events are sent by
+ * the time we enter wfe() then each flag variable should be
+ * checked.
+ */
+void wait_for_events(unsigned event_id)
+{
+ unsigned ctr, event_count = 0, num_cpus = 0;
+
+ if (switcher) {
+ num_cpus = num_secondaries() + 1;
+ } else {
+ num_cpus = CLUSTER_CPU_COUNT(host_cluster)
+ + CLUSTER_CPU_COUNT(!host_cluster);
+ }
+
+ do {
+ for (ctr = 0; ctr < num_cpus; ctr++) {
+ if (TRUE == get_event(event_id, ctr)) {
+ event_count++;
+ reset_event(event_id, ctr);
+ }
+ }
+
+ if (event_count != num_cpus)
+ wfe();
+ else
+ break;
+ } while(1);
+
+ return;
+}
+
+void set_events(unsigned event_id)
+{
+ unsigned ctr, num_cpus = 0;
+
+ if (switcher) {
+ num_cpus = num_secondaries() + 1;
+ } else {
+ num_cpus = CLUSTER_CPU_COUNT(host_cluster)
+ + CLUSTER_CPU_COUNT(!host_cluster);
+ }
+
+ for (ctr = 0; ctr < num_cpus; ctr++) {
+ set_event(event_id, ctr);
+ }
+ return;
+}