1 /*
2  * Copyright (c) 2020, Google, Inc. All rights reserved
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #pragma once
25 
26 #include <list.h>
27 #include <reflist.h>
28 #include <stdint.h>
29 #include <sys/types.h>
30 
31 #include <kernel/spinlock.h>
32 #include <lib/trusty/handle.h>
33 #include <lib/trusty/uuid.h>
34 #include <uapi/trusty_uevent.h>
35 
36 /**
37  * struct event_source_ops - user provided callbacks for event source
38  * @open:   invoked when the first client connects to event source
39  * @mask:   invoked to mask underlying event source
40  * @unmask: invoked to unmask underlying events source
41  * @close:  invoked when the last client connected to event source
42  *          goes away
43  *
44  * Note: The @open and @close callbacks are invoked with global mutex held
45  * so it is not allowed to create or close another event in that context.
46  * The  @mask and @unmask callback are invoked in context with spinlock
47  * (private to event source obejct) held and interrupts disabled.
48  */
49 struct event_source_ops {
50     void (*open)(const void* priv);
51     void (*mask)(const void* priv);
52     void (*unmask)(const void* priv);
53     void (*close)(const void* priv);
54 };
55 
56 /**
57  * event_source_create() - create new event source object
58  * @name:      name of the object to create (non-empty string)
59  * @ops:       pointer to &struct event_source_ops
60  * @ops_arg:   @priv argument of callbacks specified by @ops parameeter
61  * @uuids:     pointer to array of &struct uuids that represents client
62  *             uuids that are allowed to connect to event source object
63  * @uuids_num: number of entries in array pointed by @uuids parameter
64  * @flags:     reserved, must be set to 0
65  * @ph:        pointer to &struct handle to return handle to caller
66  *
67  * Note1: in general @ops are optional.
68  *
69  * Note2: if @ops are present both &struct event_source_ops->open and
70  * &struct event_source_ops->close callbacks must be provided.
71  *
72  * Note3: if &struct event_source_ops->mask callback is provided corresponding
73  * &struct event_source_ops->unmask callback must be provided too.
74  *
75  * Note4: the retains an ownership of memory referenced by @name, @ops,
76  * @ops_arg and @uuids parameters and should keep this memory around for event
77  * source object duration. This memory should be only freed after the last
78  * reference to event source handle had been closed.
79  *
80  * Return: 0 on success, negative error otherwise
81  */
82 int event_source_create(const char* name,
83                         const struct event_source_ops* ops,
84                         const void* ops_arg,
85                         const uuid_t* uuids,
86                         unsigned int uuids_num,
87                         unsigned int flags,
88                         struct handle** ph);
89 
90 /**
91  * event_source_publish() - publish event source event
92  * @h: pointer to &struct handle of event source to publish
93  *
94  * This routine makes an event source object (previously created with
95  * event_source_create() call) available for clients.
96  *
97  * Return: 0 on success, negative error otherwise
98  */
99 int event_source_publish(struct handle* h);
100 
101 /**
102  * event_source_open() - open specified event source
103  * @cid:      pointer to client's &struct uuid
104  * @name:     pointer to buffer containing event source name
105  * @max_name: max size of the buffer containing name
106  * @flags:    reserved, must be zero
107  * @ph:       pointer to &struct handle to return handle to caller
108  *
109  * Return: 0 on success, negative error otherwise
110  */
111 int event_source_open(const struct uuid* cid,
112                       const char* name,
113                       size_t max_name,
114                       unsigned int flags,
115                       struct handle** ph);
116 
117 /**
118  * event_source_signal() - signal event source
119  * @h: pointer to &struct handle to signal
120  *
121  * Note1: It is safe to call this routine from interrupt context.
122  *
123  * Note2: if underlying event source object implements
124  * &struct event_source_ops->mask callback it is illegal to call this routine
125  * again for objects that are already in signaled state. (It is expected that
126  * event source is  masked which should prevent signaling it again). For this
127  * schema it is guaranteed that all clients would see an event exactly once for
128  * each invocation of event_source_signal() routine.
129  *
130  * Note: for all other valid callback combinations, it is OK to call this
131  * routine multiple times in any state, but some events might be lost. This is
132  * similar to receiving a new edge triggered interrupt while previous one is
133  * not handled yet. It is also guaranteed that all clients will be notified
134  * after the last call to event_source_signal() at least once.
135  *
136  * Return: 0 on success, negative error otherwise
137  */
138 int event_source_signal(struct handle* h);
139 
140 /**
141  * event_client_notify_handled() - change event client state
142  * @h:   pointer to &struct handle to change state
143  *
144  * This routine is called on client handle to indicate that the client has
145  * finished handling an event and underlying object has to change it's state
146  * accordingly.
147  *
148  * Return: 0 on success, negative error otherwise
149  */
150 int event_client_notify_handled(struct handle* h);
151