]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
OvmfPkg/SmbiosPlatformDxe: return EFI_NOT_FOUND if there is no SMBIOS data
[mirror_edk2.git] / OvmfPkg / SmbiosPlatformDxe / SmbiosPlatformDxe.c
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 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include <IndustryStandard/SmBios.h> // SMBIOS_TABLE_TYPE0
12 #include <Library/DebugLib.h> // ASSERT_EFI_ERROR()
13 #include <Library/MemoryAllocationLib.h> // FreePool()
14 #include <Library/UefiBootServicesTableLib.h> // gBS
15 #include <Protocol/Smbios.h> // EFI_SMBIOS_PROTOCOL
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
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
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
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 Status = EFI_NOT_FOUND;
196 //
197 // Add Xen or QEMU SMBIOS data if found
198 //
199 EntryPointStructure = GetXenSmbiosTables ();
200 if (EntryPointStructure != NULL) {
201 SmbiosTables = (UINT8*)(UINTN)EntryPointStructure->TableAddress;
202 } else {
203 SmbiosTables = GetQemuSmbiosTables ();
204 }
205
206 if (SmbiosTables != NULL) {
207 Status = InstallAllStructures (Smbios, SmbiosTables);
208
209 //
210 // Free SmbiosTables if allocated by Qemu (i.e., NOT by Xen):
211 //
212 if (EntryPointStructure == NULL) {
213 FreePool (SmbiosTables);
214 }
215 }
216
217 return Status;
218 }