5fe1cb987ba7d29ca4ee04291ba1450884025c04
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / udi_lib / physio / meta_bus.c
1 /**
2  * Acess2 UDI Layer
3  * - By John Hodge (thePowersGang)
4  *
5  * udi_lib/physio/meta_bus.c
6  * - Bus Bridge Metalanguage
7  */
8 #define DEBUG   1
9 #include <udi.h>
10 #include <udi_physio.h>
11 #include <acess.h>
12 #include <udi_internal.h>
13
14 #define USE_MEI 0
15
16 #define udi_mei_info    udi_meta_info__bridge
17
18 extern tUDI_MetaLang    cMetaLang_BusBridge;
19 extern udi_mei_init_t   udi_meta_info__bridge;
20
21 // === EXPORTS ===
22 EXPORT(udi_bus_bind_req);
23 EXPORT(udi_bus_bind_ack);
24 EXPORT(udi_bus_unbind_req);
25 EXPORT(udi_bus_unbind_ack);
26 EXPORT(udi_intr_attach_req);
27 EXPORT(udi_intr_attach_ack);
28 EXPORT(udi_intr_attach_ack_unused);
29 EXPORT(udi_intr_detach_req);
30 EXPORT(udi_intr_detach_ack);
31 EXPORT(udi_intr_detach_ack_unused);
32 EXPORT(udi_intr_event_ind);
33 EXPORT(udi_intr_event_rdy);
34
35 #define PREP_OPS(type,ml,num)   const type *ops = UDI_int_ChannelPrepForCall(UDI_GCB(cb), ml, num); \
36         if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; }
37
38 #define PREP_OPS_DEVICE const udi_bus_device_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM ); \
39         if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; }
40
41 // === CODE ===
42 #if !USE_MEI
43 void udi_bus_unbind_req(udi_bus_bind_cb_t *cb)
44 {
45         UNIMPLEMENTED();
46 }
47 void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb)
48 {
49         UNIMPLEMENTED();
50 }
51
52 void udi_bus_bind_req(udi_bus_bind_cb_t *cb)
53 {
54         LOG("cb=%p{...}", cb);
55         PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM)
56         
57         UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->bus_bind_req_op );
58 }
59
60 struct marshalled_bus_bind_ack
61 {
62         tUDI_DeferredCall       Call;
63         udi_dma_constraints_t   dma_constraints;
64         udi_ubit8_t     preferred_endianness;
65         udi_status_t    status;
66 };
67
68 static void _unmarshal_bus_bind_ack(tUDI_DeferredCall *Call)
69 {
70         LOG("Call=%p", Call);
71         struct marshalled_bus_bind_ack *info = (void*)Call;
72         UDI_int_ChannelReleaseFromCall( Call->cb );
73         ((udi_bus_bind_ack_op_t*)Call->Handler)(
74                 UDI_MCB(Call->cb, udi_bus_bind_cb_t),
75                 info->dma_constraints,
76                 info->preferred_endianness,
77                 info->status);
78         free(info);
79 }
80
81 void udi_bus_bind_ack(
82         udi_bus_bind_cb_t       *cb,
83         udi_dma_constraints_t   dma_constraints,
84         udi_ubit8_t     preferred_endianness,
85         udi_status_t    status
86         )
87 {
88         LOG("cb=%p{...}, dma_constraints=%p, preferred_endianness=%i,status=%i",
89                 cb, dma_constraints, preferred_endianness, status);
90         PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM)
91         
92         struct marshalled_bus_bind_ack *call = NEW(struct marshalled_bus_bind_ack,);
93         call->Call.Unmarshal = _unmarshal_bus_bind_ack;
94         call->Call.cb = UDI_GCB(cb);
95         call->Call.Handler = (udi_op_t*)ops->bus_bind_ack_op;
96         call->dma_constraints = dma_constraints;
97         call->preferred_endianness = preferred_endianness;
98         call->status = status;
99         UDI_int_AddDeferred(&call->Call);
100 }
101
102 void udi_intr_attach_req(udi_intr_attach_cb_t *cb)
103 {
104         LOG("cb=%p", cb);
105         PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM)
106         UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_attach_req_op );
107 }
108 void udi_intr_attach_ack(udi_intr_attach_cb_t *cb, udi_status_t status)
109 {
110         LOG("cb=%p,status=%i", cb, status);
111         PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM)
112         UDI_int_MakeDeferredCbS( UDI_GCB(cb), (udi_op_t*)ops->intr_attach_ack_op, status );
113 }
114
115 void udi_intr_detach_req(udi_intr_detach_cb_t *cb)
116 {
117         LOG("cb=%p", cb);
118         PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM)
119         UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_detach_req_op );
120 }
121 void udi_intr_detach_ack(udi_intr_detach_cb_t *cb)
122 {
123         LOG("cb=%p", cb);
124         PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM)
125         UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_detach_ack_op );
126 }
127 #endif
128
129 void udi_intr_event_ind(udi_intr_event_cb_t *cb, udi_ubit8_t flags)
130 {
131         LOG("cb=%p,flags=0x%x", cb, flags);
132         PREP_OPS(udi_intr_handler_ops_t, &cMetaLang_BusBridge, UDI_BUS_INTR_HANDLER_OPS_NUM)
133         UDI_int_MakeDeferredCbU8( UDI_GCB(cb), (udi_op_t*)ops->intr_event_ind_op, flags );
134 }
135
136 void udi_intr_event_rdy(udi_intr_event_cb_t *cb)
137 {
138         LOG("cb=%p", cb);
139         PREP_OPS(udi_intr_dispatcher_ops_t, &cMetaLang_BusBridge, UDI_BUS_INTR_DISPATCH_OPS_NUM)
140         UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_event_rdy_op );
141 }
142
143 void udi_intr_attach_ack_unused(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status)
144 {
145         Log_Error("UDI", "Driver %s caused %s to be called",
146                 UDI_int_ChannelGetInstance(UDI_GCB(intr_attach_cb), false, NULL)->Module->ModuleName,
147                 __func__);
148 }
149 void udi_intr_detach_ack_unused(udi_intr_detach_cb_t *intr_detach_cb)
150 {
151         Log_Error("UDI", "Driver %s caused %s to be called",
152                 UDI_int_ChannelGetInstance(UDI_GCB(intr_detach_cb), false, NULL)->Module->ModuleName,
153                 __func__);
154 }
155
156 #if USE_MEI
157 UDI_MEI_STUBS(udi_bus_bind_ack, udi_bus_bind_cb_t, 3,
158         (dma_constraints,       preferred_endianness, status      ),
159         (udi_dma_constraints_t, udi_ubit8_t,          udi_status_t),
160         (UDI_VA_POINTER,        UDI_VA_UBIT8_T,       UDI_VA_STATUS_T),
161         UDI_BUS_DEVICE_OPS_NUM, 1)
162 UDI_MEI_STUBS(udi_bus_unbind_ack, udi_bus_bind_cb_t, 0,
163         (), (), (),
164         UDI_BUS_DEVICE_OPS_NUM, 2)
165 UDI_MEI_STUBS(udi_intr_attach_ack, udi_intr_attach_cb_t, 1,
166         (status), (udi_status_t), (UDI_VA_STATUS_T),
167         UDI_BUS_DEVICE_OPS_NUM, 3)
168 UDI_MEI_STUBS(udi_intr_detach_ack, udi_intr_detach_cb_t, 0,
169         (), (), (),
170         UDI_BUS_DEVICE_OPS_NUM, 4)
171
172 UDI_MEI_STUBS(udi_bus_bind_req, udi_bus_bind_cb_t, 0,
173         (), (), (),
174         UDI_BUS_BRIDGE_OPS_NUM, 1)
175 UDI_MEI_STUBS(udi_bus_unbind_req, udi_bus_bind_cb_t, 0,
176         (), (), (),
177         UDI_BUS_BRIDGE_OPS_NUM, 2)
178 UDI_MEI_STUBS(udi_intr_attach_req, udi_intr_attach_cb_t, 0,
179         (), (), (),
180         UDI_BUS_BRIDGE_OPS_NUM, 3)
181 UDI_MEI_STUBS(udi_intr_detach_req, udi_intr_detach_cb_t, 0,
182         (), (), (),
183         UDI_BUS_BRIDGE_OPS_NUM, 4)
184
185 #endif
186
187 // === GLOBALS ==
188 udi_layout_t    udi_meta_info__bridge__bus_bind_cb[] = {
189         UDI_DL_END
190 };
191 udi_layout_t    udi_meta_info__bridge__intr_attach_cb[] = {
192         UDI_DL_STATUS_T,
193         UDI_DL_UBIT8_T,
194         UDI_DL_PIO_HANDLE_T,
195         UDI_DL_END
196 };
197 udi_layout_t    udi_meta_info__bridge__intr_detach_cb[] = {
198         UDI_DL_INDEX_T,
199         UDI_DL_END
200 };
201 udi_layout_t    udi_meta_info__bridge__intr_event_cb[] = {
202         UDI_DL_END
203 };
204
205 udi_layout_t    _BUS_BIND_cb_layout[] = {
206         UDI_DL_END
207 };
208
209 #if USE_MEI
210 udi_layout_t    _noargs_marshal[] = {
211         UDI_DL_END
212 };
213 udi_layout_t    _bus_bind_ack_marshal[] = {
214         UDI_DL_DMA_CONSTRAINTS_T,
215         UDI_DL_UBIT8_T,
216         UDI_DL_STATUS_T,
217         UDI_DL_END
218 };
219 udi_layout_t    _udi_intr_attach_ack_marshal[] = {
220         UDI_DL_STATUS_T,
221         UDI_DL_END
222 };
223
224 #define UDI__OPS_NUM    0
225 #define MEI_OPINFO(name,cat,flags,cbtype,rsp_ops,rsp_idx,err_ops,err_idx)       \
226         {#name, UDI_MEI_OPCAT_##cat,flags,UDI_##cbtype##_CB_NUM, \
227                 UDI_##rsp_ops##_OPS_NUM,rsp_idx,UDI_##err_ops##_OPS_NUM,err_idx, \
228                 name##_direct, name##_backend, _##cbtype##_cb_layout, _##name##_marshal_layout }
229
230 udi_mei_op_template_t   udi_meta_info__bridge__bus_ops[] = {
231         #define _udi_bus_bind_req_marshal_layout        _noargs_marshal
232         MEI_OPINFO(udi_bus_bind_req, REQ, 0, BUS_BIND, BUS_DEVICE,1, ,0),
233 //      {"udi_bus_bind_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_BIND_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,1, 0,0,
234 //              udi_bus_bind_req_direct, udi_bus_bind_req_backend, udi_meta_info__bridge__bus_bind_cb,
235 //              _noargs_marshal},
236         {"udi_bus_unbind_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_BIND_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,2, 0,0,
237                 udi_bus_unbind_req_direct, udi_bus_unbind_req_backend, udi_meta_info__bridge__bus_bind_cb,
238                 _noargs_marshal},
239         {"udi_intr_attach_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_INTR_ATTACH_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,3, 0,0,
240                 udi_intr_attach_req_direct, udi_intr_attach_req_backend, udi_meta_info__bridge__intr_attach_cb,
241                 _noargs_marshal},
242         {"udi_intr_detach_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_INTR_DETACH_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,4, 0,0,
243                 udi_intr_detach_req_direct, udi_intr_detach_req_backend, udi_meta_info__bridge__intr_detach_cb,
244                 _noargs_marshal},
245         {0}
246 };
247 udi_mei_op_template_t   udi_meta_info__bridge__device_ops[] = {
248         {"udi_bus_bind_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_BIND_CB_NUM, 0,0, 0,0,
249                 udi_bus_bind_ack_direct, udi_bus_bind_ack_backend, udi_meta_info__bridge__bus_bind_cb,
250                 _bus_bind_ack_marshal},
251         {"udi_bus_unbind_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_BIND_CB_NUM, 0,0, 0,0,
252                 udi_bus_unbind_ack_direct, udi_bus_unbind_ack_backend, udi_meta_info__bridge__bus_bind_cb,
253                 _noargs_marshal},
254         {"udi_intr_attach_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_INTR_ATTACH_CB_NUM, 0,0, 0,0,
255                 udi_intr_attach_ack_direct, udi_intr_attach_ack_backend, udi_meta_info__bridge__intr_attach_cb,
256                 _udi_intr_attach_ack_marshal},
257         {"udi_intr_detach_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_INTR_DETACH_CB_NUM, 0,0, 0,0,
258                 udi_intr_detach_ack_direct, udi_intr_detach_ack_backend, udi_meta_info__bridge__intr_detach_cb,
259                 _noargs_marshal},
260         {0}
261 };
262 udi_mei_ops_vec_template_t      udi_meta_info__bridge_ops[] = {
263         {UDI_BUS_BRIDGE_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND, udi_meta_info__bridge__bus_ops},
264         {UDI_BUS_DEVICE_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND, udi_meta_info__bridge__device_ops},
265         {0}
266 };
267 udi_mei_init_t  udi_meta_info__bridge = {
268         udi_meta_info__bridge_ops,
269         NULL
270 };
271 #endif
272 tUDI_MetaLang   cMetaLang_BusBridge = {
273         "udi_bridge",
274         #if USE_MEI
275         &udi_meta_info__bridge,
276         #else
277         NULL,
278         #endif
279         // CB Types
280         5,
281         {
282                 {0},    // 0: Empty
283                 {sizeof(udi_bus_bind_cb_t), udi_meta_info__bridge__bus_bind_cb},
284                 {sizeof(udi_intr_attach_cb_t), udi_meta_info__bridge__intr_attach_cb},
285                 {sizeof(udi_intr_detach_cb_t), udi_meta_info__bridge__intr_detach_cb},
286                 {sizeof(udi_intr_event_cb_t), NULL}
287         }
288 };

UCC git Repository :: git.ucc.asn.au