1 /*++
2 
3 Copyright (c) 2006  - 2014, Intel Corporation. All rights reserved.<BR>
4 
5 
6   This program and the accompanying materials are licensed and made available under
7 
8   the terms and conditions of the BSD License that accompanies this distribution.
9 
10   The full text of the license may be found at
11 
12   http://opensource.org/licenses/bsd-license.php.
13 
14 
15 
16   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
17 
18   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 
20 
21 
22 
23 
24 Module Name:
25 
26   MiscProcessorCacheFunction.c
27 
28 Abstract:
29 
30   BIOS processor cache details.
31   Misc. subclass type 7.
32   SMBIOS type 7.
33 
34 --*/
35 #include "CommonHeader.h"
36 #include "MiscSubclassDriver.h"
37 #include <Protocol/DataHub.h>
ConvertBase2ToRaw(IN EFI_EXP_BASE2_DATA * Data)38 #include <Guid/DataHubRecords.h>
39 
40 
41 extern  SMBIOS_TABLE_TYPE7            *SmbiosRecordL1;
42 extern  SMBIOS_TABLE_TYPE7            *SmbiosRecordL2;
43 extern  SMBIOS_TABLE_TYPE7            *SmbiosRecordL3;
44 
45 
46 UINT32
47 ConvertBase2ToRaw (
48   IN  EFI_EXP_BASE2_DATA             *Data)
49 {
50   UINTN         Index;
51   UINT32        RawData;
52 
MISC_SMBIOS_TABLE_FUNCTION(MiscProcessorCache)53   RawData = Data->Value;
54   for (Index = 0; Index < (UINTN) Data->Exponent; Index++) {
55      RawData <<= 1;
56   }
57 
58   return  RawData;
59 }
60 
61 
62 MISC_SMBIOS_TABLE_FUNCTION(MiscProcessorCache)
63 {
64 	EFI_SMBIOS_HANDLE     SmbiosHandle;
65 	SMBIOS_TABLE_TYPE7            *SmbiosRecordL1;
66 	SMBIOS_TABLE_TYPE7            *SmbiosRecordL2;
67 
68 	EFI_CACHE_SRAM_TYPE_DATA      CacheSramType;
69 	CHAR16                          *SocketDesignation;
70 	CHAR8                           *OptionalStrStart;
71 	UINTN                           SocketStrLen;
72 	STRING_REF                      TokenToGet;
73 	EFI_DATA_HUB_PROTOCOL           *DataHub;
74 	UINT64                          MonotonicCount;
75 	EFI_DATA_RECORD_HEADER          *Record;
76 	EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
77 	UINT8                           *SrcData;
78 	UINT32                          SrcDataSize;
79 	EFI_STATUS                      Status;
80 
81 	//
82 	// Memory Device LOcator
83 	//
84 	DEBUG ((EFI_D_ERROR, "type 7\n"));
85 
86 	TokenToGet = STRING_TOKEN (STR_SOCKET_DESIGNATION);
87 	SocketDesignation = SmbiosMiscGetString (TokenToGet);
88 	SocketStrLen = StrLen(SocketDesignation);
89 	if (SocketStrLen > SMBIOS_STRING_MAX_LENGTH) {
90 	return EFI_UNSUPPORTED;
91 	}
92 
93 	SmbiosRecordL1 = AllocatePool(sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
94 	ASSERT (SmbiosRecordL1 != NULL);
95 	ZeroMem(SmbiosRecordL1, sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
96 
97 	SmbiosRecordL2 = AllocatePool(sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
98 	ASSERT (SmbiosRecordL2 != NULL);
99 	ZeroMem(SmbiosRecordL2, sizeof (SMBIOS_TABLE_TYPE7) + 7 + 1 + 1);
100 
101 	//
102 	// Get the Data Hub Protocol. Assume only one instance
103 	//
104 	Status = gBS->LocateProtocol (
105 	                &gEfiDataHubProtocolGuid,
106 	                NULL,
107 	                (VOID **)&DataHub
108 	                );
109 	ASSERT_EFI_ERROR(Status);
110 
111 	MonotonicCount = 0;
112 	Record = NULL;
113 
114 	do {
115 	Status = DataHub->GetNextRecord (
116 	                    DataHub,
117 	                    &MonotonicCount,
118 	                    NULL,
119 	                    &Record
120 	                    );
121 		if (!EFI_ERROR(Status)) {
122 			if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
123 				DataHeader  = (EFI_SUBCLASS_TYPE1_HEADER *)(Record + 1);
124 				SrcData     = (UINT8  *)(DataHeader + 1);
125 				SrcDataSize = Record->RecordSize - Record->HeaderSize - sizeof (EFI_SUBCLASS_TYPE1_HEADER);
126 				if (CompareGuid(&Record->DataRecordGuid, &gEfiCacheSubClassGuid) && (DataHeader->RecordType == CacheSizeRecordType)) {
127           			if (DataHeader->SubInstance == EFI_CACHE_L1) {
128 						SmbiosRecordL1->InstalledSize += (UINT16) (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData) >> 10);
129 						SmbiosRecordL1->MaximumCacheSize = SmbiosRecordL1->InstalledSize;
130           			}
131          			 else if (DataHeader->SubInstance == EFI_CACHE_L2) {
132 						SmbiosRecordL2->InstalledSize += (UINT16) (ConvertBase2ToRaw((EFI_EXP_BASE2_DATA *)SrcData) >> 10);
133 						SmbiosRecordL2->MaximumCacheSize = SmbiosRecordL2->InstalledSize;
134           			} else {
135            				 continue;
136           			}
137 		  		}
138 	      	}
139     	}
140 	} while (!EFI_ERROR(Status) && (MonotonicCount != 0));
141 
142 	//
143 	//Filling SMBIOS type 7 information for different cache levels.
144 	//
145 
146 	SmbiosRecordL1->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
147 	SmbiosRecordL1->Hdr.Length = (UINT8) sizeof (SMBIOS_TABLE_TYPE7);
148 	SmbiosRecordL1->Hdr.Handle = 0;
149 
150 	SmbiosRecordL1->Associativity = CacheAssociativity8Way;
151 	SmbiosRecordL1->SystemCacheType = CacheTypeUnknown;
152 	SmbiosRecordL1->SocketDesignation = 0x01;
153 	SmbiosRecordL1->CacheSpeed = 0;
154 	SmbiosRecordL1->CacheConfiguration = 0x0180;
155 	ZeroMem (&CacheSramType, sizeof (EFI_CACHE_SRAM_TYPE_DATA));
156 	CacheSramType.Synchronous = 1;
157 	CopyMem(&SmbiosRecordL1->SupportedSRAMType, &CacheSramType, 2);
158 	CopyMem(&SmbiosRecordL1->CurrentSRAMType, &CacheSramType, 2);
159 	SmbiosRecordL1->ErrorCorrectionType = EfiCacheErrorSingleBit;
160 
161 
162 	SmbiosRecordL2->Hdr.Type = EFI_SMBIOS_TYPE_CACHE_INFORMATION;
163 	SmbiosRecordL2->Hdr.Length = (UINT8) sizeof (SMBIOS_TABLE_TYPE7);
164 	SmbiosRecordL2->Hdr.Handle = 0;
165 
166 	SmbiosRecordL2->Associativity = CacheAssociativity16Way;
167 	SmbiosRecordL2->SystemCacheType = CacheTypeInstruction;
168 	SmbiosRecordL2->SocketDesignation = 0x01;
169 	SmbiosRecordL2->CacheSpeed = 0;
170 	SmbiosRecordL2->CacheConfiguration = 0x0281;
171 	ZeroMem (&CacheSramType, sizeof (EFI_CACHE_SRAM_TYPE_DATA));
172 	CacheSramType.Synchronous = 1;
173 	CopyMem(&SmbiosRecordL2->SupportedSRAMType, &CacheSramType, 2);
174 	CopyMem(&SmbiosRecordL2->CurrentSRAMType, &CacheSramType, 2);
175 	SmbiosRecordL2->ErrorCorrectionType = EfiCacheErrorSingleBit;
176 
177 
178 
179 	//
180 	//Adding SMBIOS type 7 records to SMBIOS table.
181 	//
182 	SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
183 	OptionalStrStart = (CHAR8 *)(SmbiosRecordL1 + 1);
184 	UnicodeStrToAsciiStr(SocketDesignation, OptionalStrStart);
185 
186 	Smbios-> Add(
187 	           Smbios,
188 	           NULL,
189 	           &SmbiosHandle,
190 	           (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecordL1
191 	           );
192 
193 	//
194 	//VLV2 incorporates two SLM modules (quad cores) in the SoC. 2 cores share BIU/L2 cache
195 	//
196 	SmbiosRecordL2->InstalledSize = (SmbiosRecordL2->InstalledSize)/2;
197 	SmbiosRecordL2->MaximumCacheSize = SmbiosRecordL2->InstalledSize;
198 	SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
199 
200 	OptionalStrStart = (CHAR8 *)(SmbiosRecordL2 + 1);
201 	UnicodeStrToAsciiStr(SocketDesignation, OptionalStrStart);
202 
203 	Smbios-> Add(
204 	           Smbios,
205 	           NULL,
206 	           &SmbiosHandle,
207 	           (EFI_SMBIOS_TABLE_HEADER *) SmbiosRecordL2
208 	           );
209 
210 	return EFI_SUCCESS;
211 }
212