]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Dxe/EfiDriverLib/EfiDriverLib.c
Sync all bug fixes between EDK1.04 and EDK1.06 into EdkCompatibilityPkg.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / EfiDriverLib / EfiDriverLib.c
CommitLineData
3eb9473e 1/*++\r
2\r
3e99020d 3Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
4ea9375a 4This program and the accompanying materials \r
3eb9473e 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 EfiDriverLib.c\r
15\r
16Abstract:\r
17\r
18 Light weight lib to support EFI drivers.\r
19\r
20--*/\r
21\r
22#include "Tiano.h"\r
23#include "EfiDriverLib.h"\r
3e99020d
LG
24#include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)\r
25\r
26#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
27\r
28VOID\r
29EFIAPI\r
30OnStatusCodeInstall (\r
31 IN EFI_EVENT Event,\r
32 IN VOID *Context\r
33 );\r
34\r
35#endif\r
3eb9473e 36\r
37//\r
38// Global Interface for Debug Mask Protocol\r
39//\r
40EFI_DEBUG_MASK_PROTOCOL *gDebugMaskInterface = NULL;\r
41\r
42EFI_STATUS\r
43EfiInitializeDriverLib (\r
44 IN EFI_HANDLE ImageHandle,\r
45 IN EFI_SYSTEM_TABLE *SystemTable\r
46 )\r
47/*++\r
48\r
49Routine Description:\r
50\r
51 Intialize Driver Lib if it has not yet been initialized. \r
52\r
53Arguments:\r
54\r
55 ImageHandle - Standard EFI Image entry parameter\r
56 \r
57 SystemTable - Standard EFI Image entry parameter\r
58\r
59Returns: \r
60\r
61 EFI_STATUS always returns EFI_SUCCESS\r
62\r
63--*/\r
64{\r
3e99020d
LG
65#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
66 VOID *Registration;\r
67#endif\r
68 \r
3eb9473e 69 gST = SystemTable;\r
70\r
71 ASSERT (gST != NULL);\r
72\r
73 gBS = gST->BootServices;\r
74 gRT = gST->RuntimeServices;\r
75\r
76 ASSERT (gBS != NULL);\r
77 ASSERT (gRT != NULL);\r
78\r
79 //\r
80 // Get driver debug mask protocol interface\r
81 //\r
82#ifdef EFI_DEBUG\r
83 gBS->HandleProtocol (\r
84 ImageHandle,\r
85 &gEfiDebugMaskProtocolGuid,\r
86 (VOID *) &gDebugMaskInterface\r
87 );\r
88#endif\r
3e99020d
LG
89\r
90#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
91 //\r
92 // Register EFI_STATUS_CODE_PROTOCOL notify function\r
93 //\r
94 EfiLibCreateProtocolNotifyEvent (\r
95 &gEfiStatusCodeRuntimeProtocolGuid,\r
96 EFI_TPL_CALLBACK,\r
97 OnStatusCodeInstall,\r
98 NULL,\r
99 &Registration\r
100 );\r
101\r
102#endif\r
103\r
3eb9473e 104 //\r
105 // Should be at EFI_D_INFO, but lets us know things are running\r
106 //\r
107 DEBUG ((EFI_D_INFO, "EfiInitializeDriverLib: Started\n"));\r
108\r
109 return EFI_SUCCESS;\r
110}\r
111\r
3e99020d
LG
112STATIC\r
113BOOLEAN\r
114IsIso639LanguageCode (\r
115 IN CHAR8 *Languages\r
116 )\r
117/*++\r
118\r
119Routine Description:\r
120\r
121 Tests whether a language code has format of ISO639-2.\r
122\r
123Arguments:\r
124\r
125 Languages - The language code to be tested.\r
126\r
127Returns:\r
128\r
129 TRUE - Language code format is ISO 639-2.\r
130 FALSE - Language code format is not ISO 639-2.\r
131\r
132--*/\r
133{\r
134 UINTN Index;\r
135\r
136 //\r
137 // Find out format of Languages\r
138 //\r
139 for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';' && Languages[Index] != '-'; Index++);\r
140 if (Languages[Index] != 0) {\r
141 //\r
142 // RFC4646 language code\r
143 //\r
144 return FALSE;\r
145 }\r
146\r
147 //\r
148 // No ';' and '-', it's either ISO639-2 code (list) or single RFC4646 code\r
149 //\r
150 if (Index == 2) {\r
151 //\r
152 // Single RFC4646 language code without country code, e.g. "en"\r
153 //\r
154 return FALSE;\r
155 }\r
156\r
157 //\r
158 // Languages in format of ISO639-2\r
159 //\r
160 return TRUE;\r
161}\r
162\r
3eb9473e 163BOOLEAN\r
164EfiLibCompareLanguage (\r
3e99020d
LG
165 IN CHAR8 *Language1,\r
166 IN CHAR8 *Language2\r
3eb9473e 167 )\r
168/*++\r
169\r
170Routine Description:\r
171\r
3e99020d
LG
172 Compare the first language instance of two language codes, either could be a\r
173 single language code or a language code list. This function assume Language1\r
174 and Language2 has the same language code format, i.e. either ISO639-2 or RFC4646.\r
3eb9473e 175\r
176Arguments:\r
177\r
3e99020d
LG
178 Language1 - The first language code to be tested.\r
179 Language2 - The second language code to be tested.\r
3eb9473e 180\r
181Returns:\r
182\r
3e99020d
LG
183 TRUE - Language code match.\r
184 FALSE - Language code mismatch.\r
3eb9473e 185\r
186--*/\r
187{\r
188 UINTN Index;\r
189\r
3e99020d
LG
190 //\r
191 // Compare first two bytes of language tag\r
192 //\r
193 if ((Language1[0] != Language2[0]) || (Language1[1] != Language2[1])) {\r
194 return FALSE;\r
3eb9473e 195 }\r
196\r
3e99020d
LG
197 if (IsIso639LanguageCode (Language1)) {\r
198 //\r
199 // ISO639-2 language code, compare the third byte of language tag\r
200 //\r
201 return (BOOLEAN) ((Language1[2] == Language2[2]) ? TRUE : FALSE);\r
3eb9473e 202 }\r
203\r
3e99020d
LG
204 //\r
205 // RFC4646 language code\r
206 //\r
207 for (Index = 0; Language1[Index] != 0 && Language1[Index] != ';'; Index++);\r
208 if ((EfiAsciiStrnCmp (Language1, Language2, Index) == 0) && (Language2[Index] == 0 || Language2[Index] == ';')) {\r
209 return TRUE;\r
3eb9473e 210 }\r
211\r
3e99020d 212 return FALSE;\r
3eb9473e 213}\r
214\r
215STATIC\r
216CHAR8 *\r
217NextSupportedLanguage (\r
218 IN CHAR8 *Languages\r
219 )\r
3e99020d
LG
220/*++\r
221\r
222Routine Description:\r
223\r
224 Step to next language code of a language code list.\r
225\r
226Arguments:\r
227\r
228 Languages - The language code list to traverse.\r
229\r
230Returns:\r
231\r
232 Pointer to next language code or NULL terminator if it's the last one.\r
233\r
234--*/\r
3eb9473e 235{\r
3e99020d 236 UINTN Index;\r
d850121e 237\r
3e99020d
LG
238 if (IsIso639LanguageCode (Languages)) {\r
239 //\r
240 // ISO639-2 language code\r
241 //\r
242 return (Languages + 3);\r
d850121e 243 }\r
244\r
3e99020d
LG
245 //\r
246 // Search in RFC4646 language code list\r
247 //\r
248 for (Index = 0; Languages[Index] != 0 && Languages[Index] != ';'; Index++);\r
249 if (Languages[Index] == ';') {\r
250 Index++;\r
251 }\r
252 return (Languages + Index);\r
3eb9473e 253}\r
254\r
255EFI_STATUS\r
256EfiLibLookupUnicodeString (\r
257 IN CHAR8 *Language,\r
258 IN CHAR8 *SupportedLanguages,\r
259 IN EFI_UNICODE_STRING_TABLE *UnicodeStringTable,\r
260 OUT CHAR16 **UnicodeString\r
261 )\r
262/*++\r
263\r
264Routine Description:\r
265\r
266 Translate a unicode string to a specified language if supported.\r
267 \r
268Arguments:\r
269\r
270 Language - The name of language to translate to\r
271 SupportedLanguages - Supported languages set\r
272 UnicodeStringTable - Pointer of one item in translation dictionary\r
273 UnicodeString - The translated string\r
274\r
275Returns: \r
276\r
277 EFI_INVALID_PARAMETER - Invalid parameter\r
278 EFI_UNSUPPORTED - System not supported this language or this string translation\r
279 EFI_SUCCESS - String successfully translated\r
280\r
281--*/\r
282{\r
283 //\r
284 // Make sure the parameters are valid\r
285 //\r
286 if (Language == NULL || UnicodeString == NULL) {\r
287 return EFI_INVALID_PARAMETER;\r
288 }\r
289\r
290 //\r
291 // If there are no supported languages, or the Unicode String Table is empty, then the\r
292 // Unicode String specified by Language is not supported by this Unicode String Table\r
293 //\r
294 if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {\r
295 return EFI_UNSUPPORTED;\r
296 }\r
297\r
298 //\r
299 // Make sure Language is in the set of Supported Languages\r
300 //\r
301 while (*SupportedLanguages != 0) {\r
302 if (EfiLibCompareLanguage (Language, SupportedLanguages)) {\r
303\r
304 //\r
305 // Search the Unicode String Table for the matching Language specifier\r
306 //\r
307 while (UnicodeStringTable->Language != NULL) {\r
308 if (EfiLibCompareLanguage (Language, UnicodeStringTable->Language)) {\r
309\r
310 //\r
311 // A matching string was found, so return it\r
312 //\r
313 *UnicodeString = UnicodeStringTable->UnicodeString;\r
314 return EFI_SUCCESS;\r
315 }\r
316\r
317 UnicodeStringTable++;\r
318 }\r
319\r
320 return EFI_UNSUPPORTED;\r
321 }\r
322\r
3e99020d 323 SupportedLanguages = NextSupportedLanguage (SupportedLanguages);\r
3eb9473e 324 }\r
325\r
326 return EFI_UNSUPPORTED;\r
327}\r
328\r
329EFI_STATUS\r
330EfiLibAddUnicodeString (\r
331 IN CHAR8 *Language,\r
332 IN CHAR8 *SupportedLanguages,\r
333 IN OUT EFI_UNICODE_STRING_TABLE **UnicodeStringTable,\r
334 IN CHAR16 *UnicodeString\r
335 )\r
336/*++\r
337\r
338Routine Description:\r
339\r
340 Add an translation to the dictionary if this language if supported.\r
341 \r
342Arguments:\r
343\r
344 Language - The name of language to translate to\r
345 SupportedLanguages - Supported languages set\r
346 UnicodeStringTable - Translation dictionary\r
347 UnicodeString - The corresponding string for the language to be translated to\r
348\r
349Returns: \r
350\r
351 EFI_INVALID_PARAMETER - Invalid parameter\r
352 EFI_UNSUPPORTED - System not supported this language\r
353 EFI_ALREADY_STARTED - Already has a translation item of this language\r
354 EFI_OUT_OF_RESOURCES - No enough buffer to be allocated\r
355 EFI_SUCCESS - String successfully translated\r
356\r
357--*/\r
358{\r
359 UINTN NumberOfEntries;\r
360 EFI_UNICODE_STRING_TABLE *OldUnicodeStringTable;\r
361 EFI_UNICODE_STRING_TABLE *NewUnicodeStringTable;\r
362 UINTN UnicodeStringLength;\r
363\r
364 //\r
365 // Make sure the parameter are valid\r
366 //\r
367 if (Language == NULL || UnicodeString == NULL || UnicodeStringTable == NULL) {\r
368 return EFI_INVALID_PARAMETER;\r
369 }\r
370\r
371 //\r
372 // If there are no supported languages, then a Unicode String can not be added\r
373 //\r
374 if (SupportedLanguages == NULL) {\r
375 return EFI_UNSUPPORTED;\r
376 }\r
377\r
378 //\r
379 // If the Unicode String is empty, then a Unicode String can not be added\r
380 //\r
381 if (UnicodeString[0] == 0) {\r
382 return EFI_INVALID_PARAMETER;\r
383 }\r
384\r
385 //\r
386 // Make sure Language is a member of SupportedLanguages\r
387 //\r
388 while (*SupportedLanguages != 0) {\r
389 if (EfiLibCompareLanguage (Language, SupportedLanguages)) {\r
390\r
391 //\r
392 // Determine the size of the Unicode String Table by looking for a NULL Language entry\r
393 //\r
394 NumberOfEntries = 0;\r
395 if (*UnicodeStringTable != NULL) {\r
396 OldUnicodeStringTable = *UnicodeStringTable;\r
397 while (OldUnicodeStringTable->Language != NULL) {\r
398 if (EfiLibCompareLanguage (Language, OldUnicodeStringTable->Language)) {\r
399 return EFI_ALREADY_STARTED;\r
400 }\r
401\r
402 OldUnicodeStringTable++;\r
403 NumberOfEntries++;\r
404 }\r
405 }\r
406\r
407 //\r
408 // Allocate space for a new Unicode String Table. It must hold the current number of\r
409 // entries, plus 1 entry for the new Unicode String, plus 1 entry for the end of table\r
410 // marker\r
411 //\r
412 NewUnicodeStringTable = EfiLibAllocatePool ((NumberOfEntries + 2) * sizeof (EFI_UNICODE_STRING_TABLE));\r
413 if (NewUnicodeStringTable == NULL) {\r
414 return EFI_OUT_OF_RESOURCES;\r
415 }\r
416\r
417 //\r
418 // If the current Unicode String Table contains any entries, then copy them to the\r
419 // newly allocated Unicode String Table.\r
420 //\r
421 if (*UnicodeStringTable != NULL) {\r
422 EfiCopyMem (\r
423 NewUnicodeStringTable,\r
424 *UnicodeStringTable,\r
425 NumberOfEntries * sizeof (EFI_UNICODE_STRING_TABLE)\r
426 );\r
427 }\r
428\r
429 //\r
430 // Allocate space for a copy of the Language specifier\r
431 //\r
3e99020d 432 NewUnicodeStringTable[NumberOfEntries].Language = EfiLibAllocateCopyPool (EfiAsciiStrSize (Language), Language);\r
3eb9473e 433 if (NewUnicodeStringTable[NumberOfEntries].Language == NULL) {\r
434 gBS->FreePool (NewUnicodeStringTable);\r
435 return EFI_OUT_OF_RESOURCES;\r
436 }\r
437\r
438 //\r
439 // Compute the length of the Unicode String\r
440 //\r
441 for (UnicodeStringLength = 0; UnicodeString[UnicodeStringLength] != 0; UnicodeStringLength++)\r
442 ;\r
443\r
444 //\r
445 // Allocate space for a copy of the Unicode String\r
446 //\r
447 NewUnicodeStringTable[NumberOfEntries].UnicodeString = EfiLibAllocateCopyPool (\r
448 (UnicodeStringLength + 1) * sizeof (CHAR16),\r
449 UnicodeString\r
450 );\r
451 if (NewUnicodeStringTable[NumberOfEntries].UnicodeString == NULL) {\r
452 gBS->FreePool (NewUnicodeStringTable[NumberOfEntries].Language);\r
453 gBS->FreePool (NewUnicodeStringTable);\r
454 return EFI_OUT_OF_RESOURCES;\r
455 }\r
456\r
457 //\r
458 // Mark the end of the Unicode String Table\r
459 //\r
460 NewUnicodeStringTable[NumberOfEntries + 1].Language = NULL;\r
461 NewUnicodeStringTable[NumberOfEntries + 1].UnicodeString = NULL;\r
462\r
463 //\r
464 // Free the old Unicode String Table\r
465 //\r
466 if (*UnicodeStringTable != NULL) {\r
467 gBS->FreePool (*UnicodeStringTable);\r
468 }\r
469\r
470 //\r
471 // Point UnicodeStringTable at the newly allocated Unicode String Table\r
472 //\r
473 *UnicodeStringTable = NewUnicodeStringTable;\r
474\r
475 return EFI_SUCCESS;\r
476 }\r
477\r
3e99020d 478 SupportedLanguages = NextSupportedLanguage (SupportedLanguages);\r
3eb9473e 479 }\r
480\r
481 return EFI_UNSUPPORTED;\r
482}\r
483\r
484EFI_STATUS\r
485EfiLibFreeUnicodeStringTable (\r
486 IN OUT EFI_UNICODE_STRING_TABLE *UnicodeStringTable\r
487 )\r
488/*++\r
489\r
490Routine Description:\r
491\r
492 Free a string table.\r
493\r
494Arguments:\r
495\r
496 UnicodeStringTable - The string table to be freed.\r
497\r
498Returns: \r
499\r
500 EFI_SUCCESS - The table successfully freed.\r
501\r
502--*/\r
503{\r
504 UINTN Index;\r
505\r
506 //\r
507 // If the Unicode String Table is NULL, then it is already freed\r
508 //\r
509 if (UnicodeStringTable == NULL) {\r
510 return EFI_SUCCESS;\r
511 }\r
512\r
513 //\r
514 // Loop through the Unicode String Table until we reach the end of table marker\r
515 //\r
516 for (Index = 0; UnicodeStringTable[Index].Language != NULL; Index++) {\r
517\r
518 //\r
519 // Free the Language string from the Unicode String Table\r
520 //\r
521 gBS->FreePool (UnicodeStringTable[Index].Language);\r
522\r
523 //\r
524 // Free the Unicode String from the Unicode String Table\r
525 //\r
526 if (UnicodeStringTable[Index].UnicodeString != NULL) {\r
527 gBS->FreePool (UnicodeStringTable[Index].UnicodeString);\r
528 }\r
529 }\r
530\r
531 //\r
532 // Free the Unicode String Table itself\r
533 //\r
534 gBS->FreePool (UnicodeStringTable);\r
535\r
536 return EFI_SUCCESS;\r
537}\r