• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   This driver installs SMBIOS information for OVMF
3 
4   Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>
5   Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
6 
7   This program and the accompanying materials
8   are licensed and made available under the terms and conditions of the BSD License
9   which accompanies this distribution.  The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #include "SmbiosPlatformDxe.h"
18 
19 #define TYPE0_STRINGS \
20   "EFI Development Kit II / OVMF\0"     /* Vendor */ \
21   "0.0.0\0"                             /* BiosVersion */ \
22   "02/06/2015\0"                        /* BiosReleaseDate */
23 //
24 // Type definition and contents of the default Type 0 SMBIOS table.
25 //
26 #pragma pack(1)
27 typedef struct {
28   SMBIOS_TABLE_TYPE0 Base;
29   UINT8              Strings[sizeof(TYPE0_STRINGS)];
30 } OVMF_TYPE0;
31 #pragma pack()
32 
33 STATIC CONST OVMF_TYPE0 mOvmfDefaultType0 = {
34   {
35     // SMBIOS_STRUCTURE Hdr
36     {
37       EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
38       sizeof (SMBIOS_TABLE_TYPE0),      // UINT8 Length
39     },
40     1,     // SMBIOS_TABLE_STRING       Vendor
41     2,     // SMBIOS_TABLE_STRING       BiosVersion
42     0xE800,// UINT16                    BiosSegment
43     3,     // SMBIOS_TABLE_STRING       BiosReleaseDate
44     0,     // UINT8                     BiosSize
45     {      // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
46       0,     // Reserved                                      :2
47       0,     // Unknown                                       :1
48       1,     // BiosCharacteristicsNotSupported               :1
49              // Remaining BiosCharacteristics bits left unset :60
50     },
51     {      // BIOSCharacteristicsExtensionBytes[2]
52       0,     // BiosReserved
53       0x1C   // SystemReserved = VirtualMachineSupported |
54              //                  UefiSpecificationSupported |
55              //                  TargetContentDistributionEnabled
56     },
57     0,     // UINT8                     SystemBiosMajorRelease
58     0,     // UINT8                     SystemBiosMinorRelease
59     0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
60     0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
61   },
62   // Text strings (unformatted area)
63   TYPE0_STRINGS
64 };
65 
66 
67 /**
68   Get SMBIOS record length.
69 
70   @param  SmbiosTable   SMBIOS pointer.
71 
72 **/
73 UINTN
SmbiosTableLength(IN SMBIOS_STRUCTURE_POINTER SmbiosTable)74 SmbiosTableLength (
75   IN SMBIOS_STRUCTURE_POINTER SmbiosTable
76   )
77 {
78   CHAR8  *AChar;
79   UINTN  Length;
80 
81   AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);
82 
83   //
84   // Each structure shall be terminated by a double-null (SMBIOS spec.7.1)
85   //
86   while ((*AChar != 0) || (*(AChar + 1) != 0)) {
87     AChar ++;
88   }
89   Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);
90 
91   return Length;
92 }
93 
94 
95 /**
96   Install all structures from the given SMBIOS structures block
97 
98   @param  Smbios               SMBIOS protocol
99   @param  TableAddress         SMBIOS tables starting address
100 
101 **/
102 EFI_STATUS
InstallAllStructures(IN EFI_SMBIOS_PROTOCOL * Smbios,IN UINT8 * TableAddress)103 InstallAllStructures (
104   IN EFI_SMBIOS_PROTOCOL       *Smbios,
105   IN UINT8                     *TableAddress
106   )
107 {
108   EFI_STATUS                Status;
109   SMBIOS_STRUCTURE_POINTER  SmbiosTable;
110   EFI_SMBIOS_HANDLE         SmbiosHandle;
111   BOOLEAN                   NeedSmbiosType0;
112 
113   SmbiosTable.Raw = TableAddress;
114   if (SmbiosTable.Raw == NULL) {
115     return EFI_INVALID_PARAMETER;
116   }
117 
118   NeedSmbiosType0 = TRUE;
119 
120   while (SmbiosTable.Hdr->Type != 127) {
121     //
122     // Log the SMBIOS data for this structure
123     //
124     SmbiosHandle = SmbiosTable.Hdr->Handle;
125     Status = Smbios->Add (
126                        Smbios,
127                        NULL,
128                        &SmbiosHandle,
129                        (EFI_SMBIOS_TABLE_HEADER*) SmbiosTable.Raw
130                        );
131     ASSERT_EFI_ERROR (Status);
132 
133     if (SmbiosTable.Hdr->Type == 0) {
134       NeedSmbiosType0 = FALSE;
135     }
136 
137     //
138     // Get the next structure address
139     //
140     SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));
141   }
142 
143   if (NeedSmbiosType0) {
144     //
145     // Add OVMF default Type 0 (BIOS Information) table
146     //
147     SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
148     Status = Smbios->Add (
149                        Smbios,
150                        NULL,
151                        &SmbiosHandle,
152                        (EFI_SMBIOS_TABLE_HEADER*) &mOvmfDefaultType0
153                        );
154     ASSERT_EFI_ERROR (Status);
155   }
156 
157   return EFI_SUCCESS;
158 }
159 
160 
161 /**
162   Installs SMBIOS information for OVMF
163 
164   @param ImageHandle     Module's image handle
165   @param SystemTable     Pointer of EFI_SYSTEM_TABLE
166 
167   @retval EFI_SUCCESS    Smbios data successfully installed
168   @retval Other          Smbios data was not installed
169 
170 **/
171 EFI_STATUS
172 EFIAPI
SmbiosTablePublishEntry(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)173 SmbiosTablePublishEntry (
174   IN EFI_HANDLE           ImageHandle,
175   IN EFI_SYSTEM_TABLE     *SystemTable
176   )
177 {
178   EFI_STATUS                Status;
179   EFI_SMBIOS_PROTOCOL       *Smbios;
180   SMBIOS_TABLE_ENTRY_POINT  *EntryPointStructure;
181   UINT8                     *SmbiosTables;
182 
183   //
184   // Find the SMBIOS protocol
185   //
186   Status = gBS->LocateProtocol (
187                   &gEfiSmbiosProtocolGuid,
188                   NULL,
189                   (VOID**)&Smbios
190                   );
191   if (EFI_ERROR (Status)) {
192     return Status;
193   }
194 
195   //
196   // Add Xen or QEMU SMBIOS data if found
197   //
198   EntryPointStructure = GetXenSmbiosTables ();
199   if (EntryPointStructure != NULL) {
200     SmbiosTables = (UINT8*)(UINTN)EntryPointStructure->TableAddress;
201   } else {
202     SmbiosTables = GetQemuSmbiosTables ();
203   }
204 
205   if (SmbiosTables != NULL) {
206     Status = InstallAllStructures (Smbios, SmbiosTables);
207 
208     //
209     // Free SmbiosTables if allocated by Qemu (i.e., NOT by Xen):
210     //
211     if (EntryPointStructure == NULL) {
212       FreePool (SmbiosTables);
213     }
214   }
215 
216   return Status;
217 }
218