blob: 5919d3b340a3ca08617feb95a96f2579d0a8c0ab [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
Madhukar Pappireddy986de722020-07-04 01:23:50 -050028 /*
29 * Make sure the cnt increment is observable by all CPUs
30 * before the event is sent.
31 */
32 dsbsy();
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020033 sev();
34}
35
36void tftf_send_event(event_t *event)
37{
38 VERBOSE("Sending event %p\n", (void *) event);
39 send_event_common(event, 1);
40}
41
42void tftf_send_event_to_all(event_t *event)
43{
44 VERBOSE("Sending event %p to all CPUs\n", (void *) event);
45 send_event_common(event, PLATFORM_CORE_COUNT);
46}
47
48void tftf_send_event_to(event_t *event, unsigned int cpus_count)
49{
50 assert(cpus_count <= PLATFORM_CORE_COUNT);
51 VERBOSE("Sending event %p to %u CPUs\n", (void *) event, cpus_count);
52 send_event_common(event, cpus_count);
53}
54
55void tftf_wait_for_event(event_t *event)
56{
57 unsigned int event_received = 0;
58
59 VERBOSE("Waiting for event %p\n", (void *) event);
60 while (!event_received) {
61
62 dsbsy();
63 /* Wait for someone to send an event */
64 if (!event->cnt) {
65 wfe();
66 } else {
67 spin_lock(&event->lock);
68
69 /*
70 * Check that the event is still pending and that no
71 * one stole it from us while we were trying to
72 * acquire the lock.
73 */
74 if (event->cnt != 0) {
75 event_received = 1;
76 --event->cnt;
77 }
78 /*
79 * No memory barrier is needed here because spin_unlock()
80 * issues a Store-Release instruction, which guarantees
81 * that loads and stores appearing in program order
82 * before the Store-Release are observed before the
83 * Store-Release itself.
84 */
85 spin_unlock(&event->lock);
86 }
87 }
88
89 VERBOSE("Received event %p\n", (void *) event);
90}