2 * This file is part of the coreboot project.
4 * Copyright (C) 2011 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 /*----------------------------------------------------------------------------------------
21 * M O D U L E S U S E D
22 *----------------------------------------------------------------------------------------
27 #include "agesawrapper.h"
28 #include "BiosCallOuts.h"
29 #include "cpuRegisters.h"
30 #include "cpuCacheInit.h"
31 #include "cpuApicUtilities.h"
32 #include "cpuEarlyInit.h"
33 #include "cpuLateInit.h"
34 #include "Dispatcher.h"
35 #include "cpuCacheInit.h"
37 #include "PlatformGnbPcieComplex.h"
40 #define FILECODE UNASSIGNED_FILE_FILECODE
42 /*----------------------------------------------------------------------------------------
43 * D E F I N I T I O N S A N D M A C R O S
44 *----------------------------------------------------------------------------------------
47 /* ACPI table pointers returned by AmdInitLate */
48 VOID *DmiTable = NULL;
49 VOID *AcpiPstate = NULL;
50 VOID *AcpiSrat = NULL;
51 VOID *AcpiSlit = NULL;
53 VOID *AcpiWheaMce = NULL;
54 VOID *AcpiWheaCmc = NULL;
55 VOID *AcpiAlib = NULL;
58 /*----------------------------------------------------------------------------------------
59 * T Y P E D E F S A N D S T R U C T U R E S
60 *----------------------------------------------------------------------------------------
63 /*----------------------------------------------------------------------------------------
64 * 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
65 *----------------------------------------------------------------------------------------
68 /*----------------------------------------------------------------------------------------
69 * E X P O R T E D F U N C T I O N S
70 *----------------------------------------------------------------------------------------
73 /*---------------------------------------------------------------------------------------
74 * L O C A L F U N C T I O N S
75 *---------------------------------------------------------------------------------------
78 agesawrapper_amdinitcpuio (
86 AMD_CONFIG_PARAMS StdHeader;
88 /* Enable legacy video routing: D18F1xF4 VGA Enable */
89 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xF4);
91 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
93 /* The platform BIOS needs to ensure the memory ranges of SB800 legacy
94 * devices (TPM, HPET, BIOS RAM, Watchdog Timer, I/O APIC and ACPI) are
95 * set to non-posted regions.
97 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x84);
98 PciData = 0x00FEDF00; // last address before processor local APIC at FEE00000
99 PciData |= 1 << 7; // set NP (non-posted) bit
100 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
101 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x80);
102 PciData = (0xFED00000 >> 8) | 3; // lowest NP address is HPET at FED00000
103 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
105 /* Map the remaining PCI hole as posted MMIO */
106 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x8C);
107 PciData = 0x00FECF00; // last address before non-posted range
108 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
109 LibAmdMsrRead (0xC001001A, &MsrReg, &StdHeader);
110 MsrReg = (MsrReg >> 8) | 3;
111 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x88);
112 PciData = (UINT32)MsrReg;
113 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
115 /* Send all IO (0000-FFFF) to southbridge. */
116 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xC4);
117 PciData = 0x0000F000;
118 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
119 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xC0);
120 PciData = 0x00000003;
121 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
122 Status = AGESA_SUCCESS;
123 return (UINT32)Status;
127 agesawrapper_amdinitmmio (
135 AMD_CONFIG_PARAMS StdHeader;
138 Set the MMIO Configuration Base Address and Bus Range onto MMIO configuration base
139 Address MSR register.
142 MsrReg = CONFIG_MMCONF_BASE_ADDRESS | (LibAmdBitScanReverse (CONFIG_MMCONF_BUS_NUMBER) << 2) | 1;
143 LibAmdMsrWrite (0xC0010058, &MsrReg, &StdHeader);
146 Set the NB_CFG MSR register. Enable CF8 extended configuration cycles.
148 LibAmdMsrRead (0xC001001F, &MsrReg, &StdHeader);
149 MsrReg = MsrReg | 0x0000400000000000;
150 LibAmdMsrWrite (0xC001001F, &MsrReg, &StdHeader);
152 /* Set Ontario Link Data */
153 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE0);
154 PciData = 0x01308002;
155 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
156 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE4);
157 PciData = (AMD_APU_SSID<<0x10)|AMD_APU_SVID;
158 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
160 Status = AGESA_SUCCESS;
161 return (UINT32)Status;
165 agesawrapper_amdinitreset (
170 AMD_INTERFACE_PARAMS AmdParamStruct;
171 AMD_RESET_PARAMS AmdResetParams;
173 LibAmdMemFill (&AmdParamStruct,
175 sizeof (AMD_INTERFACE_PARAMS),
176 &(AmdParamStruct.StdHeader));
179 LibAmdMemFill (&AmdResetParams,
181 sizeof (AMD_RESET_PARAMS),
182 &(AmdResetParams.StdHeader));
184 AmdParamStruct.AgesaFunctionName = AMD_INIT_RESET;
185 AmdParamStruct.AllocationMethod = ByHost;
186 AmdParamStruct.NewStructSize = sizeof(AMD_RESET_PARAMS);
187 AmdParamStruct.NewStructPtr = &AmdResetParams;
188 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
189 AmdParamStruct.StdHeader.CalloutPtr = NULL;
190 AmdParamStruct.StdHeader.Func = 0;
191 AmdParamStruct.StdHeader.ImageBasePtr = 0;
192 AmdCreateStruct (&AmdParamStruct);
193 AmdResetParams.HtConfig.Depth = 0;
195 status = AmdInitReset ((AMD_RESET_PARAMS *)AmdParamStruct.NewStructPtr);
196 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
197 AmdReleaseStruct (&AmdParamStruct);
198 return (UINT32)status;
202 agesawrapper_amdinitearly (
207 AMD_INTERFACE_PARAMS AmdParamStruct;
208 AMD_EARLY_PARAMS *AmdEarlyParamsPtr;
210 LibAmdMemFill (&AmdParamStruct,
212 sizeof (AMD_INTERFACE_PARAMS),
213 &(AmdParamStruct.StdHeader));
215 AmdParamStruct.AgesaFunctionName = AMD_INIT_EARLY;
216 AmdParamStruct.AllocationMethod = PreMemHeap;
217 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
218 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
219 AmdParamStruct.StdHeader.Func = 0;
220 AmdParamStruct.StdHeader.ImageBasePtr = 0;
221 AmdCreateStruct (&AmdParamStruct);
223 AmdEarlyParamsPtr = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
224 OemCustomizeInitEarly (AmdEarlyParamsPtr);
226 status = AmdInitEarly ((AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr);
227 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
228 AmdReleaseStruct (&AmdParamStruct);
230 return (UINT32)status;
234 agesawrapper_amdinitpost (
241 AMD_INTERFACE_PARAMS AmdParamStruct;
242 BIOS_HEAP_MANAGER *BiosManagerPtr;
244 LibAmdMemFill (&AmdParamStruct,
246 sizeof (AMD_INTERFACE_PARAMS),
247 &(AmdParamStruct.StdHeader));
249 AmdParamStruct.AgesaFunctionName = AMD_INIT_POST;
250 AmdParamStruct.AllocationMethod = PreMemHeap;
251 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
252 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
253 AmdParamStruct.StdHeader.Func = 0;
254 AmdParamStruct.StdHeader.ImageBasePtr = 0;
256 AmdCreateStruct (&AmdParamStruct);
257 status = AmdInitPost ((AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr);
258 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
259 AmdReleaseStruct (&AmdParamStruct);
260 /* Initialize heap space */
261 BiosManagerPtr = (BIOS_HEAP_MANAGER *)BIOS_HEAP_START_ADDRESS;
263 HeadPtr = (UINT32 *) ((UINT8 *) BiosManagerPtr + sizeof (BIOS_HEAP_MANAGER));
264 for (i = 0; i < ((BIOS_HEAP_SIZE/4) - (sizeof (BIOS_HEAP_MANAGER)/4)); i++)
266 *HeadPtr = 0x00000000;
269 BiosManagerPtr->StartOfAllocatedNodes = 0;
270 BiosManagerPtr->StartOfFreedNodes = 0;
272 return (UINT32)status;
276 agesawrapper_amdinitenv (
281 AMD_INTERFACE_PARAMS AmdParamStruct;
285 LibAmdMemFill (&AmdParamStruct,
287 sizeof (AMD_INTERFACE_PARAMS),
288 &(AmdParamStruct.StdHeader));
290 AmdParamStruct.AgesaFunctionName = AMD_INIT_ENV;
291 AmdParamStruct.AllocationMethod = PostMemDram;
292 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
293 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
294 AmdParamStruct.StdHeader.Func = 0;
295 AmdParamStruct.StdHeader.ImageBasePtr = 0;
296 AmdCreateStruct (&AmdParamStruct);
297 status = AmdInitEnv ((AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr);
298 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
299 /* Initialize Subordinate Bus Number and Secondary Bus Number
300 * In platform BIOS this address is allocated by PCI enumeration code
303 PciAddress.Address.Bus = 0;
304 PciAddress.Address.Device = 1;
305 PciAddress.Address.Function = 0;
306 PciAddress.Address.Register = 0x18;
307 /* Write to D1F0x18 */
308 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
309 PciValue |= 0x00010100;
310 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
312 /* Initialize GMM Base Address for Legacy Bridge Mode
315 PciAddress.Address.Bus = 1;
316 PciAddress.Address.Device = 5;
317 PciAddress.Address.Function = 0;
318 PciAddress.Address.Register = 0x18;
320 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
321 PciValue |= 0x96000000;
322 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
324 /* Initialize FB Base Address for Legacy Bridge Mode
327 PciAddress.Address.Register = 0x10;
328 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
329 PciValue |= 0x80000000;
330 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
332 /* Initialize GMM Base Address for Pcie Mode
335 PciAddress.Address.Bus = 0;
336 PciAddress.Address.Device = 1;
337 PciAddress.Address.Function = 0;
338 PciAddress.Address.Register = 0x18;
340 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
341 PciValue |= 0x96000000;
342 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
344 /* Initialize FB Base Address for Pcie Mode
347 PciAddress.Address.Register = 0x10;
348 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
349 PciValue |= 0x80000000;
350 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
353 /* Initialize MMIO Base and Limit Address
356 PciAddress.Address.Bus = 0;
357 PciAddress.Address.Device = 1;
358 PciAddress.Address.Function = 0;
359 PciAddress.Address.Register = 0x20;
361 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
362 PciValue |= 0x96009600;
363 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
365 /* Initialize MMIO Prefetchable Memory Limit and Base
368 PciAddress.Address.Register = 0x24;
369 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
370 PciValue |= 0x8FF18001;
371 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
372 AmdReleaseStruct (&AmdParamStruct);
374 return (UINT32)status;
378 agesawrapper_getlateinitptr (
403 agesawrapper_amdinitmid (
408 AMD_INTERFACE_PARAMS AmdParamStruct;
410 /* Enable MMIO on AMD CPU Address Map Controller */
411 agesawrapper_amdinitcpuio ();
413 LibAmdMemFill (&AmdParamStruct,
415 sizeof (AMD_INTERFACE_PARAMS),
416 &(AmdParamStruct.StdHeader));
418 AmdParamStruct.AgesaFunctionName = AMD_INIT_MID;
419 AmdParamStruct.AllocationMethod = PostMemDram;
420 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
421 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
422 AmdParamStruct.StdHeader.Func = 0;
423 AmdParamStruct.StdHeader.ImageBasePtr = 0;
425 AmdCreateStruct (&AmdParamStruct);
427 status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
428 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
429 AmdReleaseStruct (&AmdParamStruct);
431 return (UINT32)status;
435 agesawrapper_amdinitlate (
440 AMD_LATE_PARAMS AmdLateParams;
442 LibAmdMemFill (&AmdLateParams,
444 sizeof (AMD_LATE_PARAMS),
445 &(AmdLateParams.StdHeader));
447 AmdLateParams.StdHeader.AltImageBasePtr = 0;
448 AmdLateParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
449 AmdLateParams.StdHeader.Func = 0;
450 AmdLateParams.StdHeader.ImageBasePtr = 0;
452 Status = AmdInitLate (&AmdLateParams);
453 if (Status != AGESA_SUCCESS) {
454 agesawrapper_amdreadeventlog();
455 ASSERT(Status == AGESA_SUCCESS);
458 DmiTable = AmdLateParams.DmiTable;
459 AcpiPstate = AmdLateParams.AcpiPState;
460 AcpiSrat = AmdLateParams.AcpiSrat;
461 AcpiSlit = AmdLateParams.AcpiSlit;
463 AcpiWheaMce = AmdLateParams.AcpiWheaMce;
464 AcpiWheaCmc = AmdLateParams.AcpiWheaCmc;
465 AcpiAlib = AmdLateParams.AcpiAlib;
467 return (UINT32)Status;
471 agesawrapper_amdlaterunaptask (
478 AP_EXE_PARAMS ApExeParams;
480 LibAmdMemFill (&ApExeParams,
482 sizeof (AP_EXE_PARAMS),
483 &(ApExeParams.StdHeader));
485 ApExeParams.StdHeader.AltImageBasePtr = 0;
486 ApExeParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
487 ApExeParams.StdHeader.Func = 0;
488 ApExeParams.StdHeader.ImageBasePtr = 0;
489 ApExeParams.StdHeader.ImageBasePtr = 0;
490 ApExeParams.FunctionNumber = Func;
491 ApExeParams.RelatedDataBlock = ConfigPtr;
493 Status = AmdLateRunApTask (&ApExeParams);
494 if (Status != AGESA_SUCCESS) {
495 agesawrapper_amdreadeventlog();
496 ASSERT(Status == AGESA_SUCCESS);
499 return (UINT32)Status;
503 agesawrapper_amdreadeventlog (
508 EVENT_PARAMS AmdEventParams;
510 LibAmdMemFill (&AmdEventParams,
512 sizeof (EVENT_PARAMS),
513 &(AmdEventParams.StdHeader));
515 AmdEventParams.StdHeader.AltImageBasePtr = 0;
516 AmdEventParams.StdHeader.CalloutPtr = NULL;
517 AmdEventParams.StdHeader.Func = 0;
518 AmdEventParams.StdHeader.ImageBasePtr = 0;
519 Status = AmdReadEventLog (&AmdEventParams);
520 while (AmdEventParams.EventClass != 0) {
521 printk(BIOS_DEBUG,"\nEventLog: EventClass = %x, EventInfo = %x.\n",AmdEventParams.EventClass,AmdEventParams.EventInfo);
522 printk(BIOS_DEBUG," Param1 = %x, Param2 = %x.\n",AmdEventParams.DataParam1,AmdEventParams.DataParam2);
523 printk(BIOS_DEBUG," Param3 = %x, Param4 = %x.\n",AmdEventParams.DataParam3,AmdEventParams.DataParam4);
524 Status = AmdReadEventLog (&AmdEventParams);
527 return (UINT32)Status;