2 /************************************************************************************************************
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
18 * AUTHOR : Nico Valster
20 * DESC : Common routines for HCF, MSF, UIL as well as USF sources
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.
27 ***************************************************************************************************************
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.
37 * COPYRIGHT © 2001 - 2004 by Agere Systems Inc. All Rights Reserved
38 * All rights reserved.
40 * Redistribution and use in source or binary forms, with or without
41 * modifications, are permitted provided that the following conditions are met:
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
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.
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.
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
72 **************************************************************************************************************/
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
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
83 /*************************************************************************************************************
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.
94 * <>NULL pointer to matching CFG_RANGE_SPEC_STRCT substructure in actor-structure matching the supplier
99 * actp address of the actor specification
100 * supp address of the supplier specification
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
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.
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.
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)
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)
139 * (the platform is LE and the LTV differs from the platform).
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
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
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
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.
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
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
177 *.ENDDOC END DOCUMENTATION
178 *************************************************************************************************************/
179 CFG_RANGE_SPEC_STRCT
*
180 mmd_check_comp( CFG_RANGES_STRCT
*actp
, CFG_SUP_RANGE_STRCT
*supp
)
183 CFG_RANGE_SPEC_BYTE_STRCT
*actq
= (CFG_RANGE_SPEC_BYTE_STRCT
*)actp
->var_rec
;
184 CFG_RANGE_SPEC_BYTE_STRCT
*supq
= (CFG_RANGE_SPEC_BYTE_STRCT
*)&(supp
->variant
);
186 int act_endian
; //actor endian flag
187 int sup_endian
; //supplier endian flag
189 act_endian
= actp
->role
== COMP_ROLE_ACT
; //true if native endian /* 1a */
190 sup_endian
= supp
->bottom
< 0x0100; //true if native endian /* 2a */
193 MMDASSERT( supp
->len
== 6, supp
->len
)
194 MMDASSERT( actp
->len
>= 6 && actp
->len
%3 == 0, actp
->len
)
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
)
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
)
220 #if HCF_BIG_ENDIAN == 0
221 act_endian
= !act_endian
; /* 1b*/
222 sup_endian
= !sup_endian
; /* 2b*/
223 #endif // HCF_BIG_ENDIAN
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
]
235 if ( i
<= 3 || supp
->len
!= 6 /*sizeof(CFG_SUP_RANGE_STRCT)/sizeof(hcf_16) - 1 */ ) {
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] ) );
243 for ( i
= 0; i
<= actp
->len
; i
+= 2 ) {
244 MMDASSERT( DO_ASSERT
, MERGE_2( ((hcf_16
*)actp
)[i
], ((hcf_16
*)actp
)[i
+1] ) );
248 return (CFG_RANGE_SPEC_STRCT
*)actq
;