blob: 42130d5e8736fa913a7b146c516f605fa4aefc23 [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <debug.h>
10#include <events.h>
11#include <platform_def.h>
12#include <tftf.h>
13#include <tftf_lib.h>
14
15void tftf_init_event(event_t *event)
16{
17 assert(event != NULL);
18 event->cnt = 0;
19 event->lock.lock = 0;
20}
21
22static void send_event_common(event_t *event, unsigned int inc)
23{
24 spin_lock(&event->lock);
25 event->cnt += inc;
26 spin_unlock(&event->lock);
27
28 sev();
29}
30
31void tftf_send_event(event_t *event)
32{
33 VERBOSE("Sending event %p\n", (void *) event);
34 send_event_common(event, 1);
35}
36
37void tftf_send_event_to_all(event_t *event)
38{
39 VERBOSE("Sending event %p to all CPUs\n", (void *) event);
40 send_event_common(event, PLATFORM_CORE_COUNT);
41}
42
43void tftf_send_event_to(event_t *event, unsigned int cpus_count)
44{
45 assert(cpus_count <= PLATFORM_CORE_COUNT);
46 VERBOSE("Sending event %p to %u CPUs\n", (void *) event, cpus_count);
47 send_event_common(event, cpus_count);
48}
49
50void tftf_wait_for_event(event_t *event)
51{
52 unsigned int event_received = 0;
53
54 VERBOSE("Waiting for event %p\n", (void *) event);
55 while (!event_received) {
56
57 dsbsy();
58 /* Wait for someone to send an event */
59 if (!event->cnt) {
60 wfe();
61 } else {
62 spin_lock(&event->lock);
63
64 /*
65 * Check that the event is still pending and that no
66 * one stole it from us while we were trying to
67 * acquire the lock.
68 */
69 if (event->cnt != 0) {
70 event_received = 1;
71 --event->cnt;
72 }
73 /*
74 * No memory barrier is needed here because spin_unlock()
75 * issues a Store-Release instruction, which guarantees
76 * that loads and stores appearing in program order
77 * before the Store-Release are observed before the
78 * Store-Release itself.
79 */
80 spin_unlock(&event->lock);
81 }
82 }
83
84 VERBOSE("Received event %p\n", (void *) event);
85}