Modules/UDI - MEI working, used for nic
authorJohn Hodge <[email protected]>
Wed, 9 Oct 2013 15:07:40 +0000 (23:07 +0800)
committerJohn Hodge <[email protected]>
Wed, 9 Oct 2013 15:07:40 +0000 (23:07 +0800)
13 files changed:
KernelLand/Modules/Interfaces/UDI/Makefile
KernelLand/Modules/Interfaces/UDI/include/udi_internal.h
KernelLand/Modules/Interfaces/UDI/management_agent.c
KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c
KernelLand/Modules/Interfaces/UDI/trans/nsr.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/imc.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c [new file with mode: 0644]
KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c
KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c
KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c
KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c

index 1f99c95..ed7c3b8 100644 (file)
@@ -6,6 +6,7 @@ CPPFLAGS = -I../../../../UDI/include -Iinclude
 # - 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
index 7bebc2f..ff7f278 100644 (file)
@@ -9,6 +9,7 @@
 #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))
@@ -70,6 +71,7 @@ struct sUDI_PropRegion
 struct sUDI_MetaLang
 {
        const char *Name;
+       //void  *MeiInfo;
         int    nCbTypes;
        struct {
                udi_size_t      Size;
@@ -208,9 +210,13 @@ extern void        UDI_int_MakeDeferredCbS(udi_cb_t *cb, udi_op_t *handler, udi_status_
 // --- 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
 
index 536c28f..ec815d4 100644 (file)
@@ -134,7 +134,7 @@ int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs,
                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);
@@ -186,7 +186,7 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
        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 )
@@ -196,7 +196,7 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
                        //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(
@@ -228,7 +228,8 @@ void UDI_MA_BindParents(tUDI_DriverModule *Module)
                        {
                                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,
index daf07f2..e5d3bf4 100644 (file)
@@ -296,14 +296,20 @@ udi_status_t pci_pio_do_io(uint32_t child_ID, udi_ubit32_t regset_idx, udi_ubit3
                // 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)
                        {
@@ -319,7 +325,7 @@ udi_status_t pci_pio_do_io(uint32_t child_ID, udi_ubit32_t regset_idx, udi_ubit3
                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; }
index a613571..2ea4506 100644 (file)
@@ -11,6 +11,9 @@
 #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,
@@ -21,13 +24,28 @@ enum {
        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 ===
@@ -37,7 +55,11 @@ void acessnsr_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t pa
 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);
@@ -51,64 +73,208 @@ void acessnsr_tx_rdy(udi_nic_tx_cb_t *cb);
 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 ===
@@ -171,6 +337,8 @@ udi_ops_init_t      acessnsr_ops_list[] = {
 };
 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 = {
index 5327cc8..a9df466 100644 (file)
@@ -6,6 +6,30 @@
  */
 #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);
@@ -37,8 +61,7 @@ void 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(
@@ -52,7 +75,38 @@ 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(
index 14bcd32..010eed0 100644 (file)
@@ -9,7 +9,22 @@
 #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)
 {
@@ -18,9 +33,12 @@ udi_cb_t *udi_cb_alloc_internal_v(tUDI_MetaLang *Meta, udi_index_t MetaCBNum,
        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)
@@ -103,8 +121,9 @@ void udi_cb_alloc_batch(
 
 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)
index e6529da..4947658 100644 (file)
@@ -36,7 +36,8 @@ extern void udi_channel_spawn(
        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);
diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c
new file mode 100644 (file)
index 0000000..97db27c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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;
+}
index e92afce..e0caec7 100644 (file)
@@ -5,12 +5,88 @@
  * 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('-');
 }
 
index 1102d74..af5b88f 100644 (file)
@@ -217,10 +217,18 @@ udi_layout_t      _udi_intr_attach_ack_marshal[] = {
        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},
index c2c229c..8297eab 100644 (file)
@@ -54,7 +54,7 @@ void udi_pio_map(udi_pio_map_call_t *callback, udi_cb_t *gcb,
 {
        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) {
@@ -71,6 +71,7 @@ void udi_pio_map(udi_pio_map_call_t *callback, udi_cb_t *gcb,
        }
        else {
                // Oops, unknown
+               Log_Warning("UDI", "Unknown bus type %s", bus_type);
                callback(gcb, UDI_NULL_PIO_HANDLE);
                return ;
        }
@@ -319,13 +320,16 @@ static inline int _write_mem(udi_cb_t *gcb, udi_buf_t *buf, void *mem_ptr,
                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;
        }
@@ -540,7 +544,7 @@ void udi_pio_trans(udi_pio_trans_call_t *callback, udi_cb_t *gcb,
                                        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 )
index 00790f0..751a369 100644 (file)
@@ -1,12 +1,20 @@
 /**
- * \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);
@@ -29,13 +37,6 @@ EXPORT(udi_nsr_rx_ind);
 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",
@@ -54,15 +55,17 @@ tUDI_MetaLang       cMetaLang_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)
 {
@@ -131,18 +134,77 @@ void udi_nd_exp_tx_req(udi_nic_tx_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
+};

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