From 40b1565117870d9124e3afee02d008e0bd9fcd66 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 4 Oct 2013 21:14:56 +0800 Subject: [PATCH] Modules/UDI - Enumeration working, ne2000 starting to bind to PCI --- KernelLand/Modules/Interfaces/UDI/main.c | 660 ++++++++++-------- .../Modules/Interfaces/UDI/management_agent.c | 55 +- .../Modules/Interfaces/UDI/trans/bus_pci.c | 9 +- .../Modules/Interfaces/UDI/udi_internal.h | 4 - .../Modules/Interfaces/UDI/udi_lib/imc.c | 2 +- .../Interfaces/UDI/udi_lib/meta_mgmt.c | 11 +- .../Interfaces/UDI/udi_lib/physio/meta_bus.c | 72 +- .../Interfaces/UDI/udi_lib/physio/pio.c | 17 +- 8 files changed, 490 insertions(+), 340 deletions(-) diff --git a/KernelLand/Modules/Interfaces/UDI/main.c b/KernelLand/Modules/Interfaces/UDI/main.c index 1d1b28c9..e9dffc5e 100644 --- a/KernelLand/Modules/Interfaces/UDI/main.c +++ b/KernelLand/Modules/Interfaces/UDI/main.c @@ -1,7 +1,7 @@ /* * Acess2 UDI Layer */ -#define DEBUG 0 +#define DEBUG 1 #define VERSION ((0<<8)|1) #include #include @@ -19,6 +19,7 @@ extern size_t pci_udiprops_size; int UDI_DetectDriver(void *Base); int UDI_LoadDriver(void *Base); tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size); +const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name); // === GLOBALS === MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL); @@ -326,333 +327,346 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch driver_module->InitInfo = info; // - Parse udiprops + const char **udipropsptrs; + + int nLines = 1; + for( int i = 0; i < udiprops_size; i++ ) { - const char **udipropsptrs; - - - int nLines = 1; - for( int i = 0; i < udiprops_size; i++ ) - { - if( udiprops[i] == '\0' ) - nLines ++; + if( udiprops[i] == '\0' ) + nLines ++; + } + + Log_Debug("UDI", "nLines = %i", nLines); + + udipropsptrs = NEW(const char*,*nLines); + int line = 0; + udipropsptrs[line++] = udiprops; + for( int i = 0; i < udiprops_size; i++ ) + { + if( udiprops[i] == '\0' ) { + udipropsptrs[line++] = &udiprops[i+1]; } - - Log_Debug("UDI", "nLines = %i", nLines); - - udipropsptrs = NEW(const char*,*nLines); - int line = 0; - udipropsptrs[line++] = udiprops; - for( int i = 0; i < udiprops_size; i++ ) + } + if(udipropsptrs[line-1] == &udiprops[udiprops_size]) + nLines --; + + // Parse out: + // 'message' into driver_module->Messages + // 'region' into driver_module->RegionTypes + // 'module' into driver_module->ModuleName + + int nLocales = 1; + for( int i = 0; i < nLines; i ++ ) + { + const char *str = udipropsptrs[i]; + int sym = _get_token_sym_v(str, &str, false, caUDI_UdipropsNames); + switch(sym) { - if( udiprops[i] == '\0' ) { - udipropsptrs[line++] = &udiprops[i+1]; - } + case UDIPROPS__module: + driver_module->ModuleName = str; + break; + case UDIPROPS__meta: + driver_module->nMetaLangs ++; + break; + case UDIPROPS__message: + driver_module->nMessages ++; + break; + case UDIPROPS__locale: + nLocales ++; + break; + case UDIPROPS__region: + driver_module->nRegionTypes ++; + break; + case UDIPROPS__device: + driver_module->nDevices ++; + break; + case UDIPROPS__parent_bind_ops: + driver_module->nParents ++; + break; + case UDIPROPS__child_bind_ops: + driver_module->nChildBindOps ++; + break; + default: + // quiet ignore + break; } - if(udipropsptrs[line-1] == &udiprops[udiprops_size]) - nLines --; - - // Parse out: - // 'message' into driver_module->Messages - // 'region' into driver_module->RegionTypes - // 'module' into driver_module->ModuleName - - int nLocales = 1; - for( int i = 0; i < nLines; i ++ ) + } + + // Allocate structures + LOG("nMessages = %i, nMetaLangs = %i", + driver_module->nMessages, + driver_module->nMetaLangs); + driver_module->Messages = NEW(tUDI_PropMessage, * driver_module->nMessages); + driver_module->RegionTypes = NEW(tUDI_PropRegion, * driver_module->nRegionTypes); + driver_module->MetaLangs = NEW(tUDI_MetaLangRef, * driver_module->nMetaLangs); + driver_module->Parents = NEW(tUDI_BindOps, * driver_module->nParents); + driver_module->ChildBindOps = NEW(tUDI_BindOps, * driver_module->nChildBindOps); + driver_module->Devices = NEW(tUDI_PropDevSpec*,* driver_module->nDevices); + + // Populate + int cur_locale = 0; + int msg_index = 0; + int ml_index = 0; + int parent_index = 0; + int child_bind_index = 0; + int device_index = 0; + int next_unpop_region = 1; + for( int i = 0; i < nLines; i ++ ) + { + const char *str = udipropsptrs[i]; + if( !*str ) + continue ; + int sym = _get_token_sym_v(str, &str, true, caUDI_UdipropsNames); + switch(sym) { - const char *str = udipropsptrs[i]; - int sym = _get_token_sym_v(str, &str, false, caUDI_UdipropsNames); - switch(sym) + case UDIPROPS__properties_version: + if( _get_token_uint32(str, &str) != 0x101 ) { + Log_Warning("UDI", "Properties version mismatch."); + } + break; + case UDIPROPS__module: + driver_module->ModuleName = str; + break; + case UDIPROPS__meta: { - case UDIPROPS__module: - driver_module->ModuleName = str; - break; - case UDIPROPS__meta: - driver_module->nMetaLangs ++; - break; - case UDIPROPS__message: - driver_module->nMessages ++; - break; - case UDIPROPS__locale: - nLocales ++; - break; - case UDIPROPS__region: - driver_module->nRegionTypes ++; - break; - case UDIPROPS__device: - driver_module->nDevices ++; - break; - case UDIPROPS__parent_bind_ops: - driver_module->nParents ++; - break; - case UDIPROPS__child_bind_ops: - driver_module->nChildBindOps ++; - break; - default: - // quiet ignore - break; + tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++]; + ml->meta_idx = _get_token_idx(str, &str); + if( !str ) continue; + ml->interface_name = str; + // TODO: May need to trim trailing spaces + ml->metalang = UDI_int_GetMetaLangByName(ml->interface_name); + if( !ml->metalang ) { + Log_Error("UDI", "Module %s referenced unsupported metalang %s", + driver_module->ModuleName, ml->interface_name); } - } - - // Allocate structures - driver_module->Messages = NEW(tUDI_PropMessage, * driver_module->nMessages); - driver_module->RegionTypes = NEW(tUDI_PropRegion, * driver_module->nRegionTypes); - driver_module->MetaLangs = NEW(tUDI_MetaLangRef, * driver_module->nMetaLangs); - driver_module->Parents = NEW(tUDI_BindOps, * driver_module->nParents); - driver_module->ChildBindOps = NEW(tUDI_BindOps, * driver_module->nChildBindOps); - driver_module->Devices = NEW(tUDI_PropDevSpec*,* driver_module->nDevices); - - // Populate - int cur_locale = 0; - int msg_index = 0; - int ml_index = 0; - int parent_index = 0; - int child_bind_index = 0; - int next_unpop_region = 1; - for( int i = 0; i < nLines; i ++ ) - { - const char *str = udipropsptrs[i]; - if( !*str ) - continue ; - int sym = _get_token_sym_v(str, &str, true, caUDI_UdipropsNames); - switch(sym) + break; + } + case UDIPROPS__message: { - case UDIPROPS__properties_version: - if( _get_token_uint32(str, &str) != 0x101 ) { - Log_Warning("UDI", "Properties version mismatch."); - } - break; - case UDIPROPS__module: - driver_module->ModuleName = str; - break; - case UDIPROPS__meta: - { - tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++]; - ml->meta_idx = _get_token_idx(str, &str); - if( !str ) continue; - ml->interface_name = str; - break; - } - case UDIPROPS__message: - { - tUDI_PropMessage *msg = &driver_module->Messages[msg_index++]; - msg->locale = cur_locale; - msg->index = _get_token_uint16(str, &str); - if( !str ) continue ; - msg->string = str; - //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string); - break; - } - case UDIPROPS__locale: - // TODO: Set locale - cur_locale = 1; - break; - case UDIPROPS__region: - { - udi_index_t rgn_idx = _get_token_idx(str, &str); - if( !str ) continue ; - // Search for region index (just in case internal_bind_ops appears earlier) - tUDI_PropRegion *rgn = &driver_module->RegionTypes[0]; - if( rgn_idx > 0 ) - { - rgn ++; - for( int i = 1; i < next_unpop_region; i ++, rgn ++ ) { - if( rgn->RegionIdx == rgn_idx ) - break; - } - if(i == next_unpop_region) { - if( next_unpop_region == driver_module->nRegionTypes ) { - // TODO: warning if reigon types overflow - continue ; - } - next_unpop_region ++; - rgn->RegionIdx = rgn_idx; - } - } - // Parse attributes - while( *str ) - { - int sym = _get_token_sym(str, &str, true, - "type", "binding", "priority", "latency", "overrun_time", NULL - ); - if( !str ) break ; - switch(sym) - { - case 0: // type - rgn->Type = _get_token_sym(str, &str, true, - "normal", "fp", NULL); - break; - case 1: // binding - rgn->Binding = _get_token_sym(str, &str, true, - "static", "dynamic", NULL); - break; - case 2: // priority - rgn->Priority = _get_token_sym(str, &str, true, - "med", "lo", "hi", NULL); - break; - case 3: // latency - rgn->Latency = _get_token_sym(str, &str, true, - "non_overrunable", "powerfail_warning", "overrunable", - "retryable", "non_critical", NULL); - break; - case 4: // overrun_time - rgn->OverrunTime = _get_token_uint32(str, &str); + tUDI_PropMessage *msg = &driver_module->Messages[msg_index++]; + msg->locale = cur_locale; + msg->index = _get_token_uint16(str, &str); + if( !str ) continue ; + msg->string = str; + //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string); + break; + } + case UDIPROPS__locale: + // TODO: Set locale + cur_locale = 1; + break; + case UDIPROPS__region: + { + udi_index_t rgn_idx = _get_token_idx(str, &str); + if( !str ) continue ; + // Search for region index (just in case internal_bind_ops appears earlier) + tUDI_PropRegion *rgn = &driver_module->RegionTypes[0]; + if( rgn_idx > 0 ) + { + rgn ++; + for( int i = 1; i < next_unpop_region; i ++, rgn ++ ) { + if( rgn->RegionIdx == rgn_idx ) break; - } - if( !str ) break ; } - break; + if(i == next_unpop_region) { + if( next_unpop_region == driver_module->nRegionTypes ) { + // TODO: warning if reigon types overflow + continue ; + } + next_unpop_region ++; + rgn->RegionIdx = rgn_idx; } - case UDIPROPS__parent_bind_ops: + } + // Parse attributes + while( *str ) + { + int sym = _get_token_sym(str, &str, true, + "type", "binding", "priority", "latency", "overrun_time", NULL + ); + if( !str ) break ; + switch(sym) { - tUDI_BindOps *bind = &driver_module->Parents[parent_index++]; - bind->meta_idx = _get_token_idx(str, &str); - if( !str ) continue ; - bind->region_idx = _get_token_idx(str, &str); - if( !str ) continue ; - bind->ops_idx = _get_token_idx(str, &str); - if( !str ) continue ; - bind->bind_cb_idx = _get_token_idx(str, &str); - if( *str ) { - // Expected EOL, didn't get it :( + case 0: // type + rgn->Type = _get_token_sym(str, &str, true, + "normal", "fp", NULL); + break; + case 1: // binding + rgn->Binding = _get_token_sym(str, &str, true, + "static", "dynamic", NULL); + break; + case 2: // priority + rgn->Priority = _get_token_sym(str, &str, true, + "med", "lo", "hi", NULL); + break; + case 3: // latency + rgn->Latency = _get_token_sym(str, &str, true, + "non_overrunable", "powerfail_warning", "overrunable", + "retryable", "non_critical", NULL); + break; + case 4: // overrun_time + rgn->OverrunTime = _get_token_uint32(str, &str); + break; } - Log_Debug("UDI", "Parent bind - meta:%i,rgn:%i,ops:%i,bind:%i", - bind->meta_idx, bind->region_idx, bind->ops_idx, bind->bind_cb_idx); - break; + if( !str ) break ; + } + break; + } + case UDIPROPS__parent_bind_ops: + { + tUDI_BindOps *bind = &driver_module->Parents[parent_index++]; + bind->meta_idx = _get_token_idx(str, &str); + if( !str ) continue ; + bind->region_idx = _get_token_idx(str, &str); + if( !str ) continue ; + bind->ops_idx = _get_token_idx(str, &str); + if( !str ) continue ; + bind->bind_cb_idx = _get_token_idx(str, &str); + if( *str ) { + // Expected EOL, didn't get it :( + } + Log_Debug("UDI", "Parent bind - meta:%i,rgn:%i,ops:%i,bind:%i", + bind->meta_idx, bind->region_idx, bind->ops_idx, bind->bind_cb_idx); + break; + } + case UDIPROPS__internal_bind_ops: + { + // Get region using index + udi_index_t meta = _get_token_idx(str, &str); + if( !str ) continue ; + udi_index_t rgn_idx = _get_token_idx(str, &str); + if( !str ) continue ; + + // Search for region index (just in case the relevant 'region' comes after) + tUDI_PropRegion *rgn = &driver_module->RegionTypes[0]; + if( rgn_idx > 0 ) + { + rgn ++; + int j; + for( j = 1; j < next_unpop_region; j ++, rgn ++ ) { + if( rgn->RegionIdx == rgn_idx ) + break; } - case UDIPROPS__internal_bind_ops: - { - // Get region using index - udi_index_t meta = _get_token_idx(str, &str); - if( !str ) continue ; - udi_index_t rgn_idx = _get_token_idx(str, &str); - if( !str ) continue ; - - // Search for region index (just in case the relevant 'region' comes after) - tUDI_PropRegion *rgn = &driver_module->RegionTypes[0]; - if( rgn_idx > 0 ) - { - rgn ++; - int j; - for( j = 1; j < next_unpop_region; j ++, rgn ++ ) { - if( rgn->RegionIdx == rgn_idx ) - break; + if( j == next_unpop_region ) { + if( next_unpop_region == driver_module->nRegionTypes ) { + // TODO: warning if reigon types overflow + continue ; } - if( j == next_unpop_region ) { - if( next_unpop_region == driver_module->nRegionTypes ) { - // TODO: warning if reigon types overflow - continue ; - } - next_unpop_region ++; - rgn->RegionIdx = rgn_idx; - } - } - - // Set properties - rgn->BindMeta = meta; - - rgn->PriBindOps = _get_token_idx(str, &str); - if( !str ) continue ; - rgn->SecBindOps = _get_token_idx(str, &str); - if( !str ) continue ; - rgn->BindCb = _get_token_idx(str, &str); - if( !str ) continue ; - if( *str ) { - // TODO: Please sir, I want an EOL - } - break; - } - case UDIPROPS__child_bind_ops: - { - tUDI_BindOps *bind = &driver_module->ChildBindOps[child_bind_index++]; - bind->meta_idx = _get_token_idx(str, &str); - if( !str ) continue ; - bind->region_idx = _get_token_idx(str, &str); - if( !str ) continue ; - bind->ops_idx = _get_token_idx(str, &str); - if( *str ) { - // Expected EOL, didn't get it :( + next_unpop_region ++; + rgn->RegionIdx = rgn_idx; } - Log_Debug("UDI", "Child bind - meta:%i,rgn:%i,ops:%i", - bind->meta_idx, bind->region_idx, bind->ops_idx); - break; - } - case UDIPROPS__supplier: - case UDIPROPS__contact: - case UDIPROPS__name: - case UDIPROPS__shortname: - case UDIPROPS__release: - break; - //case UDIPROPS__requires: - // // TODO: Requires - // break; - case UDIPROPS__device: - { - int n_attr = 0; - // Count properties (and validate) - _get_token_idx(str, &str); // message - if( !str ) continue; - _get_token_idx(str, &str); // meta - if( !str ) continue; - while( *str ) + } + + // Set properties + rgn->BindMeta = meta; + + rgn->PriBindOps = _get_token_idx(str, &str); + if( !str ) continue ; + rgn->SecBindOps = _get_token_idx(str, &str); + if( !str ) continue ; + rgn->BindCb = _get_token_idx(str, &str); + if( !str ) continue ; + if( *str ) { + // TODO: Please sir, I want an EOL + } + break; + } + case UDIPROPS__child_bind_ops: + { + tUDI_BindOps *bind = &driver_module->ChildBindOps[child_bind_index++]; + bind->meta_idx = _get_token_idx(str, &str); + if( !str ) continue ; + bind->region_idx = _get_token_idx(str, &str); + if( !str ) continue ; + bind->ops_idx = _get_token_idx(str, &str); + if( *str ) { + // Expected EOL, didn't get it :( + } + Log_Debug("UDI", "Child bind - meta:%i,rgn:%i,ops:%i", + bind->meta_idx, bind->region_idx, bind->ops_idx); + break; + } + case UDIPROPS__supplier: + case UDIPROPS__contact: + case UDIPROPS__name: + case UDIPROPS__shortname: + case UDIPROPS__release: + break; + //case UDIPROPS__requires: + // // TODO: Requires + // break; + case UDIPROPS__device: + { + int n_attr = 0; + // Count properties (and validate) + _get_token_idx(str, &str); // message + if( !str ) continue; + _get_token_idx(str, &str); // meta + if( !str ) continue; + while( *str ) + { + _get_token_str(str, &str, NULL); + if( !str ) break; + _get_token_sym(str, &str, true, "string", "ubit32", "boolean", "array", NULL); + if( !str ) break; + _get_token_str(str, &str, NULL); + if( !str ) break; + n_attr ++; + } + // Rewind and actually parse + _get_token_str(udipropsptrs[i], &str, NULL); + + tUDI_PropDevSpec *dev = NEW_wA(tUDI_PropDevSpec, Attribs, n_attr); + driver_module->Devices[device_index++] = dev;; + dev->MessageNum = _get_token_idx(str, &str); + dev->MetaIdx = _get_token_idx(str, &str); + dev->nAttribs = n_attr; + n_attr = 0; + while( *str ) + { + udi_instance_attr_list_t *at = &dev->Attribs[n_attr]; + _get_token_str(str, &str, at->attr_name); + if( !str ) break; + at->attr_type = _get_token_sym(str, &str, true, + " ", "string", "array", "ubit32", "boolean", NULL); + if( !str ) break; + udi_ubit32_t val; + switch( dev->Attribs[n_attr].attr_type ) { + case 1: // String + at->attr_length = _get_token_str(str, &str, (char*)at->attr_value); + break; + case 2: // Array + // TODO: Array + Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'"); _get_token_str(str, &str, NULL); - if( !str ) break; - _get_token_sym(str, &str, true, "string", "ubit32", "boolean", "array", NULL); - if( !str ) break; - _get_token_str(str, &str, NULL); - if( !str ) break; - n_attr ++; - } - // Rewind and actually parse - _get_token_str(udipropsptrs[i], &str, NULL); - - tUDI_PropDevSpec *dev = NEW_wA(tUDI_PropDevSpec, Attribs, n_attr); - dev->MessageNum = _get_token_idx(str, &str); - dev->MetaIdx = _get_token_idx(str, &str); - dev->nAttribs = n_attr; - n_attr = 0; - while( *str ) - { - udi_instance_attr_list_t *at = &dev->Attribs[n_attr]; - _get_token_str(str, &str, at->attr_name); - if( !str ) break; - at->attr_type = _get_token_sym(str, &str, true, - " ", "string", "array", "ubit32", "boolean", NULL); - if( !str ) break; - switch( dev->Attribs[n_attr].attr_type ) - { - case 1: // String - at->attr_length = _get_token_str(str, &str, (char*)at->attr_value); - break; - case 2: // Array - // TODO: Array - Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'"); - _get_token_str(str, &str, NULL); - break; - case 3: // ubit32 - at->attr_length = sizeof(udi_ubit32_t); - UDI_ATTR32_SET(at->attr_value, _get_token_uint32(str, &str)); - break; - case 4: // boolean - at->attr_length = sizeof(udi_boolean_t); - UDI_ATTR32_SET(at->attr_value, _get_token_bool(str, &str)); - break; - } - if( !str ) break; - n_attr ++; + break; + case 3: // ubit32 + at->attr_length = sizeof(udi_ubit32_t); + val = _get_token_uint32(str, &str); + Log_Debug("UDI", "device %i: Value '%s'=%x", device_index, + at->attr_name, val); + UDI_ATTR32_SET(at->attr_value, val); + break; + case 4: // boolean + at->attr_length = sizeof(udi_boolean_t); + UDI_ATTR32_SET(at->attr_value, _get_token_bool(str, &str)); + break; } - - break; - } - default: - Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]); - break; + if( !str ) break; + n_attr ++; } + + break; + } + default: + Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]); + break; } - - // Sort message list - // TODO: Sort message list } + free(udipropsptrs); + + // Sort message list + // TODO: Sort message list int nSecondaryRgns = 0; for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ ) @@ -772,6 +786,12 @@ tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t index) void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel) { const udi_cb_init_t *cb_init; + LOG("Inst=%p, bind_cb_idx=%i, channel=%p", Inst, bind_cb_idx, channel); + if(Inst) { + ASSERT(Inst->Module); + ASSERT(Inst->Module->InitInfo); + ASSERT(Inst->Module->InitInfo->cb_init_list); + } cb_init = Inst ? Inst->Module->InitInfo->cb_init_list : cUDI_MgmtCbInitList; for( ; cb_init->cb_idx; cb_init ++ ) { @@ -779,10 +799,18 @@ void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, { // TODO: Get base size using meta/cbnum tUDI_MetaLang *metalang = UDI_int_GetMetaLang(Inst, cb_init->meta_idx); - ASSERT(metalang); + if( !metalang ) { + Log_Warning("UDI", "Metalang referenced in %s CB %i is invalid (%i)", + Inst->Module->ModuleName, bind_cb_idx, cb_init->meta_idx); + return NULL; + } ASSERTC(cb_init->meta_cb_num, <, metalang->nCbTypes); size_t base = metalang->CbTypes[cb_init->meta_cb_num].Size; - udi_cb_t *ret = NEW(udi_cb_t, + base + cb_init->inline_size + cb_init->scratch_requirement); + ASSERTC(base, >=, sizeof(udi_cb_t)); + base -= sizeof(udi_cb_t); + LOG("+ %i + %i + %i", base, cb_init->inline_size, cb_init->scratch_requirement); + udi_cb_t *ret = NEW(udi_cb_t, + base + + cb_init->inline_size + cb_init->scratch_requirement); ret->channel = channel; return ret; } @@ -793,3 +821,19 @@ void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, } +const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name) +{ + //extern tUDI_MetaLang cMetaLang_Management; + extern tUDI_MetaLang cMetaLang_BusBridge; + const tUDI_MetaLang *langs[] = { + &cMetaLang_BusBridge, + NULL + }; + for( int i = 0; langs[i]; i ++ ) + { + if( strcmp(Name, langs[i]->Name) == 0 ) + return langs[i]; + } + return NULL; +} + diff --git a/KernelLand/Modules/Interfaces/UDI/management_agent.c b/KernelLand/Modules/Interfaces/UDI/management_agent.c index 38a6a124..eb441aa4 100644 --- a/KernelLand/Modules/Interfaces/UDI/management_agent.c +++ b/KernelLand/Modules/Interfaces/UDI/management_agent.c @@ -5,6 +5,7 @@ * management_agent.c * - Managment Agent */ +#define DEBUG 1 #include #include #include "udi_internal.h" @@ -124,6 +125,11 @@ int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs, } if( enum_attr ) { + //LOG("Match = '%s' (%i %x == %i %x)", + // dev_attr->attr_name, + // dev_attr->attr_length, UDI_ATTR32_GET(dev_attr->attr_value), + // enum_attr->attr_length, UDI_ATTR32_GET(enum_attr->attr_value) + // ); if( enum_attr->attr_length != dev_attr->attr_length ) return 0; if( memcmp(enum_attr->attr_value, dev_attr->attr_value, dev_attr->attr_length) != 0 ) @@ -133,8 +139,10 @@ 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("n_matches = %i", n_matches); return n_matches; } @@ -142,7 +150,7 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx) { // Current side is MA, other is instance tUDI_DriverInstance *inst = UDI_int_ChannelGetInstance( UDI_GCB(cb), true ); - LOG("inst = %p", inst); + //LOG("inst = %p", inst); // Search for existing child with same child_ID and ops for( tUDI_ChildBinding *child = inst->FirstChild; child; child = child->Next ) @@ -166,7 +174,6 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx) // - Locate child_bind_ops definition for( int i = 0; i < inst->Module->nChildBindOps; i ++ ) { - LOG(" %i == %i?", inst->Module->ChildBindOps[i].ops_idx, ops_idx); if( inst->Module->ChildBindOps[i].ops_idx == ops_idx ) { child->BindOps = &inst->Module->ChildBindOps[i]; break; @@ -211,7 +218,29 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx) void UDI_MA_BindParents(tUDI_DriverModule *Module) { - UNIMPLEMENTED(); + // Scan active instances for enumerated children that can be handled by this module + for( int i = 0; i < Module->nDevices; i ++ ) + { + // TODO: Have list of unbound enumerated children + for( tUDI_DriverInstance *inst = gpUDI_ActiveInstances; inst; inst = inst->Next ) + { + // Loop children + for( tUDI_ChildBinding *child = inst->FirstChild; child; child = child->Next ) + { + if( child->BoundInstance ) + continue ; + // Check for match + int level = UDI_MA_CheckDeviceMatch( + Module->Devices[i]->nAttribs, Module->Devices[i]->Attribs, + child->nAttribs, child->Attribs + ); + // No match: Continue + if( level == 0 ) + continue ; + UDI_MA_CreateChildInstance(Module, inst, child); + } + } + } } tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module, @@ -231,20 +260,24 @@ tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module, UDI_BindChannel(channel,true, inst, parent->ops_idx, parent->region_idx); UDI_BindChannel(channel,false, ParentInstance, ChildBinding->Ops->ops_idx, ChildBinding->BindOps->region_idx); - - udi_cb_t *bind_cb = udi_cb_alloc_internal(inst, parent->bind_cb_idx, channel); - if( !bind_cb ) { - Log_Warning("UDI", "Bind CB index is invalid"); - return NULL; - } udi_channel_event_cb_t ev_cb; + memset(&ev_cb, 0, sizeof(ev_cb)); int n_handles = Module->InitInfo->primary_init_info->per_parent_paths; udi_buf_path_t handles[n_handles]; - memset(&ev_cb, 0, sizeof(ev_cb)); ev_cb.gcb.channel = channel; ev_cb.event = UDI_CHANNEL_BOUND; - ev_cb.params.parent_bound.bind_cb = bind_cb; + if( parent->bind_cb_idx == 0 ) + ev_cb.params.parent_bound.bind_cb = NULL; + else { + ev_cb.params.parent_bound.bind_cb = udi_cb_alloc_internal(inst, parent->bind_cb_idx, channel); + if( !ev_cb.params.parent_bound.bind_cb ) { + Log_Warning("UDI", "Bind CB index is invalid"); + return NULL; + } + UDI_int_ChannelFlip( ev_cb.params.parent_bound.bind_cb ); + } + ev_cb.params.parent_bound.parent_ID = 1; ev_cb.params.parent_bound.path_handles = handles; diff --git a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c index 394ae39a..0dac0c2b 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c @@ -131,11 +131,12 @@ void pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb) { UNIMPLEMENTED(); } -void pci_unbind_req(udi_bus_bind_cb_t *cb) +void pci_bind_req(udi_bus_bind_cb_t *cb) { - UNIMPLEMENTED(); + // TODO: DMA constraints + udi_bus_bind_ack(cb, 0, UDI_DMA_LITTLE_ENDIAN, UDI_OK); } -void pci_bind_req_op(udi_bus_bind_cb_t *cb) +void pci_unbind_req(udi_bus_bind_cb_t *cb) { UNIMPLEMENTED(); } @@ -158,8 +159,8 @@ udi_mgmt_ops_t pci_mgmt_ops = { udi_ubit8_t pci_mgmt_op_flags[4] = {0,0,0,0}; udi_bus_bridge_ops_t pci_bridge_ops = { pci_bridge_ch_event_ind, + pci_bind_req, pci_unbind_req, - pci_bind_req_op, pci_intr_attach_req, pci_intr_detach_req }; diff --git a/KernelLand/Modules/Interfaces/UDI/udi_internal.h b/KernelLand/Modules/Interfaces/UDI/udi_internal.h index 2d298ca7..b2089303 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_internal.h +++ b/KernelLand/Modules/Interfaces/UDI/udi_internal.h @@ -70,10 +70,6 @@ struct sUDI_PropRegion struct sUDI_MetaLang { const char *Name; - int nOpGroups; - struct { - void *OpList; - } OpGroups; int nCbTypes; struct { size_t Size; diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c index 2f9f3fe6..ce646dfc 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c @@ -80,5 +80,5 @@ void udi_channel_event_ind(udi_channel_event_cb_t *cb) void udi_channel_event_complete(udi_channel_event_cb_t *cb, udi_status_t status) { - Warning("%s Unimplemented", __func__); + UNIMPLEMENTED(); } diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c index 87a54fd4..6a80292d 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c @@ -22,12 +22,10 @@ EXPORT(udi_final_cleanup_ack); tUDI_MetaLang cMetaLang_Management = { "udi_mgmt", - 1, - {NULL}, 1, { - {sizeof(udi_enumerate_cb_t)-sizeof(udi_cb_t), NULL} + {sizeof(udi_enumerate_cb_t), NULL} } }; @@ -40,7 +38,8 @@ void udi_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level) Log_Warning("UDI", "%s on wrong channel type", __func__); return ; } - + + // Non-deferred because it's usually called with a stack allocated cb UDI_int_ChannelReleaseFromCall( UDI_GCB(cb) ); ops->usage_ind_op(cb, resource_level); } @@ -67,8 +66,6 @@ void udi_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level) } UDI_int_MakeDeferredCbU8( UDI_GCB(cb), (udi_op_t*)ops->enumerate_req_op, enumeration_level ); -// UDI_int_ChannelReleaseFromCall( UDI_GCB(cb) ); -// ops->enumerate_req_op(cb, enumeration_level); } void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level) @@ -83,7 +80,7 @@ void udi_enumerate_ack(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_result, u switch( enumeration_result ) { case UDI_ENUMERATE_OK: - #if DEBUG + #if DEBUG && 0 for( int i = 0; i < cb->attr_valid_length; i ++ ) { udi_instance_attr_list_t *at = &cb->attr_list[i]; 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 e1e6a47d..dadb4421 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c @@ -1,10 +1,35 @@ /** - * \file physio/meta_bus.c - * \author John Hodge (thePowersGang) + * Acess2 UDI Layer + * - By John Hodge (thePowersGang) + * + * udi_lib/physio/meta_bus.c + * - Bus Bridge Metalanguage */ +#define DEBUG 1 #include #include #include +#include "../../udi_internal.h" + +// === GLOBALS == +udi_layout_t cMetaLang_BusBridge_IntrAttachCbLayout[] = { + UDI_DL_STATUS_T, + UDI_DL_UBIT8_T, + UDI_DL_ORIGIN_T, // TODO: handle + 0 +}; +tUDI_MetaLang cMetaLang_BusBridge = { + "udi_bridge", + // CB Types + 5, + { + {0}, // 0: Empty + {sizeof(udi_bus_bind_cb_t), NULL}, // Defined, but is just a gcb + {sizeof(udi_intr_attach_cb_t), NULL}, + {sizeof(udi_intr_detach_cb_t), NULL}, + {sizeof(udi_intr_event_cb_t), NULL} + } +}; // === EXPORTS === EXPORT(udi_bus_unbind_req); @@ -12,6 +37,12 @@ EXPORT(udi_bus_unbind_ack); EXPORT(udi_bus_bind_req); EXPORT(udi_bus_bind_ack); +#define PREP_OPS(type,ml,num) const type *ops = UDI_int_ChannelPrepForCall(UDI_GCB(cb), ml, num); \ + if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; } + +#define PREP_OPS_DEVICE const udi_bus_device_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM ); \ + if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; } + // === CODE === void udi_bus_unbind_req(udi_bus_bind_cb_t *cb) { @@ -24,7 +55,29 @@ void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb) void udi_bus_bind_req(udi_bus_bind_cb_t *cb) { - UNIMPLEMENTED(); + LOG("cb=%p{...}", cb); + PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM) + + UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->bus_bind_req_op ); +} + +struct marshalled_bus_bind_ack +{ + tUDI_DeferredCall Call; + udi_dma_constraints_t dma_constraints; + udi_ubit8_t preferred_endianness; + udi_status_t status; +}; + +static void _unmarshal_bus_bind_ack(tUDI_DeferredCall *Call) +{ + struct marshalled_bus_bind_ack *info = (void*)Call; + ((udi_bus_bind_ack_op_t*)Call->Handler)( + UDI_MCB(Call->cb, udi_bus_bind_cb_t), + info->dma_constraints, + info->preferred_endianness, + info->status); + free(info); } void udi_bus_bind_ack( @@ -34,5 +87,16 @@ void udi_bus_bind_ack( udi_status_t status ) { - UNIMPLEMENTED(); + LOG("cb=%p{...}, dma_constraints=%p, preferred_endianness=%i,status=%i", + cb, dma_constraints, preferred_endianness, status); + PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM) + + struct marshalled_bus_bind_ack *call = NEW(struct marshalled_bus_bind_ack,); + call->Call.Unmarshal = _unmarshal_bus_bind_ack; + call->Call.cb = UDI_GCB(cb); + call->Call.Handler = (udi_op_t*)ops->bus_bind_ack_op; + call->dma_constraints = dma_constraints; + call->preferred_endianness = preferred_endianness; + call->status = status; + UDI_int_AddDeferred(&call->Call); } diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c index 03849ae1..a4825909 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c @@ -20,7 +20,22 @@ void udi_pio_map(udi_pio_map_call_t *callback, udi_cb_t *gcb, udi_pio_trans_t *trans_list, udi_ubit16_t list_length, udi_ubit16_t pio_attributes, udi_ubit32_t pace, udi_index_t serialization_domain) { - UNIMPLEMENTED(); + char bus_type[16]; + 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) { + callback(gcb, UDI_NULL_HANDLE); + return ; + } + + if( strcmp(bus_type, "pci") == 0 ) { + // Ask PCI binding + } + else { + // Oops, unknown + callback(gcb, UDI_NULL_HANDLE); + return ; + } } void udi_pio_unmap(udi_pio_handle_t pio_handle) -- 2.20.1