X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FInterfaces%2FUDI%2Fmain.c;h=7b36de96fe2c34a772b4d1d6fe983655073a4f90;hb=301dc9a238658b902d9d394b6e930d1ec4832190;hp=a4a1504a95502caed08e08bbc50f749082f547b0;hpb=48743e39650eb1ef988380e9d95f27fd40d3a9ce;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Interfaces/UDI/main.c b/KernelLand/Modules/Interfaces/UDI/main.c index a4a1504a..7b36de96 100644 --- a/KernelLand/Modules/Interfaces/UDI/main.c +++ b/KernelLand/Modules/Interfaces/UDI/main.c @@ -6,12 +6,16 @@ #include #include #include +#include "udi_internal.h" // === PROTOTYPES === int UDI_Install(char **Arguments); int UDI_DetectDriver(void *Base); int UDI_LoadDriver(void *Base); +tUDI_DriverInstance *UDI_CreateInstance(tUDI_DriverModule *DriverModule); +tUDI_DriverRegion *UDI_InitRegion(tUDI_DriverInstance *Inst, udi_ubit16_t Index, udi_ubit16_t Type, size_t RDataSize); + // === GLOBALS === MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL); tModuleLoader gUDI_Loader = { @@ -34,7 +38,17 @@ int UDI_Install(char **Arguments) */ int UDI_DetectDriver(void *Base) { - if( Binary_FindSymbol(Base, "udi_init_info", NULL) == 0) { + Uint unused; + + if( Binary_FindSymbol(Base, "udi_init_info", &unused) == 0) { + return 0; + } + if( Binary_FindSymbol(Base, "_udiprops", &unused) == 0 ) { + Log_Warning("UDI", "Driver has udi_init_info, but no _udiprops symbol"); + return 0; + } + if( Binary_FindSymbol(Base, "_udiprops_end", &unused) == 0) { + Log_Warning("UDI", "Driver has udi_init_info, but no _udiprops_end symbol"); return 0; } @@ -48,57 +62,20 @@ int UDI_LoadDriver(void *Base) { udi_init_t *info; char *udiprops = NULL; - int udiprops_size = 0; - int i; - // int j; + char *udiprops_end = 0; - Log_Debug("UDI", "UDI_LoadDriver: (Base=%p)", Base); + ENTER("pBase", Base); if( Binary_FindSymbol(Base, "udi_init_info", (Uint*)&info) == 0) { Binary_Unload(Base); + LEAVE('i', 0); return 0; } - if( Binary_FindSymbol(Base, "_udiprops", (Uint*)&udiprops) == 0 ) { - Log_Warning("UDI", "_udiprops is not defined, this is usually bad"); - } - else { - Uint udiprops_end = 0; - int i, j, nLines; - char **udipropsptrs; - - if( Binary_FindSymbol(Base, "_udiprops_end", (Uint*)&udiprops_end) == 0) - Log_Warning("UDI", "_udiprops_end is not defined"); - Log_Debug("UDI", "udiprops_end = %p", udiprops_end); - udiprops_size = udiprops_end - (Uint)udiprops; - Log_Debug("UDI", "udiprops = %p, udiprops_size = 0x%x", udiprops, udiprops_size); - - Debug_HexDump("UDI_LoadDriver", udiprops, udiprops_size); - - nLines = 1; - for( i = 0; i < udiprops_size; i++ ) - { - if( udiprops[i] == '\0' ) - nLines ++; - } - - Log_Debug("UDI", "nLines = %i", nLines); - - udipropsptrs = malloc( sizeof(char*)*nLines ); - udipropsptrs[0] = udiprops; - j = 0; - for( i = 0; i < udiprops_size; i++ ) - { - if( udiprops[i] == '\0' ) { - //Log_Debug("UDI", "udipropsptrs[%i] = '%s'", j, udipropsptrs[j]); - udipropsptrs[j++] = &udiprops[i+1]; - } - } - Log_Debug("UDI", "udipropsptrs[%i] = '%s'", j, udipropsptrs[j]); - Log_Debug("UDI", "udiprops = \"%s\"", udiprops); - } - - + Binary_FindSymbol(Base, "_udiprops", (Uint*)&udiprops); + Binary_FindSymbol(Base, "_udiprops_end", (Uint*)&udiprops_end); + + #if 0 Log("primary_init_info = %p = {", info->primary_init_info); { Log(" .mgmt_ops = %p = {", info->primary_init_info->mgmt_ops); @@ -126,10 +103,16 @@ int UDI_LoadDriver(void *Base) Log(" .per_parent_paths = 0x%x", info->primary_init_info->per_parent_paths); } Log("}"); - Log("secondary_init_list = %p", info->secondary_init_list); + Log("secondary_init_list = %p {", info->secondary_init_list); + for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ ) + { + Log(" [%i] = { .region_idx=%i, .rdata_size=0x%x }", + info->secondary_init_list[i].region_idx, info->secondary_init_list[i].rdata_size); + } + LOG("}"); Log("ops_init_list = %p", info->ops_init_list); - for( i = 0; info->ops_init_list[i].ops_idx; i++ ) + for( int i = 0; info->ops_init_list[i].ops_idx; i++ ) { Log("info->ops_init_list[%i] = {", i); Log(" .ops_idx = 0x%x", info->ops_init_list[i].ops_idx); @@ -140,6 +123,163 @@ int UDI_LoadDriver(void *Base) // Log(" .op_flags = %p", info->ops_init_list[i].op_flags); Log("}"); } + #endif + + + // TODO: Multiple modules? + tUDI_DriverModule *driver_module = NEW(tUDI_DriverModule,); + driver_module->InitInfo = info; + + // - Parse udiprops + { + char **udipropsptrs; + + Log_Debug("UDI", "udiprops = %p, udiprops_end = %p", udiprops, udiprops_end); + size_t udiprops_size = udiprops_end - udiprops; + + int nLines = 1; + for( int i = 0; i < udiprops_size; i++ ) + { + if( udiprops[i] == '\0' ) + nLines ++; + } + + Log_Debug("UDI", "nLines = %i", nLines); + + udipropsptrs = NEW(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]; + } + } + if(udipropsptrs[line-1] == &udiprops[udiprops_size]) + nLines --; + + for( int i = 0; i < nLines; i ++ ) + { + } + + // Parse out: + // 'message' into driver_module->Messages + // 'region' into driver_module->RegionTypes + // 'module' into driver_module->ModuleName + + int nMessages = 0; + int nLocales = 1; + int nRegionTypes = 0; + for( int i = 0; i < nLines; i ++ ) + { + const char *str = udipropsptrs[i]; + if( strncmp("module ", str, 7) == 0 ) { + driver_module->ModuleName = str + 7; + } + else if( strncmp("message ", str, 8) == 0 ) { + nMessages ++; + } + else if( strncmp("locale ", str, 7) == 0 ) { + nLocales ++; + } + else if( strncmp("region ", str, 7) == 0 ) { + nRegionTypes ++; + } + } + + // Allocate structures + driver_module->nMessages = nMessages; + driver_module->Messages = NEW(tUDI_PropMessage, *nMessages); + driver_module->nRegionTypes = nRegionTypes; + driver_module->RegionTypes = NEW(tUDI_PropRegion, *nRegionTypes); + + // Populate + int cur_locale = 0; + int msg_index = 0; + for( int i = 0; i < nLines; i ++ ) + { + const char *str = udipropsptrs[i]; + if( strncmp("module ", str, 7) == 0 ) { + driver_module->ModuleName = str + 7; + } + else if( strncmp("message ", str, 8) == 0 ) { + tUDI_PropMessage *msg = &driver_module->Messages[msg_index++]; + char *end; + msg->locale = cur_locale; + msg->index = strtoul(str+8, &end, 10); + if( *end != ' ' && *end != '\t' ) { + // Oops. + continue ; + } + while( isspace(*end) ) + end ++; + msg->string = end; + + Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string); + } + else if( strncmp("locale ", str, 7) == 0 ) { + // TODO: Set locale + cur_locale = 1; + } + else if( strncmp("region ", str, 7) == 0 ) { + nRegionTypes ++; + } + else { + Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]); + } + } + + // 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 ++ ) + nSecondaryRgns ++; + driver_module->nSecondaryRegions = nSecondaryRgns; + + // Create initial driver instance + tUDI_DriverInstance *inst = UDI_CreateInstance(driver_module); + + for( int i = 0; i < 1+driver_module->nSecondaryRegions; i ++ ) + Log("Rgn %i: %p", i, inst->Regions[i]); + + // Send usage indication + udi_usage_cb_t ucb; + memset(&ucb, 0, sizeof(ucb)); + ucb.gcb.channel = inst->ManagementChannel; + udi_usage_ind(&ucb, UDI_RESOURCES_NORMAL); return 0; } + +tUDI_DriverInstance *UDI_CreateInstance(tUDI_DriverModule *DriverModule) +{ + tUDI_DriverInstance *inst = NEW_wA(tUDI_DriverInstance, Regions, (1+DriverModule->nSecondaryRegions)); + inst->Module = DriverModule; + inst->Regions[0] = UDI_InitRegion(inst, 0, 0, DriverModule->InitInfo->primary_init_info->rdata_size); + udi_secondary_init_t *sec_init = DriverModule->InitInfo->secondary_init_list; + if( sec_init ) + { + for( int i = 0; sec_init[i].region_idx; i ++ ) + { + inst->Regions[1+i] = UDI_InitRegion(inst, i, sec_init[i].region_idx, sec_init[i].rdata_size); + } + } + + inst->ManagementChannel = UDI_CreateChannel(METALANG_MGMT, 0, NULL, 0, inst, 0); + + return inst; +} + +tUDI_DriverRegion *UDI_InitRegion(tUDI_DriverInstance *Inst, udi_ubit16_t Index, udi_ubit16_t Type, size_t RDataSize) +{ +// ASSERTCR( RDataSize, <=, UDI_MIN_ALLOC_LIMIT, NULL ); + ASSERTCR( RDataSize, >, sizeof(udi_init_context_t), NULL ); + tUDI_DriverRegion *rgn = NEW(tUDI_DriverRegion,+RDataSize); + rgn->InitContext = (void*)(rgn+1); + rgn->InitContext->region_idx = Type; +// rgn->InitContext->limits + return rgn; +} +