# - UDI Library Files
LIB_OBJS := core/logging.o core/strmem.o core/imc.o core/mem.o core/buf.o
LIB_OBJS += core/queues.o core/time.o core/attr.o core/mei.o core/cb.o
+LIB_OBJS += core/layout.o
LIB_OBJS += core/meta_mgmt.o core/meta_gio.o
LIB_OBJS += physio.o physio/meta_bus.o physio/pio.o physio/dma.o
LIB_OBJS += scsi.o
#define _UDI_INTERNAL_H_
#include <stdbool.h>
+#include <stdarg.h>
#define NEW(type,extra) (type*)calloc(sizeof(type)extra,1)
#define NEW_wA(type,fld,cnt) NEW(type,+(sizeof(((type*)NULL)->fld[0])*cnt))
struct sUDI_MetaLang
{
const char *Name;
+ //void *MeiInfo;
int nCbTypes;
struct {
udi_size_t Size;
// --- CBs ---
extern void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel);
extern udi_cb_t *udi_cb_alloc_internal_v(tUDI_MetaLang *Meta, udi_index_t MetaCBNum, size_t inline_size, size_t scratch_size, udi_channel_t channel);
+extern tUDI_MetaLang *UDI_int_GetCbType(udi_cb_t *gcb, udi_index_t *meta_cb_num);
// --- Attribute Management ---
extern udi_instance_attr_type_t udi_instance_attr_get_internal(udi_cb_t *gcb, const char *attr_name, udi_ubit32_t child_ID, void *attr_value, udi_size_t attr_length, udi_size_t *actual_length);
+// --- Layout ---
+extern size_t _udi_marshal_values(void *buf, udi_layout_t *layout, va_list values);
+
#endif
else
{
// Attribute desired is missing, error?
- LOG("attr '%s' missing", dev_attr->attr_name);
+ //LOG("attr '%s' missing", dev_attr->attr_name);
}
}
//LOG("n_matches = %i", n_matches);
inst->FirstChild = child;
// and search for a handler
- tUDI_MetaLang *metalang = UDI_int_GetMetaLang(inst->Module, child->Ops->meta_idx);
+ child->Metalang = UDI_int_GetMetaLang(inst->Module, child->Ops->meta_idx);
int best_level = 0;
tUDI_DriverModule *best_module = NULL;
for( tUDI_DriverModule *module = gpUDI_LoadedModules; module; module = module->Next )
//LOG("%s:%i %p ?== %p",
// module->ModuleName, i,
// module->Devices[i]->Metalang, metalang);
- if( module->Devices[i]->Metalang != metalang )
+ if( module->Devices[i]->Metalang != child->Metalang )
continue ;
int level = UDI_MA_CheckDeviceMatch(
{
if( child->BoundInstance )
continue ;
- // TODO: Check metalangs
+ if( Module->Devices[i]->Metalang != child->Metalang )
+ continue ;
// Check for match
int level = UDI_MA_CheckDeviceMatch(
Module->Devices[i]->nAttribs, Module->Devices[i]->Attribs,
// TODO:
return UDI_STAT_NOT_SUPPORTED;
case UDI_PCI_BAR_0 ... UDI_PCI_BAR_5: {
- Uint64 bar = PCI_GetBAR(pciid, regset_idx);
+ Uint32 bar = PCI_GetBAR(pciid, regset_idx);
if(bar & 1)
{
// IO BAR
bar &= ~3;
#define _IO(fc, type) do {\
- if( isOutput ) out##fc(bar+ofs, *(type*)data); \
- else *(type*)data = in##fc(bar+ofs); \
+ if( isOutput ) { \
+ LOG("out"#fc"(0x%x, 0x%x)",bar+ofs,*(type*)data);\
+ out##fc(bar+ofs, *(type*)data); \
+ } \
+ else { \
+ *(type*)data = in##fc(bar+ofs); \
+ LOG("in"#fc"(0x%x) = 0x%x",bar+ofs,*(type*)data);\
+ }\
} while(0)
switch(len)
{
else
{
// Memory BAR
- bar = PCI_GetValidBAR(pciid, regset_idx, PCI_BARTYPE_MEM);
+ //Uint64 longbar = PCI_GetValidBAR(pciid, regset_idx, PCI_BARTYPE_MEM);
return UDI_STAT_NOT_SUPPORTED;
}
break; }
#include <acess.h>
#include <trans_nsr.h>
#include <IPStack/include/adapters_api.h>
+#include <workqueue.h>
+
+#define NUM_RX_BUFFERS 4
enum {
ACESSNSR_OPS_CTRL = 1,
ACESSNSR_META_NIC = 1
};
enum {
- ACESSNSR_CB_CTRL = 1
+ ACESSNSR_CB_CTRL = 1,
+ ACESSNSR_CB_RX,
+ ACESSNSR_CB_TX
};
// === TYPES ===
typedef struct
{
- udi_init_context_t init_context;
+ udi_init_context_t init_context;
+ udi_cb_t *active_cb;
+
+ udi_index_t init_idx;
+ udi_buf_t *rx_buffers[NUM_RX_BUFFERS];
+ udi_nic_rx_cb_t *rx_cbs[NUM_RX_BUFFERS];
+
+ tWorkqueue RXQueue;
+
+ tIPStack_AdapterType AdapterType;
+ void *ipstack_handle;
+
+ udi_channel_t rx_channel;
+ udi_channel_t tx_channel;
} acessnsr_rdata_t;
// === PROTOTYPES ===
void acessnsr_final_cleanup_req(udi_mgmt_cb_t *cb);
// --- NSR Control
void acessnsr_ctrl_channel_event_ind(udi_channel_event_cb_t *cb);
+void acessnsr_ctrl_ch_ev_ind__rx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel);
+void acessnsr_ctrl_ch_ev_ind__tx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel);
void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status);
+void acessnsr_ctrl_bind_ack__rx_buf_allocated(udi_cb_t *gcb, udi_buf_t *new_buf);
+void acessnsr_ctrl_bind_ack__rx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb);
void acessnsr_ctrl_unbind_ack(udi_nic_cb_t *cb, udi_status_t status);
void acessnsr_ctrl_enable_ack(udi_nic_cb_t *cb, udi_status_t status);
void acessnsr_ctrl_disable_ack(udi_nic_cb_t *cb, udi_status_t status);
void acessnsr_rx_channel_event_ind(udi_channel_event_cb_t *cb);
void acessnsr_rx_ind(udi_nic_rx_cb_t *cb);
void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb);
+// --- Acess IPStack
+ int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer);
+tIPStackBuffer *acessnsr_WaitForPacket(void *Card);
// === CODE ===
// --- Management metalang
void acessnsr_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
{
+ acessnsr_rdata_t *rdata = UDI_GCB(cb)->context;
+ switch(resource_level)
+ {
+ }
+
+ Workqueue_Init(&rdata->RXQueue, "AcessNSR RX", offsetof(udi_nic_rx_cb_t, chain));
+
+ udi_usage_res(cb);
}
void acessnsr_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID)
{
+ UNIMPLEMENTED();
}
void acessnsr_final_cleanup_req(udi_mgmt_cb_t *cb)
{
+ UNIMPLEMENTED();
}
// --- NSR Control
void acessnsr_ctrl_channel_event_ind(udi_channel_event_cb_t *cb)
{
- //acessnsr_rdata_t *rdata = UDI_GCB(cb)->context;
+ acessnsr_rdata_t *rdata = UDI_GCB(cb)->context;
switch(cb->event)
{
-
+ case UDI_CHANNEL_CLOSED:
+ break;
+ case UDI_CHANNEL_BOUND: {
+ rdata->active_cb = UDI_GCB(cb);
+ udi_channel_spawn(acessnsr_ctrl_ch_ev_ind__rx_channel_spawned,
+ cb->params.parent_bound.bind_cb, UDI_GCB(cb)->channel,
+ 1, ACESSNSR_OPS_RX, rdata);
+ // V V V V
+ break; }
}
}
+void acessnsr_ctrl_ch_ev_ind__rx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel)
+{
+ acessnsr_rdata_t *rdata = gcb->context;
+ rdata->rx_channel = channel;
+ udi_channel_spawn(acessnsr_ctrl_ch_ev_ind__tx_channel_spawned, gcb, gcb->channel,
+ 2, ACESSNSR_OPS_TX, rdata);
+ // V V V V
+}
+void acessnsr_ctrl_ch_ev_ind__tx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel)
+{
+ acessnsr_rdata_t *rdata = gcb->context;
+ rdata->tx_channel = channel;
+ udi_nic_bind_cb_t *bind_cb = UDI_MCB(gcb, udi_nic_bind_cb_t);
+ udi_nd_bind_req(bind_cb, 2, 1);
+ // V V V V
+}
void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status)
{
+ acessnsr_rdata_t *rdata = UDI_GCB(cb)->context;
+ // TODO: Parse cb and register with IPStack
+ // - Pass on capabilities and media type
+ switch(cb->media_type)
+ {
+ case UDI_NIC_ETHER: rdata->AdapterType.Type = ADAPTERTYPE_ETHERNET_10M; break;
+ case UDI_NIC_FASTETHER: rdata->AdapterType.Type = ADAPTERTYPE_ETHERNET_100M; break;
+ case UDI_NIC_GIGETHER: rdata->AdapterType.Type = ADAPTERTYPE_ETHERNET_1G; break;
+ default:
+ udi_channel_event_complete( UDI_MCB(rdata->active_cb,udi_channel_event_cb_t), UDI_OK );
+ break;
+ }
+
+ if(cb->capabilities & UDI_NIC_CAP_TX_IP_CKSUM)
+ rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_IP4;
+ if(cb->capabilities & UDI_NIC_CAP_TX_TCP_CKSUM)
+ rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_TCP;
+ if(cb->capabilities & UDI_NIC_CAP_TX_UDP_CKSUM)
+ rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_UDP;
+
+ rdata->AdapterType.Name = "udi";
+ rdata->AdapterType.SendPacket = acessnsr_SendPacket;
+ rdata->AdapterType.WaitForPacket = acessnsr_WaitForPacket;
+
+ rdata->ipstack_handle = IPStack_Adapter_Add(&rdata->AdapterType, rdata, cb->mac_addr);
+
+ // Allocate RX CBs and buffers
+ rdata->init_idx = -1;
+ acessnsr_ctrl_bind_ack__rx_buf_allocated(rdata->active_cb, NULL);
+ // V V V V
+}
+void acessnsr_ctrl_bind_ack__rx_buf_allocated(udi_cb_t *gcb, udi_buf_t *new_buf)
+{
+ acessnsr_rdata_t *rdata = gcb->context;
+ if( rdata->init_idx != (udi_index_t)-1 )
+ {
+ rdata->rx_buffers[rdata->init_idx] = new_buf;
+ }
+ rdata->init_idx ++;
+ if( rdata->init_idx < NUM_RX_BUFFERS )
+ {
+ UDI_BUF_ALLOC(acessnsr_ctrl_bind_ack__rx_buf_allocated, gcb, NULL, 0, NULL);
+ // A A A A
+ return ;
+ }
+
+ rdata->init_idx = -1;
+ acessnsr_ctrl_bind_ack__rx_cb_allocated(gcb, NULL);
+}
+void acessnsr_ctrl_bind_ack__rx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb)
+{
+ acessnsr_rdata_t *rdata = gcb->context;
+ if( rdata->init_idx != (udi_index_t)-1 )
+ {
+ udi_nic_rx_cb_t *cb = UDI_MCB(new_cb, udi_nic_rx_cb_t);
+ rdata->rx_cbs[rdata->init_idx] = cb;
+ cb->rx_buf = rdata->rx_buffers[rdata->init_idx];
+ udi_nd_rx_rdy(cb);
+ }
+ rdata->init_idx ++;
+ if( rdata->init_idx < NUM_RX_BUFFERS )
+ {
+ udi_cb_alloc(acessnsr_ctrl_bind_ack__rx_cb_allocated, gcb, ACESSNSR_CB_RX, rdata->rx_channel);
+ // A A A A
+ return ;
+ }
+ udi_channel_event_complete( UDI_MCB(rdata->active_cb,udi_channel_event_cb_t), UDI_OK );
+ // = = = =
}
void acessnsr_ctrl_unbind_ack(udi_nic_cb_t *cb, udi_status_t status)
{
+ UNIMPLEMENTED();
}
void acessnsr_ctrl_enable_ack(udi_nic_cb_t *cb, udi_status_t status)
{
+ UNIMPLEMENTED();
}
void acessnsr_ctrl_disable_ack(udi_nic_cb_t *cb, udi_status_t status)
{
+ UNIMPLEMENTED();
}
void acessnsr_ctrl_ctrl_ack(udi_nic_ctrl_cb_t *cb, udi_status_t status)
{
+ UNIMPLEMENTED();
}
void acessnsr_ctrl_status_ind(udi_nic_status_cb_t *cb)
{
+ UNIMPLEMENTED();
}
void acessnsr_ctrl_info_ack(udi_nic_info_cb_t *cb)
{
+ UNIMPLEMENTED();
}
// --- NSR TX
void acessnsr_tx_channel_event_ind(udi_channel_event_cb_t *cb)
{
+ UNIMPLEMENTED();
}
void acessnsr_tx_rdy(udi_nic_tx_cb_t *cb)
{
+ UNIMPLEMENTED();
}
// --- NSR RX
void acessnsr_rx_channel_event_ind(udi_channel_event_cb_t *cb)
{
+ UNIMPLEMENTED();
}
void acessnsr_rx_ind(udi_nic_rx_cb_t *cb)
{
+ acessnsr_rdata_t *rdata = UDI_GCB(cb)->context;
+ udi_nic_rx_cb_t *next;
+ do {
+ next = cb->chain;
+ Workqueue_AddWork(&rdata->RXQueue, cb);
+ } while( (cb = next) );
}
void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb)
{
+ UNIMPLEMENTED();
+}
+// --- Acess IPStack
+int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer)
+{
+ UNIMPLEMENTED();
+ return 1;
+}
+void _FreeHeapSubBuf(void *Arg, size_t Pre, size_t Post, const void *DataBuf)
+{
+ free(Arg);
+}
+tIPStackBuffer *acessnsr_WaitForPacket(void *Card)
+{
+ acessnsr_rdata_t *rdata = Card;
+ udi_nic_rx_cb_t *cb = Workqueue_GetWork(&rdata->RXQueue);
+
+ tIPStackBuffer *ret = IPStack_Buffer_CreateBuffer(1);
+ void *data = malloc( cb->rx_buf->buf_size );
+ udi_buf_read(cb->rx_buf, 0, cb->rx_buf->buf_size, data);
+ IPStack_Buffer_AppendSubBuffer(ret, cb->rx_buf->buf_size, 0, data, _FreeHeapSubBuf, data);
+
+ udi_nd_rx_rdy(cb);
+ return ret;
}
// === UDI Bindings ===
};
udi_cb_init_t acessnsr_cb_init_list[] = {
{ACESSNSR_CB_CTRL, ACESSNSR_META_NIC, UDI_NIC_BIND_CB_NUM, 0, 0,NULL},
+ {ACESSNSR_CB_RX, ACESSNSR_META_NIC, UDI_NIC_RX_CB_NUM, 0, 0,NULL},
+ {ACESSNSR_CB_TX, ACESSNSR_META_NIC, UDI_NIC_TX_CB_NUM, 0, 0,NULL},
{0}
};
const udi_init_t acessnsr_init = {
*/
#include <acess.h>
#include <udi.h>
+#include <udi_internal.h>
+
+typedef struct sUDI_BufTag
+{
+ struct sUDI_BufTag *Next;
+// udi_buf_tag_t tag;
+ struct sUDI_BufSect *Sect;
+} tUDI_BufTag;
+
+typedef struct sUDI_BufSect
+{
+ struct sUDI_BufSect *Next;
+ size_t Offset;
+ size_t Length;
+ size_t Space;
+ // data
+} tUDI_BufSect;
+
+typedef struct
+{
+ udi_buf_t buf;
+ tUDI_BufTag *Tags;
+ tUDI_BufSect *Sections;
+} tUDI_BufInt;
// === EXPORTS ===
EXPORT(udi_buf_copy);
* \param src_len Length of source data
* \param dst_buf Destination buffer
* \param dst_off Destination offset in the buffer
- * \param dst_len Length of destination area (What the?, Redundant
- * Department of redundacny department)
+ * \param dst_len Length of destination area
* \param path_handle ???
*/
void udi_buf_write(
udi_buf_path_t path_handle
)
{
- UNIMPLEMENTED();
+ tUDI_BufInt *dst = (void*)dst_buf;
+ if( !dst ) {
+ dst = NEW(tUDI_BufInt,);
+ }
+
+ if( dst_len == 0 )
+ {
+ // Insert / Initialise
+ if( src_len > 0 )
+ {
+ Log_Warning("UDI", "TODO: udi_buf_write - insert");
+ }
+ // no-op
+ else
+ {
+ }
+ }
+ else
+ {
+ // Overwrite
+ if( src_len > 0 )
+ {
+ Log_Warning("UDI", "TODO: udi_buf_write - overwrite");
+ }
+ // Delete
+ else
+ {
+ Log_Warning("UDI", "TODO: udi_buf_write - delete");
+ }
+ }
+
+ callback(gcb, &dst->buf);
}
void udi_buf_read(
#include <udi_internal.h>
#include <udi_internal_ma.h> // for cUDI_MgmtCbInitList
+typedef struct sUDI_CBHeader
+{
+ tUDI_MetaLang *Metalang;
+ udi_index_t MetaCBNum;
+ udi_cb_t cb;
+} tUDI_CBHeader;
+
// === CODE ===
+tUDI_MetaLang *UDI_int_GetCbType(udi_cb_t *cb, udi_index_t *meta_cb_num)
+{
+ tUDI_CBHeader *hdr = (void*)cb - offsetof(tUDI_CBHeader, cb);
+ if(meta_cb_num)
+ *meta_cb_num = hdr->MetaCBNum;
+ return hdr->Metalang;
+}
+
udi_cb_t *udi_cb_alloc_internal_v(tUDI_MetaLang *Meta, udi_index_t MetaCBNum,
size_t inline_size, size_t scratch_size, udi_channel_t channel)
{
ASSERTC(base, >=, sizeof(udi_cb_t));
base -= sizeof(udi_cb_t);
LOG("+ %i + %i + %i", base, inline_size, scratch_size);
- udi_cb_t *ret = NEW(udi_cb_t, + base + inline_size + scratch_size);
+ tUDI_CBHeader *cbhdr = NEW(tUDI_CBHeader, + base + inline_size + scratch_size);
+ cbhdr->Metalang = Meta;
+ cbhdr->MetaCBNum = MetaCBNum;
+ udi_cb_t *ret = &cbhdr->cb;
ret->channel = channel;
- ret->scratch = (void*)ret + sizeof(udi_cb_t) + base + inline_size;
+ ret->scratch = (void*)(ret + 1) + base + inline_size;
return ret;
}
void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel)
void udi_cb_free(udi_cb_t *cb)
{
+ tUDI_CBHeader *hdr = (void*)cb - offsetof(tUDI_CBHeader, cb);
// TODO: Ensure that cb is inactive
- free(cb);
+ free(hdr);
}
void udi_cancel(udi_cancel_call_t *callback, udi_cb_t *gcb)
udi_index_t ops_idx, void *channel_context
)
{
- LOG("gcb=%p,channel=%p", gcb, channel, spawn_idx, ops_idx, channel_context);
+ LOG("gcb=%p,channel=%p,spawn_idx=%i,ops_idx=%i,channel_context=%p",
+ gcb, channel, spawn_idx, ops_idx, channel_context);
// Search existing channel for a matching spawn_idx
udi_channel_t ret = UDI_CreateChannel_Linked(channel, spawn_idx);
--- /dev/null
+/*
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * udi_lib/core/layout.c
+ * - udi_layout_t related functions
+ */
+#define DEBUG 1
+#include <udi.h>
+#include <acess.h>
+#include <udi_internal.h>
+
+// === CODE ===
+#define alignto(ofs,type) \
+ ofs + ((sizeof(type)-ofs%sizeof(type)) % sizeof(type));
+#define _PUT(type,vtype) do{\
+ ofs = alignto(ofs,type); \
+ if(buf){\
+ *(type*)(buf+ofs) = va_arg(values,vtype);\
+ LOG(#type" %p %x", buf+ofs, *(type*)(buf+ofs));\
+ }\
+ else va_arg(values,vtype); \
+ ofs += sizeof(type); \
+}while(0)
+
+size_t _udi_marshal_values(void *buf, udi_layout_t *layout, va_list values)
+{
+ size_t ofs = 0;
+ while( *layout != UDI_DL_END )
+ {
+ switch(*layout++)
+ {
+ case UDI_DL_UBIT8_T: _PUT(udi_ubit8_t, UDI_VA_UBIT8_T); break;
+ case UDI_DL_SBIT8_T: _PUT(udi_sbit8_t, UDI_VA_SBIT8_T); break;
+ case UDI_DL_UBIT16_T: _PUT(udi_ubit16_t, UDI_VA_UBIT16_T); break;
+ case UDI_DL_SBIT16_T: _PUT(udi_sbit16_t, UDI_VA_SBIT16_T); break;
+ case UDI_DL_UBIT32_T: _PUT(udi_ubit32_t, UDI_VA_UBIT32_T); break;
+ case UDI_DL_SBIT32_T: _PUT(udi_sbit32_t, UDI_VA_SBIT16_T); break;
+ case UDI_DL_BOOLEAN_T: _PUT(udi_boolean_t, UDI_VA_BOOLEAN_T); break;
+ case UDI_DL_STATUS_T: _PUT(udi_status_t, UDI_VA_STATUS_T); break;
+
+ case UDI_DL_INDEX_T: _PUT(udi_index_t, UDI_VA_INDEX_T); break;
+
+ case UDI_DL_CHANNEL_T: _PUT(udi_channel_t, UDI_VA_CHANNEL_T); break;
+ case UDI_DL_ORIGIN_T: _PUT(udi_origin_t, UDI_VA_ORIGIN_T); break;
+
+ default:
+ Log_Error("UDI", "_udi_marshal_values - Unknown layout code %i", layout[-1]);
+ return -1;
+ }
+ }
+ return ofs;
+}
* udi_lib/mei.c
* - Metalanguage-to-Environment Interface
*/
+#define DEBUG 1
#include <udi.h>
#include <acess.h>
+#include <udi_internal.h>
+
+typedef struct {
+ tUDI_DeferredCall DCall;
+ const udi_mei_op_template_t *mei_op;
+} tUDI_MeiCall;
// === CODE ===
+void _udi_mei_call_unmarshal(tUDI_DeferredCall *DCall)
+{
+ tUDI_MeiCall *Call = (void*)DCall;
+ const udi_mei_op_template_t *mei_op = Call->mei_op;
+ mei_op->backend_stub(Call->DCall.Handler, Call->DCall.cb, Call+1);
+}
+
void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops_num, udi_index_t vec_idx, ...)
{
- UNIMPLEMENTED();
+ ENTER("pgcb pmeta_info imeta_ops_num ivec_idx",
+ gcb, meta_info, meta_ops_num, vec_idx);
+ const udi_mei_op_template_t *mei_op;
+
+ {
+ udi_mei_ops_vec_template_t *ops = meta_info->ops_vec_template_list;
+ for( ; ops->meta_ops_num && ops->meta_ops_num != meta_ops_num; ops ++ )
+ ;
+ if( !ops->meta_ops_num ) {
+ LEAVE('-');
+ return ;
+ }
+ mei_op = &ops->op_template_list[vec_idx-1];
+ }
+
+ LOG("%s", mei_op->op_name);
+
+ // Check CB type
+ udi_index_t cb_type;
+ tUDI_MetaLang *metalang = UDI_int_GetCbType(gcb, &cb_type);
+ //if( metalang->MeiInfo != meta_info )
+ // return ;
+ if( mei_op->meta_cb_num != cb_type ) {
+ LEAVE('-');
+ return ;
+ }
+ // Check call type
+ udi_op_t *const*ops = UDI_int_ChannelPrepForCall(gcb, metalang, meta_ops_num);
+ udi_op_t *op = ops[vec_idx];
+
+ // Start va_args
+ // Determine if indirect call is needed
+ // > check stack depth?
+ // > Direction?
+ int indirect_call = (mei_op->op_category == UDI_MEI_OPCAT_REQ)
+ || (mei_op->op_category == UDI_MEI_OPCAT_IND);
+ if( indirect_call )
+ {
+ va_list args;
+ va_start(args, vec_idx);
+ size_t marshal_size = _udi_marshal_values(NULL, mei_op->marshal_layout, args);
+ va_end(args);
+ tUDI_MeiCall *call = malloc(sizeof(tUDI_MeiCall) + marshal_size);
+ call->DCall.Next = NULL;
+ call->DCall.Unmarshal = _udi_mei_call_unmarshal;
+ call->DCall.cb = gcb;
+ call->DCall.Handler = op;
+ call->mei_op = mei_op;
+ void *marshal_space = (void*)(call+1);
+ va_start(args, vec_idx);
+ _udi_marshal_values(marshal_space, mei_op->marshal_layout, args);
+ va_end(args);
+
+ UDI_int_AddDeferred(&call->DCall);
+ }
+ else
+ {
+ va_list args;
+ va_start(args, vec_idx);
+ mei_op->direct_stub( op, gcb, args );
+ va_end(args);
+ }
+ LEAVE('-');
}
UDI_DL_END
};
+#define UDI__OPS_NUM 0
+#define MEI_OPINFO(name,cat,flags,cbtype,rsp_ops,rsp_idx,err_ops,err_idx) \
+ {#name, UDI_MEI_OPCAT_##cat,flags,UDI_##cbtype##_CB_NUM, \
+ UDI_##rsp_ops##_OPS_NUM,rsp_idx,UDI_##err_ops##_OPS_NUM,err_idx, \
+ name##_direct, name##_backend, _##cbtype##_cb_layout, _##name##_marshal_layout }
+
udi_mei_op_template_t udi_meta_info__bridge__bus_ops[] = {
- {"udi_bus_bind_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_BIND_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,1, 0,0,
- udi_bus_bind_req_direct, udi_bus_bind_req_backend, udi_meta_info__bridge__bus_bind_cb,
- _noargs_marshal},
+ #define _udi_bus_bind_req_marshal_layout _noargs_marshal
+ MEI_OPINFO(udi_bus_bind_req, REQ, 0, BUS_BIND, BUS_DEVICE,1, ,0),
+// {"udi_bus_bind_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_BIND_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,1, 0,0,
+// udi_bus_bind_req_direct, udi_bus_bind_req_backend, udi_meta_info__bridge__bus_bind_cb,
+// _noargs_marshal},
{"udi_bus_unbind_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_BIND_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,2, 0,0,
udi_bus_unbind_req_direct, udi_bus_unbind_req_backend, udi_meta_info__bridge__bus_bind_cb,
_noargs_marshal},
{
LOG("gcb=%p,regset_idx=%i,base_offset=0x%x,length=0x%x,trans_list=%p,list_length=%i,...",
gcb, regset_idx, base_offset, length, trans_list, list_length);
- char bus_type[16];
+ char bus_type[16] = {0};
udi_instance_attr_type_t type;
type = udi_instance_attr_get_internal(gcb, "bus_type", 0, bus_type, sizeof(bus_type), NULL);
if(type != UDI_ATTR_STRING) {
}
else {
// Oops, unknown
+ Log_Warning("UDI", "Unknown bus type %s", bus_type);
callback(gcb, UDI_NULL_PIO_HANDLE);
return ;
}
break;
case UDI_PIO_SCRATCH:
ASSERTCR( (ofs & (size-1)), ==, 0, 1);
+ LOG("scr %p+%i = %i %x,...", gcb->scratch, ofs, size, val->words[0]);
memcpy(gcb->scratch + ofs, val, size);
break;
case UDI_PIO_BUF:
+ LOG("buf %p+%i = %i %x,...", buf, ofs, size, val->words[0]);
udi_buf_write(NULL,NULL, val, size, buf, ofs, size, UDI_NULL_BUF_PATH);
break;
case UDI_PIO_MEM:
ASSERTCR( (ofs & (size-1)), ==, 0, 1);
+ LOG("mem %p+%i = %i %x,...", mem_ptr, ofs, size, val->words[0]);
memcpy(mem_ptr + ofs, val, size);
break;
}
pio_handle->IOFunc(pio_handle->ChildID, pio_handle->RegSet,
pio_ofs, tran_size, &tmpval, dir_is_out);
if( !dir_is_out )
- _read_mem(gcb,buf,mem_ptr, mode, tran_size,
+ _write_mem(gcb,buf,mem_ptr, mode, tran_size,
mem_reg, &tmpval);
pio_ofs += pio_stride;
if( mode != UDI_PIO_DIRECT )
/**
- * \file physio.c
- * \author John Hodge (thePowersGang)
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * udi_lib/udi_nic.c
+ * - Network Interface metalanguage
*/
+#define DEBUG 1
#include <udi.h>
#include <udi_nic.h>
#include <acess.h> // for EXPORT
#include <udi_internal.h>
+
+extern udi_mei_init_t udi_mei_info__nic;
+#define udi_mei_info udi_mei_info__nic
+
// === EXPORTS ===
EXPORT(udi_nd_bind_req);
EXPORT(udi_nsr_bind_ack);
EXPORT(udi_nsr_exp_rx_ind);
EXPORT(udi_nd_rx_rdy);
-#define UDI_NIC_STD_CB_NUM 1
-#define UDI_NIC_BIND_CB_NUM 2
-#define UDI_NIC_CTRL_CB_NUM 3
-#define UDI_NIC_STATUS_CB_NUM 4
-#define UDI_NIC_INFO_CB_NUM 5
-#define UDI_NIC_TX_CB_NUM 6
-#define UDI_NIC_RX_CB_NUM 7
// === GLOBALS ===
tUDI_MetaLang cMetaLang_NIC = {
"udi_nic",
// === CODE ===
// --- Control Ops ---
-void udi_nd_bind_req(udi_nic_bind_cb_t *cb, udi_index_t tx_chan_index, udi_index_t rx_chan_index)
-{
- UNIMPLEMENTED();
-}
-
-void udi_nsr_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status)
-{
- UNIMPLEMENTED();
-}
+UDI_MEI_STUBS(udi_nd_bind_req, udi_nic_bind_cb_t,
+ 2,
+ (tx_chan_index, rx_chan_index),
+ (udi_index_t, udi_index_t),
+ (UDI_VA_INDEX_T, UDI_VA_INDEX_T),
+ UDI_ND_CTRL_OPS_NUM, 1)
+udi_layout_t _udi_nd_bind_req_marshal_layout[] = { UDI_DL_INDEX_T, UDI_DL_INDEX_T, UDI_DL_END };
+UDI_MEI_STUBS(udi_nsr_bind_ack, udi_nic_bind_cb_t,
+ 1, (status), (udi_status_t), (UDI_VA_STATUS_T),
+ UDI_NSR_CTRL_OPS_NUM, 1)
+udi_layout_t _udi_nsr_bind_ack_marshal_layout[] = { UDI_DL_STATUS_T, UDI_DL_END };
void udi_nd_unbind_req(udi_nic_cb_t *cb)
{
}
// --- RX ---
-void udi_nsr_rx_ind(udi_nic_rx_cb_t *cb)
-{
- UNIMPLEMENTED();
-}
-
-void udi_nsr_exp_rx_ind(udi_nic_rx_cb_t *cb)
-{
- UNIMPLEMENTED();
-}
+UDI_MEI_STUBS(udi_nsr_rx_ind, udi_nic_rx_cb_t, 0, (), (), (), UDI_NSR_RX_OPS_NUM, 1)
+udi_layout_t _udi_nsr_rx_ind_marshal_layout[] = { UDI_DL_END };
+UDI_MEI_STUBS(udi_nsr_exp_rx_ind, udi_nic_rx_cb_t, 0, (), (), (), UDI_NSR_RX_OPS_NUM, 2)
+udi_layout_t _udi_nsr_exp_rx_ind_marshal_layout[] = { UDI_DL_END };
+UDI_MEI_STUBS(udi_nd_rx_rdy, udi_nic_rx_cb_t, 0, (), (), (), UDI_ND_RX_OPS_NUM, 1)
+udi_layout_t _udi_nd_rx_rdy_marshal_layout[] = { UDI_DL_END };
+
+#define UDI__OPS_NUM 0
+#define MEI_OPINFO(name,cat,flags,cbtype,rsp_ops,rsp_idx,err_ops,err_idx) \
+ {#name, UDI_MEI_OPCAT_##cat,flags,UDI_##cbtype##_CB_NUM, \
+ UDI_##rsp_ops##_OPS_NUM,rsp_idx,UDI_##err_ops##_OPS_NUM,err_idx, \
+ name##_direct, name##_backend, _##cbtype##_cb_layout, _##name##_marshal_layout }
+
+udi_layout_t _NIC_BIND_cb_layout[] = {
+ UDI_DL_UBIT8_T, // media_type
+ UDI_DL_UBIT32_T, // min_pdu_size
+ UDI_DL_UBIT32_T,
+ UDI_DL_UBIT32_T,
+ UDI_DL_UBIT32_T,
+ UDI_DL_UBIT8_T, // max_perfect_multicast
+ UDI_DL_UBIT8_T,
+ UDI_DL_UBIT8_T, // mac_addr_len
+ UDI_DL_ARRAY, // mac_addr
+ UDI_NIC_MAC_ADDRESS_SIZE,
+ UDI_DL_UBIT8_T,
+ UDI_DL_END,
+ UDI_DL_END
+};
+udi_layout_t _NIC_RX_cb_layout[] = {
+ UDI_DL_CB, // chain
+ UDI_DL_BUF, 0, 0, 0, // rx_buf
+ UDI_DL_UBIT8_T, // rx_status
+ UDI_DL_UBIT8_T, // addr_match
+ UDI_DL_UBIT8_T, // rx_valid
+ UDI_DL_END
+};
-void udi_nd_rx_rdy(udi_nic_rx_cb_t *cb)
-{
- UNIMPLEMENTED();
-}
+udi_mei_op_template_t udi_mei_info__nic__nd_ctrl_ops[] = {
+ MEI_OPINFO(udi_nd_bind_req, REQ, 0, NIC_BIND, NSR_CTRL,1, ,0),
+ {0}
+};
+udi_mei_op_template_t udi_mei_info__nic__nsr_ctrl_ops[] = {
+ MEI_OPINFO(udi_nsr_bind_ack, ACK, 0, NIC_BIND, ,0, ,0),
+ {0}
+};
+udi_mei_op_template_t udi_mei_info__nic__nd_tx_ops[] = {
+ {0}
+};
+udi_mei_op_template_t udi_mei_info__nic__nsr_tx_ops[] = {
+ {0}
+};
+udi_mei_op_template_t udi_mei_info__nic__nd_rx_ops[] = {
+ MEI_OPINFO(udi_nd_rx_rdy, RDY, 0, NIC_RX, ,0, ,0),
+ {0}
+};
+udi_mei_op_template_t udi_mei_info__nic__nsr_rx_ops[] = {
+ MEI_OPINFO(udi_nsr_rx_ind, IND, 0, NIC_RX, ND_RX,1, ,0),
+ MEI_OPINFO(udi_nsr_exp_rx_ind, IND, 0, NIC_RX, ND_RX,1, ,0),
+ {0}
+};
+udi_mei_ops_vec_template_t udi_mei_info__nic_ops[] = {
+ {UDI_ND_CTRL_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND|UDI_MEI_REL_INITIATOR, udi_mei_info__nic__nd_ctrl_ops},
+ {UDI_NSR_CTRL_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND, udi_mei_info__nic__nsr_ctrl_ops},
+ {UDI_ND_TX_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_INITIATOR, udi_mei_info__nic__nd_tx_ops},
+ {UDI_NSR_TX_OPS_NUM, UDI_MEI_REL_EXTERNAL, udi_mei_info__nic__nsr_tx_ops},
+ {UDI_ND_RX_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_INITIATOR, udi_mei_info__nic__nd_rx_ops},
+ {UDI_NSR_RX_OPS_NUM, UDI_MEI_REL_EXTERNAL, udi_mei_info__nic__nsr_rx_ops},
+ {0}
+};
+udi_mei_init_t udi_mei_info__nic = {
+ udi_mei_info__nic_ops,
+ NULL
+};