From: John Hodge Date: Mon, 3 Feb 2014 05:13:23 +0000 (+0800) Subject: Modules/UDI - GIO Metalanguage Binding, GIO UART support, init error handling X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=3bbdda25a43af7c2c97719ff7ebd9fd2187ae272;p=tpg%2Facess2.git Modules/UDI - GIO Metalanguage Binding, GIO UART support, init error handling --- diff --git a/KernelLand/Modules/Interfaces/UDI/Makefile b/KernelLand/Modules/Interfaces/UDI/Makefile index ed7c3b81..3b1387be 100644 --- a/KernelLand/Modules/Interfaces/UDI/Makefile +++ b/KernelLand/Modules/Interfaces/UDI/Makefile @@ -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 index 00000000..42e256b9 --- /dev/null +++ b/KernelLand/Modules/Interfaces/UDI/include/trans_uart.h @@ -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 + diff --git a/KernelLand/Modules/Interfaces/UDI/main.c b/KernelLand/Modules/Interfaces/UDI/main.c index fabdcbbe..7a61d81f 100644 --- a/KernelLand/Modules/Interfaces/UDI/main.c +++ b/KernelLand/Modules/Interfaces/UDI/main.c @@ -14,6 +14,7 @@ #include #include #include +#include // === 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 }; diff --git a/KernelLand/Modules/Interfaces/UDI/management_agent.c b/KernelLand/Modules/Interfaces/UDI/management_agent.c index ec815d45..5ac91a42 100644 --- a/KernelLand/Modules/Interfaces/UDI/management_agent.c +++ b/KernelLand/Modules/Interfaces/UDI/management_agent.c @@ -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 ; diff --git a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c index 2d7459a8..2582804f 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c @@ -5,7 +5,7 @@ * trans/bus_pci.c * - PCI Bus Driver */ -#define DEBUG 1 +#define DEBUG 0 #include #include #include @@ -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 index 00000000..41491457 --- /dev/null +++ b/KernelLand/Modules/Interfaces/UDI/trans/gio_uart.c @@ -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 +//#include +#include +#include +#include +#include + +#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 (acess@mutabah.net)\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); diff --git a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c index 616c3650..d9c43575 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c @@ -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); } diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c index b4116a01..9bf8f118 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c @@ -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; } } diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c index 2df3178e..45f601b3 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c @@ -24,10 +24,10 @@ 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 ) diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c index 051df92b..29217ac8 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c @@ -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; diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_gio.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_gio.c index 1618c27f..11a17499 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_gio.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_gio.c @@ -2,8 +2,9 @@ * \file meta_gio.c * \author John Hodge (thePowersGang) */ -#include +#include // EXPORT #include +#include // 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}, + } +}; diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c index 635544c1..f0428fc7 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c @@ -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, ®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; } @@ -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<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;