Modules/UDI - GIO Metalanguage Binding, GIO UART support, init error handling
authorJohn Hodge <[email protected]>
Mon, 3 Feb 2014 05:13:23 +0000 (13:13 +0800)
committerJohn Hodge <[email protected]>
Mon, 3 Feb 2014 05:14:40 +0000 (13:14 +0800)
12 files changed:
KernelLand/Modules/Interfaces/UDI/Makefile
KernelLand/Modules/Interfaces/UDI/include/trans_uart.h [new file with mode: 0644]
KernelLand/Modules/Interfaces/UDI/main.c
KernelLand/Modules/Interfaces/UDI/management_agent.c
KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c
KernelLand/Modules/Interfaces/UDI/trans/gio_uart.c [new file with mode: 0644]
KernelLand/Modules/Interfaces/UDI/trans/nsr.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_gio.c
KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c

index ed7c3b8..3b1387b 100644 (file)
@@ -12,7 +12,7 @@ LIB_OBJS += physio.o physio/meta_bus.o physio/pio.o physio/dma.o
 LIB_OBJS += scsi.o
 LIB_OBJS += udi_nic.o
 # - UDI->Acess Translation Layer
-TRANS_OBJS := bus_pci.o nsr.o
+TRANS_OBJS := bus_pci.o nsr.o gio_uart.o
 
 OBJ  = main.o channels.o deferred_calls.o management_agent.o
 OBJ += $(LIB_OBJS:%=udi_lib/%) $(TRANS_OBJS:%=trans/%)
diff --git a/KernelLand/Modules/Interfaces/UDI/include/trans_uart.h b/KernelLand/Modules/Interfaces/UDI/include/trans_uart.h
new file mode 100644 (file)
index 0000000..42e256b
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * trans_uart.h
+ * - Attaches a PTY to a GIO "uart" type
+ */
+#ifndef _TRANS_UART_H_
+#define _TRANS_UART_H_
+
+extern const udi_init_t        acessuart_init;
+extern const char      acessuart_udiprops[];
+extern size_t  acessuart_udiprops_size;
+
+#endif
+
index fabdcbb..7a61d81 100644 (file)
@@ -14,6 +14,7 @@
 #include <udi_internal_ma.h>
 #include <trans_pci.h>
 #include <trans_nsr.h>
+#include <trans_uart.h>
 
 // === PROTOTYPES ===
  int   UDI_Install(char **Arguments);
@@ -42,6 +43,7 @@ int UDI_Install(char **Arguments)
 
        UDI_int_LoadDriver(NULL, &pci_init, pci_udiprops, pci_udiprops_size);
        UDI_int_LoadDriver(NULL, &acessnsr_init, acessnsr_udiprops, acessnsr_udiprops_size);
+       UDI_int_LoadDriver(NULL, &acessuart_init, acessuart_udiprops, acessuart_udiprops_size);
 
        return MODULE_ERR_OK;
 }
@@ -406,6 +408,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, co
        driver_module->Devices      = NEW(tUDI_PropDevSpec*,* driver_module->nDevices);
 
        // Populate
+       bool    error_hit = false;
         int    cur_locale = 0;
         int    msg_index = 0;
         int    ml_index = 0;
@@ -424,13 +427,13 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, co
                case UDIPROPS__properties_version:
                        if( _get_token_uint32(str, &str) != 0x101 ) {
                                Log_Warning("UDI", "Properties version mismatch.");
+                               error_hit = true;
                        }
                        break;
                case UDIPROPS__module:
                        driver_module->ModuleName = str;
                        break;
-               case UDIPROPS__meta:
-                       {
+               case UDIPROPS__meta: {
                        tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++];
                        ml->meta_idx = _get_token_idx(str, &str);
                        if( !str )      continue;
@@ -440,9 +443,10 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, co
                        if( !ml->metalang ) {
                                Log_Error("UDI", "Module %s referenced unsupported metalang %s",
                                        driver_module->ModuleName, ml->interface_name);
+                               error_hit = true;
+                               // TODO: error
                        }
-                       break;
-                       }
+                       break; }
                case UDIPROPS__message:
                        {
                        tUDI_PropMessage *msg = &driver_module->Messages[msg_index++];
@@ -641,6 +645,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, co
                                        // TODO: Array
                                        Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'");
                                        _get_token_str(str, &str, NULL);
+                                       error_hit = true;
                                        break;
                                case 3: // ubit32
                                        at->attr_length = sizeof(udi_ubit32_t);
@@ -666,6 +671,20 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, co
                }
        }
        free(udipropsptrs);
