blob: 67eaca194df3fd8e37c938512e7a224210901446 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * AMD SLIT, ACPI table related API functions.
6 *
7 * Contains code that generates the SLIT table
8 *
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: CPU
12 * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
13 *
14 */
15/*
16 ******************************************************************************
17 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080018 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
19 * All rights reserved.
zbao7d94cf92012-07-02 14:19:14 +080020 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080021 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
zbao7d94cf92012-07-02 14:19:14 +080031 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080032 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zbao7d94cf92012-07-02 14:19:14 +080042 ******************************************************************************
43 */
44
45/*----------------------------------------------------------------------------
46 * This file provides functions, that will generate SLIT tables
47 *----------------------------------------------------------------------------
48 */
49
50/*----------------------------------------------------------------------------------------
51 * M O D U L E S U S E D
52 *----------------------------------------------------------------------------------------
53 */
54
55#include "AGESA.h"
56#include "amdlib.h"
57#include "OptionSlit.h"
58#include "heapManager.h"
59#include "cpuLateInit.h"
60#include "cpuRegisters.h"
61#include "Ids.h"
62#include "cpuFeatures.h"
63#include "cpuFamilyTranslation.h"
64#include "cpuL3Features.h"
65#include "Filecode.h"
66CODE_GROUP (G3_DXE)
67RDATA_GROUP (G3_DXE)
68
69#define FILECODE PROC_CPU_FEATURE_CPUSLIT_FILECODE
70/*----------------------------------------------------------------------------------------
71 * D E F I N I T I O N S A N D M A C R O S
72 *----------------------------------------------------------------------------------------
73 */
74
75extern OPTION_SLIT_CONFIGURATION OptionSlitConfiguration; // global user config record
76
77STATIC ACPI_TABLE_HEADER ROMDATA CpuSlitHdrStruct =
78{
79 {'S','L','I','T'},
80 0,
81 1,
82 0,
83 {'A','M','D',' ',' ',' '},
84 {'A','G','E','S','A',' ',' ',' '},
85 1,
86 {'A','M','D',' '},
87 1
88};
89
90/*----------------------------------------------------------------------------------------
91 * T Y P E D E F S A N D S T R U C T U R E S
92 *----------------------------------------------------------------------------------------
93 */
94
95/*----------------------------------------------------------------------------------------
96 * P R O T O T Y P E S O F L O C A L F U N C T I O N S
97 *----------------------------------------------------------------------------------------
98 */
99VOID
100STATIC
101AcpiSlitHBufferFind (
102 IN OUT AMD_CONFIG_PARAMS *StdHeader,
103 IN UINT8 **SocketTopologyPtr
104 );
105
106/*----------------------------------------------------------------------------------------
107 * P R O T O T Y P E S O F E X P O R T E D F U N C T I O N S
108 *----------------------------------------------------------------------------------------
109 */
110AGESA_STATUS
111GetAcpiSlitStub (
112 IN OUT AMD_CONFIG_PARAMS *StdHeader,
113 IN PLATFORM_CONFIGURATION *PlatformConfig,
114 IN OUT VOID **SlitPtr
115 );
116
117AGESA_STATUS
118GetAcpiSlitMain (
119 IN OUT AMD_CONFIG_PARAMS *StdHeader,
120 IN PLATFORM_CONFIGURATION *PlatformConfig,
121 IN OUT VOID **SlitPtr
122 );
123
124AGESA_STATUS
125ReleaseSlitBufferStub (
126 IN OUT AMD_CONFIG_PARAMS *StdHeader
127 );
128
129AGESA_STATUS
130ReleaseSlitBuffer (
131 IN OUT AMD_CONFIG_PARAMS *StdHeader
132 );
133
134/*----------------------------------------------------------------------------------------
135 * E X P O R T E D F U N C T I O N S
136 *----------------------------------------------------------------------------------------
137 */
138
139extern CPU_FAMILY_SUPPORT_TABLE L3FeatureFamilyServiceTable;
140
141/*---------------------------------------------------------------------------------------*/
142/**
143 *
144 * This function generates a complete SLIT table into a memory buffer.
145 * After completion, this table must be set by the system BIOS into its
146 * internal ACPI namespace, and linked into the RSDT/XSDT
147 *
148 * @param[in, out] StdHeader Standard Head Pointer
149 * @param[in] PlatformConfig Config handle for platform specific information
150 * @param[in, out] SlitPtr Point to Slit Struct including buffer address and length
151 *
152 * @retval UINT32 AGESA_STATUS
153 */
154AGESA_STATUS
155CreateAcpiSlit (
156 IN OUT AMD_CONFIG_PARAMS *StdHeader,
157 IN PLATFORM_CONFIGURATION *PlatformConfig,
158 IN OUT VOID **SlitPtr
159 )
160{
161 AGESA_TESTPOINT (TpProcCpuEntrySlit, StdHeader);
162 return ((*(OptionSlitConfiguration.SlitFeature)) (StdHeader, PlatformConfig, SlitPtr));
163}
164
165/*---------------------------------------------------------------------------------------*/
166/**
167 *
168 * This is the default routine for use when the SLIT option is NOT requested.
169 *
170 * The option install process will create and fill the transfer vector with
171 * the address of the proper routine (Main or Stub). The link optimizer will
172 * strip out of the .DLL the routine that is not used.
173 *
174 * @param[in, out] StdHeader Standard Head Pointer
175 * @param[in] PlatformConfig Config handle for platform specific information
176 * @param[in, out] SlitPtr Point to Slit Struct including buffer address and length
177 *
178 * @retval AGESA_STATUS
179 */
180
181AGESA_STATUS
182GetAcpiSlitStub (
183 IN OUT AMD_CONFIG_PARAMS *StdHeader,
184 IN PLATFORM_CONFIGURATION *PlatformConfig,
185 IN OUT VOID **SlitPtr
186 )
187{
188 return AGESA_UNSUPPORTED;
189}
190/*---------------------------------------------------------------------------------------*/
191/**
192 *
193 * This function generates a complete SLIT table into a memory buffer.
194 * After completion, this table must be set by the system BIOS into its
195 * internal ACPI namespace, and linked into the RSDT/XSDT
196 *
197 * @param[in, out] StdHeader Standard Head Pointer
198 * @param[in] PlatformConfig Config handle for platform specific information
199 * @param[in, out] SlitPtr Point to Slit Struct including buffer address and length
200 *
201 * @retval UINT32 AGESA_STATUS
202 */
203AGESA_STATUS
204GetAcpiSlitMain (
205 IN OUT AMD_CONFIG_PARAMS *StdHeader,
206 IN PLATFORM_CONFIGURATION *PlatformConfig,
207 IN OUT VOID **SlitPtr
208 )
209{
210 UINT8 MaxHops;
211 UINT8 SocketNum;
212 UINT8 i;
213 UINT8 j;
214 UINT8 *BufferPtr;
215 UINT8 *SocketTopologyDataPtr;
216 UINT8 *SocketTopologyPtr;
217 UINT32 Socket;
218 BOOLEAN IsProbeFilterEnabled;
219 ACPI_TABLE_HEADER *CpuSlitHeaderStructPtr;
220 AGESA_STATUS Flag;
221 ALLOCATE_HEAP_PARAMS AllocStruct;
222 L3_FEATURE_FAMILY_SERVICES *FamilyServices;
223
224 MaxHops = 0;
225 SocketTopologyPtr = NULL;
226 Flag = AGESA_ERROR;
227 IsProbeFilterEnabled = FALSE;
228
229 // find out the pointer to the BufferHandle which contains
230 // Node Topology information
231 AcpiSlitHBufferFind (StdHeader, &SocketTopologyPtr);
232 if (SocketTopologyPtr == NULL) {
233 return (Flag);
234 }
235
236 SocketNum = *SocketTopologyPtr;
237
238 IDS_HDT_CONSOLE (CPU_TRACE, " SLIT is created\n");
239
240 // create a buffer by calling IBV callout routine
241 AllocStruct.RequestedBufferSize = (SocketNum * SocketNum) + AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + sizeof (ACPI_TABLE_HEADER);
242 AllocStruct.BufferHandle = AMD_ACPI_SLIT_BUFFER_HANDLE;
243 AllocStruct.Persist = HEAP_SYSTEM_MEM;
244 if (HeapAllocateBuffer (&AllocStruct, StdHeader) != AGESA_SUCCESS) {
245 return (Flag);
246 }
247 *SlitPtr = AllocStruct.BufferPtr;
248
249 //SLIT header
250 LibAmdMemCopy (*SlitPtr, (VOID *) &CpuSlitHdrStruct, (UINTN) (sizeof (ACPI_TABLE_HEADER)), StdHeader);
251 CpuSlitHeaderStructPtr = (ACPI_TABLE_HEADER *) *SlitPtr;
252 CpuSlitHeaderStructPtr->TableLength = (UINT32) AllocStruct.RequestedBufferSize;
253 BufferPtr = *SlitPtr;
254
255 Flag = AGESA_SUCCESS;
256 // SLIT body
257 // Check if Probe Filter is enabled
258 if (IsFeatureEnabled (L3Features, PlatformConfig, StdHeader)) {
259 IsProbeFilterEnabled = TRUE;
260 for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
261 if (IsProcessorPresent (Socket, StdHeader)) {
262 GetFeatureServicesOfSocket (&L3FeatureFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader);
263 if ((FamilyServices == NULL) || (!FamilyServices->IsHtAssistSupported (FamilyServices, PlatformConfig, StdHeader))) {
264 IsProbeFilterEnabled = FALSE;
265 break;
266 }
267 }
268 }
269 }
270
271
272 if (!IsProbeFilterEnabled) {
273 // probe filter is disabled
274 // get MaxHops
275 SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum);
276 for (i = 0; i < SocketNum; i++) {
277 for (j = 0; j < SocketNum; j++) {
278 if (*SocketTopologyDataPtr > MaxHops) {
279 MaxHops = *SocketTopologyDataPtr;
280 }
281 SocketTopologyDataPtr++;
282 }
283 }
284
285 // the Max hop entries have a value of 13
286 // and all other entries have 10.
287 SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum);
288 for (i = 0; i < SocketNum; i++) {
289 for (j = 0; j < SocketNum; j++) {
290 if (*SocketTopologyDataPtr++ == MaxHops) {
291 *(BufferPtr + sizeof (ACPI_TABLE_HEADER) +
292 AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = 13;
293 } else {
294 *(BufferPtr + sizeof (ACPI_TABLE_HEADER) +
295 AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) = 10;
296 }
297 }
298 }
299 } else {
300 // probe filter is enabled
301 // formula : num_hops * 6 + 10
302 SocketTopologyDataPtr = SocketTopologyPtr + sizeof (SocketNum);
303 for (i = 0; i < SocketNum; i++) {
304 for (j = 0; j < SocketNum; j++) {
305 *(BufferPtr + sizeof (ACPI_TABLE_HEADER) +
306 AMD_ACPI_SLIT_SOCKET_NUM_LENGTH + (i * SocketNum) + j) =
307 ((*SocketTopologyDataPtr++) * 6) + 10;
308 }
309 }
310 }
311
312 BufferPtr += sizeof (ACPI_TABLE_HEADER);
313 *((UINT64 *) BufferPtr) = (UINT64) SocketNum;
314
315 //Update SLIT header Checksum
316 ChecksumAcpiTable ((ACPI_TABLE_HEADER *) *SlitPtr, StdHeader);
317
318 return (Flag);
319}
320
321/*---------------------------------------------------------------------------------------
322 * L O C A L F U N C T I O N S
323 *---------------------------------------------------------------------------------------
324 */
325
326/*---------------------------------------------------------------------------------------*/
327/**
328 *
329 * Find out the pointer to the BufferHandle which contains
330 * Node Topology information
331 *
332 * @param[in, out] StdHeader Standard Head Pointer
333 * @param[in] SocketTopologyPtr Point to the address of Socket Topology
334 *
335 */
336VOID
337STATIC
338AcpiSlitHBufferFind (
339 IN OUT AMD_CONFIG_PARAMS *StdHeader,
340 IN UINT8 **SocketTopologyPtr
341 )
342{
343 LOCATE_HEAP_PTR LocateBuffer;
344
345 LocateBuffer.BufferHandle = HOP_COUNT_TABLE_HANDLE;
346 if (HeapLocateBuffer (&LocateBuffer, StdHeader) == AGESA_SUCCESS) {
347 *SocketTopologyPtr = (UINT8 *) LocateBuffer.BufferPtr;
348 }
349
350 return;
351}
352
353
354/* -----------------------------------------------------------------------------*/
355/**
356 * ReleaseSlitBufferStub
357 *
358 * Description:
359 * This is the default routine for use when the SLIT option is NOT requested.
360 *
361 * Parameters:
362 * @param[in, out] *StdHeader
363 *
364 * @retval AGESA_STATUS
365 *
366 */
367AGESA_STATUS
368ReleaseSlitBufferStub (
369 IN OUT AMD_CONFIG_PARAMS *StdHeader
370 )
371{
372 return AGESA_UNSUPPORTED;
373}
374
375/* -----------------------------------------------------------------------------*/
376/**
377 * ReleaseSlitBuffer
378 *
379 * Description:
380 * Deallocate SLIT buffer
381 *
382 * Parameters:
383 * @param[in, out] *StdHeader
384 *
385 * @retval AGESA_STATUS
386 *
387 */
388AGESA_STATUS
389ReleaseSlitBuffer (
390 IN OUT AMD_CONFIG_PARAMS *StdHeader
391 )
392{
393 HeapDeallocateBuffer ((UINT32) HOP_COUNT_TABLE_HANDLE, StdHeader);
394
395 return AGESA_SUCCESS;
396}