00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <assert.h>
00029 #include <string.h>
00030
00031 #include <stdlib.h>
00032 #include "kapi_internal.h"
00033 #include "kapi.h"
00034 #include "kapi_ia64.h"
00035 #include "kapi_util.h"
00036 #include "kapi_error.h"
00037 #include "kapi_parse.h"
00038
00039
00040
00041
00042
00043
00044 #define pchNULL_PRINT( pch ) ( ( pch ) ? (pch) : "Null" )
00045
00046 static void ParseClusterDistance( char *pch, char **ppchClrSrc,
00047 char **ppchClrDest, char **ppchValue );
00048 static void ParseLatency( char *pch, char **ppchFcSrc,
00049 char **ppchOppSrc, int *piLatency );
00050 static void ParseBypass( char *pch, char **ppchFcSrc, char **ppchPortSrc,
00051 char **ppchOppSrc,
00052 char **ppchFcDest, char **ppchPortDest, char **ppchOppDest,
00053 char **ppchLatency );
00054 static void ParseIntraCluster( char *mpchTmp,
00055 char **ppchClr,
00056 char **ppchFcSrc, char **ppchOppSrc, char **ppchCportSrc,
00057 char **ppchFcDest, char **ppchOppDest, char **ppchCportDest,
00058 char **ppchLatency );
00059 static void ParseInterCluster( char *mpchTmp,
00060 char **ppchClrSrc, char **ppchFcSrc,
00061 char **ppchOppSrc, char **ppchCportSrc,
00062 char **ppchClrDest, char **ppchFcDest,
00063 char **ppchOppDest, char **ppchCportDest,
00064 char **ppchLatency );
00065
00066 static int fOkProcessClusterDistance( knobs_t *pknobs, char *pchClrSrc,
00067 char *pchClrDest, char *pchValue,
00068 int *iclusterSrc, int *iclusterDest, int *ivalue );
00069 static int fOkProcessIntraCluster( knobs_t *pknobs, aby_t *pabyTmp,
00070 char *pchClr,
00071 char *pchFcSrc, char *pchOppSrc, char *pchCportSrc,
00072 char *pchFcDest, char *pchOppDest, char *pchCportDest,
00073 char *pchLatency );
00074
00075 static int fOkProcessInterCluster( knobs_t *pknobs, eby_t *pebyTmp,
00076 char *pchClrSrc, char *pchFcSrc,
00077 char *pchOppSrc, char *pchCportSrc,
00078 char *pchClrDest, char *pchFcDest,
00079 char *pchOppDest, char *pchCportDest,
00080 char *pchLatency );
00081
00082
00083 static void kapi_InitNumberOfClrNutCportPort( knobs_t *pknobs );
00084 static void kapi_InitInstructionType( knobs_t *pknobs );
00085 static void kapi_ProcessCportPortClr( knobs_t *pknobs );
00086 static void kapi_SetupWidths( knobs_t *pknobs );
00087 static void kapi_ProcessFu( knobs_t *pknobs );
00088 static void kapi_ProcessSensitivity( knobs_t *pknobs );
00089 static void kapi_ProcessCoreLatency( knobs_t *pknobs );
00090 static void kapi_ProcessInterclusterLatency( knobs_t *pknobs );
00091 static void kapi_ProcessIntraclusterLatency( knobs_t *pknobs );
00092 static void kapi_ProcessClusterDistance( knobs_t *pknobs );
00093 static void kapi_ProcessInstructionData( knobs_t *pknobs );
00094 static void kapi_ProcessCacheData( knobs_t *pknobs);
00095
00096 static void DecodeInstructionInformation( knobs_t *pknobs, char *pch );
00097
00098
00099
00100 int
00101 kapi_fEnableIA64Calls( knobs_t *pknobs )
00102 {
00103
00104
00105 kapi_InitBidAndSyllable( pknobs );
00106
00107 kapi_InitNumberOfClrNutCportPort( pknobs );
00108
00109 kapi_InitInstructionType( pknobs );
00110
00111 kapi_ProcessCportPortClr( pknobs );
00112
00113 kapi_SetupWidths( pknobs );
00114 kapi_ProcessFu( pknobs );
00115 kapi_ProcessSensitivity( pknobs );
00116 kapi_ProcessCoreLatency( pknobs );
00117 kapi_ProcessClusterDistance( pknobs );
00118 kapi_ProcessInstructionData( pknobs );
00119 kapi_ProcessIntraclusterLatency( pknobs );
00120 kapi_ProcessInterclusterLatency( pknobs );
00121 kapi_ProcessCacheData( pknobs );
00122 if ( kapi_cntSemanticError > 0 || kapi_cntSyntaxError > 0 ) {
00123 return( 0 );
00124 } else {
00125 return( 1 );
00126 }
00127 }
00128
00129 static void
00130 kapi_ProcessCportPortClr( knobs_t *pknobs )
00131 {
00132 int iport, icluster, icutport, nutTotal;
00133 kapi_ut_t ut;
00134 kapi_ut_t nutMAX[ kapi_nUT ];
00135
00136
00137 nutMAX[ kapi_utI ] = maxICPORTS;
00138 nutMAX[ kapi_utF ] = maxFCPORTS;
00139 nutMAX[ kapi_utB ] = maxBCPORTS;
00140 nutMAX[ kapi_utM ] = maxMCPORTS;
00141
00142
00143
00144 nutTotal = 0;
00145 for ( icluster=0; icluster<pknobs->nclr; icluster++ ) {
00146 clr_t *pclr;
00147
00148 pclr = &(pknobs->mpclrTable[ icluster ]);
00149 for ( ut=kapi_utFIRST; ut<=kapi_utLAST; ut++ ) {
00150 if ( pclr->mpncutport[ ut ] > nutMAX[ ut ] ) {
00151 kapi_Error_i1( 0, 0, "KAPI Implementation maximum for %c units exceeded on cluster",
00152 kapi_ut2ch( ut ) );
00153 }
00154 nutTotal += pclr->mpncutport[ ut ];
00155 }
00156 }
00157 if ( nutTotal > maxPORTS ) {
00158 kapi_Error_i1( 0, 0, "KAPI implementation maximum units (%d) exceeded",
00159 maxPORTS );
00160 }
00161
00162 iport = 0;
00163 while ( iport < pknobs->nports ) {
00164 for ( icluster=0; icluster<pknobs->nclr; icluster++ ) {
00165 clr_t *pclr;
00166 kapi_cport_t icport;
00167
00168 icport = 0;
00169 pclr = &(pknobs->mpclrTable[ icluster ]);
00170 for ( ut=kapi_utFIRST; ut<=kapi_utLAST; ut++ ) {
00171 if ( pclr->mpncutport[ ut ] > nutMAX[ ut ] ) {
00172 kapi_Error_i1( 0, 0, "KAPI Implementation maximum for %c units exceeded on cluster",
00173 kapi_ut2ch( ut ) );
00174 }
00175 for ( icutport=0; icutport<pclr->mpncutport[ ut ]; icutport++ ) {
00176
00177 pknobs->port2cluster[ iport ] = icluster;
00178 pclr->cport2port[ icport ] = iport;
00179 pclr->dmppcportinfoTable[ ut ][ icutport ].cport = icport;
00180 pclr->dmppcportinfoTable[ ut ][ icutport ].cutport = icutport;
00181 pclr->dmppcportinfoTable[ ut ][ icutport ].ut = ut;
00182 pclr->mppcportinfoTable[ icport ]
00183 = &(pclr->dmppcportinfoTable[ ut ][ icutport ]);
00184 iport++;
00185 icport++;
00186 }
00187 }
00188 }
00189 }
00190 }
00191
00192 static void
00193 kapi_ProcessSensitivity( knobs_t *pknobs )
00194 {
00195 int nfu, i, ndir;
00196
00197 nfu = KAPI_EnumCardinality( pknobs, "fu_t");
00198
00199 pknobs->dmpfudirTable = (int *)malloc( sizeof( int ) * nfu );
00200
00201 ndir = KAPI_EnumCardinality( pknobs, "operand_direction_t");
00202 if ( KAPI_error_attribute ) {
00203 kapi_Error( kapi_cLine, 0, "'operand_direction_t' not defined" );
00204 return;
00205 }
00206
00207 pknobs->fudirDestination = KAPI_EnumIndex( pknobs, "operand_direction_t",
00208 "operand_direction_destination" );
00209 pknobs->fudirSource = KAPI_EnumIndex( pknobs, "operand_direction_t",
00210 "operand_direction_source" );
00211 if ( pknobs->fudirSource != 0 ||
00212 pknobs->fudirDestination != 1 ) {
00213 kapi_Error_pch1( kapi_cLine, 0, "operand_direction_t must be defined to be enum (operand_direction_source, operand_direction_destination)", "" );
00214 }
00215
00216 for ( i=0; i<nfu; i++ ) {
00217 pknobs->dmpfudirTable[ i ] =
00218 KAPI_GetEnumVariable(pknobs,"operand_direction", i);
00219 }
00220 }
00221
00222 static void
00223 kapi_SetupWidths( knobs_t *pknobs )
00224 {
00225 int icluster;
00226 char mpchTmp[ 300 ];
00227
00228
00229 for ( icluster=0; icluster<pknobs->nclr; icluster++ ) {
00230 sprintf( mpchTmp, "cluster%dMaxBundleIssue", icluster );
00231 pknobs->maxBundleIssue[ icluster ] =
00232 KAPI_GetIntegerVariable( pknobs, mpchTmp, 0 );
00233
00234 pknobs->maxInstructionIssue[ icluster ] = pknobs->maxBundleIssue[ icluster ] * nSYLBID;
00235
00236 if ( KAPI_error_attribute ) {
00237 kapi_Error_pch1( kapi_cLine, 0, "'%s' must be defined of type int", mpchTmp );
00238 }
00239 }
00240
00241 }
00242
00243 static void
00244 kapi_InitInstructionType( knobs_t *pknobs )
00245 {
00246 int nit, i, fError;
00247
00248 nit = KAPI_EnumCardinality( pknobs, "it_t");
00249 if ( KAPI_error_attribute ) {
00250 kapi_Error( kapi_cLine, 0, "'it_t' not defined" );
00251 return;
00252 }
00253
00254 if ( nit != kapi_nIT ) {
00255 kapi_Error_i1( kapi_cLine, 0, "'it_t' must currently have %d components", kapi_nIT );
00256 return;
00257 }
00258
00259 fError = 0;
00260 for ( i=0; i<nit; i++ ) {
00261 char *pch;
00262
00263 pch = KAPI_EnumName( pknobs, i, "it_t" );
00264 switch( i ) {
00265 case kapi_itA:
00266 if ( 0 != strcmp( pch, "itA" ) ) {
00267 fError = 1;
00268 }
00269 break;
00270 case kapi_itI:
00271 if ( 0 != strcmp( pch, "itI" ) ) {
00272 fError = 1;
00273 }
00274 break;
00275 case kapi_itF:
00276 if ( 0 != strcmp( pch, "itF" ) ) {
00277 fError = 1;
00278 }
00279 break;
00280 case kapi_itM:
00281 if ( 0 != strcmp( pch, "itM" ) ) {
00282 fError = 1;
00283 }
00284 break;
00285 case kapi_itBl:
00286 if ( 0 != strcmp( pch, "itBl" ) ) {
00287 fError = 1;
00288 }
00289 break;
00290 case kapi_itB:
00291 if ( 0 != strcmp( pch, "itB" ) ) {
00292 fError = 1;
00293 }
00294 break;
00295 }
00296 }
00297
00298 if ( fError ) {
00299 kapi_Error( kapi_cLine, 0, "Order of 'it_t' enums is not correct" );
00300 return;
00301 }
00302
00303 pknobs->nitinfoTable = nit;
00304 pknobs->dmpitinfoTable = (itinfo_t *)malloc( sizeof( itinfo_t ) * nit );
00305
00306 #define INIT_IT_ENTRY( _idxit, _pchit, _bv32syl ) \
00307 pknobs->dmpitinfoTable[ (_idxit) ].pchitName = (_pchit); \
00308 pknobs->dmpitinfoTable[ (_idxit) ].it = (_idxit); \
00309 pknobs->dmpitinfoTable[ (_idxit) ].bv32sylAllowed = _bv32syl;
00310
00311 INIT_IT_ENTRY( kapi_itA, "itA", bv32sylI | bv32sylM );
00312 INIT_IT_ENTRY( kapi_itI, "itI", bv32sylI );
00313 INIT_IT_ENTRY( kapi_itM, "itM", bv32sylM );
00314 INIT_IT_ENTRY( kapi_itB, "itB", bv32sylB );
00315 INIT_IT_ENTRY( kapi_itBl, "itBl", bv32sylB );
00316 INIT_IT_ENTRY( kapi_itF, "itF", bv32sylF );
00317 INIT_IT_ENTRY( kapi_itL, "itL", bv32sylL );
00318
00319
00320
00321 pknobs->dmpitinfoTable[ kapi_itA ].maxAvail =
00322 pknobs->mpnut[ kapi_utI ] +
00323 pknobs->mpnut[ kapi_utM ];
00324 pknobs->dmpitinfoTable[ kapi_itM ].maxAvail =
00325 pknobs->mpnut[ kapi_utM ];
00326 pknobs->dmpitinfoTable[ kapi_itI ].maxAvail =
00327 pknobs->mpnut[ kapi_utI ];
00328 pknobs->dmpitinfoTable[ kapi_itB ].maxAvail =
00329 pknobs->mpnut[ kapi_utB ];
00330 pknobs->dmpitinfoTable[ kapi_itF ].maxAvail =
00331 pknobs->mpnut[ kapi_utF ];
00332
00333
00334 pknobs->dmpitinfoTable[ kapi_itBl ].maxAvail =
00335 pknobs->mpnut[ kapi_utF ];
00336 pknobs->dmpitinfoTable[ kapi_itL ].maxAvail =
00337 pknobs->mpnut[ kapi_utF ];
00338 }
00339
00340
00341 static void
00342 kapi_InitNumberOfClrNutCportPort( knobs_t *pknobs )
00343 {
00344 int i, nut, iclr, iport, cutport;
00345 int fError, nclr;
00346 kapi_ut_t ut;
00347
00348 clr_t *pclr;
00349
00350 nut = KAPI_EnumCardinality( pknobs, "ut_t" );
00351 if ( KAPI_error_attribute ) {
00352 kapi_Error( kapi_cLine, 0, "'ut_t' not defined or incorrect" );
00353 return;
00354 }
00355 if ( nut != kapi_nUT ) {
00356 kapi_Error( kapi_cLine, 0, "There must currently be 4 unit types defined" );
00357 return;
00358 }
00359
00360 fError = 0;
00361 for ( i=0; i<nut; i++ ) {
00362 char *pch;
00363
00364 pch = KAPI_EnumName( pknobs, i, "ut_t" );
00365 switch( i ) {
00366 case kapi_utI:
00367 if ( 0 != strcmp( pch, "utI" ) ) {
00368 fError = 1;
00369 }
00370 break;
00371 case kapi_utF:
00372 if ( 0 != strcmp( pch, "utF" ) ) {
00373 fError = 1;
00374 }
00375 break;
00376 case kapi_utM:
00377 if ( 0 != strcmp( pch, "utM" ) ) {
00378 fError = 1;
00379 }
00380 break;
00381 case kapi_utB:
00382 if ( 0 != strcmp( pch, "utB" ) ) {
00383 fError = 1;
00384 }
00385 break;
00386 default:
00387 assert( 0 );
00388 }
00389 }
00390 if ( fError ) {
00391 kapi_Error( kapi_cLine, 0, "Order of 'ut_t' enums is not correct" );
00392 return;
00393 }
00394
00395
00396 nclr = KAPI_GetIntegerVariable( pknobs, "NumberOfClusters", 0 );
00397 if ( nclr > maxCLR ) {
00398 kapi_Error_i1( kapi_cLine, 0,
00399 "Kapi currently supports a maximum of %d clusters", nclr );
00400 return;
00401 }
00402 if ( nclr > 0 ) {
00403 pknobs->nclr = nclr;
00404 }
00405
00406
00407 for ( i=0; i<nut; i++ ) {
00408 pknobs->mpnut[ i ] = 0;
00409 }
00410 pknobs->nports = 0;
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 for ( iclr=0; iclr<nclr; iclr++ ) {
00421 char mpchCluster[ 100 ];
00422
00423 sprintf( mpchCluster, "cluster%dCutports", iclr );
00424 pclr = &(pknobs->mpclrTable[ iclr ]);
00425
00426 if ( KAPI_VariableCardinality( pknobs, mpchCluster ) == -1 ) {
00427 kapi_Error_pch1( 0, 0, "%s must be defined", mpchCluster );
00428 continue;
00429 }
00430
00431 pclr->ncports = 0;
00432
00433 for ( ut=kapi_utFIRST; ut<=kapi_utLAST; ut++ ) {
00434 pclr->mpncutport[ ut ]
00435 = KAPI_GetIntegerVariable( pknobs, mpchCluster, ut );
00436 if ( pclr->mpncutport[ ut ] == -1 ) {
00437 kapi_Error_i1( kapi_cLine, 0,
00438 "Number of units for cluster %d not fully specified", nclr );
00439 pknobs->nclr = iclr;
00440 pclr->mpncutport[ ut ] = 0;
00441 }
00442
00443
00444 pknobs->mpnut[ ut ] += pclr->mpncutport[ ut ];
00445 pknobs->nports += pclr->mpncutport[ ut ];
00446 pclr->ncports += pclr->mpncutport[ ut ];
00447 }
00448 }
00449
00450
00451 iport = 0;
00452 for ( iclr=0; iclr<pknobs->nclr; iclr++ ) {
00453 pclr = &(pknobs->mpclrTable[ iclr ]);
00454
00455 for ( ut=kapi_utFIRST; ut<=kapi_utLAST; ut++ ) {
00456 for ( cutport=0;
00457 cutport < pclr->mpncutport[ ut ];
00458 cutport++ ){
00459 pknobs->mppportinfoTable[ iport ] =
00460 &(pclr->dmppcportinfoTable[ ut ][ cutport ]);
00461 iport++;
00462 }
00463 }
00464 }
00465 }
00466
00467 char *
00468 pchTranslateBypass2Intracluster( knobs_t *pknobs, char *pchIn )
00469 {
00470 char *pchfuSrc, *pchPortSrc, *pchOppSrc, *pchValue;
00471 char *pchfuDest, *pchPortDest, *pchOppDest;
00472 char mpchTmp[ 400 ];
00473 char mpchTmp2[ 400 ], *pchNew;
00474
00475 (void)strncpy( (char *)mpchTmp, pchIn, 399 );
00476
00477 ParseBypass( mpchTmp,
00478 &pchfuSrc, &pchPortSrc, &pchOppSrc,
00479 &pchfuDest, &pchPortDest, &pchOppDest,
00480 &pchValue );
00481
00482 if ( pchOppSrc != NULL || pchOppDest != NULL ) {
00483 kapi_Error( kapi_cLine, 0, "Cannot translate KAPI2x BYPASS -- cannot handle operand specifications" );
00484 }
00485
00486 mpchTmp2[ 0 ] = '\0';
00487 pchNew = strcat( mpchTmp2, pchfuSrc );
00488 if ( pchPortSrc != NULL ) {
00489 pchNew = strcat( pchNew, "/primary/c" );
00490 pchNew = strcat( pchNew, pchPortSrc );
00491 }
00492
00493 pchNew = strcat( pchNew, ":" );
00494 pchNew = strcat( pchNew, pchfuDest );
00495
00496 if ( pchPortDest != NULL ) {
00497 pchNew = strcat( pchNew, "/primary/c" );
00498 pchNew = strcat( pchNew, pchPortDest );
00499 }
00500
00501 pchNew = strcat( pchNew, "=" );
00502 pchNew = strcat( pchNew, pchValue );
00503
00504 return( strdup( pchNew ) );
00505 }
00506
00507 static void
00508 ParseBypass( char *pch, char **ppchFcSrc, char **ppchPortSrc, char **ppchOppSrc,
00509 char **ppchFcDest, char **ppchPortDest, char **ppchOppDest,
00510 char **ppchLatency )
00511 {
00512 char *pchSrc, *pchDest, *pchVal;
00513
00514
00515
00516 pchVal = (char *)strchr( pch, '=' );
00517 if ( pchVal == NULL ) {
00518 kapi_Error_pch1( -1, 0, "Malformed bypass attribute '%s' -- '=' required", pch );
00519 return;
00520 }
00521 *pchVal = '\0';
00522
00523
00524 *ppchLatency = pchVal + 1;
00525
00526
00527
00528
00529 pchDest = (char *)strchr( pch, ':' );
00530 if ( pchDest == NULL ) {
00531 kapi_Error_pch1( -1, 0, "Malformed bypass attribute '%s' -- ':' required", pch );
00532 return;
00533 }
00534 *pchDest = '\0';
00535 pchDest = pchDest + 1;
00536 pchSrc = pch;
00537
00538
00539 *ppchFcSrc = NULL;
00540 *ppchPortSrc = NULL;
00541 *ppchOppSrc = NULL;
00542 *ppchFcDest = NULL;
00543 *ppchPortDest = NULL;
00544 *ppchOppDest = NULL;
00545
00546
00547 *ppchFcSrc = strtok( pchSrc, " /" );
00548 if ( *ppchFcSrc ) {
00549 *ppchPortSrc = strtok( NULL, " /" );
00550 if ( *ppchPortSrc ) {
00551 *ppchOppSrc = strtok( NULL, " /" );
00552 }
00553 }
00554
00555
00556 *ppchFcDest = strtok( pchDest, "/" );
00557 if ( *ppchFcDest ) {
00558 *ppchPortDest = strtok( NULL, " /" );
00559 if ( *ppchPortDest ) {
00560 *ppchOppDest = strtok( NULL, " /" );
00561 }
00562 }
00563 }
00564
00565 void
00566 kapi_InitBidAndSyllable( knobs_t *pknobs )
00567 {
00568 int i, nsyl, nbid;
00569 kapi_it_t it;
00570 kapi_bid_t bid;
00571 kapi_syl_t syl;
00572 int fError;
00573
00574
00575 nsyl = KAPI_EnumCardinality( pknobs, "syl_t" );
00576
00577 if ( KAPI_error_attribute ) {
00578 kapi_Error( kapi_cLine, 0, "'syl_t' not defined according to EAS" );
00579 }
00580
00581 if ( nsyl != 5 ) {
00582 kapi_Error( kapi_cLine, 0, "Current EAS requires syl_t to have 5 syllable types" );
00583 return;
00584 }
00585
00586 fError = 0;
00587 for ( i=0; i<nsyl; i++ ) {
00588 char *pch;
00589 pch = KAPI_EnumName( pknobs, i, "syl_t" );
00590 if ( KAPI_error_attribute ) {
00591 kapi_Error_i1( kapi_cLine, 0, "Constant %d of 'syl_t' not defined", i );
00592 }
00593
00594 switch( i ) {
00595 case kapi_sylL:
00596 if ( 0 != strcmp( pch, "sylL" ) ) {
00597 fError = 1;
00598 }
00599 break;
00600 case kapi_sylI:
00601 if ( 0 != strcmp( pch, "sylI" ) ) {
00602 fError = 1;
00603 }
00604 break;
00605 case kapi_sylF:
00606 if ( 0 != strcmp( pch, "sylF" ) ) {
00607 fError = 1;
00608 }
00609 break;
00610 case kapi_sylM:
00611 if ( 0 != strcmp( pch, "sylM" ) ) {
00612 fError = 1;
00613 }
00614 break;
00615 case kapi_sylB:
00616 if ( 0 != strcmp( pch, "sylB" ) ) {
00617 fError = 1;
00618 }
00619 break;
00620 }
00621 }
00622 if ( fError ) {
00623 kapi_Error( kapi_cLine, 0, "Order of 'syl_t' enums is not correct" );
00624 return;
00625 }
00626
00627 pknobs->nsylinfoTable = nsyl;
00628 pknobs->dmpsylinfoTable = (sylinfo_t *)malloc( sizeof( sylinfo_t ) * nsyl );
00629
00630
00631 nbid = KAPI_EnumCardinality( pknobs, "bid_t");
00632 if ( KAPI_error_attribute ) {
00633 kapi_Error( kapi_cLine, 0, "'bid_t' not defined according to EAS" );
00634 return;
00635 }
00636
00637 if ( nbid != kapi_nBID ) {
00638 kapi_Error( kapi_cLine, 0, "Current EAS requires bid_t to have 16 entries" );
00639 return;
00640 }
00641
00642 pknobs->nbidinfoTable = nbid;
00643 pknobs->dmpbidinfoTable = (bidinfo_t *)malloc( sizeof( bidinfo_t ) * nbid );
00644
00645
00646
00647
00648 pknobs->dmpbidinfoTable[ bidMII ].pchBID = "bidMII";
00649 pknobs->dmpbidinfoTable[ bidMI_I ].pchBID = "bidMI_I";
00650 pknobs->dmpbidinfoTable[ bidMLI ].pchBID = "bidMLX";
00651 pknobs->dmpbidinfoTable[ bidRESERVED_3 ].pchBID = "bidRESERVED_3";
00652 pknobs->dmpbidinfoTable[ bidMMI ].pchBID = "bidMMI";
00653 pknobs->dmpbidinfoTable[ bidM_MI ].pchBID = "bidM_MI";
00654 pknobs->dmpbidinfoTable[ bidMFI ].pchBID = "bidMFI";
00655 pknobs->dmpbidinfoTable[ bidMMF ].pchBID = "bidMMF";
00656 pknobs->dmpbidinfoTable[ bidMIB ].pchBID = "bidMIB";
00657 pknobs->dmpbidinfoTable[ bidMBB ].pchBID = "bidMBB";
00658 pknobs->dmpbidinfoTable[ bidRESERVED_A ].pchBID = "bidRESERVED_A";
00659 pknobs->dmpbidinfoTable[ bidBBB ].pchBID = "bidBBB";
00660 pknobs->dmpbidinfoTable[ bidMMB ].pchBID = "bidMMB";
00661 pknobs->dmpbidinfoTable[ bidRESERVED_D ].pchBID = "bidRESERVED_D";
00662 pknobs->dmpbidinfoTable[ bidMFB ].pchBID = "bidMFB";
00663 pknobs->dmpbidinfoTable[ bidRESERVED_F ].pchBID = "bidRESERVED_F";
00664
00665 for ( bid=kapi_bidFIRST; bid<=kapi_bidLAST; bid++ ) {
00666 char *pchBid;
00667
00668 for ( syl=kapi_sylFIRST; syl<=kapi_sylLAST; syl++ ) {
00669 pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ syl ] = 0;
00670 }
00671 for ( it=kapi_itFIRST; it<=kapi_itLAST; it++ ) {
00672 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ it ] = 0;
00673 }
00674 pknobs->dmpbidinfoTable[ bid ].fReserved = 0;
00675 pknobs->dmpbidinfoTable[ bid ].isylSbit = 0;
00676
00677 pchBid = KAPI_EnumName( pknobs, bid, "bid_t" );
00678 if ( 1 != KAPI_GetIntegerVariable( pknobs, "AllowAlternateBids", 0 ) ) {
00679 if ( strcmp( pchBid, pknobs->dmpbidinfoTable[ bid ].pchBID ) ) {
00680 #if 0
00681 if ( bid == bidMMF && 0 == strcmp( pchBID, "bidRESERVED_7" ) ) {
00682 } else {
00683 }
00684 #else
00685 kapi_Error_i1( kapi_cLine, 0,
00686 "Enumeration constant at position %d of 'bid_t' not defined according to EAS 2.5", bid );
00687 #endif
00688 }
00689 }
00690 }
00691
00692 pknobs->dmpbidinfoTable[ bidMII ].mpnsylAvail[ kapi_sylI ] = 2;
00693 pknobs->dmpbidinfoTable[ bidMII ].mpnsylAvail[ kapi_sylM ] = 1;
00694
00695 pknobs->dmpbidinfoTable[ bidMII ].mpsylType[ 0 ] = kapi_sylM;
00696 pknobs->dmpbidinfoTable[ bidMII ].mpsylType[ 1 ] = kapi_sylI;
00697 pknobs->dmpbidinfoTable[ bidMII ].mpsylType[ 2 ] = kapi_sylI;
00698
00699
00700 pknobs->dmpbidinfoTable[ bidMI_I ].mpnsylAvail[ kapi_sylI ] = 2;
00701 pknobs->dmpbidinfoTable[ bidMI_I ].mpnsylAvail[ kapi_sylM ] = 1;
00702 pknobs->dmpbidinfoTable[ bidMI_I ].isylSbit = 2;
00703
00704 pknobs->dmpbidinfoTable[ bidMI_I ].mpsylType[ 0 ] = kapi_sylM;
00705 pknobs->dmpbidinfoTable[ bidMI_I ].mpsylType[ 1 ] = kapi_sylI;
00706 pknobs->dmpbidinfoTable[ bidMI_I ].mpsylType[ 2 ] = kapi_sylI;
00707
00708
00709 pknobs->dmpbidinfoTable[ bidMLI ].mpnsylAvail[ kapi_sylM ] = 1;
00710 pknobs->dmpbidinfoTable[ bidMLI ].mpnsylAvail[ kapi_sylL ] = 1;
00711
00712 pknobs->dmpbidinfoTable[ bidMLI ].mpsylType[ 0 ] = kapi_sylM;
00713 pknobs->dmpbidinfoTable[ bidMLI ].mpsylType[ 1 ] = kapi_sylL;
00714 pknobs->dmpbidinfoTable[ bidMLI ].mpsylType[ 2 ] = kapi_sylI;
00715
00716
00717 pknobs->dmpbidinfoTable[ bidRESERVED_3 ].fReserved = 1;
00718 pknobs->dmpbidinfoTable[ bidRESERVED_3 ].mpsylType[ 0 ] = kapi_sylI;
00719 pknobs->dmpbidinfoTable[ bidRESERVED_3 ].mpsylType[ 1 ] = kapi_sylI;
00720 pknobs->dmpbidinfoTable[ bidRESERVED_3 ].mpsylType[ 2 ] = kapi_sylI;
00721
00722
00723 pknobs->dmpbidinfoTable[ bidMMI ].mpnsylAvail[ kapi_sylI ] = 1;
00724 pknobs->dmpbidinfoTable[ bidMMI ].mpnsylAvail[ kapi_sylM ] = 2;
00725
00726 pknobs->dmpbidinfoTable[ bidMMI ].mpsylType[ 0 ] = kapi_sylM;
00727 pknobs->dmpbidinfoTable[ bidMMI ].mpsylType[ 1 ] = kapi_sylM;
00728 pknobs->dmpbidinfoTable[ bidMMI ].mpsylType[ 2 ] = kapi_sylI;
00729
00730
00731 pknobs->dmpbidinfoTable[ bidM_MI ].mpnsylAvail[ kapi_sylI ] = 1;
00732 pknobs->dmpbidinfoTable[ bidM_MI ].mpnsylAvail[ kapi_sylM ] = 2;
00733 pknobs->dmpbidinfoTable[ bidM_MI ].isylSbit = 1;
00734
00735 pknobs->dmpbidinfoTable[ bidM_MI ].mpsylType[ 0 ] = kapi_sylM;
00736 pknobs->dmpbidinfoTable[ bidM_MI ].mpsylType[ 1 ] = kapi_sylM;
00737 pknobs->dmpbidinfoTable[ bidM_MI ].mpsylType[ 2 ] = kapi_sylI;
00738
00739
00740 pknobs->dmpbidinfoTable[ bidMFI ].mpnsylAvail[ kapi_sylI ] = 1;
00741 pknobs->dmpbidinfoTable[ bidMFI ].mpnsylAvail[ kapi_sylF ] = 1;
00742 pknobs->dmpbidinfoTable[ bidMFI ].mpnsylAvail[ kapi_sylM ] = 1;
00743
00744 pknobs->dmpbidinfoTable[ bidMFI ].mpsylType[ 0 ] = kapi_sylM;
00745 pknobs->dmpbidinfoTable[ bidMFI ].mpsylType[ 1 ] = kapi_sylF;
00746 pknobs->dmpbidinfoTable[ bidMFI ].mpsylType[ 2 ] = kapi_sylI;
00747
00748
00749 pknobs->dmpbidinfoTable[ bidMMF ].mpnsylAvail[ kapi_sylI ] = 0;
00750 pknobs->dmpbidinfoTable[ bidMMF ].mpnsylAvail[ kapi_sylF ] = 1;
00751 pknobs->dmpbidinfoTable[ bidMMF ].mpnsylAvail[ kapi_sylM ] = 2;
00752
00753 pknobs->dmpbidinfoTable[ bidMMF ].mpsylType[ 0 ] = kapi_sylM;
00754 pknobs->dmpbidinfoTable[ bidMMF ].mpsylType[ 1 ] = kapi_sylM;
00755 pknobs->dmpbidinfoTable[ bidMMF ].mpsylType[ 2 ] = kapi_sylF;
00756
00757
00758 pknobs->dmpbidinfoTable[ bidMIB ].mpnsylAvail[ kapi_sylI ] = 1;
00759 pknobs->dmpbidinfoTable[ bidMIB ].mpnsylAvail[ kapi_sylB ] = 1;
00760 pknobs->dmpbidinfoTable[ bidMIB ].mpnsylAvail[ kapi_sylM ] = 1;
00761
00762 pknobs->dmpbidinfoTable[ bidMIB ].mpsylType[ 0 ] = kapi_sylM;
00763 pknobs->dmpbidinfoTable[ bidMIB ].mpsylType[ 1 ] = kapi_sylI;
00764 pknobs->dmpbidinfoTable[ bidMIB ].mpsylType[ 2 ] = kapi_sylB;
00765
00766
00767 pknobs->dmpbidinfoTable[ bidMBB ].mpnsylAvail[ kapi_sylB ] = 2;
00768 pknobs->dmpbidinfoTable[ bidMBB ].mpnsylAvail[ kapi_sylM ] = 1;
00769
00770 pknobs->dmpbidinfoTable[ bidMBB ].mpsylType[ 0 ] = kapi_sylM;
00771 pknobs->dmpbidinfoTable[ bidMBB ].mpsylType[ 1 ] = kapi_sylB;
00772 pknobs->dmpbidinfoTable[ bidMBB ].mpsylType[ 2 ] = kapi_sylB;
00773
00774
00775 pknobs->dmpbidinfoTable[ bidRESERVED_A ].fReserved = 1;
00776
00777 pknobs->dmpbidinfoTable[ bidRESERVED_A ].mpsylType[ 0 ] = kapi_sylI;
00778 pknobs->dmpbidinfoTable[ bidRESERVED_A ].mpsylType[ 1 ] = kapi_sylI;
00779 pknobs->dmpbidinfoTable[ bidRESERVED_A ].mpsylType[ 2 ] = kapi_sylI;
00780
00781
00782 pknobs->dmpbidinfoTable[ bidBBB ].mpnsylAvail[ kapi_sylB ] = 3;
00783
00784 pknobs->dmpbidinfoTable[ bidBBB ].mpsylType[ 0 ] = kapi_sylB;
00785 pknobs->dmpbidinfoTable[ bidBBB ].mpsylType[ 1 ] = kapi_sylB;
00786 pknobs->dmpbidinfoTable[ bidBBB ].mpsylType[ 2 ] = kapi_sylB;
00787
00788
00789 pknobs->dmpbidinfoTable[ bidMMB ].mpnsylAvail[ kapi_sylB ] = 1;
00790 pknobs->dmpbidinfoTable[ bidMMB ].mpnsylAvail[ kapi_sylM ] = 2;
00791
00792 pknobs->dmpbidinfoTable[ bidMMB ].mpsylType[ 0 ] = kapi_sylM;
00793 pknobs->dmpbidinfoTable[ bidMMB ].mpsylType[ 1 ] = kapi_sylM;
00794 pknobs->dmpbidinfoTable[ bidMMB ].mpsylType[ 2 ] = kapi_sylB;
00795
00796
00797 pknobs->dmpbidinfoTable[ bidRESERVED_D ].fReserved = 1;
00798
00799 pknobs->dmpbidinfoTable[ bidRESERVED_D ].mpsylType[ 0 ] = kapi_sylI;
00800 pknobs->dmpbidinfoTable[ bidRESERVED_D ].mpsylType[ 1 ] = kapi_sylI;
00801 pknobs->dmpbidinfoTable[ bidRESERVED_D ].mpsylType[ 2 ] = kapi_sylI;
00802
00803
00804 pknobs->dmpbidinfoTable[ bidMFB ].mpnsylAvail[ kapi_sylF ] = 1;
00805 pknobs->dmpbidinfoTable[ bidMFB ].mpnsylAvail[ kapi_sylB ] = 1;
00806 pknobs->dmpbidinfoTable[ bidMFB ].mpnsylAvail[ kapi_sylM ] = 1;
00807
00808 pknobs->dmpbidinfoTable[ bidMFB ].mpsylType[ 0 ] = kapi_sylM;
00809 pknobs->dmpbidinfoTable[ bidMFB ].mpsylType[ 1 ] = kapi_sylF;
00810 pknobs->dmpbidinfoTable[ bidMFB ].mpsylType[ 2 ] = kapi_sylB;
00811
00812
00813 pknobs->dmpbidinfoTable[ bidRESERVED_F ].fReserved = 1;
00814
00815 pknobs->dmpbidinfoTable[ bidRESERVED_F ].mpsylType[ 0 ] = kapi_sylI;
00816 pknobs->dmpbidinfoTable[ bidRESERVED_F ].mpsylType[ 1 ] = kapi_sylI;
00817 pknobs->dmpbidinfoTable[ bidRESERVED_F ].mpsylType[ 2 ] = kapi_sylI;
00818
00819
00820 for ( bid=kapi_bidFIRST; bid<=kapi_bidLAST; bid++ ) {
00821 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ kapi_itI ] =
00822 pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylI ];
00823 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ kapi_itM ] =
00824 pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylM ];
00825 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ kapi_itA ] =
00826 pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylI ]
00827 + pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylM ];
00828 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ kapi_itB ] =
00829 pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylB ];
00830 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ kapi_itBl ] =
00831 ( pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylB ] > 0 );
00832 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ kapi_itF ] =
00833 pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylF ];
00834 pknobs->dmpbidinfoTable[ bid ].mpnitAvail[ kapi_itL ] =
00835 pknobs->dmpbidinfoTable[ bid ].mpnsylAvail[ kapi_sylL ];
00836 }
00837
00838
00839
00840 pknobs->dmpsylinfoTable[ kapi_sylI ].mpnutNeeded[ kapi_utI ] = 1;
00841 pknobs->dmpsylinfoTable[ kapi_sylI ].mpnutNeeded[ kapi_utF ] = 0;
00842 pknobs->dmpsylinfoTable[ kapi_sylI ].mpnutNeeded[ kapi_utB ] = 0;
00843 pknobs->dmpsylinfoTable[ kapi_sylI ].mpnutNeeded[ kapi_utM ] = 0;
00844 pknobs->dmpsylinfoTable[ kapi_sylI ].itMajor = kapi_itA;
00845
00846 pknobs->dmpsylinfoTable[ kapi_sylF ].mpnutNeeded[ kapi_utI ] = 0;
00847 pknobs->dmpsylinfoTable[ kapi_sylF ].mpnutNeeded[ kapi_utF ] = 1;
00848 pknobs->dmpsylinfoTable[ kapi_sylF ].mpnutNeeded[ kapi_utB ] = 0;
00849 pknobs->dmpsylinfoTable[ kapi_sylF ].mpnutNeeded[ kapi_utM ] = 0;
00850 pknobs->dmpsylinfoTable[ kapi_sylF ].itMajor = kapi_itF;
00851
00852 pknobs->dmpsylinfoTable[ kapi_sylB ].mpnutNeeded[ kapi_utI ] = 0;
00853 pknobs->dmpsylinfoTable[ kapi_sylB ].mpnutNeeded[ kapi_utF ] = 0;
00854 pknobs->dmpsylinfoTable[ kapi_sylB ].mpnutNeeded[ kapi_utB ] = 1;
00855 pknobs->dmpsylinfoTable[ kapi_sylB ].mpnutNeeded[ kapi_utM ] = 0;
00856 pknobs->dmpsylinfoTable[ kapi_sylB ].itMajor = kapi_itB;
00857
00858 pknobs->dmpsylinfoTable[ kapi_sylM ].mpnutNeeded[ kapi_utI ] = 0;
00859 pknobs->dmpsylinfoTable[ kapi_sylM ].mpnutNeeded[ kapi_utF ] = 0;
00860 pknobs->dmpsylinfoTable[ kapi_sylM ].mpnutNeeded[ kapi_utB ] = 0;
00861 pknobs->dmpsylinfoTable[ kapi_sylM ].mpnutNeeded[ kapi_utM ] = 1;
00862 pknobs->dmpsylinfoTable[ kapi_sylM ].itMajor = kapi_itA;
00863
00864 pknobs->dmpsylinfoTable[ kapi_sylL ].mpnutNeeded[ kapi_utI ] = 1;
00865 pknobs->dmpsylinfoTable[ kapi_sylL ].mpnutNeeded[ kapi_utF ] = 1;
00866 pknobs->dmpsylinfoTable[ kapi_sylL ].mpnutNeeded[ kapi_utB ] = 0;
00867 pknobs->dmpsylinfoTable[ kapi_sylL ].mpnutNeeded[ kapi_utM ] = 0;
00868 pknobs->dmpsylinfoTable[ kapi_sylL ].itMajor = kapi_itL;
00869 }
00870
00871 int kapi_CharCount(char c, char *pString)
00872 {
00873 int count=0;
00874 while (*pString)
00875 {
00876 if (*pString==c)
00877 count++;
00878 pString++;
00879 }
00880 return count;
00881 }
00882
00883 int kapi_ParseOpAttribute(knobs_t *pknobs, char *pAttribute, int *fuIdx, int *nOpNames, char **pOpNames)
00884 {
00885 char *sName,*pWalker=pAttribute;
00886 int fPrimary,iOpIndex,i;
00887 int fNoPrimary=0;
00888
00889
00890 if (kapi_CharCount('*',pAttribute) > 1)
00891 {
00892 kapi_Error_pch1(0,0,"bad attribute, there can be only one primary operand\n\t\t \"%s\"!",pAttribute);
00893 *nOpNames=0;
00894 *fuIdx=0;
00895 return 0;
00896 }
00897 if (kapi_CharCount('*',pAttribute) == 0)
00898 {
00899 kapi_Warning_pch1(0,0,"No primary operand defined\n\t\t \"%s\"!",pAttribute);
00900 fNoPrimary=1;
00901 }
00902
00903
00904 *nOpNames = kapi_CharCount(',',pAttribute)+1;
00905 while ((*pWalker) && *pWalker!=':')
00906 pWalker++;
00907
00908
00909 sName=(char *)malloc( sizeof(char) * (pWalker - pAttribute +1) );
00910 strncpy(sName,pAttribute, pWalker - pAttribute);
00911 sName[pWalker - pAttribute]=0;
00912 *fuIdx = KAPI_EnumIndex( pknobs, "fu_t", sName );
00913 free(sName);
00914 if (*fuIdx<0)
00915 {
00916 kapi_Error_pch1(0,0,"bad attribute, or no such fu_t \"%s\"!",pAttribute);
00917 }
00918 pOpNames[0]="primary";
00919 if (fNoPrimary)
00920 iOpIndex=0;
00921 else
00922 iOpIndex=1;
00923
00924 for (i=0, fPrimary=0; i < *nOpNames ; i++, fPrimary=0)
00925 {
00926
00927 pAttribute=++pWalker;
00928 if (*pAttribute=='*')
00929 {
00930 pAttribute++;
00931 fPrimary=1;
00932 }
00933 while ( (*pWalker) &&
00934 (*pWalker != ',') )
00935 pWalker++;
00936
00937
00938 sName=(char *)malloc( sizeof(char) * (pWalker - pAttribute +1) );
00939 strncpy(sName,pAttribute, pWalker - pAttribute);
00940 sName[pWalker - pAttribute]=0;
00941
00942
00943 if (fPrimary)
00944 pOpNames[0]=sName;
00945 else
00946 pOpNames[iOpIndex++]=sName;
00947 }
00948 return fNoPrimary;
00949 }
00950
00951 static void
00952 kapi_ProcessFuOperands(knobs_t *pknobs )
00953 {
00954 int nOpAttributes=0,i;
00955 char *pOpNames[maxSOURCES + maxDESTINATIONS];
00956 int nOpNames, fuIdx;
00957 char *pAttribute;
00958
00959
00960
00961
00962
00963
00964 nOpAttributes = KAPI_count4attribute( pknobs, "SOURCES" );
00965 if (nOpAttributes<=0)
00966 {
00967 kapi_Error(0,0,"SOURCES attribute not defined or is wrong!");
00968 }
00969 for (i=0;i<nOpAttributes;i++)
00970 {
00971 pAttribute=KAPI_attribute4index(pknobs,"SOURCES",i);
00972 if (kapi_ParseOpAttribute(pknobs,pAttribute, &fuIdx, &nOpNames, pOpNames))
00973 {
00974 pknobs->dmpfuinfoTable[fuIdx].bv32InfoBits |= (1<<kapi_fu_info_no_primary_source);
00975 }
00976 pknobs->dmpfuinfoTable[fuIdx].cntSrc=nOpNames;
00977 while (--nOpNames>=0)
00978 {
00979 pknobs->dmpfuinfoTable[fuIdx].mppchSrcName[nOpNames] =
00980 pOpNames[nOpNames];
00981 }
00982 }
00983
00984
00985
00986
00987
00988 nOpAttributes = KAPI_count4attribute( pknobs, "DESTINATIONS" );
00989 if (nOpAttributes<=0)
00990 {
00991 kapi_Error(0,0,"DESTINATIONS attribute not defined or is wrong!");
00992 }
00993 for (i=0;i<nOpAttributes;i++)
00994 {
00995 pAttribute=KAPI_attribute4index(pknobs,"DESTINATIONS",i);
00996 if (kapi_ParseOpAttribute(pknobs,pAttribute, &fuIdx, &nOpNames, pOpNames))
00997 {
00998 pknobs->dmpfuinfoTable[fuIdx].bv32InfoBits |= (1<<kapi_fu_info_no_primary_destination);
00999 }
01000 pknobs->dmpfuinfoTable[fuIdx].cntDest=nOpNames;
01001 while (--nOpNames>=0)
01002 {
01003 pknobs->dmpfuinfoTable[fuIdx].mppchDestName[nOpNames] =
01004 pOpNames[nOpNames];
01005 }
01006 }
01007 }
01008
01009 static void
01010 kapi_ProcessFuInfoBits( knobs_t *pknobs, kapi_fu_t fu )
01011 {
01012 bv_t *pbvTmp;
01013 bv32_t bv;
01014
01015 pbvTmp = KAPI_GetBvVariable(pknobs,"fuInfoBits",fu);
01016 if (pbvTmp != NULL)
01017 {
01018 bv=pbvTmp->pint32Data[0];
01019 free(pbvTmp);
01020 } else
01021 bv = 0;
01022
01023 pknobs->dmpfuinfoTable[fu].bv32InfoBits = bv;
01024 }
01025
01026
01027
01028 static void
01029 kapi_ProcessFu( knobs_t *pknobs )
01030 {
01031 int i, j, nfu, clr;
01032
01033 for ( clr=0; clr<pknobs->nclr; clr++ ) {
01034 clr_t *pclr;
01035 char mpchCluster[ 40 ];
01036 kapi_ut_t ut;
01037 int cuport;
01038
01039 sprintf( mpchCluster, "cluster%dCportMask", clr );
01040 pclr = &(pknobs->mpclrTable[ clr ]);
01041
01042 if ( KAPI_VariableCardinality( pknobs, mpchCluster ) == -1 ) {
01043 kapi_Error_pch1( 0, 0, "%s must be defined", mpchCluster );
01044 continue;
01045 }
01046 for ( ut=kapi_utFIRST; ut<=kapi_utLAST; ut++ ) {
01047 for ( cuport=0; cuport<pclr->mpncutport[ ut ]; cuport++ ) {
01048 char mpchTmp[ 20 ];
01049 int idx;
01050 bv_t *pbv;
01051
01052 sprintf( mpchTmp, "%%cport%c%d", kapi_ut2ch( ut ), cuport );
01053
01054 idx = KAPI_ArrayIndex( pknobs, mpchCluster, mpchTmp );
01055 if ( idx != -1 ) {
01056 pbv = KAPI_GetBvVariable( pknobs, mpchCluster, idx );
01057 pclr->dmppcportinfoTable[ ut ][ cuport ].bvfuAllowed = *pbv;
01058 } else {
01059 kapi_Error_pch2( 0, 0, "Index %s for %s not defined", &(mpchTmp[1]), mpchCluster );
01060 }
01061 }
01062 }
01063 }
01064
01065 for ( i=0; i<pknobs->nfuinfoTable; i++ ) {
01066
01067 pknobs->dmpfuinfoTable[i].iCoreLatency[ 0 ] =
01068 KAPI_GetIntegerVariable( pknobs, "fuLatency", i );
01069
01070 if ( KAPI_error_attribute ) {
01071 kapi_Error_i1( kapi_cLine, 0,
01072 "Retrieving value of fuLatency[ %d ]", i );
01073 }
01074 }
01075
01076 nfu = KAPI_EnumCardinality( pknobs, "fu_t");
01077 if ( KAPI_error_attribute ) {
01078 kapi_Error( kapi_cLine, 0, "'fu_t' not defined or incorrect" );
01079 return;
01080 }
01081
01082
01083 pknobs->nfuinfoTable = nfu;
01084 pknobs->dmpfuinfoTable = (fuinfo_t *)malloc( sizeof( fuinfo_t ) * nfu );
01085
01086 for ( i=0; i<nfu; i++ ) {
01087 pknobs->dmpfuinfoTable[i].fu = i;
01088 pknobs->dmpfuinfoTable[i].pchName =
01089 kapi_pchCopy( KAPI_EnumName( pknobs, i, "fu_t" ) );
01090 pknobs->dmpfuinfoTable[i].cntDest = 1;
01091 pknobs->dmpfuinfoTable[i].cntSrc = 2;
01092 pknobs->dmpfuinfoTable[i].mppchDestName[0] = "primary";
01093 pknobs->dmpfuinfoTable[i].mppchSrcName[0] = "primary";
01094 pknobs->dmpfuinfoTable[i].mppchSrcName[1] = "predicate";
01095 for ( j=0;j<maxDESTINATIONS;j++ ) {
01096 pknobs->dmpfuinfoTable[i].iCoreLatency[j] = -1;
01097 }
01098 kapi_ProcessFuInfoBits(pknobs,i);
01099 }
01100
01101 kapi_ProcessFuOperands(pknobs);
01102
01103 }
01104
01105 static void
01106 kapi_ProcessCoreLatency( knobs_t *pknobs )
01107 {
01108 int i, nlatency;
01109
01110 for ( i=0; i<pknobs->nfuinfoTable; i++ ) {
01111 int iLatency;
01112
01113 iLatency=KAPI_GetIntegerVariable( pknobs, "fuLatency", i );
01114
01115 if (pknobs->dmpfuinfoTable[i].bv32InfoBits & (1<<kapi_fu_info_no_primary_destination))
01116 {
01117 if (iLatency != -1)
01118 {
01119 kapi_Error_pch1(0,0,"fuLatency invalid since fuClass %s has no primary destination operand",
01120 pknobs->dmpfuinfoTable[i].pchName);
01121 }
01122 } else
01123 {
01124 pknobs->dmpfuinfoTable[i].iCoreLatency[ 0 ] = iLatency;
01125 }
01126
01127
01128 if ( KAPI_error_attribute ) {
01129 kapi_Error_i1( kapi_cLine, 0,
01130 "Retrieving value of fuLatency[ %d ]", i );
01131 }
01132 }
01133
01134 nlatency = KAPI_count4attribute( pknobs, "LATENCY" );
01135
01136 for ( i=0; i<nlatency; i++ ) {
01137 char *pch, *pchFcSrc, *pchOpp;
01138 char mpchTmp[ 400 ];
01139 int iLatency, opp;
01140 kapi_fu_t fu;
01141
01142
01143 pch = KAPI_attribute4index( pknobs, "LATENCY", i );
01144
01145 (void)strncpy( (char *)mpchTmp, pch, 399 );
01146
01147 ParseLatency( mpchTmp, &pchFcSrc, &pchOpp, &iLatency );
01148
01149 fu = KAPI_EnumIndex( pknobs, "fu_t", pchFcSrc );
01150 if ( -1 == fu ) {
01151
01152 continue;
01153 } else {
01154 if ( pknobs->dmpfudirTable[ fu ] == pknobs->fudirSource ) {
01155 opp = KAPI_oppGetSource( pknobs, fu, pchOpp );
01156 } else {
01157 opp = KAPI_oppGetDest( pknobs, fu, pchOpp );
01158 }
01159 if ( -1 == opp || pchOpp == NULL ) {
01160
01161 kapi_Error_pch1(0,0,"Bad operand in attribute: %s",pch);
01162 continue;
01163 } else {
01164 pknobs->dmpfuinfoTable[ fu ].iCoreLatency[ opp ] = iLatency;
01165 }
01166 }
01167 }
01168 }
01169
01170 static void
01171 ParseClusterDistance( char *pch, char **ppchClrSrc, char **ppchClrDest,
01172 char **ppchValue )
01173 {
01174 char *pchSrc, *pchValue;
01175
01176
01177
01178 pchValue = (char *)strchr( pch, '=' );
01179 if ( pchValue == NULL ) {
01180 kapi_Error_pch1( -1, 0,
01181 "Malformed cluster distance attribute '%s' -- '=' required",
01182 pch );
01183 return;
01184 }
01185 *pchValue = '\0';
01186
01187
01188 pchValue = pchValue + 1;
01189
01190 *ppchValue = pchValue;
01191
01192
01193
01194
01195 pchSrc = pch;
01196
01197
01198 *ppchClrSrc = NULL;
01199 *ppchClrSrc = NULL;
01200
01201
01202 *ppchClrSrc = strtok( pchSrc, " :" );
01203 if ( *ppchClrSrc ) {
01204 *ppchClrDest = strtok( NULL, " :" );
01205 }
01206 }
01207
01208 static int
01209 fOkProcessClusterDistance( knobs_t *pknobs, char *pchClrSrc,
01210 char *pchClrDest, char *pchValue,
01211 int *piClrSrc, int *piClrDest, int *pivalue )
01212 {
01213 int iclr;
01214
01215
01216 if ( strspn( pchValue, "0123456789-" ) != strlen( pchValue ) ) {
01217 kapi_Error_pch1( -1, 0,
01218 "Badly formed cluster distance: value '%s' not valid",
01219 pchNULL_PRINT(pchValue) );
01220 return( 0 );
01221 }
01222
01223 *pivalue = atoi( pchValue );
01224
01225
01226 iclr = clusterInterpretpchclr( pchClrSrc );
01227 if ( iclr < 0 ) {
01228 kapi_Error_pch1( -1, 0,
01229 "Badly formed source cluster name: cluster '%s' not valid",
01230 pchNULL_PRINT(pchClrSrc) );
01231 return( 0 );
01232 }
01233 *piClrSrc = iclr;
01234
01235
01236 iclr = clusterInterpretpchclr( pchClrDest );
01237 if ( iclr < 0 ) {
01238 kapi_Error_pch1( -1, 0,
01239 "Badly formed destination cluster: cluster '%s' not valid",
01240 pchNULL_PRINT(pchClrDest) );
01241 return( 0 );
01242 }
01243 *piClrDest = iclr;
01244
01245
01246 if ( *piClrSrc >= pknobs->nclr ) {
01247
01248 return( 0 );
01249 }
01250
01251 if ( *piClrDest >= pknobs->nclr ) {
01252
01253 return( 0 );
01254 }
01255
01256
01257 return( 1 );
01258 }
01259
01260 static void
01261 kapi_ProcessClusterDistance( knobs_t *pknobs )
01262 {
01263 int i, j, ncdist;
01264
01265
01266 for ( i=0; i<maxCLR; i++ ) {
01267 for ( j=0; j<maxCLR; j++ ) {
01268 pknobs->mpclrTable[ i ].distClr[ j ] = 0;
01269 }
01270 }
01271
01272 ncdist = KAPI_count4attribute( pknobs, "CLUSTERDISTANCE" );
01273 for ( i=0; i<ncdist; i++ ) {
01274 char *pch, *pchClrSrc, *pchClrDest, *pchValue;
01275 char mpchTmp[ 400 ];
01276 int ivalue, fOk, iclrSrc, iclrDest;
01277
01278
01279 pch = KAPI_attribute4index( pknobs, "CLUSTERDISTANCE", i );
01280
01281 (void)strncpy( (char *)mpchTmp, pch, 399 );
01282
01283 ParseClusterDistance( mpchTmp, &pchClrSrc, &pchClrDest, &pchValue );
01284
01285 fOk = fOkProcessClusterDistance( pknobs, pchClrSrc, pchClrDest, pchValue,
01286 &iclrSrc, &iclrDest, &ivalue );
01287 if ( fOk ) {
01288 pknobs->mpclrTable[ iclrSrc ].distClr[ iclrDest ] = ivalue;
01289 }
01290 }
01291 }
01292
01293 static void
01294 ParseLatency( char *pch, char **ppchFcSrc, char **ppchOppSrc, int *piLatency )
01295 {
01296 char *pchSrc, *pchVal, *pchLatency;
01297
01298
01299
01300 pchVal = (char *)strchr( pch, '=' );
01301 if ( pchVal == NULL ) {
01302 kapi_Error_pch1( -1, 0, "Malformed latency attribute '%s' -- '=' required", pch );
01303 return;
01304 }
01305 *pchVal = '\0';
01306
01307
01308 pchLatency = pchVal + 1;
01309
01310 if ( strspn( pchLatency, "0123456789-" ) != strlen( pchLatency ) ) {
01311 kapi_Error_pch1( -1, 0, "Badly formed bypass: latency value '%s' not valid",
01312 pchNULL_PRINT(pchLatency) );
01313 return;
01314 }
01315 *piLatency = atoi( pchLatency );
01316
01317
01318
01319
01320 pchSrc = pch;
01321
01322
01323 *ppchFcSrc = NULL;
01324 *ppchOppSrc = NULL;
01325
01326
01327 *ppchFcSrc = strtok( pchSrc, " /" );
01328 if ( *ppchFcSrc ) {
01329 *ppchOppSrc = strtok( NULL, " /" );
01330 }
01331 }
01332
01333 static void
01334 ParseIntraCluster( char *pch_in, char **ppchClr,
01335 char **ppchFcSrc, char **ppchOppSrc, char **ppchCportSrc,
01336 char **ppchFcDest, char **ppchOppDest, char **ppchCportDest,
01337 char **ppchValue )
01338 {
01339 char *pchClr, *pchSrc, *pchDest, *pchVal;
01340 kapi_cutport_t cutport;
01341
01342
01343
01344 pchVal = (char *)strchr( pch_in, '=' );
01345 if ( pchVal == NULL ) {
01346 kapi_Error_pch1( -1, 0, "Malformed intracluster bypass '%s' -- '=' required", pch_in );
01347 return;
01348 }
01349 *pchVal = '\0';
01350
01351
01352 *ppchValue = pchVal + 1;
01353
01354
01355
01356
01357 pchDest = (char *)strchr( pch_in, ':' );
01358 if ( pchDest == NULL ) {
01359 kapi_Error_pch1( -1, 0, "Malformed intracluster bypass '%s' -- ':' required", pch_in );
01360 return;
01361 }
01362 *pchDest = '\0';
01363 pchDest = pchDest + 1;
01364
01365
01366 pchSrc = strchr( pch_in, '\\' );
01367 if ( pchSrc == NULL ) {
01368 pchSrc = pch_in;
01369 pchClr = NULL;
01370 } else {
01371 *pchSrc = '\0';
01372 pchSrc += 1;
01373 pchClr = pch_in;
01374 }
01375
01376
01377 if ( pchClr ) {
01378 *ppchClr = pchClr;
01379 } else {
01380 *ppchClr = NULL;
01381 }
01382
01383 *ppchFcSrc = NULL;
01384 *ppchOppSrc = NULL;
01385 *ppchCportSrc = NULL;
01386
01387 *ppchFcDest = NULL;
01388 *ppchOppDest = NULL;
01389 *ppchCportDest = NULL;
01390
01391
01392
01393 *ppchFcSrc = strtok( pchSrc, " /" );
01394 if ( *ppchFcSrc ) {
01395 *ppchOppSrc = strtok( NULL, " /" );
01396 if ( *ppchOppSrc ) {
01397 if (-1!=utInterpretCportName( *ppchOppSrc, &cutport ))
01398 {
01399 *ppchCportSrc=*ppchOppSrc;
01400 *ppchOppSrc=NULL;
01401 } else
01402 *ppchCportSrc = strtok( NULL, " /" );
01403 if ( *ppchCportSrc ) {
01404 if ( strtok( NULL, " /" ) ) {
01405 kapi_Error_pch1( -1, 0,
01406 "Malformed intracluster bypass too many '/' segments in LHS (%s)",
01407 pch_in );
01408 return;
01409 }
01410 }
01411 }
01412 }
01413
01414
01415 *ppchFcDest = strtok( pchDest, " /" );
01416 if ( *ppchFcDest ) {
01417 *ppchOppDest = strtok( NULL, " /" );
01418 if ( *ppchOppDest ) {
01419 if (-1!=utInterpretCportName( *ppchOppDest, &cutport ))
01420 {
01421 *ppchCportDest=*ppchOppDest;
01422 *ppchOppDest=NULL;
01423 } else
01424 *ppchCportDest = strtok( NULL, " /" );
01425 if ( *ppchCportDest ) {
01426 if ( strtok( NULL, " /" ) ) {
01427 kapi_Error_pch1( -1, 0,
01428 "Malformed intracluster bypass too many '/' segments in LHS (%s)",
01429 pch_in );
01430 return;
01431 }
01432 }
01433 }
01434 }
01435
01436 }
01437
01438 static void
01439 ParseInterCluster( char *pch_in, char **ppchClrSrc, char **ppchFcSrc,
01440 char **ppchOppSrc, char **ppchCportSrc,
01441 char **ppchClrDest, char **ppchFcDest,
01442 char **ppchOppDest, char **ppchCportDest,
01443 char **ppchValue )
01444 {
01445 char *pchSrc, *pchDest, *pchVal;
01446
01447
01448
01449 pchVal = (char *)strchr( pch_in, '=' );
01450 if ( pchVal == NULL ) {
01451 kapi_Error_pch1( -1, 0, "Malformed intercluster bypass '%s' -- '=' required", pch_in );
01452 return;
01453 }
01454 *pchVal = '\0';
01455
01456
01457 *ppchValue = pchVal + 1;
01458
01459
01460
01461
01462 pchDest = (char *)strchr( pch_in, ':' );
01463 if ( pchDest == NULL ) {
01464 kapi_Error_pch1( -1, 0, "Malformed intercluster bypass '%s' -- ':' required", pch_in );
01465 return;
01466 }
01467 *pchDest = '\0';
01468 pchDest = pchDest + 1;
01469 pchSrc = pch_in;
01470
01471
01472 *ppchClrSrc = NULL;
01473 *ppchFcSrc = NULL;
01474 *ppchOppSrc = NULL;
01475 *ppchCportSrc = NULL;
01476
01477 *ppchClrDest = NULL;
01478 *ppchFcDest = NULL;
01479 *ppchOppDest = NULL;
01480 *ppchCportDest = NULL;
01481
01482
01483
01484 *ppchClrSrc = strtok( pchSrc, " /" );
01485 if ( *ppchClrSrc ) {
01486 *ppchFcSrc = strtok( NULL, " /" );
01487 if ( *ppchFcSrc ) {
01488 *ppchOppSrc = strtok( NULL, " /" );
01489 if ( *ppchOppSrc ) {
01490 *ppchCportSrc = strtok( NULL, " /" );
01491 }
01492 }
01493 }
01494
01495
01496 *ppchClrDest = strtok( pchDest, " /" );
01497 if ( *ppchClrDest ) {
01498 *ppchFcDest = strtok( NULL, " /" );
01499 if ( *ppchFcDest ) {
01500 *ppchOppDest = strtok( NULL, " /" );
01501 if ( *ppchOppDest ) {
01502 *ppchCportDest = strtok( NULL, " /" );
01503 }
01504 }
01505 }
01506
01507 }
01508
01509 static int
01510 fOkProcessIntraCluster( knobs_t *pknobs, aby_t *paby,
01511 char *pchClr,
01512 char *pchFcSrc, char *pchOppSrc, char *pchCportSrc,
01513 char *pchFcDest, char *pchOppDest, char *pchCportDest,
01514 char *pchValue )
01515 {
01516 kapi_ut_t utDest, utSrc;
01517
01518
01519 if ( strspn( pchValue, "0123456789-" ) != strlen( pchValue ) ) {
01520 kapi_Error_pch1( -1, 0, "Badly formed intracluster bypass: value '%s' not valid",
01521 pchNULL_PRINT(pchValue) );
01522 return( 0 );
01523 }
01524 paby->iValue = atoi( pchValue );
01525
01526
01527
01528 if ( pchClr ) {
01529 paby->cluster = clusterInterpretpchclr( pchClr );
01530 } else {
01531 paby->cluster = -1;
01532 }
01533
01534
01535
01536 if ( paby->cluster >= pknobs->nclr ) {
01537 return( 0 );
01538 }
01539
01540
01541
01542
01543 paby->fuSrc = KAPI_EnumIndex( pknobs, "fu_t", pchFcSrc );
01544 paby->fuDest = KAPI_EnumIndex( pknobs, "fu_t", pchFcDest );
01545 if ( -1 == paby->fuSrc || paby->fuDest == -1 ) {
01546 kapi_Warning_pch2( 0, 0, "INTRACLUSTER dropped due to illegal fu %s -> %s\n", pchFcSrc, pchFcDest );
01547 return( 0 );
01548 }
01549
01550
01551
01552
01553 paby->oppSrc = KAPI_oppGetDest( pknobs, paby->fuSrc, pchOppSrc );
01554 if ( -1 == paby->oppSrc ) {
01555 kapi_Error_pch2( -1, 0,
01556 "Invalid destination operand (%s) for source instruction (%s)",
01557 pchOppSrc, KAPI_EnumName( pknobs, paby->fuSrc, "fu_t" ) );
01558 return( 0 );
01559 }
01560
01561
01562 if ( pchOppSrc == NULL && pchCportSrc != NULL ) {
01563 kapi_Warning_pch1( -1, 0,
01564 "INTRACLUSTER defined source port w/o source operand '%s'",
01565 pchCportSrc );
01566
01567 }
01568
01569 paby->oppDest = KAPI_oppGetSource( pknobs, paby->fuDest, pchOppDest );
01570 if ( -1 == paby->oppDest ) {
01571 kapi_Error_pch2( -1, 0,
01572 "Invalid source operand (%s) for source instruction (%s)",
01573 pchOppDest, KAPI_EnumName( pknobs, paby->fuDest, "fu_t" ) );
01574 return( 0 );
01575 }
01576
01577
01578 if ( pchOppDest == NULL && pchCportDest != NULL ) {
01579 kapi_Warning_pch1( -1, 0,
01580 "INTRACLUSTER defined destination port w/o source operand '%s'",
01581 pchCportDest );
01582
01583 }
01584
01585
01586
01587 if ( pchCportSrc != NULL ) {
01588 int cutport;
01589
01590 utSrc = utInterpretCportName( pchCportSrc, &cutport );
01591 if ( -1 == utSrc ) {
01592 kapi_Error_pch1( -1, 0,
01593 "Invalid source cport '%s'", pchCportSrc );
01594 return( 0 );
01595 } else {
01596 paby->cutportSrc = cutport;
01597 paby->utSrc = utSrc;
01598 }
01599 } else {
01600 paby->cutportSrc = -1;
01601 paby->utSrc = -1;
01602 }
01603
01604 if ( pchCportDest != NULL ) {
01605 int cutport;
01606
01607 utDest = utInterpretCportName( pchCportDest, &cutport );
01608 if ( -1 == utDest ) {
01609 kapi_Error_pch1( -1, 0,
01610 "Invalid destination cport '%s'", pchCportDest );
01611 return( 0 );
01612 } else {
01613 paby->cutportDest = cutport;
01614 paby->utDest = utDest;
01615 }
01616 } else {
01617 paby->cutportDest = -1;
01618 paby->utDest = -1;
01619 }
01620
01621 return( 1 );
01622 }
01623
01624 static int
01625 fOkProcessInterCluster( knobs_t *pknobs, eby_t *peby,
01626 char *pchClrSrc, char *pchFcSrc,
01627 char *pchOppSrc, char *pchCportSrc,
01628 char *pchClrDest, char *pchFcDest,
01629 char *pchOppDest, char *pchCportDest,
01630 char *pchValue )
01631 {
01632 kapi_ut_t utDest, utSrc;
01633
01634
01635 if ( strspn( pchValue, "0123456789-" ) != strlen( pchValue ) ) {
01636 kapi_Error_pch1( -1, 0, "Badly formed intercluster bypass: value '%s' not valid",
01637 pchNULL_PRINT(pchValue) );
01638 return 0;
01639 }
01640 peby->iValue = atoi( pchValue );
01641
01642
01643
01644 peby->clusterSrc = clusterInterpretpchclr( pchClrSrc );
01645 peby->clusterDest = clusterInterpretpchclr( pchClrDest );
01646
01647 if ( peby->clusterSrc < 0 || peby->clusterDest < 0 ) {
01648 kapi_Error( -1, 0,
01649 "INTERCLUSTER source and destination instructions must have a cluster specified" );
01650 return( 0 );
01651 }
01652
01653 if ( peby->clusterSrc == peby->clusterDest ) {
01654 kapi_Error( -1, 0,
01655 "INTERCLUSTER source and destination instructions must have different clusters specified" );
01656 return( 0 );
01657 }
01658
01659
01660 if ( peby->clusterSrc >= pknobs->nclr || peby->clusterDest >= pknobs->nclr ) {
01661 return( 0 );
01662 }
01663
01664
01665
01666
01667 peby->fuSrc = KAPI_EnumIndex( pknobs, "fu_t", pchFcSrc );
01668 peby->fuDest = KAPI_EnumIndex( pknobs, "fu_t", pchFcDest );
01669 if ( -1 == peby->fuSrc || peby->fuDest == -1 ) {
01670 kapi_Warning_pch2( 0, 0, "INTERCLUSTER dropped due to illegal fu %s -> %s\n", pchFcSrc, pchFcDest );
01671 return( 0 );
01672 }
01673
01674
01675
01676
01677 peby->oppSrc = KAPI_oppGetDest( pknobs, peby->fuSrc, pchOppSrc );
01678 if ( -1 == peby->oppSrc ) {
01679 kapi_Error_pch2( -1, 0,
01680 "Invalid destination operand (%s) for source instruction (%s)",
01681 pchOppSrc, KAPI_EnumName( pknobs, peby->fuSrc, "fu_t" ) );
01682 return( 0 );
01683 }
01684
01685
01686 if ( pchOppSrc == NULL && pchCportSrc != NULL ) {
01687 kapi_Error_pch1( -1, 0,
01688 "INTERCLUSTER cannot specify source port w/o source operand '%s'",
01689 pchCportSrc );
01690 return( 0 );
01691 }
01692
01693 peby->oppDest = KAPI_oppGetSource( pknobs, peby->fuDest, pchOppDest );
01694 if ( -1 == peby->oppDest ) {
01695 kapi_Error_pch2( -1, 0,
01696 "Invalid source register (%s) for source instruction (%s)",
01697 pchOppDest, KAPI_EnumName( pknobs, peby->fuDest, "fu_t" ) );
01698 return( 0 );
01699 }
01700
01701
01702 if ( pchOppDest == NULL && pchCportDest != NULL ) {
01703 kapi_Error_pch1( -1, 0,
01704 "INTERCLUSTER cannot specify destination port w/o source operand '%s'",
01705 pchCportDest );
01706 return( 0 );
01707 }
01708
01709
01710
01711 if ( pchCportSrc != NULL ) {
01712 int cutportSrc;
01713
01714 utSrc = utInterpretCportName( pchCportSrc, &cutportSrc );
01715 if ( -1 == utSrc ) {
01716 kapi_Error_pch1( -1, 0,
01717 "Invalid source port '%s'", pchCportSrc );
01718 return( 0 );
01719 } else {
01720 peby->cutportSrc = cutportSrc;
01721 peby->utSrc = utSrc;
01722 }
01723 } else {
01724 peby->cutportSrc = -1;
01725 peby->utSrc = -1;
01726 }
01727
01728 if ( pchCportDest != NULL ) {
01729 int cutportDest;
01730
01731 utDest = utInterpretCportName( pchCportDest, &cutportDest );
01732 if ( -1 == utDest ) {
01733 kapi_Error_pch1( -1, 0,
01734 "Invalid destination port '%s'", pchCportDest );
01735 return( 0 );
01736 } else {
01737 peby->cutportDest = cutportDest;
01738 peby->utDest = utDest;
01739 }
01740 } else {
01741 peby->cutportDest = -1;
01742 peby->utDest = -1;
01743 }
01744
01745 return( 1 );
01746 }
01747
01748 static void
01749 kapi_ProcessInterclusterLatency( knobs_t *pknobs )
01750 {
01751 int maxeby, idx, i;
01752
01753 maxeby = KAPI_count4attribute( pknobs, "INTERCLUSTER" );
01754
01755 if ( maxeby > 0 ) {
01756 pknobs->dmpebyInterTable =
01757 (eby_t *)malloc( sizeof(eby_t)*maxeby );
01758 } else {
01759 pknobs->dmpebyInterTable = NULL;
01760 pknobs->nRawInter = 0;
01761 return;
01762 }
01763
01764 idx = 0;
01765 for ( i=0; i<maxeby; i++ ) {
01766 char *pch;
01767 char mpchTmp[ 400 ], *pchLatency;
01768 char *pchClrSrc, *pchFcSrc, *pchOppSrc, *pchCportSrc,
01769 *pchClrDest, *pchFcDest, *pchOppDest, *pchCportDest;
01770 eby_t ebyTmp;
01771 int fOk;
01772
01773
01774 pch = KAPI_attribute4index( pknobs, "INTERCLUSTER", i );
01775
01776 (void)strncpy( (char *)mpchTmp, pch, 399 );
01777
01778 ParseInterCluster( mpchTmp, &pchClrSrc, &pchFcSrc,
01779 &pchOppSrc, &pchCportSrc,
01780 &pchClrDest, &pchFcDest,
01781 &pchOppDest, &pchCportDest,
01782 &pchLatency );
01783
01784 fOk = fOkProcessInterCluster( pknobs, &ebyTmp,
01785 pchClrSrc, pchFcSrc,
01786 pchOppSrc, pchCportSrc,
01787 pchClrDest, pchFcDest,
01788 pchOppDest, pchCportDest,
01789 pchLatency );
01790
01791 if ( fOk ) {
01792 pknobs->dmpebyInterTable[ idx ] = ebyTmp;
01793 idx++;
01794 #if 0
01795 printf("INTERCLUSTER %d/%d/%d/%d : %d/%d/%d/%d = %d\n",
01796 ebyTmp.clusterSrc, ebyTmp.fuSrc, ebyTmp.oppSrc, ebyTmp.cportSrc,
01797 ebyTmp.clusterDest, ebyTmp.fuDest, ebyTmp.oppDest, ebyTmp.cportDest, ebyTmp.iValue );
01798 #endif
01799 } else {
01800 kapi_Warning_pch1( 0, 0, "INTERCLUSTER dropped '%s'\n", pch );
01801 }
01802 }
01803
01804 pknobs->nRawInter = idx;
01805 }
01806
01807 static void
01808 kapi_ProcessIntraclusterLatency( knobs_t *pknobs )
01809 {
01810 int maxaby, idx, i;
01811
01812 maxaby = KAPI_count4attribute( pknobs, "INTRACLUSTER" );
01813
01814 if ( maxaby > 0 ) {
01815 pknobs->dmpabyIntraTable =
01816 (aby_t *)malloc( sizeof(aby_t)*maxaby );
01817 } else {
01818 pknobs->dmpabyIntraTable = NULL;
01819 pknobs->nRawIntra = 0;
01820 return;
01821 }
01822
01823 idx = 0;
01824 for ( i=0; i<maxaby; i++ ) {
01825 char *pch;
01826 char mpchTmp[ 400 ], *pchLatency;
01827 char *pchClr, *pchFcSrc, *pchOppSrc, *pchCportSrc,
01828 *pchFcDest, *pchOppDest, *pchCportDest;
01829 aby_t abyTmp;
01830 int fOk;
01831
01832
01833 if (i==0x154)
01834 pch=NULL;
01835 pch = KAPI_attribute4index( pknobs, "INTRACLUSTER", i );
01836
01837 (void)strncpy( (char *)mpchTmp, pch, 399 );
01838
01839 ParseIntraCluster( mpchTmp, &pchClr,
01840 &pchFcSrc, &pchOppSrc, &pchCportSrc,
01841 &pchFcDest, &pchOppDest, &pchCportDest,
01842 &pchLatency );
01843
01844 fOk = fOkProcessIntraCluster( pknobs, &abyTmp, pchClr,
01845 pchFcSrc, pchOppSrc, pchCportSrc,
01846 pchFcDest, pchOppDest, pchCportDest,
01847 pchLatency );
01848
01849
01850 if ( fOk ) {
01851 pknobs->dmpabyIntraTable[ idx ] = abyTmp;
01852 pknobs->dmpabyIntraTable[ idx ].pchEntry = pch;
01853 idx++;
01854 #if 0
01855 printf("INTRACLUSTER %d\\ %d/%d/%d : %d/%d/%d = %d\n",
01856 abyTmp.cluster,
01857 abyTmp.fuSrc, abyTmp.oppSrc, abyTmp.cutportSrc,
01858 abyTmp.fuDest, abyTmp.oppDest, abyTmp.cutportDest, abyTmp.iValue );
01859 #endif
01860 } else {
01861 pknobs->dmpabyIntraTable[ idx ].pchEntry = NULL;
01862 kapi_Warning_pch1( 0, 0, "INTRACLUSTER dropped '%s'\n", pch );
01863 }
01864 }
01865
01866 pknobs->nRawIntra = idx;
01867 }
01868
01869
01870 static int
01871 kapi_GetOpIndex(knobs_t *pknobs,char *pchOp,kapi_fu_t fu,int fRole)
01872 {
01873 int iIndex;
01874 if (fRole==0)
01875 {
01876 iIndex=KAPI_oppGetDest(pknobs,fu,pchOp);
01877 }
01878 if (fRole==1)
01879 {
01880 iIndex=KAPI_oppGetSource(pknobs,fu,pchOp);
01881 }
01882 if (iIndex==-1)
01883 kapi_Error_pch3(0,0,
01884 "Bad %s operand type (for fu %s), %s",
01885 (fRole) ? "source" : "destination",
01886 KAPI_fu2fuName(pknobs,fu,0),pchOp);
01887 return 0;
01888 }
01889
01890 static void
01891 kapi_ParseSingleOp(knobs_t *pknobs, kapi_fu_t fu, char *pch, operand_match_t *pOp)
01892 {
01893 char *pWalker=pch;
01894 int fNewOp=0;
01895 int fRole=99;
01896 char *pchOp=NULL;
01897
01898 pOp->iType=type_single;
01899 pOp->pIndexes[0].pOperand=-1;
01900 pOp->pIndexes[1].pOperand=-1;
01901 while (*pWalker)
01902 {
01903 switch (*pWalker)
01904 {
01905 case '+':
01906 fRole=0;
01907 fNewOp=1;
01908 *pWalker=0;
01909 break;
01910 case '-':
01911 case '?':
01912 fRole=1;
01913 fNewOp=1;
01914 *pWalker=0;
01915 break;
01916 case '*':
01917 pchOp++;
01918 break;
01919 default:
01920 break;
01921 }
01922 pWalker++;
01923 if (fNewOp && pchOp!=NULL)
01924 {
01925 pOp->pIndexes[fRole].pOperand=
01926 kapi_GetOpIndex(pknobs,pchOp,fu,fRole);
01927 }
01928 if (fNewOp)
01929 {
01930 fNewOp=0;
01931 pchOp=pWalker;
01932 }
01933 }
01934 if (pchOp)
01935 {
01936 pOp->pIndexes[fRole].pOperand=
01937 kapi_GetOpIndex(pknobs,pchOp,fu,fRole);
01938 }
01939 }
01940
01941 static void
01942 kapi_ParseInstOp(knobs_t *pknobs, kapi_fu_t fu,char *pch, operand_match_t *pOperandList)
01943 {
01944 operand_match_t *pOpWalker;
01945 int i,nOperands=kapi_CharCount('/',pch)+1;
01946 char *pchOp;
01947
01948 if (0==strcmp(pch,"none"))
01949 return;
01950
01951 if (1==nOperands)
01952 {
01953 kapi_ParseSingleOp(pknobs,fu,pch,pOperandList);
01954 } else
01955 {
01956 pOperandList->iType=type_multiple;
01957 pOperandList->pIndexes[0].pOperandList =
01958 (operand_match_t *) malloc(nOperands * sizeof(operand_match_t));
01959 pOpWalker=pOperandList->pIndexes[0].pOperandList;
01960 pchOp = strtok(pch,"/");
01961 for (i=0 ; (i<nOperands) && pchOp ; i++)
01962 {
01963 kapi_ParseSingleOp(pknobs,fu,pchOp,&pOpWalker[i]);
01964 pchOp=strtok(NULL,"/");
01965 }
01966 }
01967 }
01968
01969 static void
01970 kapi_ParseInstOps(knobs_t *pknobs, kapi_fu_t fu,char *pch,
01971 operand_match_t **pExplicitOps, operand_match_t **pImplicitOps)
01972 {
01973 operand_match_t *pOps;
01974 int nOps,iIndex;
01975 char *pchExplicits,*pchImplicits, *pWalker;
01976 char buffer[1024];
01977
01978 pchExplicits = strchr(pch,':')+1;
01979 pWalker = strchr(pchExplicits,':');
01980 *pWalker++=0;
01981 pchImplicits=pWalker;
01982
01983
01984 nOps = kapi_CharCount(',',pchExplicits) + 1;
01985 pOps = (operand_match_t *)malloc(nOps * sizeof(operand_match_t));
01986
01987 strncpy(buffer,pchExplicits,1024);
01988 pWalker=strtok(buffer,",");
01989 iIndex=0;
01990 while (pWalker)
01991 {
01992 kapi_ParseInstOp(pknobs,fu,pWalker,&pOps[iIndex++]);
01993 pWalker=strtok(NULL,",");
01994 }
01995
01996 *pExplicitOps=pOps;
01997
01998
01999 nOps = kapi_CharCount(',',pchImplicits) + 1;
02000 pOps = (operand_match_t *)malloc(nOps * sizeof(operand_match_t));
02001
02002 strncpy(buffer,pchImplicits,1024);
02003 pWalker=strtok(buffer,",");
02004 iIndex=0;
02005 while (pWalker)
02006 {
02007 kapi_ParseInstOp(pknobs,fu,pWalker,&pOps[iIndex++]);
02008 pWalker=strtok(NULL,",");
02009 }
02010
02011 *pImplicitOps=pOps;
02012
02013 }
02014
02015 static void
02016 DecodeInstructionInformation( knobs_t *pknobs, char *pch )
02017 {
02018 char mpch[ 200 ];
02019 char *pchNumber, *pchUniqueName, *pchMnemonic, *pchit, *pchfu;
02020 kapi_it_t it;
02021 kapi_fu_t fu;
02022 int idx;
02023 operand_match_t *pExplicitOps=0,*pImplicitOps=0;
02024 char *pWalker;
02025
02026
02027 strncpy( mpch, pch, 199 );
02028 pchNumber = strtok( mpch, "," );
02029 pchUniqueName = strtok( NULL, "," );
02030 pchMnemonic = strtok( NULL, "," );
02031 pchit = strtok( NULL, "," );
02032 pchfu = strtok( NULL, "," );
02033
02034 if (pWalker=strchr(pchfu,':'))
02035 *pWalker=0;
02036 idx = atoi( pchNumber );
02037 if (idx >= pknobs->ninstTable)
02038 {
02039 char buffer[200]="";
02040 sprintf(buffer,
02041 "There are only %d instruction attributes,\n"
02042 "\tbut there is an instruction with index %d!\n"
02043 "\tAn instruction or more are missing!",pknobs->ninstTable,idx);
02044 kapi_Error(kapi_cLine, 0, buffer);
02045 return;
02046 }
02047
02048 if (pknobs->dmpinstTable[ idx ].fu!=-1)
02049 {
02050 pknobs->ninstTable--;
02051 kapi_Warning_pch1( kapi_cLine,1, "Instruction %s override",pchNumber);
02052 }
02053
02054 it = KAPI_EnumIndex( pknobs, "it_t", pchit );
02055 fu = KAPI_EnumIndex( pknobs, "fu_t", pchfu );
02056
02057 if ( it == -1 ) {
02058 kapi_Error_pch1( kapi_cLine, 0, "%s not a valid instruction type", pchit );
02059 }
02060 if ( fu == -1 ) {
02061 kapi_Error_pch1( kapi_cLine, 0, "%s not a valid function class", pchfu );
02062 }
02063
02064
02065 if (pWalker)
02066 {
02067 kapi_ParseInstOps(pknobs, fu , pch,
02068 &pExplicitOps, &pImplicitOps);
02069 }
02070
02071 pknobs->dmpinstTable[ idx ].fu = fu;
02072 pknobs->dmpinstTable[ idx ].it = it;
02073 pknobs->dmpinstTable[ idx ].pchfu = kapi_pchCopy( pchfu );
02074 pknobs->dmpinstTable[ idx ].pchit = kapi_pchCopy( pchit );
02075 pknobs->dmpinstTable[ idx ].pchMnemonic = kapi_pchCopy( pchMnemonic );
02076 pknobs->dmpinstTable[ idx ].pchUniqueName = kapi_pchCopy( pchUniqueName );
02077
02078 pknobs->dmpinstTable[ idx ].pExplicitOps=pExplicitOps;
02079 pknobs->dmpinstTable[ idx ].pImplicitOps=pImplicitOps;
02080
02081 }
02082
02083 static void
02084 kapi_ProcessInstructionData( knobs_t *pknobs )
02085 {
02086 int niid, i;
02087 char *pch;
02088
02089 niid = KAPI_count4attribute( pknobs, "instruction" );
02090 pknobs->dmpinstTable = NULL;
02091 pknobs->ninstTable = 0;
02092 if ( KAPI_error_attribute ) {
02093 kapi_Error( kapi_cLine, 0, "Attribute 'instruction' not defined or incorrect" );
02094 return;
02095 } else if ( niid <= 10 ) {
02096 kapi_Error( kapi_cLine, 0,
02097 "Attribute 'instruction' not defined or incorrect" );
02098 return;
02099 } else {
02100 pknobs->ninstTable = niid;
02101 }
02102
02103 pknobs->dmpinstTable = (inst_t *)malloc( sizeof(inst_t) * niid );
02104
02105 for ( i=0; i<niid; i++ )
02106 pknobs->dmpinstTable[i].fu=-1;
02107 assert( pknobs->dmpinstTable );
02108 for ( i=0; i<niid; i++ ) {
02109 pch = KAPI_attribute4index( pknobs, "instruction", i );
02110 DecodeInstructionInformation( pknobs, pch );
02111 }
02112 }
02113
02114
02115 kapi_cport_t
02116 cport4utcport( knobs_t *pknobs, kapi_cluster_t cluster, kapi_ut_t ut, int cportut )
02117 {
02118 return( pknobs->mpclrTable[ cluster ].dmppcportinfoTable[ ut ][ cportut ].cport );
02119 }
02120
02121 static void kapi_ProcessCacheData( knobs_t *pknobs)
02122 {
02123 int i,iType,iLevel,iPort;
02124 int iEnumIndex;
02125 int iCacheNames;
02126 char *pchTmp;
02127 bv_t *pbvTmp;
02128 char pchBuffer[100];
02129 char **levelNames[cache_type_enum_size];
02130 cache_t *pcacheTmp;
02131 iCacheNames=KAPI_EnumCardinality(pknobs,"cache_names_t");
02132 for (i=0;i<cache_type_enum_size;i++)
02133 {
02134 pknobs->nCacheLevels[i]=0;
02135 }
02136 if (iCacheNames<=0)
02137 {
02138 kapi_Warning( kapi_cLine, 0,
02139 "Attribute 'cache_names_t' not defined or incorrect" );
02140 return;
02141 }
02142
02143
02144 for (i=0;i<iCacheNames;i++)
02145 {
02146 pchTmp=KAPI_EnumName(pknobs,i,"cache_names_t");
02147 if (strchr(pchTmp,'I')!=NULL) {
02148 pknobs->nCacheLevels[cache_type_instruction]++;
02149 }
02150 else if (strchr(pchTmp,'D')!=NULL) {
02151 pknobs->nCacheLevels[cache_type_data]++;
02152 }
02153 else {
02154 pknobs->nCacheLevels[cache_type_unified]++;
02155 }
02156 free(pchTmp);
02157 }
02158 for (i=0;i<cache_type_enum_size;i++)
02159 {
02160 levelNames[i]=(char **)malloc(sizeof(char *)*pknobs->nCacheLevels[i]);
02161 pknobs->nCacheLevels[i]=0;
02162 }
02163
02164 for (i=0;i<iCacheNames;i++)
02165 {
02166 pchTmp=KAPI_EnumName(pknobs,i,"cache_names_t");
02167 if (strchr(pchTmp,'I')!=NULL) {
02168 levelNames[cache_type_instruction][pknobs->nCacheLevels[cache_type_instruction]]=pchTmp;
02169 pknobs->nCacheLevels[cache_type_instruction]++;
02170 }
02171 else if (strchr(pchTmp,'D')!=NULL) {
02172 levelNames[cache_type_data][pknobs->nCacheLevels[cache_type_data]]=pchTmp;
02173 pknobs->nCacheLevels[cache_type_data]++;
02174 }
02175 else {
02176 levelNames[cache_type_unified][pknobs->nCacheLevels[cache_type_unified]]=pchTmp;
02177 pknobs->nCacheLevels[cache_type_unified]++;
02178 }
02179 }
02180
02181 for (i=0;i<cache_type_enum_size;i++)
02182 {
02183 pknobs->dmpcacheTable[i]=(cache_t *)malloc(sizeof(cache_t)*pknobs->nCacheLevels[i]);
02184 }
02185
02186 for (iType=0;iType<cache_type_enum_size;iType++)
02187 {
02188 for (iLevel=0;iLevel<pknobs->nCacheLevels[iType];iLevel++)
02189 {
02190 iEnumIndex=KAPI_EnumIndex(pknobs,"cache_names_t",levelNames[iType][iLevel]);
02191 pcacheTmp=&(pknobs->dmpcacheTable[iType][iLevel]);
02192 assert(pcacheTmp!=NULL);
02193 pcacheTmp->nLines=KAPI_GetIntegerVariable(pknobs,"CACHE_Lines",iEnumIndex);
02194 pcacheTmp->nBytesLine=KAPI_GetIntegerVariable(pknobs,"CACHE_BytesPerLine",iEnumIndex);
02195 pcacheTmp->nWays=KAPI_GetIntegerVariable(pknobs,"CACHE_Ways",iEnumIndex);
02196 pcacheTmp->nCyclesRead=KAPI_GetIntegerVariable(pknobs,"CACHE_ReadLatency",iEnumIndex);
02197 pbvTmp=KAPI_GetBvVariable(pknobs,"CACHE_Content",iEnumIndex);
02198 if (pbvTmp==NULL)
02199 {
02200 *pchBuffer='\0';
02201 sprintf(pchBuffer+strlen(pchBuffer),"CACHE_Content[%s]",levelNames[iType][iLevel]);
02202 kapi_Error_pch1( kapi_cLine, 1,
02203 " %s should exists according to definition but is not defined.",pchBuffer );
02204 return;
02205 }
02206 pcacheTmp->bv32CacheContents=pbvTmp->pint32Data[0];
02207 free(pbvTmp);
02208 pcacheTmp->iWritePolicy=KAPI_GetEnumVariable(pknobs,"CACHE_PolicyWrite",iEnumIndex);
02209 pcacheTmp->iReplPolicy=KAPI_GetEnumVariable(pknobs,"CACHE_PolicyRepl",iEnumIndex);
02210 pcacheTmp->iAllocPolicy=KAPI_GetEnumVariable(pknobs,"CACHE_PolicyAlloc",iEnumIndex);
02211 pcacheTmp->nCachePorts=KAPI_GetIntegerVariable(pknobs,"CACHE_Ports",iEnumIndex);
02212 for (iPort=0;iPort<pcacheTmp->nCachePorts;iPort++)
02213 {
02214
02215
02216
02217 *pchBuffer='\0';
02218 sprintf(pchBuffer,"CACHE_Port%dAccessTypes",iPort);
02219 pbvTmp=KAPI_GetBvVariable(pknobs,pchBuffer,iEnumIndex);
02220 if (pbvTmp!=NULL) {
02221 pcacheTmp->cacheportInfo[iPort].bv32AccessMode=pbvTmp->pint32Data[0];
02222 free(pbvTmp);
02223 } else {
02224 sprintf(pchBuffer+strlen(pchBuffer),"[%s]",levelNames[iType][iLevel]);
02225 kapi_Error_pch1( kapi_cLine, 1,
02226 " %s should exists according to definition but is not defined.",pchBuffer );
02227 return;
02228 }
02229 }
02230
02231 for (;iPort<KAPI_MAX_CACHE_PORTS_IMPL;iPort++)
02232 pcacheTmp->cacheportInfo[iPort].bv32AccessMode=0;
02233
02234 }
02235 }
02236 }
02237
02238 void *KAPI_ia64_Initialize(void *pConfig)
02239 {
02240 knobs_t *pknobs=(knobs_t *)pConfig;
02241 int fOk;
02242
02243 fOk = kapi_fEnableIA64Calls( pknobs );
02244 if ( !fOk ) {
02245 kapi_Error( -1, 0, "Unable to build structured information table" );
02246 KAPI_error_attribute = 1;
02247 return( NULL );
02248 } else
02249 return pConfig;
02250 }
02251