+       if( error_hit ) {
+               Log_Error("UDI", "Error encountered while parsing udiprops for '%s' (%p), bailing",
+                       driver_module->ModuleName, LoadBase);
+               for( int i = 0; i < device_index; i ++ )
+                       free(driver_module->Devices[i]);
+               free(driver_module->Messages);
+               free(driver_module->RegionTypes);
+               free(driver_module->MetaLangs);
+               free(driver_module->Parents);
+               free(driver_module->ChildBindOps);
+               free(driver_module->Devices);
+               free(driver_module);
+               return NULL;
+       }
 
        for( int i = 0; i < driver_module->nDevices; i ++ )
                driver_module->Devices[i]->Metalang = UDI_int_GetMetaLang(driver_module,
@@ -790,9 +809,11 @@ const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name)
 {
        //extern tUDI_MetaLang  cMetaLang_Management;
        extern tUDI_MetaLang    cMetaLang_BusBridge;
+       extern tUDI_MetaLang    cMetaLang_GIO;
        extern tUDI_MetaLang    cMetaLang_NIC;
        const tUDI_MetaLang     *langs[] = {
                &cMetaLang_BusBridge,
+               &cMetaLang_GIO,
                &cMetaLang_NIC,
                NULL
        };
index ec815d4..5ac91a4 100644 (file)
@@ -26,6 +26,7 @@ tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule,
        udi_primary_init_t      *pri_init = DriverModule->InitInfo->primary_init_info;
        inst->Module = DriverModule;
        inst->Regions[0] = UDI_MA_InitRegion(inst, 0, 0, pri_init->rdata_size);
+       if( !inst->Regions[0] ) goto _error;
        udi_secondary_init_t    *sec_init = DriverModule->InitInfo->secondary_init_list;
        if( sec_init )
        {
@@ -33,6 +34,7 @@ tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule,
                {
                        inst->Regions[1+i] = UDI_MA_InitRegion(inst, i,
                                sec_init[i].region_idx, sec_init[i].rdata_size);
+                       if( !inst->Regions[1+i] )       goto _error;
                }
        }
 
@@ -70,6 +72,11 @@ tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule,
        // udi_usage_res causes next state transition
        
        return inst;
+_error:
+       for( int i = 0; i < DriverModule->nRegions; i++ )
+               free(inst->Regions[i]);
+       free(inst);
+       return NULL;
 }
 
 tUDI_DriverRegion *UDI_MA_InitRegion(tUDI_DriverInstance *Inst,
@@ -176,7 +183,7 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
                }
        }
        if( !child->BindOps ) {
-               Log_Error("UDI", "Driver '%s' doesn't have a 'child_bind_ops' for %i",
+               Log_Error("UDI", "Driver '%s' doesn't have a 'child_bind_ops' for ops_idx %i",
                        inst->Module->ModuleName, ops_idx);
                free(child);
                return ;
index 2d7459a..2582804 100644 (file)
@@ -5,7 +5,7 @@
  * trans/bus_pci.c
  * - PCI Bus Driver
  */
-#define DEBUG  1
+#define DEBUG  0
 #include <udi.h>
 #include <udi_physio.h>
 #include <udi_pci.h>
@@ -156,6 +156,13 @@ void pci_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
                        attr_list ++;
                        DPT_SET_ATTR32(attr_list, "pci_device_id", dev);
                        attr_list ++;
+                       
+                       DPT_SET_ATTR32(attr_list, "pci_baseclass", class >> 16);
+                       attr_list ++;
+                       DPT_SET_ATTR32(attr_list, "pci_sub_class", (class >> 8) & 0xFF);
+                       attr_list ++;
+                       DPT_SET_ATTR32(attr_list, "pci_prog_if", (class >> 0) & 0xFF);
+                       attr_list ++;
 
                        cb->attr_valid_length = attr_list - cb->attr_list;
                        cb->child_ID = rdata->cur_iter;
@@ -384,7 +391,7 @@ udi_primary_init_t  pci_pri_init = {
        .mgmt_ops = &pci_mgmt_ops,
        .mgmt_op_flags = pci_mgmt_op_flags,
        .mgmt_scratch_requirement = 0,
-       .enumeration_attr_list_length = 4,
+       .enumeration_attr_list_length = 7,
        .rdata_size = sizeof(pci_rdata_t),
        .child_data_size = 0,
        .per_parent_paths = 0
diff --git a/KernelLand/Modules/Interfaces/UDI/trans/gio_uart.c b/KernelLand/Modules/Interfaces/UDI/trans/gio_uart.c
new file mode 100644 (file)
index 0000000..4149145
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * trans/gio_uart.c
+ * - GIO UART translation (presents "uart" type GIO drivers as serial ports)
+ */
+#define DEBUG  1
+#include <udi.h>
+//#include <udi_gio.h>
+#include <acess.h>
+#include <drv_pty.h>
+#include <trans_uart.h>
+#include <workqueue.h>
+
+#define NUM_TX_CBS     1
+
+typedef struct {
+       udi_init_context_t      init_context;
+       udi_cb_t        *active_cb;
+       tPTY    *PTYInstance;
+       tWorkqueue      CBWorkQueue;
+} rdata_t;
+
+enum {
+       ACESSUART_CB_BIND = 1,
+       ACESSUART_CB_XFER
+};
+enum {
+       ACESSUART_OPS_GIO = 1
+};
+enum {
+       ACESSUART_META_GIO = 1,
+};
+
+// === PROTOTYPES ===
+void   acessuart_pty_output(void *Handle, size_t Length, const void *Data);
+
+// === CODE ===
+void acessuart_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
+{
+       udi_cb_t        *gcb = UDI_GCB(cb);
+       rdata_t *rdata = gcb->context;
+       Workqueue_Init(&rdata->CBWorkQueue, "UDI UART TX", offsetof(udi_gio_xfer_cb_t, gcb.initiator_context));
+       udi_usage_res(cb);
+}
+void acessuart_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID)
+{
+       UNIMPLEMENTED();
+}
+void acessuart_final_cleanup_req(udi_mgmt_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+// ----
+void acessuart_channel_event_ind(udi_channel_event_cb_t *cb);
+void acessuart_channel_event_ind__tx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_cb);
+void acessuart_bind_ack(udi_gio_bind_cb_t *cb, udi_ubit32_t device_size_lo, udi_ubit32_t device_size_hi, udi_status_t status);
+
+void acessuart_channel_event_ind(udi_channel_event_cb_t *cb)
+{
+       udi_cb_t        *gcb = UDI_GCB(cb);
+       rdata_t *rdata = gcb->context;
+       ASSERT(rdata);
+       switch(cb->event)
+       {
+       case UDI_CHANNEL_CLOSED:
+               break;
+       case UDI_CHANNEL_BOUND: {
+               rdata->active_cb = gcb;
+               // 
+               udi_cb_alloc_batch(acessuart_channel_event_ind__tx_cbs_allocated, cb->params.parent_bound.bind_cb,
+                       ACESSUART_CB_XFER, NUM_TX_CBS, FALSE, 0, UDI_NULL_BUF_PATH);
+               // V V V V
+               break; }
+       }
+}
+void acessuart_channel_event_ind__tx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_cb)
+{
+       rdata_t *rdata = gcb->context;
+       udi_gio_bind_cb_t       *cb = UDI_MCB(gcb, udi_gio_bind_cb_t);
+       ASSERT(rdata);
+
+       while( first_cb )
+       {
+               udi_cb_t        *next = first_cb->initiator_context;
+               first_cb->initiator_context = NULL;
+               Workqueue_AddWork(&rdata->CBWorkQueue, first_cb);
+               first_cb = next;
+       }
+
+       udi_gio_bind_req(cb);
+       // continued in acessuart_bind_ack
+}
+void acessuart_bind_ack(udi_gio_bind_cb_t *cb, udi_ubit32_t device_size_lo, udi_ubit32_t device_size_hi, udi_status_t status)
+{
+       udi_cb_t        *gcb = UDI_GCB(cb);
+       rdata_t *rdata = gcb->context;
+       udi_channel_event_cb_t  *channel_cb = UDI_MCB(rdata->active_cb, udi_channel_event_cb_t);
+       
+       if( device_size_lo != 0 || device_size_hi != 0 ) {
+               // Oops... binding failed. UARTS should not have a size
+               udi_channel_event_complete( channel_cb, UDI_STAT_NOT_UNDERSTOOD);
+               return ;
+       }
+       
+       // bound, create PTY instance
+       rdata->PTYInstance = PTY_Create("serial#", rdata, acessuart_pty_output, NULL, NULL);
+       if( !rdata->PTYInstance ) {
+               udi_channel_event_complete(channel_cb, UDI_STAT_RESOURCE_UNAVAIL);
+               return ;
+       }
+       
+       udi_channel_event_complete(channel_cb, UDI_OK);
+}
+void acessuart_unbind_ack(udi_gio_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void acessuart_xfer_ack(udi_gio_xfer_cb_t *cb)
+{
+       udi_cb_t        *gcb = UDI_GCB(cb);
+       rdata_t *rdata = gcb->context;
+       if( cb->op == UDI_GIO_OP_WRITE ) {
+               // Write, no action required except returning the CB to the pool
+               udi_buf_free(cb->data_buf);
+               Workqueue_AddWork(&rdata->CBWorkQueue, cb);
+               return ;
+       }
+       else if( cb->op == UDI_GIO_OP_READ ) {
+               // Send data to PTY
+               UNIMPLEMENTED();
+       }
+       else {
+               // Well, that was unexpected
+       }
+}
+void acessuart_xfer_nak(udi_gio_xfer_cb_t *cb, udi_status_t status)
+{
+       UNIMPLEMENTED();
+}
+void acessuart_event_ind(udi_gio_event_cb_t *cb)
+{
+       // grab the input CB, and request data
+       UNIMPLEMENTED();
+}
+
+
+void acessuart_pty_output(void *Handle, size_t Length, const void *Data);
+void acessuart_pty_output__buf_allocated(udi_cb_t *gcb, udi_buf_t *buffer);
+
+void acessuart_pty_output(void *Handle, size_t Length, const void *Data)
+{
+       LOG("Output '%.*s'", Length, Data);
+       
+       rdata_t *rdata = Handle;
+       udi_gio_xfer_cb_t       *cb = Workqueue_GetWork(&rdata->CBWorkQueue);
+       udi_cb_t        *gcb = UDI_GCB(cb);
+       
+       UDI_BUF_ALLOC(acessuart_pty_output__buf_allocated, gcb, Data, Length, UDI_NULL_BUF_PATH);
+       // don't bother waiting for tx to complete, workqueue will block when everything is in use
+}
+void acessuart_pty_output__buf_allocated(udi_cb_t *gcb, udi_buf_t *buffer)
+{
+       //rdata_t       *rdata = gcb->context;
+       LOG("buffer = %p\n", buffer);
+       udi_gio_xfer_cb_t       *cb = UDI_MCB(gcb, udi_gio_xfer_cb_t);
+
+       cb->op = UDI_GIO_OP_WRITE;
+       cb->tr_params = NULL;
+       cb->data_buf = buffer;  
+
+       udi_gio_xfer_req(cb);
+}
+
+
+// --------------------------------------------------------------------
+udi_mgmt_ops_t acessuart_mgmt_ops = {
+       acessuart_usage_ind,
+       udi_enumerate_no_children,
+       acessuart_devmgmt_req,
+       acessuart_final_cleanup_req
+};
+udi_ubit8_t    acessuart_mgmt_ops_flags[4] = {0,0,0,0};
+
+udi_primary_init_t     acessuart_pri_init = {
+       .mgmt_ops = &acessuart_mgmt_ops,
+       .mgmt_op_flags = acessuart_mgmt_ops_flags,
+       .mgmt_scratch_requirement = 0,
+       .enumeration_attr_list_length = 0,
+       .rdata_size = sizeof(rdata_t),
+       .child_data_size = 0,
+       .per_parent_paths = 0
+};
+
+udi_gio_client_ops_t   acessuart_gio_ops = {
+       acessuart_channel_event_ind,
+       acessuart_bind_ack,
+       acessuart_unbind_ack,
+       acessuart_xfer_ack,
+       acessuart_xfer_nak,
+       acessuart_event_ind
+};
+udi_ubit8_t    acessuart_gio_op_flags[7] = {0};
+
+udi_ops_init_t acessuart_ops_list[] = {
+       {
+               ACESSUART_OPS_GIO, ACESSUART_META_GIO, UDI_GIO_CLIENT_OPS_NUM,
+               0, (udi_ops_vector_t*)&acessuart_gio_ops, acessuart_gio_op_flags
+       },
+       {0}
+};
+udi_cb_init_t  acessuart_cb_init_list[] = {
+       {ACESSUART_CB_BIND, ACESSUART_META_GIO, UDI_GIO_BIND_CB_NUM, 0, 0,NULL},
+       {ACESSUART_CB_XFER, ACESSUART_META_GIO, UDI_GIO_XFER_CB_NUM, 0, 0,NULL},
+       {0}
+};
+const udi_init_t       acessuart_init = {
+       .primary_init_info = &acessuart_pri_init,
+       .ops_init_list = acessuart_ops_list,
+       .cb_init_list = acessuart_cb_init_list,
+};
+const char     acessuart_udiprops[] = 
+       "properties_version 0x101\0"
+       "message 1 Acess2 Kernel\0"
+       "message 2 John Hodge ([email protected])\0"
+       "message 3 Acess2 UART\0"
+       "supplier 1\0"
+       "contact 2\0"
+       "name 3\0"
+       "module acess_uart\0"
+       "shortname acessuart\0"
+       "requires udi 0x101\0"
+       "requires udi_gio 0x101\0"
+       "meta 1 udi_gio\0"
+       "message 101 UART\0"
+       "device 101 1 gio_type string uart\0"
+       "parent_bind_ops 1 0 1 1\0"
+       "\0";
+size_t acessuart_udiprops_size = sizeof(acessuart_udiprops);
index 616c365..d9c4357 100644 (file)
@@ -333,7 +333,7 @@ void acessnsr_SendPacket__buf_write_complete(udi_cb_t *gcb, udi_buf_t *buf)
        udi_nd_tx_req(cb);
        // continued in acessnsr_tx_rdy
 }
-void _FreeHeapSubBuf(void *Arg, size_t Pre, size_t Post, const void *DataBuf)
+static void _FreeHeapSubBuf(void *Arg, size_t Pre, size_t Post, const void *DataBuf)
 {
        free(Arg);
 }
index b4116a0..9bf8f11 100644 (file)
@@ -160,7 +160,14 @@ void udi_cb_alloc_batch(
                                // No-op        
                        }
                        
-                       cur_ofs += _udi_marshal_step(NULL, 0, &layout, NULL);
+                       size_t  sz = _udi_marshal_step(NULL, 0, &layout, NULL);
+                       if( sz == 0 ) {
+                               Log_Warning("UDI", "Metalang CB %s:%i has an invalid layout",
+                                       metalang->Name, cb_init->meta_cb_num);
+                               callback(gcb, NULL);
+                               return ;
+                       }
+                       cur_ofs += sz;
                }
        }
 
