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