1 /*++
2
3 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 MiscSubclassDriverEntryPoint.c
15
16 Abstract:
17
18 This driver parses the mMiscSubclassDataTable structure and reports
19 any generated data to the DataHub.
20
21 **/
22
23 #include "MiscSubClassDriver.h"
24
25 EFI_HII_HANDLE mHiiHandle;
26
27 /**
28 This is the standard EFI driver point that detects whether there is a
29 MemoryConfigurationData Variable and, if so, reports memory configuration info
30 to the DataHub.
31
32 @param ImageHandle Handle for the image of this driver
33 @param SystemTable Pointer to the EFI System Table
34
35 @return EFI_SUCCESS if the data is successfully reported
36 @return EFI_NOT_FOUND if the HOB list could not be located.
37
38 **/
39 EFI_STATUS
LogMemorySmbiosRecord(VOID)40 LogMemorySmbiosRecord (
41 VOID
42 )
43 {
44 EFI_STATUS Status;
45 UINT64 TotalMemorySize;
46 UINT8 NumSlots;
47 SMBIOS_TABLE_TYPE19 *Type19Record;
48 EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
49 EFI_SMBIOS_PROTOCOL *Smbios;
50 CHAR16 *MemString;
51
52 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
53 ASSERT_EFI_ERROR (Status);
54
55 NumSlots = 1;
56
57 //
58 // Process Memory String in form size!size ...
59 // So 64!64 is 128 MB
60 //
61 MemString = (CHAR16 *)PcdGetPtr (PcdEmuMemorySize);
62 for (TotalMemorySize = 0; *MemString != '\0';) {
63 TotalMemorySize += StrDecimalToUint64 (MemString);
64 while (*MemString != '\0') {
65 if (*MemString == '!') {
66 MemString++;
67 break;
68 }
69 MemString++;
70 }
71 }
72
73 //
74 // Convert Total Memory Size to based on KiloByte
75 //
76 TotalMemorySize = LShiftU64 (TotalMemorySize, 20);
77 //
78 // Generate Memory Array Mapped Address info
79 //
80 Type19Record = AllocateZeroPool(sizeof (SMBIOS_TABLE_TYPE19) + 2);
81 Type19Record->Hdr.Type = EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS;
82 Type19Record->Hdr.Length = sizeof(SMBIOS_TABLE_TYPE19);
83 Type19Record->Hdr.Handle = 0;
84 Type19Record->StartingAddress = 0;
85 Type19Record->EndingAddress = (UINT32)RShiftU64(TotalMemorySize, 10) - 1;
86 Type19Record->MemoryArrayHandle = 0;
87 Type19Record->PartitionWidth = (UINT8)(NumSlots);
88
89 //
90 // Generate Memory Array Mapped Address info (TYPE 19)
91 //
92 Status = AddSmbiosRecord (Smbios, &MemArrayMappedAddrSmbiosHandle, (EFI_SMBIOS_TABLE_HEADER*) Type19Record);
93
94 FreePool(Type19Record);
95 ASSERT_EFI_ERROR (Status);
96
97 return Status;
98 }
99
100
101 EFI_STATUS
102 EFIAPI
MiscSubclassDriverEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)103 MiscSubclassDriverEntryPoint (
104 IN EFI_HANDLE ImageHandle,
105 IN EFI_SYSTEM_TABLE *SystemTable
106 )
107 /*++
108 Description:
109
110 Standard EFI driver point. This driver parses the mMiscSubclassDataTable
111 structure and reports any generated data to the DataHub.
112
113 Arguments:
114
115 ImageHandle
116 Handle for the image of this driver
117
118 SystemTable
119 Pointer to the EFI System Table
120
121 Returns:
122
123 EFI_SUCCESS
124 The data was successfully reported to the Data Hub.
125
126 **/
127 {
128 UINTN Index;
129 EFI_STATUS EfiStatus;
130 EFI_SMBIOS_PROTOCOL *Smbios;
131
132 EfiStatus = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);
133
134 if (EFI_ERROR(EfiStatus)) {
135 DEBUG((EFI_D_ERROR, "Could not locate SMBIOS protocol. %r\n", EfiStatus));
136 return EfiStatus;
137 }
138
139 mHiiHandle = HiiAddPackages (
140 &gEfiCallerIdGuid,
141 NULL,
142 MiscSubclassStrings,
143 NULL
144 );
145 ASSERT (mHiiHandle != NULL);
146
147 for (Index = 0; Index < mMiscSubclassDataTableEntries; ++Index) {
148 //
149 // If the entry have a function pointer, just log the data.
150 //
151 if (mMiscSubclassDataTable[Index].Function != NULL) {
152 EfiStatus = (*mMiscSubclassDataTable[Index].Function)(
153 mMiscSubclassDataTable[Index].RecordData,
154 Smbios
155 );
156
157 if (EFI_ERROR(EfiStatus)) {
158 DEBUG((EFI_D_ERROR, "Misc smbios store error. Index=%d, ReturnStatus=%r\n", Index, EfiStatus));
159 return EfiStatus;
160 }
161 }
162 }
163
164 //
165 // Log Memory SMBIOS Record
166 //
167 EfiStatus = LogMemorySmbiosRecord();
168 return EfiStatus;
169 }
170
171 /**
172 Add an SMBIOS record.
173
174 @param Smbios The EFI_SMBIOS_PROTOCOL instance.
175 @param SmbiosHandle A unique handle will be assigned to the SMBIOS record.
176 @param Record The data for the fixed portion of the SMBIOS record. The format of the record is
177 determined by EFI_SMBIOS_TABLE_HEADER.Type. The size of the formatted area is defined
178 by EFI_SMBIOS_TABLE_HEADER.Length and either followed by a double-null (0x0000) or
179 a set of null terminated strings and a null.
180
181 @retval EFI_SUCCESS Record was added.
182 @retval EFI_OUT_OF_RESOURCES Record was not added due to lack of system resources.
183
184 **/
185 EFI_STATUS
AddSmbiosRecord(IN EFI_SMBIOS_PROTOCOL * Smbios,OUT EFI_SMBIOS_HANDLE * SmbiosHandle,IN EFI_SMBIOS_TABLE_HEADER * Record)186 AddSmbiosRecord (
187 IN EFI_SMBIOS_PROTOCOL *Smbios,
188 OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
189 IN EFI_SMBIOS_TABLE_HEADER *Record
190 )
191 {
192 *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
193 return Smbios->Add (
194 Smbios,
195 NULL,
196 SmbiosHandle,
197 Record
198 );
199 }
200
201