blob: 2bd4139ea4118f513d46789592b073485cdf44a4 [file] [log] [blame]
Antonio Nino Diaz9bf1d232018-11-08 09:21:48 +00001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <errno.h>
9#include <stdint.h>
10#include <string.h>
11
12#include "sprt_queue.h"
13
14void sprt_queue_init(void *queue_base, uint32_t entry_num, uint32_t entry_size)
15{
16 assert(queue_base != NULL);
17 assert(entry_size > 0U);
18 assert(entry_num > 0U);
19
20 struct sprt_queue *queue = (struct sprt_queue *)queue_base;
21
22 queue->entry_num = entry_num;
23 queue->entry_size = entry_size;
24 queue->idx_write = 0U;
25 queue->idx_read = 0U;
26
27 memset(queue->data, 0, entry_num * entry_size);
28}
29
30int sprt_queue_is_empty(void *queue_base)
31{
32 assert(queue_base != NULL);
33
34 struct sprt_queue *queue = (struct sprt_queue *)queue_base;
35
36 return (queue->idx_write == queue->idx_read);
37}
38
39int sprt_queue_is_full(void *queue_base)
40{
41 assert(queue_base != NULL);
42
43 struct sprt_queue *queue = (struct sprt_queue *)queue_base;
44
45 uint32_t idx_next_write = (queue->idx_write + 1) % queue->entry_num;
46
47 return (idx_next_write == queue->idx_read);
48}
49
50int sprt_queue_push(void *queue_base, const void *entry)
51{
52 assert(entry != NULL);
53 assert(queue_base != NULL);
54
55 if (sprt_queue_is_full(queue_base) != 0) {
56 return -ENOMEM;
57 }
58
59 struct sprt_queue *queue = (struct sprt_queue *)queue_base;
60
61 uint8_t *dst_entry = &queue->data[queue->entry_size * queue->idx_write];
62
63 memcpy(dst_entry, entry, queue->entry_size);
64
65 /*
66 * Make sure that the message data is visible before increasing the
67 * counter of available messages.
68 */
69 __asm__ volatile("dmb st" ::: "memory");
70
71 queue->idx_write = (queue->idx_write + 1) % queue->entry_num;
72
73 __asm__ volatile("dmb st" ::: "memory");
74
75 return 0;
76}
77
78int sprt_queue_pop(void *queue_base, void *entry)
79{
80 assert(entry != NULL);
81 assert(queue_base != NULL);
82
83 if (sprt_queue_is_empty(queue_base) != 0) {
84 return -ENOENT;
85 }
86
87 struct sprt_queue *queue = (struct sprt_queue *)queue_base;
88
89 uint8_t *src_entry = &queue->data[queue->entry_size * queue->idx_read];
90
91 memcpy(entry, src_entry, queue->entry_size);
92
93 /*
94 * Make sure that the message data is visible before increasing the
95 * counter of read messages.
96 */
97 __asm__ volatile("dmb st" ::: "memory");
98
99 queue->idx_read = (queue->idx_read + 1) % queue->entry_num;
100
101 __asm__ volatile("dmb st" ::: "memory");
102
103 return 0;
104}