]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
OvmfPkg/SmbiosPlatformDxe: split GetXenSmbiosTables() decl. to new header
[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 #include "XenSmbiosPlatformDxe.h"
19
20 #define TYPE0_STRINGS \
21 "EFI Development Kit II / OVMF\0" /* Vendor */ \
22 "0.0.0\0" /* BiosVersion */ \
23 "02/06/2015\0" /* BiosReleaseDate */
24 //
25 // Type definition and contents of the default Type 0 SMBIOS table.
26 //
27 #pragma pack(1)
28 typedef struct {
29 SMBIOS_TABLE_TYPE0 Base;
30 UINT8 Strings[sizeof(TYPE0_STRINGS)];
31 } OVMF_TYPE0;
32 #pragma pack()
33
34 STATIC CONST OVMF_TYPE0 mOvmfDefaultType0 = {
35 {
36 // SMBIOS_STRUCTURE Hdr
37 {
38 EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
39 sizeof (SMBIOS_TABLE_TYPE0), // UINT8 Length
40 },
41 1, // SMBIOS_TABLE_STRING Vendor
42 2, // SMBIOS_TABLE_STRING BiosVersion
43 0xE800,// UINT16 BiosSegment
44 3, // SMBIOS_TABLE_STRING BiosReleaseDate
45 0, // UINT8 BiosSize
46 { // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
47 0, // Reserved :2
48 0, // Unknown :1
49 1, // BiosCharacteristicsNotSupported :1
50 // Remaining BiosCharacteristics bits left unset :60
51 },
52 { // BIOSCharacteristicsExtensionBytes[2]
53 0, // BiosReserved
54 0x1C // SystemReserved = VirtualMachineSupported |
55 // UefiSpecificationSupported |
56 // TargetContentDistributionEnabled
57 },
58 0, // UINT8 SystemBiosMajorRelease
59 0, // UINT8 SystemBiosMinorRelease
60 0xFF, // UINT8 EmbeddedControllerFirmwareMajorRelease
61 0xFF // UINT8 EmbeddedControllerFirmwareMinorRelease
62 },
63 // Text strings (unformatted area)
64 TYPE0_STRINGS
65 };
66
67
68 /**
69 Get SMBIOS record length.
70
71 @param SmbiosTable SMBIOS pointer.
72
73 **/
74 UINTN
75 SmbiosTableLength (
76 IN SMBIOS_STRUCTURE_POINTER SmbiosTable
77 )
78 {
79 CHAR8 *AChar;
80 UINTN Length;
81
82 AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);
83
84 //
85 // Each structure shall be terminated by a double-null (SMBIOS spec.7.1)
86 //
87 while ((*AChar != 0) || (*(AChar + 1) != 0)) {
88 AChar ++;
89 }
90 Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);
91
92 return Length;
93 }
94
95
96 /**
97 Install all structures from the given SMBIOS structures block
98
99 @param TableAddress SMBIOS tables starting address
100
101 **/
102 EFI_STATUS
103 InstallAllStructures (
104 IN UINT8 *TableAddress
105 )
106 {
107 EFI_SMBIOS_PROTOCOL *Smbios;
108 EFI_STATUS Status;
109 SMBIOS_STRUCTURE_POINTER SmbiosTable;
110 EFI_SMBIOS_HANDLE SmbiosHandle;
111 BOOLEAN NeedSmbiosType0;
112
113 //
114 // Find the SMBIOS protocol
115 //
116 Status = gBS->LocateProtocol (
117 &gEfiSmbiosProtocolGuid,
118 NULL,
119 (VOID**)&Smbios
120 );
121 if (EFI_ERROR (Status)) {
122 return Status;
123 }
124
125 SmbiosTable.Raw = TableAddress;
126 if (SmbiosTable.Raw == NULL) {
127 return EFI_INVALID_PARAMETER;
128 }
129
130 NeedSmbiosType0 = TRUE;
131
132 while (SmbiosTable.Hdr->Type != 127) {
133 //
134 // Log the SMBIOS data for this structure
135 //
136 SmbiosHandle = SmbiosTable.Hdr->Handle;
137 Status = Smbios->Add (
138 Smbios,
139 NULL,
140 &SmbiosHandle,
141 (EFI_SMBIOS_TABLE_HEADER*) SmbiosTable.Raw
142 );
143 ASSERT_EFI_ERROR (Status);
144
145 if (SmbiosTable.Hdr->Type == 0) {
146 NeedSmbiosType0 = FALSE;
147 }
148
149 //
150 // Get the next structure address
151 //
152 SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));
153 }
154
155 if (NeedSmbiosType0) {
156 //
157 // Add OVMF default Type 0 (BIOS Information) table
158 //
159 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
160 Status = Smbios->Add (
161 Smbios,
162 NULL,
163 &SmbiosHandle,
164 (EFI_SMBIOS_TABLE_HEADER*) &mOvmfDefaultType0
165 );
166 ASSERT_EFI_ERROR (Status);
167 }
168
169 return EFI_SUCCESS;
170 }
171
172
173 /**
174 Installs SMBIOS information for OVMF
175
176 @param ImageHandle Module's image handle
177 @param SystemTable Pointer of EFI_SYSTEM_TABLE
178
179 @retval EFI_SUCCESS Smbios data successfully installed
180 @retval Other Smbios data was not installed
181
182 **/
183 EFI_STATUS
184 EFIAPI
185 SmbiosTablePublishEntry (
186 IN EFI_HANDLE ImageHandle,
187 IN EFI_SYSTEM_TABLE *SystemTable
188 )
189 {
190 EFI_STATUS Status;
191 SMBIOS_TABLE_ENTRY_POINT *EntryPointStructure;
192 UINT8 *SmbiosTables;
193
194 Status = EFI_NOT_FOUND;
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 (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 }