1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * $FreeBSD$
5 */
6
7 #ifndef _RPMSG_INTERNAL_H_
8 #define _RPMSG_INTERNAL_H_
9
10 #include <stdint.h>
11 #include <openamp/rpmsg.h>
12
13 #if defined __cplusplus
14 extern "C" {
15 #endif
16
17 #ifdef RPMSG_DEBUG
18 #include <metal/log.h>
19
20 #define RPMSG_ASSERT(_exp, _msg) do { \
21 if (!(_exp)) { \
22 metal_log(METAL_LOG_EMERGENCY, \
23 "FATAL: %s - "_msg, __func__); \
24 metal_assert(_exp); \
25 } \
26 } while (0)
27 #else
28 #define RPMSG_ASSERT(_exp, _msg) metal_assert(_exp)
29 #endif
30
31 /* Mask to get the rpmsg buffer held counter from rpmsg_hdr reserved field */
32 #define RPMSG_BUF_HELD_SHIFT 16
33 #define RPMSG_BUF_HELD_MASK (0xFFFFU << RPMSG_BUF_HELD_SHIFT)
34
35 #define RPMSG_LOCATE_HDR(p) \
36 ((struct rpmsg_hdr *)((unsigned char *)(p) - sizeof(struct rpmsg_hdr)))
37 #define RPMSG_LOCATE_DATA(p) ((unsigned char *)(p) + sizeof(struct rpmsg_hdr))
38
39 /**
40 * @brief dynamic name service announcement flags
41 */
42 enum rpmsg_ns_flags {
43 /** A new remote service was just created */
44 RPMSG_NS_CREATE = 0,
45 /** A known remote service was just destroyed */
46 RPMSG_NS_DESTROY = 1,
47 };
48
49 /**
50 * @brief Common header for all RPMsg messages
51 *
52 * Every message sent(/received) on the RPMsg bus begins with this header.
53 */
54 METAL_PACKED_BEGIN
55 struct rpmsg_hdr {
56 /** Source address */
57 uint32_t src;
58
59 /** Destination address */
60 uint32_t dst;
61
62 /** Reserved for future use */
63 uint32_t reserved;
64
65 /** Length of payload (in bytes) */
66 uint16_t len;
67
68 /** Message flags */
69 uint16_t flags;
70 } METAL_PACKED_END;
71
72 /**
73 * @brief Dynamic name service announcement message
74 *
75 * This message is sent across to publish a new service, or announce
76 * about its removal. When we receive these messages, an appropriate
77 * RPMsg channel (i.e device) is created/destroyed. In turn, the ->probe()
78 * or ->remove() handler of the appropriate RPMsg driver will be invoked
79 * (if/as-soon-as one is registered).
80 */
81 METAL_PACKED_BEGIN
82 struct rpmsg_ns_msg {
83 /** Name of the remote service that is being published */
84 char name[RPMSG_NAME_SIZE];
85
86 /** Endpoint address of the remote service that is being published */
87 uint32_t addr;
88
89 /** Indicates whether service is created or destroyed */
90 uint32_t flags;
91 } METAL_PACKED_END;
92
93 int rpmsg_send_ns_message(struct rpmsg_endpoint *ept, unsigned long flags);
94
95 struct rpmsg_endpoint *rpmsg_get_endpoint(struct rpmsg_device *rvdev,
96 const char *name, uint32_t addr,
97 uint32_t dest_addr);
98 void rpmsg_register_endpoint(struct rpmsg_device *rdev,
99 struct rpmsg_endpoint *ept,
100 const char *name,
101 uint32_t src, uint32_t dest,
102 rpmsg_ept_cb cb,
103 rpmsg_ns_unbind_cb ns_unbind_cb, void *priv);
104
105 static inline struct rpmsg_endpoint *
rpmsg_get_ept_from_addr(struct rpmsg_device * rdev,uint32_t addr)106 rpmsg_get_ept_from_addr(struct rpmsg_device *rdev, uint32_t addr)
107 {
108 return rpmsg_get_endpoint(rdev, NULL, addr, RPMSG_ADDR_ANY);
109 }
110
111 /**
112 * @internal
113 *
114 * @brief Increase the endpoint reference count
115 *
116 * This function is used to avoid calling ept_cb after release lock causes race condition
117 * it should be called under lock protection.
118 *
119 * @param ept pointer to rpmsg endpoint
120 *
121 */
122 void rpmsg_ept_incref(struct rpmsg_endpoint *ept);
123
124 /**
125 * @internal
126 *
127 * @brief Decrease the end point reference count
128 *
129 * This function is used to avoid calling ept_cb after release lock causes race condition
130 * it should be called under lock protection.
131 *
132 * @param ept pointer to rpmsg endpoint
133 */
134 void rpmsg_ept_decref(struct rpmsg_endpoint *ept);
135
136 #if defined __cplusplus
137 }
138 #endif
139
140 #endif /* _RPMSG_INTERNAL_H_ */
141