linux/drivers/staging/wlags49_h2/mmd.c
<<
>>
Prefs
   1
   2/************************************************************************************************************
   3*
   4* FILE    : mmd.c
   5*
   6* DATE    : $Date: 2004/07/23 11:57:45 $   $Revision: 1.4 $
   7* Original: 2004/05/28 14:05:35    Revision: 1.32      Tag: hcf7_t20040602_01
   8* Original: 2004/05/13 15:31:45    Revision: 1.30      Tag: hcf7_t7_20040513_01
   9* Original: 2004/04/15 09:24:42    Revision: 1.25      Tag: hcf7_t7_20040415_01
  10* Original: 2004/04/08 15:18:17    Revision: 1.24      Tag: t7_20040413_01
  11* Original: 2004/04/01 15:32:55    Revision: 1.22      Tag: t7_20040401_01
  12* Original: 2004/03/10 15:39:28    Revision: 1.18      Tag: t20040310_01
  13* Original: 2004/03/03 14:10:12    Revision: 1.16      Tag: t20040304_01
  14* Original: 2004/03/02 09:27:12    Revision: 1.14      Tag: t20040302_03
  15* Original: 2004/02/24 13:00:29    Revision: 1.12      Tag: t20040224_01
  16* Original: 2004/01/30 09:59:33    Revision: 1.11      Tag: t20040219_01
  17*
  18* AUTHOR  : Nico Valster
  19*
  20* DESC    : Common routines for HCF, MSF, UIL as well as USF sources
  21*
  22* Note: relative to Asserts, the following can be observed:
  23*       Since the IFB is not known inside the routine, the macro HCFASSERT is replaced with MDDASSERT.
  24*       Also the line number reported in the assert is raised by FILE_NAME_OFFSET (20000) to discriminate the
  25*       MMD Asserts from HCF and DHF asserts.
  26*
  27***************************************************************************************************************
  28*
  29*
  30* SOFTWARE LICENSE
  31*
  32* This software is provided subject to the following terms and conditions,
  33* which you should read carefully before using the software.  Using this
  34* software indicates your acceptance of these terms and conditions.  If you do
  35* not agree with these terms and conditions, do not use the software.
  36*
  37* COPYRIGHT © 2001 - 2004       by Agere Systems Inc.   All Rights Reserved
  38* All rights reserved.
  39*
  40* Redistribution and use in source or binary forms, with or without
  41* modifications, are permitted provided that the following conditions are met:
  42*
  43* . Redistributions of source code must retain the above copyright notice, this
  44*    list of conditions and the following Disclaimer as comments in the code as
  45*    well as in the documentation and/or other materials provided with the
  46*    distribution.
  47*
  48* . Redistributions in binary form must reproduce the above copyright notice,
  49*    this list of conditions and the following Disclaimer in the documentation
  50*    and/or other materials provided with the distribution.
  51*
  52* . Neither the name of Agere Systems Inc. nor the names of the contributors
  53*    may be used to endorse or promote products derived from this software
  54*    without specific prior written permission.
  55*
  56* Disclaimer
  57*
  58* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  59* INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
  60* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
  61* USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
  62* RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
  63* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  64* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  66* ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
  67* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  68* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  69* DAMAGE.
  70*
  71*
  72**************************************************************************************************************/
  73
  74#include "hcf.h"                                // Needed as long as we do not really sort out the mess
  75#include "hcfdef.h"                             // get CNV_LITTLE_TO_SHORT
  76#include "mmd.h"                                // MoreModularDriver common include file
  77
  78//to distinguish DHF from HCF asserts by means of line number
  79#undef  FILE_NAME_OFFSET
  80#define FILE_NAME_OFFSET DHF_FILE_NAME_OFFSET
  81
  82
  83/*************************************************************************************************************
  84*
  85*.MODULE                CFG_RANGE_SPEC_STRCT* mmd_check_comp( CFG_RANGES_STRCT *actp, CFG_SUP_RANGE_STRCT *supp )
  86*.PURPOSE               Checks compatibility between an actor and a supplier.
  87*
  88*.ARGUMENTS
  89*       actp
  90*       supp
  91*
  92*.RETURNS
  93*       NULL    incompatible
  94*       <>NULL  pointer to matching CFG_RANGE_SPEC_STRCT substructure in actor-structure matching the supplier
  95*
  96*.NARRATIVE
  97*
  98*  Parameters:
  99*       actp    address of the actor specification
 100*       supp    address of the supplier specification
 101*
 102*       Description: mmd_check_comp is a support routine to check the compatibility between an actor and a
 103*       supplier.  mmd_check_comp is independent of the endianness of the actp and supp structures. This is
 104*       achieved by checking the "bottom" or "role" fields of these structures. Since these fields are restricted
 105*       to a limited range, comparing the contents to a value with a known endian-ess gives a clue to their actual
 106*       endianness.
 107*
 108*.DIAGRAM
 109*1a: The role-field of the actor structure has a known non-zero, not "byte symmetric" value (namely
 110*       COMP_ROLE_ACT or 0x0001), so if and only the contents of this field matches COMP_ROLE_ACT (in Native
 111*       Endian format), the actor structure is Native Endian.
 112*2a: Since the role-field of the supplier structure is 0x0000, the test as used for the actor does not work
 113*       for a supplier. A supplier has always exactly 1 variant,top,bottom record with (officially, but see the
 114*       note below) each of these 3 values in the range 1 through 99, so one byte of the word value of variant,
 115*       top and bottom words is 0x00 and the other byte is non-zero. Whether the lowest address byte or the
 116*       highest address byte is non-zero depends on the Endianness of the LTV. If and only if the word value of
 117*       bottom is less than 0x0100, the supplier is Native Endian.
 118*       NOTE: the variant field of the supplier structure can not be used for the Endian Detection Algorithm,
 119*       because a a zero-valued variant has been used as Controlled Deployment indication in the past.
 120*       Note: An actor may have multiple sets of variant,top,bottom records, including dummy sets with variant,
 121*       top and bottom fields with a zero-value. As a consequence the endianness of the actor can not be determined
 122*       based on its variant,top,bottom values.
 123*
 124*       Note: the L and T field of the structures are always in Native Endian format, so you can not draw
 125*       conclusions concerning the Endianness of the structure based on these two fields.
 126*
 127*1b/2b
 128*       The only purpose of the CFG_RANGE_SPEC_BYTE_STRCT is to give easy access to the non-zero byte of the word
 129*       value of variant, top and bottom. The variables sup_endian and act_endian are used for the supplier and
 130*       actor structure respectively. These variables must be 0 when the structure has LE format and 1 if the
 131*       structure has BE format. This can be phrased as:
 132*       the variable is false (i.e 0x0000) if either
 133*               (the platform is LE and the LTV is the same as the platform)
 134*       or
 135*               (the platform is BE and the LTV differs from the platform).
 136*       the variable is true (i.e 0x0001) if either
 137*               (the platform is BE and the LTV is the same as the platform)
 138*       or
 139*               (the platform is LE and the LTV differs from the platform).
 140*
 141*       Alternatively this can be phrased as:
 142*       if the platform is LE
 143*               if the LTV is LE (i.e the same as the platform), then the variable = 0
 144*               else (the LTV is BE (i.e. different from the platform) ), then the variable = 1
 145*       if the platform is BE
 146*               if the LTV is BE (i.e the same as the platform), then the variable = 1
 147*               else (the LTV is LE (i.e. different from the platform) ), then the variable = 0
 148*
 149*       This is implemented as:
 150*       #if HCF_BIG_ENDIAN == 0 //platform is LE
 151*               sup/act_endian becomes reverse of structure-endianness as determined in 1a/1b
 152*       #endif
 153*6:     Each of the actor variant-bottom-top records is checked against the (single) supplier variant-bottom-top
 154*       range till either an acceptable match is found or all actor records are tried. As explained above, due to
 155*       the limited ranges of these values, checking a byte is acceptable and suitable.
 156*8:     depending on whether a match was found or not (as reflected by the value of the control variable of the
 157*       for loop), the NULL pointer or a pointer to the matching Number/Bottom/Top record of the Actor structure
 158*       is returned.
 159*       As an additional safety, checking the supplier length protects against invalid Supplier structures, which
 160*       may be caused by failing hcf_get_info (in which case the len-field is zero). Note that the contraption
 161*       "supp->len != sizeof(CFG_SUP_RANGE_STRCT)/sizeof(hcf_16) - 1"
 162*       did turn out not to work for a compiler which padded the structure definition.
 163*
 164* Note: when consulting references like DesignNotes and Architecture specifications there is a confusing use
 165*       of the notions number and variant. This resulted in an inconsistent use in the HCF nomenclature as well.
 166*       This makes the logic hard to follow and one has to be very much aware of the context when walking through
 167*       the code.
 168* NOTE: The Endian Detection Algorithm places limitations on future extensions of the fields, i.e. they should
 169*       stay within the currently defined boundaries of 1 through 99 (although 1 through 255) would work as well
 170*       and there should never be used a zero value for the bottom of a valid supplier.
 171* Note: relative to Asserts, the following can be observed:
 172*       1: Supplier variant 0x0000 has been used for Controlled Deployment
 173*       2: An actor may have one or more variant record specifications with a top of zero and a non-zero bottom
 174*       to override the HCF default support of a particular variant by the MSF programmer via hcfcfg.h
 175*       3:      An actor range can be specified as all zeros, e.g. as padding in the automatically generated firmware
 176*       image files.
 177*.ENDDOC                                END DOCUMENTATION
 178*************************************************************************************************************/
 179CFG_RANGE_SPEC_STRCT*
 180mmd_check_comp( CFG_RANGES_STRCT *actp, CFG_SUP_RANGE_STRCT *supp )
 181{
 182
 183CFG_RANGE_SPEC_BYTE_STRCT  *actq = (CFG_RANGE_SPEC_BYTE_STRCT*)actp->var_rec;
 184CFG_RANGE_SPEC_BYTE_STRCT  *supq = (CFG_RANGE_SPEC_BYTE_STRCT*)&(supp->variant);
 185hcf_16  i;
 186int             act_endian;                                     //actor endian flag
 187int             sup_endian;                                     //supplier endian flag
 188
 189        act_endian = actp->role == COMP_ROLE_ACT;       //true if native endian                         /* 1a */
 190        sup_endian = supp->bottom < 0x0100;                     //true if native endian                         /* 2a */
 191
 192#if HCF_ASSERT
 193        MMDASSERT( supp->len == 6,                                                                                                                              supp->len )
 194        MMDASSERT( actp->len >= 6 && actp->len%3 == 0,                                                                                  actp->len )
 195
 196        if ( act_endian ) {                                                     //native endian
 197                MMDASSERT( actp->role == COMP_ROLE_ACT,                                                                                         actp->role )
 198                MMDASSERT( 1 <= actp->id && actp->id <= 99,                                                                             actp->id )
 199        } else {                                                                        //non-native endian
 200                MMDASSERT( actp->role == CNV_END_SHORT(COMP_ROLE_ACT),                                                          actp->role )
 201                MMDASSERT( 1 <= CNV_END_SHORT(actp->id) && CNV_END_SHORT(actp->id) <= 99,                               actp->id )
 202        }
 203        if ( sup_endian ) {                                                     //native endian
 204                MMDASSERT( supp->role == COMP_ROLE_SUPL,                                                                                        supp->role )
 205                MMDASSERT( 1 <= supp->id      && supp->id <= 99,                                                                        supp->id )
 206                MMDASSERT( 1 <= supp->variant && supp->variant <= 99,                                                           supp->variant )
 207                MMDASSERT( 1 <= supp->bottom  && supp->bottom <= 99,                                                            supp->bottom )
 208                MMDASSERT( 1 <= supp->top     && supp->top <= 99,                                                                       supp->top )
 209                MMDASSERT( supp->bottom <= supp->top,                                                   supp->bottom << 8 | supp->top )
 210        } else {                                                                        //non-native endian
 211                MMDASSERT( supp->role == CNV_END_SHORT(COMP_ROLE_SUPL),                                                                 supp->role )
 212                MMDASSERT( 1 <= CNV_END_SHORT(supp->id) && CNV_END_SHORT(supp->id) <= 99,                               supp->id )
 213                MMDASSERT( 1 <= CNV_END_SHORT(supp->variant) && CNV_END_SHORT(supp->variant) <= 99,             supp->variant )
 214                MMDASSERT( 1 <= CNV_END_SHORT(supp->bottom)  && CNV_END_SHORT(supp->bottom) <=99,               supp->bottom )
 215                MMDASSERT( 1 <= CNV_END_SHORT(supp->top)     && CNV_END_SHORT(supp->top) <=99,                  supp->top )
 216                MMDASSERT( CNV_END_SHORT(supp->bottom) <= CNV_END_SHORT(supp->top),     supp->bottom << 8 |     supp->top )
 217        }
 218#endif // HCF_ASSERT
 219
 220#if HCF_BIG_ENDIAN == 0
 221        act_endian = !act_endian;                                                                                                                                               /* 1b*/
 222        sup_endian = !sup_endian;                                                                                                                                               /* 2b*/
 223#endif // HCF_BIG_ENDIAN
 224
 225        for ( i = actp->len ; i > 3; actq++, i -= 3 ) {                                                                                                 /* 6 */
 226                MMDASSERT( actq->variant[act_endian] <= 99, i<<8 | actq->variant[act_endian] )
 227                MMDASSERT( actq->bottom[act_endian] <= 99 , i<<8 | actq->bottom[act_endian] )
 228                MMDASSERT( actq->top[act_endian] <= 99    , i<<8 | actq->top[act_endian] )
 229                MMDASSERT( actq->bottom[act_endian] <= actq->top[act_endian], i<<8 | actq->bottom[act_endian] )
 230                if ( actq->variant[act_endian] == supq->variant[sup_endian] &&
 231                         actq->bottom[act_endian]  <= supq->top[sup_endian] &&
 232                         actq->top[act_endian]     >= supq->bottom[sup_endian]
 233                   ) break;
 234        }
 235        if ( i <= 3 || supp->len != 6 /*sizeof(CFG_SUP_RANGE_STRCT)/sizeof(hcf_16) - 1 */ ) {
 236           actq = NULL;                                                                                                                                                                 /* 8 */
 237        }
 238#if HCF_ASSERT
 239        if ( actq == NULL ) {
 240                for ( i = 0; i <= supp->len; i += 2 ) {
 241                        MMDASSERT( DO_ASSERT, MERGE_2( ((hcf_16*)supp)[i], ((hcf_16*)supp)[i+1] ) );
 242                }
 243                for ( i = 0; i <= actp->len; i += 2 ) {
 244                        MMDASSERT( DO_ASSERT, MERGE_2( ((hcf_16*)actp)[i], ((hcf_16*)actp)[i+1] ) );
 245                }
 246        }
 247#endif // HCF_ASSERT
 248        return (CFG_RANGE_SPEC_STRCT*)actq;
 249} // mmd_check_comp
 250
 251