index 2df3178..45f601b 100644 (file)
        ofs += sizeof(type); \
 }while(0)
 
-size_t _udi_marshal_step(void *buf, size_t cur_ofs, udi_layout_t **layoutp, va_list *values)
+size_t _udi_marshal_step(void *buf, size_t cur_ofs, const udi_layout_t **layoutp, va_list *values)
 {
        size_t  ofs = cur_ofs;
-       udi_layout_t    *layout = *layoutp;
+       const udi_layout_t      *layout = *layoutp;
        switch(*layout++)
        {
        case UDI_DL_UBIT8_T:    _PUT(udi_ubit8_t, UDI_VA_UBIT8_T);      break;
@@ -51,16 +51,32 @@ size_t _udi_marshal_step(void *buf, size_t cur_ofs, udi_layout_t **layoutp, va_l
        case UDI_DL_CB:
                _PUT(udi_cb_t*,UDI_VA_POINTER);
                break;
+       case UDI_DL_INLINE_UNTYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               break;
+       case UDI_DL_INLINE_DRIVER_TYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               break;
+       case UDI_DL_MOVABLE_UNTYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               break;
+       
+       case UDI_DL_INLINE_TYPED:
+       case UDI_DL_MOVABLE_TYPED:
+               _PUT(void*,UDI_VA_POINTER);
+               while(*layout++ != UDI_DL_END)
+                       ;
+               break;
 
        default:
-               Log_Error("UDI", "_udi_marshal_values - Unknown layout code %i", layout[-1]);
+               Log_Error("UDI", "_udi_marshal_step - Unknown layout code %i", layout[-1]);
                return 0;
        }
        *layoutp = layout;
        return ofs;
 }
 
-size_t _udi_marshal_values(void *buf, udi_layout_t *layout, va_list values)
+size_t _udi_marshal_values(void *buf, const udi_layout_t *layout, va_list values)
 {
        size_t  ofs = 0;
        while( *layout != UDI_DL_END )
index 051df92..29217ac 100644 (file)
@@ -35,7 +35,7 @@ void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops
                for( ; ops->meta_ops_num && ops->meta_ops_num != meta_ops_num; ops ++ )
                        ;
                if( !ops->meta_ops_num ) {
-                       LEAVE('-');
+//                     LEAVE('-');
                        return ;
                }
                mei_op = &ops->op_template_list[vec_idx-1];
@@ -82,6 +82,11 @@ void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops
                va_list args;
                va_start(args, vec_idx);
                size_t  marshal_size = _udi_marshal_values(NULL, mei_op->marshal_layout, args);
+               if( marshal_size == 0 && mei_op->marshal_layout[0] != UDI_DL_END ) {
+                       Warning("udi_mei_call(%s) - Marshalling failure", mei_op->op_name);
+//                     LEAVE('-');
+                       return ;
+               }
                va_end(args);
                tUDI_MeiCall    *call = malloc(sizeof(tUDI_MeiCall) + marshal_size);
                call->DCall.Next = NULL;
index 1618c27..11a1749 100644 (file)
@@ -2,8 +2,9 @@
  * \file meta_gio.c
  * \author John Hodge (thePowersGang)
  */
-#include <acess.h>
+#include <acess.h>     // EXPORT
 #include <udi.h>
+#include <udi_internal.h>      // tUDI_MetaLang
 
 // === EXPORTS ===
 EXPORT(udi_gio_bind_req);
@@ -17,52 +18,136 @@ EXPORT(udi_gio_event_res);
 EXPORT(udi_gio_event_ind);
 EXPORT(udi_gio_event_res_unused);
 
+extern udi_mei_init_t  udi_mei_info__gio;
+#define udi_mei_info   udi_mei_info__gio
+
 // === CODE ===
-void udi_gio_bind_req(udi_gio_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_bind_ack(
-       udi_gio_bind_cb_t       *cb,
-       udi_ubit32_t    device_size_lo,
-       udi_ubit32_t    device_size_hi,
-       udi_status_t    status
-       )
-{
-       UNIMPLEMENTED();
-}
+UDI_MEI_STUBS(udi_gio_bind_req, udi_gio_bind_cb_t,
+       0, (), (), (),
+       UDI_GIO_PROVIDER_OPS_NUM, 1)
+udi_layout_t   _udi_gio_bind_req_marshal_layout[] = { UDI_DL_END };
 
-void udi_gio_unbind_req(udi_gio_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_unbind_ack(udi_gio_bind_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
+UDI_MEI_STUBS(udi_gio_bind_ack, udi_gio_bind_cb_t,
+       3, (device_size_lo, device_size_hi, status), (udi_ubit32_t, udi_ubit32_t, udi_status_t), (UDI_VA_UBIT32_T, UDI_VA_UBIT32_T, UDI_VA_STATUS_T),
+       UDI_GIO_CLIENT_OPS_NUM, 1)
+udi_layout_t   _udi_gio_bind_ack_marshal_layout[] = { UDI_DL_UBIT32_T, UDI_DL_UBIT32_T, UDI_DL_INDEX_T, UDI_DL_END };
 
-void udi_gio_xfer_req(udi_gio_xfer_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_xfer_ack(udi_gio_xfer_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_xfer_nak(udi_gio_xfer_cb_t *cb, udi_status_t status)
-{
-       UNIMPLEMENTED();
-}
 
-void udi_gio_event_res(udi_gio_event_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-void udi_gio_event_ind(udi_gio_event_cb_t *cb)
+
+UDI_MEI_STUBS(udi_gio_unbind_req, udi_gio_bind_cb_t,
+       0, (), (), (),
+       UDI_GIO_PROVIDER_OPS_NUM, 2)
+udi_layout_t   _udi_gio_unbind_req_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_gio_unbind_ack, udi_gio_bind_cb_t,
+       0, (), (), (),
+       UDI_GIO_CLIENT_OPS_NUM, 2)
+udi_layout_t   _udi_gio_unbind_ack_marshal_layout[] = { UDI_DL_END };
+
+
+UDI_MEI_STUBS(udi_gio_xfer_req, udi_gio_xfer_cb_t,
+       0, (), (), (),
+       UDI_GIO_PROVIDER_OPS_NUM, 3)
+udi_layout_t   _udi_gio_xfer_req_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_gio_xfer_ack, udi_gio_xfer_cb_t,
+       0, (), (), (),
+       UDI_GIO_CLIENT_OPS_NUM, 3)
+udi_layout_t   _udi_gio_xfer_ack_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_gio_xfer_nak, udi_gio_xfer_cb_t,
+       1, (status), (udi_status_t), (UDI_VA_STATUS_T),
+       UDI_GIO_CLIENT_OPS_NUM, 4)
+udi_layout_t   _udi_gio_xfer_nak_marshal_layout[] = { UDI_DL_STATUS_T, UDI_DL_END };
+
+
+UDI_MEI_STUBS(udi_gio_event_res, udi_gio_event_cb_t,
+       0, (), (), (),
+       UDI_GIO_PROVIDER_OPS_NUM, 4)
+udi_layout_t   _udi_gio_event_res_marshal_layout[] = { UDI_DL_END };
+
+void udi_gio_event_ind_unused(udi_gio_event_cb_t *cb)
 {
        UNIMPLEMENTED();
 }
+
+UDI_MEI_STUBS(udi_gio_event_ind, udi_gio_event_cb_t,
+       0, (), (), (),
+       UDI_GIO_CLIENT_OPS_NUM, 5)
+udi_layout_t   _udi_gio_event_ind_marshal_layout[] = { UDI_DL_END };
+
 void udi_gio_event_res_unused(udi_gio_event_cb_t *cb)
 {
        UNIMPLEMENTED();
 }
+
+// -----------
+// 1: UDI_GIO_BIND_CB_NUM
+udi_layout_t   _GIO_BIND_cb_layout[] = {
+       //UDI_DL_XFER_CONSTRAINTS,
+               UDI_DL_UBIT32_T,
+               UDI_DL_UBIT32_T,
+               UDI_DL_UBIT32_T,
+               UDI_DL_BOOLEAN_T,
+               UDI_DL_BOOLEAN_T,
+               UDI_DL_BOOLEAN_T,
+       UDI_DL_END
+};
+// 2: UDI_GIO_XFER_CB_NUM
+udi_layout_t   _GIO_XFER_cb_layout[] = {
+       UDI_DL_UBIT8_T, // udi_gio_op_t
+       UDI_DL_INLINE_DRIVER_TYPED,
+       UDI_DL_BUF,
+               offsetof(udi_gio_xfer_cb_t, op),
+               UDI_GIO_DIR_WRITE,
+               UDI_GIO_DIR_WRITE,
+       UDI_DL_END
+};
+// 3: UDI_GIO_EVENT_CB_NUM
+udi_layout_t   _GIO_EVENT_cb_layout[] = {
+       UDI_DL_UBIT8_T,
+       UDI_DL_INLINE_DRIVER_TYPED,
+       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_mei_info__gio__prov_ops[] = {
+       MEI_OPINFO(udi_gio_bind_req, REQ, 0, GIO_BIND, GIO_CLIENT,1, ,0),
+       MEI_OPINFO(udi_gio_unbind_req, REQ, 0, GIO_BIND, GIO_CLIENT,2, ,0),
+       MEI_OPINFO(udi_gio_xfer_req, REQ, UDI_MEI_OP_ABORTABLE, GIO_XFER, GIO_CLIENT,3, GIO_CLIENT,4),
+       MEI_OPINFO(udi_gio_event_res, RES, 0, GIO_EVENT, ,0, ,0),
+       {0}
+};
+udi_mei_op_template_t  udi_mei_info__gio__client_ops[] = {
+       MEI_OPINFO(udi_gio_bind_ack, ACK, 0, GIO_BIND, ,0, ,0),
+       MEI_OPINFO(udi_gio_unbind_ack, ACK, 0, GIO_BIND, ,0, ,0),
+       MEI_OPINFO(udi_gio_xfer_ack, ACK, 0, GIO_XFER, ,0, ,0),
+       MEI_OPINFO(udi_gio_xfer_nak, ACK, 0, GIO_XFER, ,0, ,0),
+       MEI_OPINFO(udi_gio_event_ind, IND, 0, GIO_EVENT, GIO_PROVIDER,4, ,0),
+       {0}
+};
+udi_mei_ops_vec_template_t     udi_mei_info__gio_ops[] = {
+       {UDI_GIO_PROVIDER_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND|UDI_MEI_REL_INITIATOR, udi_mei_info__gio__prov_ops},
+       {UDI_GIO_CLIENT_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND, udi_mei_info__gio__client_ops},
+       {0}
+};
+udi_mei_init_t udi_mei_info__gio = {
+       udi_mei_info__gio_ops,
+       NULL
+};
+tUDI_MetaLang  cMetaLang_GIO = {
+       "udi_gio",
+       &udi_mei_info__gio,
+       4,
+       {
+               {0},
+               {sizeof(udi_gio_bind_cb_t),  0, _GIO_BIND_cb_layout},
+               {sizeof(udi_gio_xfer_cb_t),  0, _GIO_XFER_cb_layout},
+               {sizeof(udi_gio_event_cb_t), 0, _GIO_EVENT_cb_layout},
+       }
+};
index 635544c..f0428fc 100644 (file)
@@ -375,6 +375,7 @@ void udi_pio_trans(udi_pio_trans_call_t *callback, udi_cb_t *gcb,
                        case UDI_PIO_IN:
                                pio_handle->IOFunc(pio_handle->ChildID, pio_handle->RegSet,
                                        operand, tran_size, &tmpval, false);
+                               LOG("IN %x = %i %x", operand, tran_size, tmpval.words[0]);
                                _write_mem(gcb, buf, mem_ptr, (pio_op&0x18), tran_size, reg, &tmpval);
                                break;
                        case UDI_PIO_OUT:
@@ -385,9 +386,11 @@ void udi_pio_trans(udi_pio_trans_call_t *callback, udi_cb_t *gcb,
                                break;
                        case UDI_PIO_LOAD:
                                _read_mem(gcb, buf, mem_ptr, (pio_op&0x18), tran_size, reg, &registers[operand]);
+                               LOG("LOAD R%x = %i %x", operand, tran_size, registers[operand].words[0]);
                                _zero_upper(tran_size, &registers[operand]);
                                break;
                        case UDI_PIO_STORE:
+                               LOG("STORE R%x (%i %x)", operand, tran_size, registers[operand].words[0]);
                                _write_mem(gcb, buf, mem_ptr, (pio_op&0x18), tran_size, reg, &registers[operand]);
                                break;
                        }
@@ -425,6 +428,7 @@ void udi_pio_trans(udi_pio_trans_call_t *callback, udi_cb_t *gcb,
                                        reg->words[0] = operand;
                                        break;
                                }
+                               LOG("LOAD IMM ");
                                _zero_upper(tran_size, reg);
                                ip += (1<<tran_size)/2-1;
                                break;
@@ -455,11 +459,13 @@ void udi_pio_trans(udi_pio_trans_call_t *callback, udi_cb_t *gcb,
                                }
                                break; }
                        case UDI_PIO_IN_IND:
+                               LOG("IN IND");
                                pio_handle->IOFunc(pio_handle->ChildID, pio_handle->RegSet,
                                        registers[operand].words[0], tran_size, reg, false);
                                _zero_upper(tran_size, reg);
                                break;
                        case UDI_PIO_OUT_IND:
+                               LOG("OUT IND");
                                pio_handle->IOFunc(pio_handle->ChildID, pio_handle->RegSet,
                                        registers[operand].words[0], tran_size, reg, true);
                                break;
@@ -522,10 +528,12 @@ void udi_pio_trans(udi_pio_trans_call_t *callback, udi_cb_t *gcb,
                        switch(pio_op)
                        {
                        case UDI_PIO_BRANCH:
+                               LOG("BRANCH %i", operand);
                                ip = _get_label(pio_handle, operand);
                                break;
                        case UDI_PIO_LABEL:
                                // nop
+                               LOG("LABEL %i", operand);
                                break;
                        case UDI_PIO_REP_IN_IND:
                        case UDI_PIO_REP_OUT_IND: {
@@ -594,8 +602,10 @@ void udi_pio_trans(udi_pio_trans_call_t *callback, udi_cb_t *gcb,
                                        ret_status = registers[operand].words[0] & 0xFFFF;
                                else
                                        ret_status = registers[operand].words[0] & 0xFF;
+                               LOG("END R%i 0x%x", operand, ret_status);
                                goto end;
                        case UDI_PIO_END_IMM:
+                               LOG("END IMM 0x%x", operand);
                                ASSERTC(tran_size, ==, UDI_PIO_2BYTE);
                                ret_status = operand;
                                goto end;

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