1 | /** @file
|
---|
2 | This driver installs SMBIOS information for OVMF
|
---|
3 |
|
---|
4 | Copyright (c) 2011, Bei Guan <[email protected]>
|
---|
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/BaseLib.h>
|
---|
13 | #include <Library/BaseMemoryLib.h>
|
---|
14 | #include <Library/DebugLib.h> // ASSERT_EFI_ERROR()
|
---|
15 | #include <Library/MemoryAllocationLib.h>
|
---|
16 | #include <Library/PcdLib.h>
|
---|
17 | #include <Library/UefiBootServicesTableLib.h> // gBS
|
---|
18 | #include <Protocol/Smbios.h> // EFI_SMBIOS_PROTOCOL
|
---|
19 |
|
---|
20 | #include "SmbiosPlatformDxe.h"
|
---|
21 |
|
---|
22 | STATIC CONST SMBIOS_TABLE_TYPE0 mOvmfDefaultType0 = {
|
---|
23 | // SMBIOS_STRUCTURE Hdr
|
---|
24 | {
|
---|
25 | EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
|
---|
26 | sizeof (SMBIOS_TABLE_TYPE0), // UINT8 Length
|
---|
27 | },
|
---|
28 | 1, // SMBIOS_TABLE_STRING Vendor
|
---|
29 | 2, // SMBIOS_TABLE_STRING BiosVersion
|
---|
30 | 0xE800, // UINT16 BiosSegment
|
---|
31 | 3, // SMBIOS_TABLE_STRING BiosReleaseDate
|
---|
32 | 0, // UINT8 BiosSize
|
---|
33 | { // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
|
---|
34 | 0, // Reserved :2
|
---|
35 | 0, // Unknown :1
|
---|
36 | 1, // BiosCharacteristicsNotSupported :1
|
---|
37 | // Remaining BiosCharacteristics bits left unset :60
|
---|
38 | },
|
---|
39 | { // BIOSCharacteristicsExtensionBytes[2]
|
---|
40 | 0, // BiosReserved
|
---|
41 | 0x1C // SystemReserved = VirtualMachineSupported |
|
---|
42 | // UefiSpecificationSupported |
|
---|
43 | // TargetContentDistributionEnabled
|
---|
44 | },
|
---|
45 | 0, // UINT8 SystemBiosMajorRelease
|
---|
46 | 0, // UINT8 SystemBiosMinorRelease
|
---|
47 | 0xFF, // UINT8 EmbeddedControllerFirmwareMajorRelease
|
---|
48 | 0xFF // UINT8 EmbeddedControllerFirmwareMinorRelease
|
---|
49 | };
|
---|
50 |
|
---|
51 | /**
|
---|
52 | Get SMBIOS record length.
|
---|
53 |
|
---|
54 | @param SmbiosTable SMBIOS pointer.
|
---|
55 |
|
---|
56 | **/
|
---|
57 | UINTN
|
---|
58 | SmbiosTableLength (
|
---|
59 | IN SMBIOS_STRUCTURE_POINTER SmbiosTable
|
---|
60 | )
|
---|
61 | {
|
---|
62 | CHAR8 *AChar;
|
---|
63 | UINTN Length;
|
---|
64 |
|
---|
65 | AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);
|
---|
66 |
|
---|
67 | //
|
---|
68 | // Each structure shall be terminated by a double-null (SMBIOS spec.7.1)
|
---|
69 | //
|
---|
70 | while ((*AChar != 0) || (*(AChar + 1) != 0)) {
|
---|
71 | AChar++;
|
---|
72 | }
|
---|
73 |
|
---|
74 | Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);
|
---|
75 |
|
---|
76 | return Length;
|
---|
77 | }
|
---|
78 |
|
---|
79 | /**
|
---|
80 | Install all structures from the given SMBIOS structures block
|
---|
81 |
|
---|
82 | @param TableAddress SMBIOS tables starting address
|
---|
83 |
|
---|
84 | **/
|
---|
85 | EFI_STATUS
|
---|
86 | InstallAllStructures (
|
---|
87 | IN UINT8 *TableAddress
|
---|
88 | )
|
---|
89 | {
|
---|
90 | EFI_SMBIOS_PROTOCOL *Smbios;
|
---|
91 | EFI_STATUS Status;
|
---|
92 | SMBIOS_STRUCTURE_POINTER SmbiosTable;
|
---|
93 | EFI_SMBIOS_HANDLE SmbiosHandle;
|
---|
94 | BOOLEAN NeedSmbiosType0;
|
---|
95 |
|
---|
96 | //
|
---|
97 | // Find the SMBIOS protocol
|
---|
98 | //
|
---|
99 | Status = gBS->LocateProtocol (
|
---|
100 | &gEfiSmbiosProtocolGuid,
|
---|
101 | NULL,
|
---|
102 | (VOID **)&Smbios
|
---|
103 | );
|
---|
104 | if (EFI_ERROR (Status)) {
|
---|
105 | return Status;
|
---|
106 | }
|
---|
107 |
|
---|
108 | SmbiosTable.Raw = TableAddress;
|
---|
109 | if (SmbiosTable.Raw == NULL) {
|
---|
110 | return EFI_INVALID_PARAMETER;
|
---|
111 | }
|
---|
112 |
|
---|
113 | NeedSmbiosType0 = TRUE;
|
---|
114 |
|
---|
115 | while (SmbiosTable.Hdr->Type != 127) {
|
---|
116 | //
|
---|
117 | // Log the SMBIOS data for this structure
|
---|
118 | //
|
---|
119 | SmbiosHandle = SmbiosTable.Hdr->Handle;
|
---|
120 | Status = Smbios->Add (
|
---|
121 | Smbios,
|
---|
122 | NULL,
|
---|
123 | &SmbiosHandle,
|
---|
124 | (EFI_SMBIOS_TABLE_HEADER *)SmbiosTable.Raw
|
---|
125 | );
|
---|
126 | ASSERT_EFI_ERROR (Status);
|
---|
127 |
|
---|
128 | if (SmbiosTable.Hdr->Type == 0) {
|
---|
129 | NeedSmbiosType0 = FALSE;
|
---|
130 | }
|
---|
131 |
|
---|
132 | //
|
---|
133 | // Get the next structure address
|
---|
134 | //
|
---|
135 | SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));
|
---|
136 | }
|
---|
137 |
|
---|
138 | if (NeedSmbiosType0) {
|
---|
139 | //
|
---|
140 | // Add OVMF default Type 0 (BIOS Information) table
|
---|
141 | //
|
---|
142 | CHAR16 *VendStr, *VersStr, *DateStr;
|
---|
143 | UINTN VendLen, VersLen, DateLen;
|
---|
144 | CHAR8 *Type0;
|
---|
145 |
|
---|
146 | VendStr = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareVendor);
|
---|
147 | VendLen = StrLen (VendStr);
|
---|
148 | if (VendLen < 3) {
|
---|
149 | VendStr = L"unknown";
|
---|
150 | VendLen = StrLen (VendStr);
|
---|
151 | }
|
---|
152 |
|
---|
153 | VersStr = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareVersionString);
|
---|
154 | VersLen = StrLen (VersStr);
|
---|
155 | if (VersLen < 3) {
|
---|
156 | VersStr = L"unknown";
|
---|
157 | VersLen = StrLen (VersStr);
|
---|
158 | }
|
---|
159 |
|
---|
160 | DateStr = (CHAR16 *)FixedPcdGetPtr (PcdFirmwareReleaseDateString);
|
---|
161 | DateLen = StrLen (DateStr);
|
---|
162 | if (DateLen < 3) {
|
---|
163 | DateStr = L"02/02/2022";
|
---|
164 | DateLen = StrLen (DateStr);
|
---|
165 | }
|
---|
166 |
|
---|
167 | DEBUG ((DEBUG_INFO, "FirmwareVendor: \"%s\" (%d chars)\n", VendStr, VendLen));
|
---|
168 | DEBUG ((DEBUG_INFO, "FirmwareVersionString: \"%s\" (%d chars)\n", VersStr, VersLen));
|
---|
169 | DEBUG ((DEBUG_INFO, "FirmwareReleaseDateString: \"%s\" (%d chars)\n", DateStr, DateLen));
|
---|
170 |
|
---|
171 | Type0 = AllocateZeroPool (sizeof (mOvmfDefaultType0) + VendLen + VersLen + DateLen + 4);
|
---|
172 | if (Type0 == NULL) {
|
---|
173 | return EFI_OUT_OF_RESOURCES;
|
---|
174 | }
|
---|
175 |
|
---|
176 | CopyMem (Type0, &mOvmfDefaultType0, sizeof (mOvmfDefaultType0));
|
---|
177 | UnicodeStrToAsciiStrS (VendStr, Type0 + sizeof (mOvmfDefaultType0), VendLen + 1);
|
---|
178 | UnicodeStrToAsciiStrS (VersStr, Type0 + sizeof (mOvmfDefaultType0) + VendLen + 1, VersLen + 1);
|
---|
179 | UnicodeStrToAsciiStrS (DateStr, Type0 + sizeof (mOvmfDefaultType0) + VendLen + VersLen + 2, DateLen + 1);
|
---|
180 |
|
---|
181 | SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
|
---|
182 | Status = Smbios->Add (
|
---|
183 | Smbios,
|
---|
184 | NULL,
|
---|
185 | &SmbiosHandle,
|
---|
186 | (EFI_SMBIOS_TABLE_HEADER *)Type0
|
---|
187 | );
|
---|
188 | ASSERT_EFI_ERROR (Status);
|
---|
189 |
|
---|
190 | FreePool (Type0);
|
---|
191 | }
|
---|
192 |
|
---|
193 | return EFI_SUCCESS;
|
---|
194 | }
|
---|