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/%)
--- /dev/null
+/*
+ * 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
+
#include <udi_internal_ma.h>
#include <trans_pci.h>
#include <trans_nsr.h>
+#include <trans_uart.h>
// === PROTOTYPES ===
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;
}
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;
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;
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++];
// 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);
}
}
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,
{
//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
};
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 )
{
{
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;
}
}
// 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,
}
}
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 ;
* trans/bus_pci.c
* - PCI Bus Driver
*/
-#define DEBUG 1
+#define DEBUG 0
#include <udi.h>
#include <udi_physio.h>
#include <udi_pci.h>
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;
.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
--- /dev/null
+/*
+ * 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 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);
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);
}
// 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;
}
}
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;
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 )
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];
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;
* \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);
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},
+ }
+};
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:
break;
case UDI_PIO_LOAD:
_read_mem(gcb, buf, mem_ptr, (pio_op&0x18), tran_size, reg, ®isters[operand]);
+ LOG("LOAD R%x = %i %x", operand, tran_size, registers[operand].words[0]);
_zero_upper(tran_size, ®isters[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, ®isters[operand]);
break;
}
reg->words[0] = operand;
break;
}
+ LOG("LOAD IMM ");
_zero_upper(tran_size, reg);
ip += (1<<tran_size)/2-1;
break;
}
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;
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: {
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;