Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2018, Arm Limited. All rights reserved. |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #ifndef __EVENTS_H__ |
| 8 | #define __EVENTS_H__ |
| 9 | |
| 10 | #include <spinlock.h> |
| 11 | |
| 12 | typedef struct { |
| 13 | /* |
| 14 | * Counter that keeps track of the minimum number of recipients of the |
| 15 | * event. When the event is sent, this counter is incremented. When it |
| 16 | * is received, it is decremented. Therefore, a zero value means that |
| 17 | * the event hasn't been sent yet, or that all recipients have already |
| 18 | * received it. |
| 19 | * |
| 20 | * Volatile is needed as it will enforce ordering relatively to |
| 21 | * accesses to the lock. |
| 22 | */ |
| 23 | volatile unsigned int cnt; |
| 24 | |
| 25 | /* Lock used to avoid concurrent accesses to the counter */ |
| 26 | spinlock_t lock; |
| 27 | } event_t; |
| 28 | |
| 29 | /* |
| 30 | * Initialise an event. |
| 31 | * event: Address of the event to initialise |
| 32 | * |
| 33 | * This function can be used either to initialise a newly created event |
| 34 | * structure or to recycle one. |
| 35 | * |
| 36 | * Note: This function is not MP-safe. It can't use the event lock as it is |
| 37 | * responsible for initialising it. Care must be taken to ensure this function |
| 38 | * is called in the right circumstances. |
| 39 | */ |
| 40 | void tftf_init_event(event_t *event); |
| 41 | |
| 42 | /* |
| 43 | * Send an event to a CPU. |
| 44 | * event: Address of the variable that acts as a synchronisation object. |
| 45 | * |
| 46 | * Which CPU receives the event is determined on a first-come, first-served |
| 47 | * basis. If several CPUs are waiting for the same event then the first CPU |
| 48 | * which takes the event will reflect that in the event structure. |
| 49 | * |
| 50 | * Note: This is equivalent to calling: |
| 51 | * tftf_send_event_to(event, 1); |
| 52 | */ |
| 53 | void tftf_send_event(event_t *event); |
| 54 | |
| 55 | /* |
| 56 | * Send an event to all CPUs. |
| 57 | * event: Address of the variable that acts as a synchronisation object. |
| 58 | * |
| 59 | * Note: This is equivalent to calling: |
| 60 | * tftf_send_event_to(event, PLATFORM_CORE_COUNT); |
| 61 | */ |
| 62 | void tftf_send_event_to_all(event_t *event); |
| 63 | |
| 64 | /* |
| 65 | * Send an event to a given number of CPUs. |
| 66 | * event: Address of the variable that acts as a synchronisation object. |
| 67 | * cpus_count: Number of CPUs to send the event to. |
| 68 | * |
| 69 | * Which CPUs receive the event is determined on a first-come, first-served |
| 70 | * basis. If more than 'cpus_count' CPUs are waiting for the same event then the |
| 71 | * first 'cpus_count' CPUs which take the event will reflect that in the event |
| 72 | * structure. |
| 73 | */ |
| 74 | void tftf_send_event_to(event_t *event, unsigned int cpus_count); |
| 75 | |
| 76 | /* |
| 77 | * Wait for an event. |
| 78 | * event: Address of the variable that acts as a synchronisation object. |
| 79 | */ |
| 80 | void tftf_wait_for_event(event_t *event); |
| 81 | |
| 82 | #endif /* __EVENTS_H__ */ |