Home | History | Annotate | Download | only in PiSmbiosRecordOnDataHubSmbiosRecordThunk
      1 /** @file
      2   Routines that support Memory SubClass data records translation.
      3 
      4 Copyright (c) 2009, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "Thunk.h"
     16 
     17 /**
     18   Field Filling Function for Memory SubClass record type 2 -- Physical Memory
     19   Array.
     20 
     21   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
     22   @param Offset           Offset of SMBIOS record which RecordData will be filled.
     23   @param RecordData       RecordData buffer will be filled.
     24   @param RecordDataSize   The size of RecordData buffer.
     25 
     26   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
     27 **/
     28 EFI_STATUS
     29 SmbiosFldMemoryType2 (
     30   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
     31   IN      UINT32                    Offset,
     32   IN      VOID                      *RecordData,
     33   IN      UINT32                    RecordDataSize
     34   )
     35 {
     36   EFI_STATUS                            Status;
     37   EFI_MEMORY_ARRAY_LOCATION_DATA        *PhyMemArray;
     38   FRAMEWORK_MEMORY_ARRAY_LOCATION_DATA  *FrameworkPhyMemArray;
     39   UINT32                                MemoryCapacity;
     40   UINT16                                NumberMemoryDevices;
     41   UINT16                                Test16;
     42 
     43   Status      = EFI_SUCCESS;
     44   PhyMemArray = (EFI_MEMORY_ARRAY_LOCATION_DATA *) RecordData;
     45   FrameworkPhyMemArray = (FRAMEWORK_MEMORY_ARRAY_LOCATION_DATA *) RecordData;
     46 
     47   *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, Location))  = (UINT8) (PhyMemArray->MemoryArrayLocation);
     48   *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, Use))  = (UINT8) (PhyMemArray->MemoryArrayUse);
     49   *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, MemoryErrorCorrection))  = (UINT8) (PhyMemArray->MemoryErrorCorrection);
     50 
     51   if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
     52     MemoryCapacity = (UINT32) (((UINTN) PhyMemArray->MaximumMemoryCapacity.Value) << PhyMemArray->MaximumMemoryCapacity.Exponent);
     53     NumberMemoryDevices = PhyMemArray->NumberMemoryDevices;
     54   } else {
     55     //
     56     // Support EDk/Framework defined Data strucutre.
     57     //
     58     MemoryCapacity      = FrameworkPhyMemArray->MaximumMemoryCapacity;
     59     NumberMemoryDevices = FrameworkPhyMemArray->NumberMemoryDevices;
     60   }
     61 
     62   CopyMem (
     63     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE16, MaximumCapacity),
     64     &MemoryCapacity,
     65     4
     66     );
     67 
     68   Test16 = 0xfffe;
     69   CopyMem (
     70     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, MemoryErrorInformationHandle),
     71     &Test16,
     72     2
     73     );
     74 
     75   CopyMem (
     76     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE16, NumberOfMemoryDevices),
     77     &NumberMemoryDevices,
     78     2
     79     );
     80 
     81   return Status;
     82 }
     83 
     84 /**
     85   Field Filling Function for Memory SubClass record type 3 -
     86   - Memory Device: SMBIOS Type 17
     87 
     88   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
     89   @param Offset           Offset of SMBIOS record which RecordData will be filled.
     90   @param RecordData       RecordData buffer will be filled.
     91   @param RecordDataSize   The size of RecordData buffer.
     92 
     93   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
     94 **/
     95 EFI_STATUS
     96 SmbiosFldMemoryType3 (
     97   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
     98   IN      UINT32                    Offset,
     99   IN      VOID                      *RecordData,
    100   IN      UINT32                    RecordDataSize
    101   )
    102 {
    103   EFI_MEMORY_ARRAY_LINK_DATA       *MemDevice;
    104   FRAMEWORK_MEMORY_ARRAY_LINK_DATA *FrameworkMemDevice;
    105   UINT64                           MemoryDeviceSize;
    106   BOOLEAN                          MemoryDeviceSizeUnitMega;
    107   UINT16                           MemoryDeviceSpeed;
    108   UINT16                           MemoryDeviceExponent;
    109   UINT16                           Test16;
    110 
    111   MemDevice = (EFI_MEMORY_ARRAY_LINK_DATA *) RecordData;
    112   FrameworkMemDevice = (FRAMEWORK_MEMORY_ARRAY_LINK_DATA *) RecordData;
    113   MemoryDeviceSpeed  = 0;
    114   MemoryDeviceExponent = 0;
    115 
    116   //
    117   // Memory Device Locator
    118   //
    119   SmbiosFldString (
    120     StructureNode,
    121     OFFSET_OF (SMBIOS_TABLE_TYPE17, DeviceLocator),
    122     &(MemDevice->MemoryDeviceLocator),
    123     sizeof (STRING_REF)
    124     );
    125 
    126   //
    127   // Memory Bank Locator
    128   //
    129   SmbiosFldString (
    130     StructureNode,
    131     OFFSET_OF (SMBIOS_TABLE_TYPE17, BankLocator),
    132     &(MemDevice->MemoryBankLocator),
    133     sizeof (STRING_REF)
    134     );
    135 
    136   //
    137   // Memory Manufacturer
    138   //
    139   SmbiosFldString (
    140     StructureNode,
    141     OFFSET_OF (SMBIOS_TABLE_TYPE17, Manufacturer),
    142     &(MemDevice->MemoryManufacturer),
    143     sizeof (STRING_REF)
    144     );
    145 
    146   //
    147   // Memory Serial Number
    148   //
    149   SmbiosFldString (
    150     StructureNode,
    151     OFFSET_OF (SMBIOS_TABLE_TYPE17, SerialNumber),
    152     &(MemDevice->MemorySerialNumber),
    153     sizeof (STRING_REF)
    154     );
    155 
    156   //
    157   // Memory Asset Tag
    158   //
    159   SmbiosFldString (
    160     StructureNode,
    161     OFFSET_OF (SMBIOS_TABLE_TYPE17, AssetTag),
    162     &(MemDevice->MemoryAssetTag),
    163     sizeof (STRING_REF)
    164     );
    165 
    166   //
    167   // Memory Part Number
    168   //
    169   SmbiosFldString (
    170     StructureNode,
    171     OFFSET_OF (SMBIOS_TABLE_TYPE17, PartNumber),
    172     &(MemDevice->MemoryPartNumber),
    173     sizeof (STRING_REF)
    174     );
    175 
    176   //
    177   // Memory Array Link
    178   //
    179   SmbiosFldInterLink (
    180     StructureNode,
    181     (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryArrayHandle),
    182     16, // SMBIOS type 16
    183     &MemDevice->MemoryArrayLink,
    184     &gEfiMemorySubClassGuid
    185     );
    186 
    187   //
    188   // Set Memory Error Information Handle to Not supported
    189   //
    190   Test16 = 0xfffe;
    191   CopyMem (
    192     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryErrorInformationHandle),
    193     &Test16,
    194     sizeof (EFI_SMBIOS_HANDLE)
    195     );
    196 
    197   //
    198   // Total width
    199   //
    200   CopyMem (
    201     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, TotalWidth),
    202     &MemDevice->MemoryTotalWidth,
    203     2
    204     );
    205 
    206   //
    207   // Data Width
    208   //
    209   CopyMem (
    210     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, DataWidth),
    211     &MemDevice->MemoryDataWidth,
    212     2
    213     );
    214 
    215   //
    216   // Device Size
    217   //
    218   if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
    219     //
    220     // Form Factor
    221     //
    222     CopyMem (
    223       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, FormFactor),
    224       &MemDevice->MemoryFormFactor,
    225       1
    226       );
    227 
    228     //
    229     // Device Set
    230     //
    231     CopyMem (
    232       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, DeviceSet),
    233       &MemDevice->MemoryDeviceSet,
    234       1
    235       );
    236 
    237     //
    238     // Type
    239     //
    240     CopyMem (
    241       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryType),
    242       &MemDevice->MemoryType,
    243       1
    244       );
    245 
    246     //
    247     // Type Detail
    248     //
    249     CopyMem (
    250       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, TypeDetail),
    251       &MemDevice->MemoryTypeDetail,
    252       2
    253       );
    254 
    255     //
    256     // Speed
    257     //
    258     MemoryDeviceSpeed    = MemDevice->MemorySpeed.Value;
    259     MemoryDeviceExponent = MemDevice->MemorySpeed.Exponent;
    260     while (MemoryDeviceExponent-- > 0) {
    261       MemoryDeviceSpeed = (UINT16) (MemoryDeviceSpeed * 10);
    262     }
    263 
    264     CopyMem (
    265       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, Speed),
    266       &MemoryDeviceSpeed,
    267       2
    268       );
    269 
    270     MemoryDeviceSize = (UINT64) (((UINTN) MemDevice->MemoryDeviceSize.Value) << MemDevice->MemoryDeviceSize.Exponent);
    271   } else {
    272     //
    273     // Form Factor
    274     //
    275     CopyMem (
    276       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, FormFactor),
    277       &FrameworkMemDevice->MemoryFormFactor,
    278       1
    279       );
    280 
    281     //
    282     // Device Set
    283     //
    284     CopyMem (
    285       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, DeviceSet),
    286       &FrameworkMemDevice->MemoryDeviceSet,
    287       1
    288       );
    289 
    290     //
    291     // Type
    292     //
    293     CopyMem (
    294       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, MemoryType),
    295       &FrameworkMemDevice->MemoryType,
    296       1
    297       );
    298 
    299     //
    300     // Type Detail
    301     //
    302     CopyMem (
    303       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, TypeDetail),
    304       &FrameworkMemDevice->MemoryTypeDetail,
    305       2
    306       );
    307 
    308     //
    309     // Speed
    310     //
    311     CopyMem (
    312       (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, Speed),
    313       &FrameworkMemDevice->MemorySpeed,
    314       2
    315       );
    316 
    317     MemoryDeviceSize = FrameworkMemDevice->MemoryDeviceSize;
    318   }
    319 
    320   MemoryDeviceSizeUnitMega  = FALSE;
    321   MemoryDeviceSize          = RShiftU64 (MemoryDeviceSize, 10);
    322   //
    323   // kilo as unit
    324   //
    325   if (MemoryDeviceSize > 0xffff) {
    326     MemoryDeviceSize = RShiftU64 (MemoryDeviceSize, 10);
    327     //
    328     // Mega as unit
    329     //
    330     MemoryDeviceSizeUnitMega = TRUE;
    331   }
    332 
    333   MemoryDeviceSize = MemoryDeviceSize & 0x7fff;
    334   if (MemoryDeviceSize != 0 && !MemoryDeviceSizeUnitMega) {
    335     MemoryDeviceSize |= 0x8000;
    336   }
    337 
    338   CopyMem (
    339     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE17, Size),
    340     &MemoryDeviceSize,
    341     2
    342     );
    343 
    344   return EFI_SUCCESS;
    345 }
    346 
    347 /**
    348   Field Filling Function for Memory SubClass record type 3 -
    349   - Memory Device: SMBIOS Type 6
    350 
    351   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
    352   @param Offset           Offset of SMBIOS record which RecordData will be filled.
    353   @param RecordData       RecordData buffer will be filled.
    354   @param RecordDataSize   The size of RecordData buffer.
    355 
    356   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
    357 **/
    358 EFI_STATUS
    359 SmbiosFldSMBIOSType6 (
    360   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
    361   IN      UINT32                    Offset,
    362   IN      VOID                      *RecordData,
    363   IN      UINT32                    RecordDataSize
    364   )
    365 {
    366   EFI_MEMORY_ARRAY_LINK_DATA       *MemDevice;
    367   UINT64                           MemoryDeviceSize;
    368   UINT8                            MemSize;
    369   UINT16                           MemType;
    370   UINT8                            MemSpeed;
    371   FRAMEWORK_MEMORY_ARRAY_LINK_DATA *FrameworkMemDevice;
    372   UINT16                           MemoryDeviceSpeed;
    373   UINT16                           MemoryDeviceExponent;
    374 
    375   MemDevice            = (EFI_MEMORY_ARRAY_LINK_DATA *) RecordData;
    376   FrameworkMemDevice   = (FRAMEWORK_MEMORY_ARRAY_LINK_DATA *) RecordData;
    377   MemoryDeviceExponent = 0;
    378 
    379   //
    380   // Memory Device Locator
    381   //
    382   SmbiosFldString (
    383     StructureNode,
    384     OFFSET_OF (SMBIOS_TABLE_TYPE6, SocketDesignation),
    385     &(MemDevice->MemoryDeviceLocator),
    386     2
    387     );
    388 
    389   if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
    390     MemoryDeviceSpeed    = MemDevice->MemorySpeed.Value;
    391     MemoryDeviceExponent = MemDevice->MemorySpeed.Exponent;
    392     while (MemoryDeviceExponent-- > 0) {
    393       MemoryDeviceSpeed = (UINT16) (MemoryDeviceSpeed * 10);
    394     }
    395     MemoryDeviceSize = (UINT64) (((UINTN) MemDevice->MemoryDeviceSize.Value) << MemDevice->MemoryDeviceSize.Exponent);
    396   } else {
    397     //
    398     // Support EDk/Framework defined Data strucutre.
    399     //
    400     MemoryDeviceSpeed = FrameworkMemDevice->MemorySpeed;
    401     MemoryDeviceSize  = FrameworkMemDevice->MemoryDeviceSize;
    402   }
    403 
    404   if (MemoryDeviceSpeed == 0) {
    405     MemSpeed = 0;
    406   } else {
    407     //
    408     // Memory speed is in ns unit
    409     //
    410     MemSpeed = (UINT8)(1000 / MemoryDeviceSpeed);
    411   }
    412 
    413   CopyMem (
    414    (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, CurrentSpeed),
    415    &MemSpeed,
    416    1
    417   );
    418 
    419 
    420   //
    421   // Device Size
    422   //
    423   MemSize = 0;
    424   if (MemoryDeviceSize == 0) {
    425     MemSize = 0x7F;
    426   } else {
    427     MemoryDeviceSize = RShiftU64 (MemoryDeviceSize, 21);
    428     while (MemoryDeviceSize != 0) {
    429       MemSize++;
    430       MemoryDeviceSize = RShiftU64(MemoryDeviceSize,1);
    431     }
    432   }
    433 
    434   CopyMem (
    435     (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, InstalledSize),
    436     &MemSize,
    437     1
    438     );
    439 
    440   CopyMem (
    441     (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, EnabledSize),
    442     &MemSize,
    443     1
    444     );
    445 
    446   //
    447   // According SMBIOS SPEC Type 6 definition
    448   //
    449   MemType = 0;
    450   if (!FeaturePcdGet(PcdFrameworkCompatibilitySupport)) {
    451     if (MemDevice->MemoryFormFactor == EfiMemoryFormFactorDimm ||
    452         MemDevice->MemoryFormFactor == EfiMemoryFormFactorFbDimm) {
    453       MemType |= 1<<8;
    454     }
    455 
    456     if (MemDevice->MemoryFormFactor == EfiMemoryFormFactorSimm) {
    457       MemType |= 1<<7;
    458     }
    459 
    460     if (MemDevice->MemoryType == EfiMemoryTypeSdram) {
    461       MemType |= 1<<10;
    462     }
    463 
    464     if (MemDevice->MemoryTypeDetail.Edo == 1) {
    465       MemType |= 1<<4;
    466     }
    467 
    468     if (MemDevice->MemoryTypeDetail.FastPaged == 1) {
    469       MemType |= 1<<3;
    470     }
    471   } else {
    472     //
    473     // Support EDk/Framework defined Data strucutre.
    474     //
    475     if (FrameworkMemDevice->MemoryFormFactor == EfiMemoryFormFactorDimm ||
    476         FrameworkMemDevice->MemoryFormFactor == EfiMemoryFormFactorFbDimm) {
    477       MemType |= 1<<8;
    478     }
    479 
    480     if (FrameworkMemDevice->MemoryFormFactor == EfiMemoryFormFactorSimm) {
    481       MemType |= 1<<7;
    482     }
    483 
    484     if (FrameworkMemDevice->MemoryType == EfiMemoryTypeSdram) {
    485       MemType |= 1<<10;
    486     }
    487 
    488     if (FrameworkMemDevice->MemoryTypeDetail.Edo == 1) {
    489       MemType |= 1<<4;
    490     }
    491 
    492     if (FrameworkMemDevice->MemoryTypeDetail.FastPaged == 1) {
    493       MemType |= 1<<3;
    494     }
    495   }
    496   //
    497   // Form Factor
    498   //
    499   CopyMem (
    500     (UINT8*)StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE6, CurrentMemoryType),
    501     &MemType,
    502     2
    503     );
    504 
    505 
    506   return EFI_SUCCESS;
    507 }
    508 
    509 /**
    510   Field Filling Function for Memory SubClass record type 4
    511   -- Memory Array Mapped Address: SMBIOS Type 19
    512 
    513   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
    514   @param Offset           Offset of SMBIOS record which RecordData will be filled.
    515   @param RecordData       RecordData buffer will be filled.
    516   @param RecordDataSize   The size of RecordData buffer.
    517 
    518   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
    519 **/
    520 EFI_STATUS
    521 SmbiosFldMemoryType4 (
    522   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
    523   IN      UINT32                    Offset,
    524   IN      VOID                      *RecordData,
    525   IN      UINT32                    RecordDataSize
    526   )
    527 {
    528   EFI_MEMORY_ARRAY_START_ADDRESS_DATA  *Masa;
    529   EFI_PHYSICAL_ADDRESS                 TempData;
    530 
    531   Masa = (EFI_MEMORY_ARRAY_START_ADDRESS_DATA *) RecordData;
    532 
    533   //
    534   // Starting Address
    535   //
    536   TempData = RShiftU64 (Masa->MemoryArrayStartAddress, 10);
    537   CopyMem (
    538     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE19, StartingAddress),
    539     &TempData,
    540     4
    541     );
    542 
    543   //
    544   // Ending Address
    545   //
    546   TempData = RShiftU64 (Masa->MemoryArrayEndAddress, 10);
    547   CopyMem (
    548     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE19, EndingAddress),
    549     &TempData,
    550     4
    551     );
    552 
    553   //
    554   // Partition Width
    555   //
    556   CopyMem (
    557     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE19, PartitionWidth),
    558     &Masa->MemoryArrayPartitionWidth,
    559     1
    560     );
    561 
    562   //
    563   // Physical Memory Array Link
    564   //
    565   return SmbiosFldInterLink (
    566           StructureNode,
    567           (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE19, MemoryArrayHandle),
    568           16, // SMBIOS type 16
    569           &Masa->PhysicalMemoryArrayLink,
    570           &gEfiMemorySubClassGuid
    571           );
    572 
    573 }
    574 
    575 /**
    576   Field Filling Function for Memory SubClass record type 5
    577   -- Memory Device Mapped Address: SMBIOS Type 20
    578 
    579   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
    580   @param Offset           Offset of SMBIOS record which RecordData will be filled.
    581   @param RecordData       RecordData buffer will be filled.
    582   @param RecordDataSize   The size of RecordData buffer.
    583 
    584   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
    585 **/
    586 EFI_STATUS
    587 SmbiosFldMemoryType5 (
    588   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
    589   IN      UINT32                    Offset,
    590   IN      VOID                      *RecordData,
    591   IN      UINT32                    RecordDataSize
    592   )
    593 {
    594   EFI_MEMORY_DEVICE_START_ADDRESS_DATA *Mdsa;
    595   EFI_PHYSICAL_ADDRESS                 TempData;
    596 
    597   Mdsa = (EFI_MEMORY_DEVICE_START_ADDRESS_DATA *) RecordData;
    598 
    599   //
    600   // Starting Address
    601   //
    602   TempData = RShiftU64 (Mdsa->MemoryDeviceStartAddress, 10);
    603   CopyMem (
    604     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, StartingAddress),
    605     &TempData,
    606     4
    607     );
    608 
    609   //
    610   // Ending Address
    611   //
    612   TempData = RShiftU64 (Mdsa->MemoryDeviceEndAddress, 10);
    613   CopyMem (
    614     (UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, EndingAddress),
    615     &TempData,
    616     4
    617     );
    618 
    619   //
    620   // Memory Device Link
    621   //
    622   SmbiosFldInterLink (
    623     StructureNode,
    624     (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE20, MemoryDeviceHandle),
    625     17, // SMBIOS type 17
    626     &Mdsa->PhysicalMemoryDeviceLink,
    627     &gEfiMemorySubClassGuid
    628     );
    629 
    630   //
    631   // Memory Array Mapped Address Link
    632   //
    633   SmbiosFldInterLink (
    634     StructureNode,
    635     (UINT16) OFFSET_OF (SMBIOS_TABLE_TYPE20, MemoryArrayMappedAddressHandle),
    636     19, // SMBIOS type 19
    637     &Mdsa->PhysicalMemoryArrayLink,
    638     &gEfiMemorySubClassGuid
    639     );
    640 
    641   //
    642   // Memory Device Partition Row Position
    643   //
    644   *(UINT8 *) ((UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, PartitionRowPosition)) = (UINT8) Mdsa->MemoryDevicePartitionRowPosition;
    645 
    646   //
    647   // Memory Device Interleave Position
    648   //
    649   *(UINT8 *) ((UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, InterleavePosition)) = (UINT8) Mdsa->MemoryDeviceInterleavePosition;
    650 
    651   //
    652   // Memory Device Interleave Data Depth
    653   //
    654   *(UINT8 *) ((UINT8 *) StructureNode->Structure + OFFSET_OF (SMBIOS_TABLE_TYPE20, InterleavedDataDepth)) = (UINT8) Mdsa->MemoryDeviceInterleaveDataDepth;
    655 
    656   return EFI_SUCCESS;
    657 }
    658 
    659 /**
    660   Field Filling Function for Memory SubClass record type 6
    661   -- Memory Channel Type: SMBIOS Type 37
    662 
    663   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
    664   @param Offset           Offset of SMBIOS record which RecordData will be filled.
    665   @param RecordData       RecordData buffer will be filled.
    666   @param RecordDataSize   The size of RecordData buffer.
    667 
    668   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
    669 **/
    670 EFI_STATUS
    671 SmbiosFldMemoryType6 (
    672   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
    673   IN      UINT32                    Offset,
    674   IN      VOID                      *RecordData,
    675   IN      UINT32                    RecordDataSize
    676   )
    677 {
    678   EFI_MEMORY_CHANNEL_TYPE_DATA  *McTa;
    679   EFI_STATUS                    Status;
    680 
    681   McTa  = (EFI_MEMORY_CHANNEL_TYPE_DATA *) RecordData;
    682 
    683   *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE37, ChannelType))  = (UINT8) (McTa->MemoryChannelType);
    684 
    685   *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE37, MaximumChannelLoad))  = (UINT8) (McTa->MemoryChannelMaximumLoad);
    686 
    687   *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE37, MemoryDeviceCount))  = (UINT8) (McTa->MemoryChannelDeviceCount);
    688 
    689   //
    690   // Update the length field
    691   // Multiple device loads are filled through SmbiosFldMemoryType7
    692   //
    693   StructureNode->Structure->Length = (UINT8)(StructureNode->Structure->Length +
    694                                        sizeof(MEMORY_DEVICE) * McTa->MemoryChannelDeviceCount);
    695   Status = SmbiosEnlargeStructureBuffer(
    696              StructureNode,
    697              StructureNode->Structure->Length,
    698              StructureNode->StructureSize,
    699              StructureNode->StructureSize + sizeof(MEMORY_DEVICE) * McTa->MemoryChannelDeviceCount
    700              );
    701   return Status;
    702 }
    703 
    704 /**
    705   Field Filling Function for Memory SubClass record type 7
    706   -- Memory Channel Device: SMBIOS Type 37
    707 
    708   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
    709   @param Offset           Offset of SMBIOS record which RecordData will be filled.
    710   @param RecordData       RecordData buffer will be filled.
    711   @param RecordDataSize   The size of RecordData buffer.
    712 
    713   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
    714 **/
    715 EFI_STATUS
    716 SmbiosFldMemoryType7 (
    717   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
    718   IN      UINT32                    Offset,
    719   IN      VOID                      *RecordData,
    720   IN      UINT32                    RecordDataSize
    721   )
    722 {
    723   EFI_MEMORY_CHANNEL_DEVICE_DATA  *Mcdd;
    724   UINTN                           DeviceLoadOffset;
    725   UINTN                           DeviceLoadHandleOffset;
    726 
    727   Mcdd = (EFI_MEMORY_CHANNEL_DEVICE_DATA *) RecordData;
    728 
    729   if (Mcdd->DeviceId < 1) {
    730     return EFI_INVALID_PARAMETER;
    731   }
    732 
    733   DeviceLoadOffset        = OFFSET_OF (SMBIOS_TABLE_TYPE37, MemoryDevice[0]) + 3 * (Mcdd->DeviceId - 1);
    734   DeviceLoadHandleOffset  = OFFSET_OF (SMBIOS_TABLE_TYPE37, MemoryDevice[1]) + 3 * (Mcdd->DeviceId - 1);
    735 
    736   *(UINT8 *) ((UINT8 *) (StructureNode->Structure) + DeviceLoadOffset) = (UINT8) (Mcdd->MemoryChannelDeviceLoad);
    737 
    738   //
    739   // Memory Device Handle Link
    740   //
    741   return SmbiosFldInterLink (
    742           StructureNode,
    743           (UINT16) DeviceLoadHandleOffset,
    744           17, // Smbios type 17 -- Physical Memory Device
    745           &Mcdd->DeviceLink,
    746           &gEfiMemorySubClassGuid
    747           );
    748 
    749 }
    750 
    751 /**
    752   Field Filling Function for Memory SubClass record type 8
    753   -- Memory Controller information: SMBIOS Type 5
    754 
    755   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
    756   @param Offset           Offset of SMBIOS record which RecordData will be filled.
    757   @param RecordData       RecordData buffer will be filled.
    758   @param RecordDataSize   The size of RecordData buffer.
    759 
    760   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
    761 **/
    762 EFI_STATUS
    763 SmbiosFldMemoryType8 (
    764   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
    765   IN      UINT32                    Offset,
    766   IN      VOID                      *RecordData,
    767   IN      UINT32                    RecordDataSize
    768   )
    769 {
    770   EFI_MEMORY_CONTROLLER_INFORMATION_DATA *MemoryController;
    771   UINT32                                 NewMinimalSize;
    772   UINT16                                 Count;
    773   EFI_INTER_LINK_DATA                    *Link;
    774   EFI_STATUS                             Status;
    775 
    776   NewMinimalSize   = 0;
    777 
    778   //
    779   // There is an update from EFI_MEMORY_CONTROLLER_INFORMATION to
    780   // EFI_MEMORY_CONTROLLER_INFORMATION_DATA. Multiple MemoryModuleConfig
    781   // handles are filled.
    782   //
    783   MemoryController = (EFI_MEMORY_CONTROLLER_INFORMATION_DATA *)RecordData;
    784 
    785   //
    786   // ErrorDetectingMethod
    787   //
    788   CopyMem (
    789     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, ErrDetectMethod),
    790     &MemoryController->ErrorDetectingMethod,
    791     1
    792     );
    793 
    794   //
    795   // ErrorCorrectingCapability
    796   //
    797   CopyMem (
    798     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, ErrCorrectCapability),
    799     &MemoryController->ErrorCorrectingCapability,
    800     1
    801     );
    802 
    803   //
    804   // MemorySupportedInterleave
    805   //
    806   CopyMem (
    807     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, SupportInterleave),
    808     &MemoryController->MemorySupportedInterleave,
    809     1
    810     );
    811 
    812   //
    813   // MemoryCurrentInterleave
    814   //
    815   CopyMem (
    816     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, CurrentInterleave),
    817     &MemoryController->MemoryCurrentInterleave,
    818     1
    819     );
    820 
    821   //
    822   // MaxMemoryModuleSize
    823   //
    824   CopyMem (
    825     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MaxMemoryModuleSize),
    826     &MemoryController->MaxMemoryModuleSize,
    827     1
    828     );
    829 
    830   //
    831   // MemorySpeedType
    832   //
    833   CopyMem (
    834     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, SupportSpeed),
    835     &MemoryController->MemorySpeedType,
    836     2
    837     );
    838 
    839   //
    840   // MemorySupportedType
    841   //
    842   CopyMem (
    843     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, SupportMemoryType),
    844     &MemoryController->MemorySupportedType,
    845     2
    846     );
    847 
    848   //
    849   // MemoryModuleVoltage
    850   //
    851   CopyMem (
    852     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleVoltage),
    853     &MemoryController->MemoryModuleVoltage,
    854     1
    855     );
    856 
    857   //
    858   // NumberofMemorySlot
    859   //
    860   CopyMem (
    861     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, AssociatedMemorySlotNum),
    862     &MemoryController->NumberofMemorySlot,
    863     1
    864     );
    865 
    866   if (MemoryController->NumberofMemorySlot == 0) {
    867     //
    868     // EnabledCorrectingCapability
    869     //
    870     CopyMem (
    871       (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleConfigHandles),
    872       &MemoryController->EnabledCorrectingCapability,
    873       1
    874       );
    875   } else {
    876     //
    877     // Memory module configuration handles exist
    878     // we should enlarge smbios entry buffer from minimal size
    879     //
    880     NewMinimalSize = (MemoryController->NumberofMemorySlot) * sizeof(UINT16) + StructureNode->StructureSize;
    881     StructureNode->Structure->Length = (UINT8) (NewMinimalSize - 2);
    882     Status = SmbiosEnlargeStructureBuffer (StructureNode, StructureNode->Structure->Length, StructureNode->StructureSize, NewMinimalSize);
    883     ASSERT_EFI_ERROR (Status);
    884 
    885     //
    886     // MemoryModuleConfigHandles
    887     //
    888     for (Count = 0, Link = MemoryController->MemoryModuleConfig;
    889          Count < MemoryController->NumberofMemorySlot;
    890          Count++, Link++) {
    891       SmbiosFldInterLink (
    892         StructureNode,
    893         (UINT16) (OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleConfigHandles) + Count * sizeof(UINT16)),
    894         6, // SMBIOS type 6
    895         Link,
    896         &gEfiMemorySubClassGuid
    897         );
    898     }
    899 
    900     //
    901     // EnabledCorrectingCapability
    902     //
    903     CopyMem (
    904       (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE5, MemoryModuleConfigHandles) + (MemoryController->NumberofMemorySlot) * sizeof(UINT16),
    905       &MemoryController->EnabledCorrectingCapability,
    906       1
    907       );
    908   }
    909 
    910   return EFI_SUCCESS;
    911 }
    912 
    913 /**
    914   Field Filling Function for Memory SubClass record type
    915   -- Memory 32 Bit Error Information: SMBIOS Type 18
    916 
    917   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
    918   @param Offset           Offset of SMBIOS record which RecordData will be filled.
    919   @param RecordData       RecordData buffer will be filled.
    920   @param RecordDataSize   The size of RecordData buffer.
    921 
    922   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
    923 **/
    924 EFI_STATUS
    925 SmbiosFldMemoryType9 (
    926   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
    927   IN      UINT32                    Offset,
    928   IN      VOID                      *RecordData,
    929   IN      UINT32                    RecordDataSize
    930   )
    931 {
    932   EFI_MEMORY_32BIT_ERROR_INFORMATION *MemoryInfo;
    933 
    934   MemoryInfo = (EFI_MEMORY_32BIT_ERROR_INFORMATION *)RecordData;
    935 
    936   //
    937   // MemoryErrorType
    938   //
    939   CopyMem (
    940     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorType),
    941     &MemoryInfo->MemoryErrorType,
    942     1
    943     );
    944 
    945   //
    946   // MemoryErrorGranularity
    947   //
    948   CopyMem (
    949     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorGranularity),
    950     &MemoryInfo->MemoryErrorGranularity,
    951     1
    952     );
    953 
    954   //
    955   // MemoryErrorOperation
    956   //
    957   CopyMem (
    958     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorOperation),
    959     &MemoryInfo->MemoryErrorOperation,
    960     1
    961     );
    962 
    963   //
    964   // VendorSyndrome
    965   //
    966   CopyMem (
    967     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, VendorSyndrome),
    968     &MemoryInfo->VendorSyndrome,
    969     4
    970     );
    971 
    972   //
    973   // MemoryArrayErrorAddress
    974   //
    975   CopyMem (
    976     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, MemoryArrayErrorAddress),
    977     &MemoryInfo->MemoryArrayErrorAddress,
    978     4
    979     );
    980 
    981   //
    982   // DeviceErrorAddress
    983   //
    984   CopyMem (
    985     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, DeviceErrorAddress),
    986     &MemoryInfo->DeviceErrorAddress,
    987     4
    988     );
    989 
    990   //
    991   // DeviceErrorResolution
    992   //
    993   CopyMem (
    994     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE18, ErrorResolution),
    995     &MemoryInfo->DeviceErrorResolution,
    996     4
    997     );
    998 
    999   return EFI_SUCCESS;
   1000 }
   1001 
   1002 /**
   1003   Field Filling Function for Memory SubClass record type
   1004   -- Memory 64 Bit Error Information: SMBIOS Type 33
   1005 
   1006   @param StructureNode    Pointer to SMBIOS_STRUCTURE_NODE which is current processed.
   1007   @param Offset           Offset of SMBIOS record which RecordData will be filled.
   1008   @param RecordData       RecordData buffer will be filled.
   1009   @param RecordDataSize   The size of RecordData buffer.
   1010 
   1011   @retval EFI_SUCCESS   Success fill RecordData into SMBIOS's record buffer.
   1012 **/
   1013 EFI_STATUS
   1014 SmbiosFldMemoryType10 (
   1015   IN OUT  SMBIOS_STRUCTURE_NODE     *StructureNode,
   1016   IN      UINT32                    Offset,
   1017   IN      VOID                      *RecordData,
   1018   IN      UINT32                    RecordDataSize
   1019   )
   1020 {
   1021   EFI_MEMORY_64BIT_ERROR_INFORMATION *MemoryInfo;
   1022 
   1023   MemoryInfo = (EFI_MEMORY_64BIT_ERROR_INFORMATION *)RecordData;
   1024 
   1025   //
   1026   // MemoryErrorType
   1027   //
   1028   CopyMem (
   1029     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorType),
   1030     &MemoryInfo->MemoryErrorType,
   1031     1
   1032     );
   1033 
   1034   //
   1035   // MemoryErrorGranularity
   1036   //
   1037   CopyMem (
   1038     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorGranularity),
   1039     &MemoryInfo->MemoryErrorGranularity,
   1040     1
   1041     );
   1042 
   1043   //
   1044   // MemoryErrorOperation
   1045   //
   1046   CopyMem (
   1047     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorOperation),
   1048     &MemoryInfo->MemoryErrorOperation,
   1049     1
   1050     );
   1051 
   1052   //
   1053   // VendorSyndrome
   1054   //
   1055   CopyMem (
   1056     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, VendorSyndrome),
   1057     &MemoryInfo->VendorSyndrome,
   1058     4
   1059     );
   1060 
   1061   //
   1062   // MemoryArrayErrorAddress
   1063   //
   1064   CopyMem (
   1065     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, MemoryArrayErrorAddress),
   1066     &MemoryInfo->MemoryArrayErrorAddress,
   1067     8
   1068     );
   1069 
   1070   //
   1071   // DeviceErrorAddress
   1072   //
   1073   CopyMem (
   1074     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, DeviceErrorAddress),
   1075     &MemoryInfo->DeviceErrorAddress,
   1076     8
   1077     );
   1078 
   1079   //
   1080   // DeviceErrorResolution
   1081   //
   1082   CopyMem (
   1083     (UINT8 *) (StructureNode->Structure) + OFFSET_OF (SMBIOS_TABLE_TYPE33, ErrorResolution),
   1084     &MemoryInfo->DeviceErrorResolution,
   1085     4
   1086     );
   1087 
   1088   return EFI_SUCCESS;
   1089 }
   1090