]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/DataHubSmBiosRecordsOnPiSmBiosThunk/ConvLib.c
Fix bug that that the template does not match fields in structure EFI_BLOCK_IO_MEDIA
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / DataHubSmBiosRecordsOnPiSmBiosThunk / ConvLib.c
CommitLineData
bd1a4d18 1/** @file\r
024b1029 2 Common filling functions used in translating Datahub's record\r
3 to PI SMBIOS's record.\r
4 \r
5Copyright (c) 2009, Intel Corporation\r
6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Thunk.h"\r
17\r
18/**\r
19 Field Filling Function for Cache SubClass record type 5&6 -- Cache SRAM type.\r
20 Offset is mandatory\r
21 \r
22 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
23 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
24 @param RecordData RecordData buffer will be filled.\r
25 @param RecordDataSize The size of RecordData buffer.\r
26 \r
27 @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.\r
28**/\r
29EFI_STATUS\r
30SmbiosFldCacheType5 (\r
31 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
32 IN UINT32 Offset,\r
33 IN VOID *RecordData,\r
34 IN UINT32 RecordDataSize\r
35 )\r
36{\r
37 EFI_CACHE_SRAM_TYPE_DATA SramData;\r
38 UINT32 Temp;\r
39\r
40 SramData = *(EFI_CACHE_SRAM_TYPE_DATA*)RecordData;\r
41\r
42 //\r
43 // Swap two fields because of inconsistency between smbios and datahub specs\r
44 //\r
45 Temp = SramData.Asynchronous;\r
46 SramData.Asynchronous = SramData.Synchronous;\r
47 SramData.Synchronous = Temp;\r
48 \r
49 //\r
50 // Truncate the data to word\r
51 //\r
52 CopyMem (\r
53 (UINT8 *) (StructureNode->Structure) + Offset,\r
54 (EFI_CACHE_SRAM_TYPE_DATA *) &SramData,\r
55 2\r
56 );\r
57\r
58 return EFI_SUCCESS;\r
59}\r
60\r
61/**\r
62 Field Filling Function for Cache SubClass record type 10 -- Cache Config.\r
63 Offset is mandatory\r
64\r
65 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
66 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
67 @param RecordData RecordData buffer will be filled.\r
68 @param RecordDataSize The size of RecordData buffer.\r
69 \r
70 @retval EFI_SUCCESS Success fill RecordData into SMBIOS's record buffer.\r
71**/\r
72EFI_STATUS\r
73SmbiosFldCacheType10 (\r
74 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
75 IN UINT32 Offset,\r
76 IN VOID *RecordData,\r
77 IN UINT32 RecordDataSize\r
78 )\r
79{\r
80\r
81 UINT16 CacheConfig;\r
82\r
83 CopyMem (&CacheConfig, RecordData, 2);\r
84\r
85 if ((CacheConfig & 0x07) == 0) {\r
86 return EFI_INVALID_PARAMETER;\r
87 }\r
88 //\r
89 // Truncate the data to 2 bytes and make cache level zero-based.\r
90 //\r
91 CacheConfig--;\r
92 CopyMem (\r
93 (UINT8 *) (StructureNode->Structure) + Offset,\r
94 &CacheConfig,\r
95 2\r
96 );\r
97\r
98 return EFI_SUCCESS;\r
99}\r
100\r
101/**\r
102 Enlarge the structure buffer of a structure node in SMBIOS database.\r
103 The function maybe lead the structure pointer for SMBIOS record changed.\r
104 \r
105 @param StructureNode The structure node whose structure buffer is to be enlarged.\r
106 @param NewLength The new length of SMBIOS record which does not include unformat area.\r
107 @param OldBufferSize The old size of SMBIOS record buffer.\r
bd1a4d18 108 @param NewBufferSize The new size is targeted for enlarged.\r
024b1029 109 \r
110 @retval EFI_OUT_OF_RESOURCES No more memory to allocate new record\r
111 @retval EFI_SUCCESS Success to enlarge the record buffer size.\r
112**/\r
113EFI_STATUS\r
114SmbiosEnlargeStructureBuffer (\r
115 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
116 UINT8 NewLength,\r
117 UINTN OldBufferSize,\r
118 UINTN NewBufferSize\r
119 )\r
120{\r
121 EFI_SMBIOS_TABLE_HEADER *NewRecord;\r
122 EFI_SMBIOS_PROTOCOL *Smbios;\r
123 EFI_STATUS Status;\r
124 UINT8 CountOfString;\r
125 \r
126 NewRecord = NULL;\r
127 Smbios = GetSmbiosProtocol();\r
128 ASSERT (Smbios != NULL);\r
129 \r
130 NewRecord = (EFI_SMBIOS_TABLE_HEADER*) AllocateZeroPool (NewBufferSize);\r
131 if (NewRecord == NULL) {\r
132 return EFI_OUT_OF_RESOURCES;\r
133 }\r
134 CopyMem (NewRecord, StructureNode->Structure, OldBufferSize);\r
135 \r
136 \r
137 Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);\r
138 ASSERT_EFI_ERROR (Status);\r
139 \r
140 //\r
141 // try to use original handle to enlarge the buffer.\r
142 //\r
143 NewRecord->Length = NewLength;\r
144 Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, NewRecord);\r
145 ASSERT_EFI_ERROR (Status);\r
146 FreePool (NewRecord);\r
147 \r
148 StructureNode->Structure = GetSmbiosBufferFromHandle (\r
149 StructureNode->SmbiosHandle, \r
150 StructureNode->SmbiosType, \r
151 NULL\r
152 );\r
153 GetSmbiosStructureSize (\r
154 StructureNode->Structure,\r
155 &StructureNode->StructureSize,\r
156 &CountOfString\r
157 );\r
158 return EFI_SUCCESS;\r
159}\r
160\r
161/**\r
162 Fill a standard Smbios string field. \r
163 \r
164 This function will convert the unicode string to single byte chars, and only\r
165 English language is supported.\r
166 This function changes the Structure pointer value of the structure node, \r
167 which should be noted by Caller.\r
168 \r
169 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
170 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
171 @param RecordData RecordData buffer will be filled.\r
172 @param RecordDataSize The size of RecordData buffer.\r
173 \r
174 @retval EFI_INVALID_PARAMETER RecordDataSize is too larger\r
175 @retval EFI_OUT_OF_RESOURCES No memory to allocate new buffer for string\r
176 @retval EFI_SUCCESS Sucess append string for a SMBIOS record.\r
177**/\r
178EFI_STATUS\r
179SmbiosFldString (\r
180 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
181 IN UINT32 Offset,\r
182 IN VOID *RecordData,\r
183 IN UINT32 RecordDataSize\r
184 )\r
185{\r
186 EFI_STATUS Status;\r
187 UINT16 *Data;\r
188 CHAR8 AsciiData[SMBIOS_STRING_MAX_LENGTH];\r
189 UINT8 CountOfStrings;\r
190 UINTN OrigStringNumber;\r
191 EFI_SMBIOS_PROTOCOL *Smbios;\r
192 EFI_SMBIOS_HANDLE SmbiosHandle;\r
193 UINT32 OrigStructureSize;\r
194 UINTN NewStructureSize;\r
195 EFI_SMBIOS_TABLE_HEADER *NewRecord;\r
196 UINT32 StringLength;\r
197 \r
198 Status = EFI_SUCCESS;\r
199 OrigStringNumber = 0;\r
200 OrigStructureSize = 0;\r
201\r
202 //\r
203 // if we have a NULL token,\r
204 //\r
205 if (0 == *((STRING_REF *) RecordData)) {\r
206 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;\r
207 return EFI_SUCCESS;\r
208 }\r
209 \r
210 //\r
211 // Get the String from the Hii Database\r
212 //\r
213 Data = HiiGetPackageString (\r
214 &(StructureNode->ProducerName),\r
215 *((EFI_STRING_ID *) RecordData),\r
216 NULL\r
217 );\r
218 if (Data == NULL) {\r
219 return EFI_INVALID_PARAMETER;\r
220 }\r
221\r
222 StringLength = (UINT32)StrLen (Data);\r
223 //\r
224 // Count the string size including the terminating 0.\r
225 //\r
226 if (StringLength == 0) {\r
227 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = 0;\r
228 FreePool (Data);\r
229 return EFI_SUCCESS;\r
230 }\r
231 \r
232 if (StringLength > SMBIOS_STRING_MAX_LENGTH) {\r
233 //\r
234 // Too long a string\r
235 //\r
236 FreePool (Data);\r
237 return EFI_INVALID_PARAMETER;\r
238 }\r
239 \r
240 Smbios = GetSmbiosProtocol();\r
241 ASSERT (Smbios != NULL);\r
242 \r
243 //\r
244 // Convert Unicode string to Ascii string which only supported by SMBIOS.\r
245 //\r
246 ZeroMem (AsciiData, SMBIOS_STRING_MAX_LENGTH);\r
247 UnicodeStrToAsciiStr (Data, AsciiData);\r
248 \r
249 //\r
250 // if the field at offset is already filled with some value,\r
251 // find out the string it points to\r
252 //\r
253 OrigStringNumber = *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset);\r
254 if (OrigStringNumber != 0) {\r
255 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Update %dth string for type[%d],offset[0x%x],handle[0x%x] to [%s]\n", \r
256 OrigStringNumber, StructureNode->SmbiosType, Offset, StructureNode->SmbiosHandle, AsciiData)); \r
257 \r
258 //\r
259 // If original string number is not zero, just update string\r
260 //\r
261 Status = Smbios->UpdateString (Smbios, &StructureNode->SmbiosHandle, &OrigStringNumber, AsciiData);\r
262 if (EFI_ERROR (Status)) {\r
263 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Fail to update %dth string in offset 0x%x for handle:0x%x type:0x%x\n", \r
264 OrigStringNumber, Offset, StructureNode->SmbiosHandle, StructureNode->SmbiosType));\r
265 ASSERT_EFI_ERROR (Status);\r
266 return Status;\r
267 }\r
268 } else {\r
269 //\r
270 // If the string has not been filled in SMBIOS database, remove it and add again\r
271 // with string appended.\r
272 //\r
273 Status = GetSmbiosStructureSize (StructureNode->Structure, &OrigStructureSize, &CountOfStrings);\r
274 ASSERT_EFI_ERROR (Status);\r
275 \r
276 if (CountOfStrings == 0) {\r
277 NewStructureSize = OrigStructureSize + StringLength;\r
278 } else {\r
279 NewStructureSize = OrigStructureSize + StringLength + 1;\r
280 }\r
281 \r
282 NewRecord = AllocateZeroPool (NewStructureSize);\r
283 if (NewRecord == NULL) {\r
284 return EFI_OUT_OF_RESOURCES;\r
285 }\r
286 CopyMem (NewRecord, StructureNode->Structure, OrigStructureSize);\r
287 \r
288 //\r
289 // Copy new string into tail of original SMBIOS record buffer.\r
290 //\r
291 if (CountOfStrings == 0) {\r
292 AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 2, AsciiData);\r
293 } else {\r
294 AsciiStrCpy ((CHAR8 *)NewRecord + OrigStructureSize - 1, AsciiData);\r
295 }\r
296 DEBUG ((EFI_D_ERROR, "[SMBIOSThunk] Type(%d) offset(0x%x) StringNumber:%d\n", \r
297 StructureNode->SmbiosType, Offset, CountOfStrings + 1));\r
298 //\r
299 // Update string reference number\r
300 //\r
301 *(UINT8 *) ((UINT8 *) NewRecord + Offset) = (UINT8) (CountOfStrings + 1);\r
302 SmbiosHandle = StructureNode->SmbiosHandle;\r
303 \r
304 //\r
305 // Remove original SMBIOS record and add new one\r
306 //\r
307 Status = Smbios->Remove (Smbios, StructureNode->SmbiosHandle);\r
308 ASSERT_EFI_ERROR (Status);\r
309 \r
310 //\r
311 // Add new SMBIOS record\r
312 //\r
313 Status = Smbios->Add (Smbios, NULL, &SmbiosHandle, NewRecord);\r
314 ASSERT_EFI_ERROR (Status);\r
315 \r
316 StructureNode->SmbiosHandle = SmbiosHandle;\r
317 \r
318 FreePool (NewRecord);\r
319 }\r
320 \r
321 //\r
322 // The SMBIOS record buffer maybe re-allocated in SMBIOS database,\r
323 // so update cached buffer pointer in DataHub structure list.\r
324 //\r
325 StructureNode->Structure = GetSmbiosBufferFromHandle (\r
326 StructureNode->SmbiosHandle, \r
327 StructureNode->SmbiosType,\r
328 NULL\r
329 );\r
330 ASSERT (StructureNode->Structure != NULL);\r
331 \r
332 //\r
333 // The string update action maybe lead the record is re-allocated in SMBIOS database\r
334 // so update cached record pointer\r
335 //\r
336 Status = GetSmbiosStructureSize (StructureNode->Structure, &StructureNode->StructureSize, &CountOfStrings);\r
337 ASSERT_EFI_ERROR (Status);\r
338 \r
339 return EFI_SUCCESS;\r
340}\r
341\r
342/**\r
343 Find a handle that matches the Link Data and the target Smbios type.\r
344 \r
345 @param TargetType the Smbios type\r
346 @param SubClass the SubClass\r
347 @param LinkData Specifies Instance, SubInstance and ProducerName\r
348 @param Handle the HandleNum found \r
349 \r
350 @retval EFI_NOT_FOUND Can not find the record according to handle\r
351 @retval EFI_SUCCESS Success to find the handle\r
352**/\r
353EFI_STATUS\r
354SmbiosFindHandle (\r
355 IN UINT8 TargetType,\r
356 IN EFI_GUID *SubClass,\r
357 IN EFI_INTER_LINK_DATA *LinkData,\r
358 IN OUT UINT16 *HandleNum\r
359 )\r
360{\r
361 LIST_ENTRY *Link;\r
362 SMBIOS_STRUCTURE_NODE *StructureNode;\r
363\r
364 StructureNode = NULL;\r
365\r
366 //\r
367 // Find out the matching handle\r
368 //\r
369 for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {\r
370 StructureNode = CR (Link, SMBIOS_STRUCTURE_NODE, Link, SMBIOS_STRUCTURE_NODE_SIGNATURE);\r
371 if (StructureNode->Structure->Type == TargetType &&\r
372 CompareGuid (&(StructureNode->SubClass), SubClass) &&\r
373 StructureNode->Instance == LinkData->Instance &&\r
374 StructureNode->SubInstance == LinkData->SubInstance\r
375 ) {\r
376 break;\r
377 }\r
378 }\r
379\r
380 if (Link == &mStructureList) {\r
381 return EFI_NOT_FOUND;\r
382 } else {\r
383 *HandleNum = StructureNode->Structure->Handle;\r
384 return EFI_SUCCESS;\r
385 }\r
386}\r
387\r
388/**\r
389 Fill the inter link field for a SMBIOS recorder.\r
390 \r
391 Some SMBIOS recorder need to reference the handle of another SMBIOS record. But\r
392 maybe another SMBIOS record has not been added, so put the InterLink request into\r
393 a linked list and the interlink will be fixedup when a new SMBIOS record is added.\r
394 \r
395 @param StructureNode Point to SMBIOS_STRUCTURE_NODE which reference another record's handle\r
396 @param LinkSmbiosNodeOffset The offset in this record for holding the handle of another SMBIOS record\r
397 @param LinkSmbiosType The type of SMBIOS record want to be linked.\r
398 @param InterLink Point to EFI_INTER_LINK_DATA will be put linked list.\r
399 @param SubClassGuid The guid of subclass for linked SMBIOS record.\r
400 \r
401 @retval EFI_SUCESS The linked record is found and no need fixup in future.\r
402 @retval !EFI_SUCESS The linked record can not be found and InterLink is put a fixing-p linked list.\r
403**/\r
404EFI_STATUS\r
405SmbiosFldInterLink (\r
406 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
407 IN UINT16 LinkSmbiosNodeOffset,\r
408 IN UINT8 LinkSmbiosType,\r
409 IN EFI_INTER_LINK_DATA *InterLink,\r
410 IN EFI_GUID *SubClassGuid\r
411 )\r
412{\r
413 EFI_STATUS Status;\r
414 SMBIOS_LINK_DATA_FIXUP_NODE *LinkDataFixupNode;\r
415 UINT16 StructureHandle;\r
416\r
417 Status = EFI_SUCCESS;\r
418 LinkDataFixupNode = NULL;\r
419\r
420 Status = SmbiosFindHandle (\r
421 LinkSmbiosType, // Smbios type\r
422 SubClassGuid,\r
423 InterLink,\r
424 &StructureHandle\r
425 );\r
426 if (!EFI_ERROR (Status)) {\r
427 //\r
428 // Set the handle\r
429 //\r
430 CopyMem (\r
431 (UINT8 *) (StructureNode->Structure) + LinkSmbiosNodeOffset,\r
432 &StructureHandle,\r
433 sizeof (EFI_SMBIOS_HANDLE)\r
434 );\r
435 } else {\r
436 //\r
437 // Hang this in the link data fixup node\r
438 //\r
439 LinkDataFixupNode = AllocateZeroPool (sizeof (SMBIOS_LINK_DATA_FIXUP_NODE));\r
bd1a4d18 440 if (LinkDataFixupNode == NULL) {\r
024b1029 441 return EFI_OUT_OF_RESOURCES;\r
442 }\r
443\r
444 LinkDataFixupNode->Signature = SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE;\r
445 LinkDataFixupNode->Offset = LinkSmbiosNodeOffset;\r
446 LinkDataFixupNode->TargetType = LinkSmbiosType;\r
447 CopyMem (\r
448 &LinkDataFixupNode->SubClass,\r
449 SubClassGuid,\r
450 sizeof (EFI_GUID)\r
451 );\r
452 CopyMem (\r
453 &LinkDataFixupNode->LinkData,\r
454 InterLink,\r
455 sizeof (EFI_INTER_LINK_DATA)\r
456 );\r
457 InsertTailList (\r
458 &StructureNode->LinkDataFixup,\r
459 &(LinkDataFixupNode->Link)\r
460 );\r
461 }\r
462\r
463 return Status;\r
464}\r
465\r
466/**\r
467 Field Filling Function. Transform an EFI_EXP_BASE10_DATA to a word, with 'Mega'\r
468 as the unit.\r
469 \r
470 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
471 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
472 @param RecordData RecordData buffer will be filled.\r
473 @param RecordDataSize The size of RecordData buffer.\r
474 \r
475 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
476 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
477**/\r
478EFI_STATUS\r
479SmbiosFldBase10ToWordWithMega (\r
480 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
481 IN UINT32 Offset,\r
482 IN VOID *RecordData,\r
483 IN UINT32 RecordDataSize\r
484 )\r
485{\r
486 EFI_EXP_BASE10_DATA *Base10Data;\r
487 INT16 Value;\r
488 INT16 Exponent;\r
489\r
490 if (RecordDataSize != sizeof (EFI_EXP_BASE10_DATA)) {\r
491 return EFI_INVALID_PARAMETER;\r
492 }\r
493\r
494 Base10Data = RecordData;\r
495 Value = Base10Data->Value;\r
496 Exponent = Base10Data->Exponent;\r
497\r
498 Exponent -= 6;\r
499 while (Exponent != 0) {\r
500 if (Exponent > 0) {\r
501 Value = (INT16) (Value * 10);\r
502 Exponent--;\r
503 } else {\r
504 Value = (INT16) (Value / 10);\r
505 Exponent++;\r
506 }\r
507 }\r
508\r
509 CopyMem (\r
510 (UINT8 *) (StructureNode->Structure) + Offset,\r
511 &Value,\r
512 2\r
513 );\r
514\r
515 return EFI_SUCCESS;\r
516}\r
517\r
518/**\r
519 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 'Kilo'\r
520 as the unit. Granularity implemented for Cache Size.\r
521 \r
522 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
523 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
524 @param RecordData RecordData buffer will be filled.\r
525 @param RecordDataSize The size of RecordData buffer.\r
526 \r
527 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
528 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
529**/\r
530EFI_STATUS\r
531SmbiosFldBase2ToWordWithKilo (\r
532 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
533 IN UINT32 Offset,\r
534 IN VOID *RecordData,\r
535 IN UINT32 RecordDataSize\r
536 )\r
537{\r
538 EFI_EXP_BASE2_DATA *Base2Data;\r
539 UINT32 Value;\r
540 UINT16 Exponent;\r
541\r
542 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {\r
543 return EFI_INVALID_PARAMETER;\r
544 }\r
545\r
546 Base2Data = RecordData;\r
547 Value = Base2Data->Value;\r
548 Exponent = Base2Data->Exponent;\r
549\r
550 Exponent -= 10;\r
551 Value <<= Exponent;\r
552 \r
553 //\r
554 // Implement cache size granularity\r
555 //\r
556 if(Value >= 0x8000) {\r
557 Value >>= 6;\r
558 Value |= 0x8000;\r
559 }\r
560 \r
561 CopyMem (\r
562 (UINT8 *) (StructureNode->Structure) + Offset,\r
563 &Value,\r
564 2\r
565 );\r
566\r
567 return EFI_SUCCESS;\r
568}\r
569\r
570/**\r
571 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a byte, with '64k'\r
572 as the unit.\r
573 \r
574 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
575 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
576 @param RecordData RecordData buffer will be filled.\r
577 @param RecordDataSize The size of RecordData buffer.\r
578 \r
579 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
580 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
581**/\r
582EFI_STATUS\r
583SmbiosFldBase2ToByteWith64K (\r
584 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
585 IN UINT32 Offset,\r
586 IN VOID *RecordData,\r
587 IN UINT32 RecordDataSize\r
588 )\r
589{\r
590 EFI_EXP_BASE2_DATA *Base2Data;\r
591 UINT16 Value;\r
592 UINT16 Exponent;\r
593\r
594 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {\r
595 return EFI_INVALID_PARAMETER;\r
596 }\r
597\r
598 Base2Data = RecordData;\r
599 Value = Base2Data->Value;\r
600 Exponent = Base2Data->Exponent;\r
601 Exponent -= 16;\r
602 Value <<= Exponent;\r
603\r
604 CopyMem (\r
605 (UINT8 *) (StructureNode->Structure) + Offset,\r
606 &Value,\r
607 1\r
608 );\r
609\r
610 return EFI_SUCCESS;\r
611}\r
612\r
613/**\r
614 Field Filling Function. Transform an EFI_EXP_BASE2_DATA to a word, with 10exp-9\r
615 as the unit.\r
616 \r
617 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
618 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
619 @param RecordData RecordData buffer will be filled.\r
620 @param RecordDataSize The size of RecordData buffer.\r
621 \r
622 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
623 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
624**/\r
625EFI_STATUS\r
626SmbiosFldBase10ToByteWithNano (\r
627 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
628 IN UINT32 Offset,\r
629 IN VOID *RecordData,\r
630 IN UINT32 RecordDataSize\r
631 )\r
632{\r
633 EFI_EXP_BASE10_DATA *Base10Data;\r
634 INT16 Value;\r
635 INT16 Exponent;\r
636\r
637 if (RecordDataSize != sizeof (EFI_EXP_BASE2_DATA)) {\r
638 return EFI_INVALID_PARAMETER;\r
639 }\r
640\r
641 Base10Data = RecordData;\r
642 Value = Base10Data->Value;\r
643 Exponent = Base10Data->Exponent;\r
644\r
645 Exponent += 9;\r
646 while (Exponent != 0) {\r
647 if (Exponent > 0) {\r
648 Value = (INT16) (Value * 10);\r
649 Exponent--;\r
650 } else {\r
651 Value = (INT16) (Value / 10);\r
652 Exponent++;\r
653 }\r
654 }\r
655\r
656 * (UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) Value;\r
657\r
658 return EFI_SUCCESS;\r
659}\r
660\r
661/**\r
662 Field Filling Function: truncate record data to byte and fill in the\r
663 field as indicated by Offset.\r
664 \r
665 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
666 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
667 @param RecordData RecordData buffer will be filled.\r
668 @param RecordDataSize The size of RecordData buffer.\r
669 \r
670 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
671 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
672**/\r
673EFI_STATUS\r
674SmbiosFldTruncateToByte (\r
675 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
676 IN UINT32 Offset,\r
677 IN VOID *RecordData,\r
678 IN UINT32 RecordDataSize\r
679 )\r
680{\r
681 EFI_STATUS Status;\r
682\r
683 Status = EFI_SUCCESS;\r
684\r
685 //\r
686 // Truncate the data to 8 bits\r
687 //\r
688 *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + Offset) = (UINT8) (*(UINT8 *) RecordData);\r
689\r
690 return Status;\r
691}\r
692\r
693/**\r
694 Field Filling Function: truncate record data to byte and fill in the\r
695 field as indicated by Offset.\r
696 \r
697 @param StructureNode Pointer to SMBIOS_STRUCTURE_NODE which is current processed.\r
698 @param Offset Offset of SMBIOS record which RecordData will be filled.\r
699 @param RecordData RecordData buffer will be filled.\r
700 @param RecordDataSize The size of RecordData buffer.\r
701 \r
702 @retval EFI_INVALID_PARAMETER RecordDataSize is invalid. \r
703 @retval EFI_SUCCESS RecordData is successed to be filled into given SMBIOS record.\r
704**/\r
705EFI_STATUS\r
706SmbiosFldTruncateToWord (\r
707 IN OUT SMBIOS_STRUCTURE_NODE *StructureNode,\r
708 IN UINT32 Offset,\r
709 IN VOID *RecordData,\r
710 IN UINT32 RecordDataSize\r
711 )\r
712{\r
713 EFI_STATUS Status;\r
714\r
715 Status = EFI_SUCCESS;\r
716\r
717 //\r
718 // Truncate the data to 8 bits\r
719 //\r
720 CopyMem (\r
721 (UINT8 *) (StructureNode->Structure) + Offset,\r
722 RecordData,\r
723 2\r
724 );\r
725\r
726 return Status;\r
727}\r
728\r
729/**\r
730 Check if OEM structure has included 2 trailing 0s in data record.\r
731 \r
732 @param RecordData Point to record data will be checked.\r
733 @param RecordDataSize The size of record data.\r
734 \r
735 @retval 0 2 trailing 0s exist in unformatted section\r
736 @retval 1 1 trailing 0 exists at the end of unformatted section\r
737 @retval -1 There is no 0 at the end of unformatted section\r
738**/\r
739INT8\r
740SmbiosCheckTrailingZero (\r
741 IN VOID *RecordData,\r
742 IN UINT32 RecordDataSize\r
743 )\r
744{\r
745 SMBIOS_STRUCTURE *Smbios;\r
746 CHAR8 *Start;\r
747 CHAR8 *End;\r
748 \r
749 Smbios = (SMBIOS_STRUCTURE *) RecordData;\r
750 \r
751 //\r
752 // Skip over formatted section\r
753 //\r
754 Start = (CHAR8 *) ((UINT8 *) Smbios + Smbios->Length);\r
755 End = (CHAR8 *) RecordData + RecordDataSize;\r
756 \r
757 //\r
758 // Unformatted section exists\r
759 //\r
760 while (Start < End - 1) {\r
761 //\r
762 // Avoid unaligned issue on IPF\r
763 //\r
764 if ((*Start == 0) && (*(Start + 1) == 0)) {\r
765 //\r
766 // 2 trailing 0s exist in unformatted section\r
767 //\r
768 return 0;\r
769 }\r
770 Start++;\r
771 }\r
772 \r
773 if (Start == End - 1) {\r
774 //\r
775 // Check if there has been already 1 trailing 0\r
776 //\r
777 if (*Start == 0) {\r
778 return 1;\r
779 } \r
780 }\r
781 \r
782 //\r
783 // There is no 0 at the end of unformatted section\r
784 //\r
785 return -1;\r
786}\r