1 /*++
2 Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
3 This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution.  The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
7 
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 
11 Module Name:
12   VfrUtilityLib.h
13 
14 Abstract:
15 
16 --*/
17 
18 #ifndef _VFRUTILITYLIB_H_
19 #define _VFRUTILITYLIB_H_
20 
21 #include "Tiano.h"
22 #include "string.h"
23 #include "EfiTypes.h"
24 #include "EfiVfr.h"
25 #include "VfrError.h"
26 
27 #define MAX_NAME_LEN                       64
28 #define DEFAULT_ALIGN                      1
29 #define DEFAULT_PACK_ALIGN                 0x8
30 #define DEFAULT_NAME_TABLE_ITEMS           1024
31 
32 #define EFI_BITS_SHIFT_PER_UINT32          0x5
33 #define EFI_BITS_PER_UINT32                (1 << EFI_BITS_SHIFT_PER_UINT32)
34 
35 #define BUFFER_SAFE_FREE(Buf)              do { if ((Buf) != NULL) { delete (Buf); } } while (0);
36 
37 class CVfrBinaryOutput {
38 public:
39   virtual VOID WriteLine (IN FILE *, IN UINT32, IN INT8 *, IN INT8 *, IN UINT32);
40   virtual VOID WriteEnd (IN FILE *, IN UINT32, IN INT8 *, IN INT8 *, IN UINT32);
41 };
42 
43 UINT32
44 _STR2U32 (
45   IN INT8 *Str
46   );
47 
48 struct SConfigInfo {
49   UINT16             mOffset;
50   UINT16             mWidth;
51   UINT8              *mValue;
52   SConfigInfo        *mNext;
53 
54   SConfigInfo (IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE);
55   ~SConfigInfo (VOID);
56 };
57 
58 struct SConfigItem {
59   INT8          *mName;         // varstore name
60   INT8          *mId;           // varstore ID
61   SConfigInfo   *mInfoStrList;  // list of Offset/Value in the varstore
62   SConfigItem   *mNext;
63 
64 public:
65   SConfigItem (IN INT8 *, IN INT8 *);
66   SConfigItem (IN INT8 *, IN INT8 *, IN UINT8, IN UINT16, IN UINT16, IN EFI_IFR_TYPE_VALUE);
67   virtual ~SConfigItem ();
68 };
69 
70 class CVfrBufferConfig {
71 private:
72   SConfigItem *mItemListHead;
73   SConfigItem *mItemListTail;
74   SConfigItem *mItemListPos;
75 
76 public:
77   CVfrBufferConfig (VOID);
78   virtual ~CVfrBufferConfig (VOID);
79 
80   virtual UINT8   Register (IN INT8 *, IN INT8 *Info = NULL);
81   virtual VOID    Open (VOID);
82   virtual BOOLEAN Eof(VOID);
83   virtual UINT8   Select (IN INT8 *, IN INT8 *Info = NULL);
84   virtual UINT8   Write (IN CONST CHAR8, IN INT8 *, IN INT8 *, IN UINT8, IN UINT16, IN UINT32, IN EFI_IFR_TYPE_VALUE);
85 #if 0
86   virtual UINT8   Read (OUT INT8 **, OUT INT8 **, OUT INT8 **, OUT INT8 **, OUT INT8 **);
87 #endif
88   virtual VOID    Close (VOID);
89   virtual VOID    OutputCFile (IN FILE *, IN INT8 *);
90 };
91 
92 extern CVfrBufferConfig gCVfrBufferConfig;
93 
94 #define ALIGN_STUFF(Size, Align) ((Align) - (Size) % (Align))
95 #define INVALID_ARRAY_INDEX      0xFFFFFFFF
96 
97 struct SVfrDataType;
98 
99 struct SVfrDataField {
100   INT8                      mFieldName[MAX_NAME_LEN];
101   SVfrDataType              *mFieldType;
102   UINT32                    mOffset;
103   UINT32                    mArrayNum;
104   SVfrDataField             *mNext;
105 };
106 
107 struct SVfrDataType {
108   INT8                      mTypeName[MAX_NAME_LEN];
109   UINT8                     mType;
110   UINT32                    mAlign;
111   UINT32                    mTotalSize;
112   SVfrDataField             *mMembers;
113   SVfrDataType              *mNext;
114 };
115 
116 #define VFR_PACK_ASSIGN     0x01
117 #define VFR_PACK_SHOW       0x02
118 #define VFR_PACK_PUSH       0x04
119 #define VFR_PACK_POP        0x08
120 
121 #define PACKSTACK_MAX_SIZE  0x400
122 
123 struct SVfrPackStackNode {
124   INT8                      *mIdentifier;
125   UINT32                    mNumber;
126   SVfrPackStackNode         *mNext;
127 
SVfrPackStackNodeSVfrPackStackNode128   SVfrPackStackNode (IN INT8 *Identifier, IN UINT32 Number) {
129     mIdentifier = NULL;
130     mNumber     = Number;
131     mNext       = NULL;
132 
133     if (Identifier != NULL) {
134       mIdentifier = new INT8[strlen (Identifier) + 1];
135       strcpy (mIdentifier, Identifier);
136     }
137   }
138 
~SVfrPackStackNodeSVfrPackStackNode139   ~SVfrPackStackNode (VOID) {
140     if (mIdentifier != NULL) {
141       delete mIdentifier;
142     }
143     mNext = NULL;
144   }
145 
MatchSVfrPackStackNode146   bool Match (IN INT8 *Identifier) {
147     if (Identifier == NULL) {
148       return TRUE;
149     } else if (mIdentifier == NULL) {
150       return FALSE;
151     } else if (strcmp (Identifier, mIdentifier) == 0) {
152       return TRUE;
153     } else {
154       return FALSE;
155     }
156   }
157 };
158 
159 class CVfrVarDataTypeDB {
160 private:
161   UINT32                    mPackAlign;
162   SVfrPackStackNode         *mPackStack;
163 
164 public:
165   EFI_VFR_RETURN_CODE       Pack (IN UINT32, IN UINT8, IN INT8 *Identifier = NULL, IN UINT32 Number = DEFAULT_PACK_ALIGN);
166 
167 private:
168   SVfrDataType              *mDataTypeList;
169 
170   SVfrDataType              *mNewDataType;
171   SVfrDataType              *mCurrDataType;
172   SVfrDataField             *mCurrDataField;
173 
174   VOID InternalTypesListInit (VOID);
175   VOID RegisterNewType (IN SVfrDataType *);
176 
177   EFI_VFR_RETURN_CODE ExtractStructTypeName (IN INT8 *&, OUT INT8 *);
178   EFI_VFR_RETURN_CODE ExtractFieldNameAndArrary (IN INT8 *&, OUT INT8 *, OUT UINT32 &);
179   EFI_VFR_RETURN_CODE GetTypeField (IN INT8 *, IN SVfrDataType *, IN SVfrDataField *&);
180   EFI_VFR_RETURN_CODE GetFieldOffset (IN SVfrDataField *, IN UINT32, OUT UINT32 &);
181   UINT8               GetFieldWidth (IN SVfrDataField *);
182   UINT32              GetFieldSize (IN SVfrDataField *, IN UINT32);
183 
184 public:
185   CVfrVarDataTypeDB (VOID);
186   ~CVfrVarDataTypeDB (VOID);
187 
188   VOID                DeclareDataTypeBegin (VOID);
189   EFI_VFR_RETURN_CODE SetNewTypeName (IN INT8 *);
190   EFI_VFR_RETURN_CODE DataTypeAddField (IN INT8 *, IN INT8 *, IN UINT32);
191   VOID                DeclareDataTypeEnd (VOID);
192 
193   EFI_VFR_RETURN_CODE GetDataType (IN INT8 *, OUT SVfrDataType **);
194   EFI_VFR_RETURN_CODE GetDataTypeSize (IN INT8 *, OUT UINT32 *);
195   EFI_VFR_RETURN_CODE GetDataTypeSize (IN UINT8, OUT UINT32 *);
196   EFI_VFR_RETURN_CODE GetDataFieldInfo (IN INT8 *, OUT UINT16 &, OUT UINT8 &, OUT UINT32 &);
197 
198   EFI_VFR_RETURN_CODE GetUserDefinedTypeNameList (OUT INT8 ***, OUT UINT32 *);
199   BOOLEAN             IsTypeNameDefined (IN INT8 *);
200 
201 #ifdef CVFR_VARDATATYPEDB_DEBUG
202   VOID ParserDB ();
203 #endif
204 };
205 
206 typedef enum {
207   EFI_VFR_VARSTORE_INVALID,
208   EFI_VFR_VARSTORE_BUFFER,
209   EFI_VFR_VARSTORE_EFI,
210   EFI_VFR_VARSTORE_NAME
211 } EFI_VFR_VARSTORE_TYPE;
212 
213 struct SVfrVarStorageNode {
214   EFI_GUID                  mGuid;
215   INT8                      *mVarStoreName;
216   EFI_VARSTORE_ID           mVarStoreId;
217   struct SVfrVarStorageNode *mNext;
218 
219   EFI_VFR_VARSTORE_TYPE     mVarStoreType;
220   union {
221     // EFI Variable
222     struct {
223       EFI_STRING_ID           mEfiVarName;
224       UINT32                  mEfiVarSize;
225     } mEfiVar;
226 
227     // Buffer Storage
228     SVfrDataType            *mDataType;
229 
230     // NameValue Storage
231 	struct {
232       EFI_STRING_ID         *mNameTable;
233       UINT32                mTableSize;
234     } mNameSpace;
235   } mStorageInfo;
236 
237 public:
238   SVfrVarStorageNode (IN EFI_GUID *, IN INT8 *, IN EFI_VARSTORE_ID, IN EFI_STRING_ID, IN UINT32);
239   SVfrVarStorageNode (IN EFI_GUID *, IN INT8 *, IN EFI_VARSTORE_ID, IN SVfrDataType *);
240   SVfrVarStorageNode (IN INT8 *, IN EFI_VARSTORE_ID);
241   ~SVfrVarStorageNode (VOID);
242 };
243 
244 struct EFI_VARSTORE_INFO {
245   EFI_VARSTORE_ID           mVarStoreId;
246   union {
247     EFI_STRING_ID           mVarName;
248     UINT16                  mVarOffset;
249   } mInfo;
250   UINT8                     mVarType;
251   UINT32                    mVarTotalSize;
252 
253   EFI_VARSTORE_INFO (VOID);
254   EFI_VARSTORE_INFO (IN EFI_VARSTORE_INFO &);
255   BOOLEAN operator == (IN EFI_VARSTORE_INFO *);
256 };
257 
258 #define EFI_VARSTORE_ID_MAX              0xFFFF
259 #define EFI_FREE_VARSTORE_ID_BITMAP_SIZE ((EFI_VARSTORE_ID_MAX + 1) / EFI_BITS_PER_UINT32)
260 
261 class CVfrDataStorage {
262 private:
263   UINT32                    mFreeVarStoreIdBitMap[EFI_FREE_VARSTORE_ID_BITMAP_SIZE];
264 
265   struct SVfrVarStorageNode *mBufferVarStoreList;
266   struct SVfrVarStorageNode *mEfiVarStoreList;
267   struct SVfrVarStorageNode *mNameVarStoreList;
268 
269   struct SVfrVarStorageNode *mCurrVarStorageNode;
270   struct SVfrVarStorageNode *mNewVarStorageNode;
271 
272 private:
273 
274   EFI_VARSTORE_ID GetFreeVarStoreId (VOID);
275   BOOLEAN         ChekVarStoreIdFree (IN EFI_VARSTORE_ID);
276   VOID            MarkVarStoreIdUsed (IN EFI_VARSTORE_ID);
277   VOID            MarkVarStoreIdUnused (IN EFI_VARSTORE_ID);
278 
279 public:
280   CVfrDataStorage ();
281   ~CVfrDataStorage ();
282 
283   EFI_VFR_RETURN_CODE DeclareNameVarStoreBegin (INT8 *);
284   EFI_VFR_RETURN_CODE NameTableAddItem (EFI_STRING_ID);
285   EFI_VFR_RETURN_CODE DeclareNameVarStoreEnd (EFI_GUID *);
286 
287   EFI_VFR_RETURN_CODE DeclareEfiVarStore (IN INT8 *, IN EFI_GUID *, IN EFI_STRING_ID, IN UINT32);
288 
289   EFI_VFR_RETURN_CODE DeclareBufferVarStore (IN INT8 *, IN EFI_GUID *, IN CVfrVarDataTypeDB *, IN INT8 *, IN EFI_VARSTORE_ID);
290 
291   EFI_VFR_RETURN_CODE GetVarStoreId (IN INT8 *, OUT EFI_VARSTORE_ID *);
292   EFI_VFR_RETURN_CODE GetVarStoreType (IN INT8 *, OUT EFI_VFR_VARSTORE_TYPE &);
293   EFI_VFR_VARSTORE_TYPE GetVarStoreType (IN EFI_VARSTORE_ID);
294   EFI_VFR_RETURN_CODE GetVarStoreName (IN EFI_VARSTORE_ID, OUT INT8 **);
295 
296   EFI_VFR_RETURN_CODE GetBufferVarStoreDataTypeName (IN INT8 *, OUT INT8 **);
297   EFI_VFR_RETURN_CODE GetEfiVarStoreInfo (IN EFI_VARSTORE_INFO *);
298   EFI_VFR_RETURN_CODE GetNameVarStoreInfo (IN EFI_VARSTORE_INFO *, IN UINT32);
299 
300   EFI_VFR_RETURN_CODE BufferVarStoreRequestElementAdd (IN INT8 *, IN EFI_VARSTORE_INFO &);
301 };
302 
303 #define EFI_QUESTION_ID_MAX              0xFFFF
304 #define EFI_FREE_QUESTION_ID_BITMAP_SIZE ((EFI_QUESTION_ID_MAX + 1) / EFI_BITS_PER_UINT32)
305 #define EFI_QUESTION_ID_INVALID          0x0
306 
307 #define DATE_YEAR_BITMASK                0x0000FFFF
308 #define DATE_MONTH_BITMASK               0x00FF0000
309 #define DATE_DAY_BITMASK                 0xFF000000
310 #define TIME_HOUR_BITMASK                0x000000FF
311 #define TIME_MINUTE_BITMASK              0x0000FF00
312 #define TIME_SECOND_BITMASK              0x00FF0000
313 
314 struct SVfrQuestionNode {
315   INT8                      *mName;
316   INT8                      *mVarIdStr;
317   EFI_QUESTION_ID           mQuestionId;
318   UINT32                    mBitMask;
319   SVfrQuestionNode          *mNext;
320 
321   SVfrQuestionNode (IN INT8 *, IN INT8 *, IN UINT32 BitMask = 0);
322   ~SVfrQuestionNode ();
323 };
324 
325 class CVfrQuestionDB {
326 private:
327   SVfrQuestionNode          *mQuestionList;
328   UINT32                    mFreeQIdBitMap[EFI_FREE_QUESTION_ID_BITMAP_SIZE];
329 
330 private:
331   EFI_QUESTION_ID GetFreeQuestionId (VOID);
332   BOOLEAN         ChekQuestionIdFree (IN EFI_QUESTION_ID);
333   VOID            MarkQuestionIdUsed (IN EFI_QUESTION_ID);
334   VOID            MarkQuestionIdUnused (IN EFI_QUESTION_ID);
335 
336 public:
337   CVfrQuestionDB ();
338   ~CVfrQuestionDB();
339 
340   EFI_VFR_RETURN_CODE RegisterQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);
341   VOID                RegisterOldDateQuestion (IN INT8 *, IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);
342   VOID                RegisterNewDateQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);
343   VOID                RegisterOldTimeQuestion (IN INT8 *, IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);
344   VOID                RegisterNewTimeQuestion (IN INT8 *, IN INT8 *, IN OUT EFI_QUESTION_ID &);
345   EFI_VFR_RETURN_CODE UpdateQuestionId (IN EFI_QUESTION_ID, IN EFI_QUESTION_ID);
346   VOID                GetQuestionId (IN INT8 *, IN INT8 *, OUT EFI_QUESTION_ID &, OUT UINT32 &);
347   EFI_VFR_RETURN_CODE FindQuestion (IN EFI_QUESTION_ID);
348   EFI_VFR_RETURN_CODE FindQuestion (IN INT8 *);
349  };
350 
351 struct SVfrDefaultStoreNode {
352   EFI_IFR_DEFAULTSTORE      *mObjBinAddr;
353   INT8                      *mRefName;
354   EFI_STRING_ID             mDefaultStoreNameId;
355   UINT16                    mDefaultId;
356 
357   SVfrDefaultStoreNode      *mNext;
358 
359   SVfrDefaultStoreNode (IN EFI_IFR_DEFAULTSTORE *, IN INT8 *, IN EFI_STRING_ID, IN UINT16);
360   ~SVfrDefaultStoreNode();
361 };
362 
363 class CVfrDefaultStore {
364 private:
365   SVfrDefaultStoreNode      *mDefaultStoreList;
366 
367 public:
368   CVfrDefaultStore ();
369   ~CVfrDefaultStore ();
370 
371   EFI_VFR_RETURN_CODE RegisterDefaultStore (IN CHAR8 *, IN INT8 *, IN EFI_STRING_ID, IN UINT16);
372   EFI_VFR_RETURN_CODE ReRegisterDefaultStoreById (IN UINT16, IN INT8 *, IN EFI_STRING_ID);
373   BOOLEAN             DefaultIdRegistered (IN UINT16);
374   EFI_VFR_RETURN_CODE GetDefaultId (IN INT8 *, OUT UINT16 *);
375   EFI_VFR_RETURN_CODE BufferVarStoreAltConfigAdd (IN EFI_VARSTORE_ID, IN EFI_VARSTORE_INFO &, IN INT8 *, IN UINT8, IN EFI_IFR_TYPE_VALUE);
376 };
377 
378 #define EFI_RULE_ID_START    0x01
379 #define EFI_RULE_ID_INVALID  0x00
380 
381 struct SVfrRuleNode {
382   UINT8                     mRuleId;
383   INT8                      *mRuleName;
384   SVfrRuleNode              *mNext;
385 
386   SVfrRuleNode(IN INT8 *, IN UINT8);
387   ~SVfrRuleNode();
388 };
389 
390 class CVfrRulesDB {
391 private:
392   SVfrRuleNode              *mRuleList;
393   UINT8                     mFreeRuleId;
394 
395 public:
396   CVfrRulesDB ();
397   ~CVfrRulesDB();
398 
399   VOID RegisterRule (IN INT8 *);
400   UINT8 GetRuleId (IN INT8 *);
401 };
402 
403 #define MIN(v1, v2) (((v1) < (v2)) ? (v1) : (v2))
404 #define MAX(v1, v2) (((v1) > (v2)) ? (v1) : (v2))
405 
406 #endif
407