From 3fe3238f90216eeec97778e3ae91f462d27c60ac Mon Sep 17 00:00:00 2001 From: John Hodge Date: Wed, 9 Oct 2013 23:07:40 +0800 Subject: [PATCH] Modules/UDI - MEI working, used for nic --- KernelLand/Modules/Interfaces/UDI/Makefile | 1 + .../Interfaces/UDI/include/udi_internal.h | 6 + .../Modules/Interfaces/UDI/management_agent.c | 9 +- .../Modules/Interfaces/UDI/trans/bus_pci.c | 14 +- KernelLand/Modules/Interfaces/UDI/trans/nsr.c | 176 +++++++++++++++++- .../Modules/Interfaces/UDI/udi_lib/core/buf.c | 60 +++++- .../Modules/Interfaces/UDI/udi_lib/core/cb.c | 25 ++- .../Modules/Interfaces/UDI/udi_lib/core/imc.c | 3 +- .../Interfaces/UDI/udi_lib/core/layout.c | 53 ++++++ .../Modules/Interfaces/UDI/udi_lib/core/mei.c | 78 +++++++- .../Interfaces/UDI/udi_lib/physio/meta_bus.c | 14 +- .../Interfaces/UDI/udi_lib/physio/pio.c | 8 +- .../Modules/Interfaces/UDI/udi_lib/udi_nic.c | 124 +++++++++--- 13 files changed, 515 insertions(+), 56 deletions(-) create mode 100644 KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c diff --git a/KernelLand/Modules/Interfaces/UDI/Makefile b/KernelLand/Modules/Interfaces/UDI/Makefile index 1f99c954..ed7c3b81 100644 --- a/KernelLand/Modules/Interfaces/UDI/Makefile +++ b/KernelLand/Modules/Interfaces/UDI/Makefile @@ -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 diff --git a/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h b/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h index 7bebc2fb..ff7f2786 100644 --- a/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h +++ b/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h @@ -9,6 +9,7 @@ #define _UDI_INTERNAL_H_ #include +#include #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 diff --git a/KernelLand/Modules/Interfaces/UDI/management_agent.c b/KernelLand/Modules/Interfaces/UDI/management_agent.c index 536c28ff..ec815d45 100644 --- a/KernelLand/Modules/Interfaces/UDI/management_agent.c +++ b/KernelLand/Modules/Interfaces/UDI/management_agent.c @@ -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, diff --git a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c index daf07f27..e5d3bf45 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c @@ -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; } diff --git a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c index a6135711..2ea4506c 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c @@ -11,6 +11,9 @@ #include #include #include +#include + +#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 = { diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c index 5327cc8b..a9df466b 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c @@ -6,6 +6,30 @@ */ #include #include +#include + +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( diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c index 14bcd326..010eed09 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c @@ -9,7 +9,22 @@ #include #include // 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) diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/imc.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/imc.c index e6529dae..49476588 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/imc.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/imc.c @@ -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 index 00000000..97db27c8 --- /dev/null +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c @@ -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 +#include +#include + +// === 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; +} diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c index e92afce3..e0caec7e 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c @@ -5,12 +5,88 @@ * udi_lib/mei.c * - Metalanguage-to-Environment Interface */ +#define DEBUG 1 #include #include +#include + +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('-'); } diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c index 1102d74a..af5b88f0 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c @@ -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}, diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c index c2c229c1..8297eab9 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c @@ -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 ) diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c index 00790f03..751a369e 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c @@ -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 #include #include // for EXPORT #include + +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 +}; -- 2.20.1