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"
41 #define FILECODE UNASSIGNED_FILE_FILECODE
43 /*------------------------------------------------------------------------------
44 * D E F I N I T I O N S A N D M A C R O S
45 *------------------------------------------------------------------------------
48 #define MMCONF_ENABLE 1
50 /* ACPI table pointers returned by AmdInitLate */
51 VOID *DmiTable = NULL;
52 VOID *AcpiPstate = NULL;
53 VOID *AcpiSrat = NULL;
54 VOID *AcpiSlit = NULL;
56 VOID *AcpiWheaMce = NULL;
57 VOID *AcpiWheaCmc = NULL;
58 VOID *AcpiAlib = NULL;
61 /*------------------------------------------------------------------------------
62 * T Y P E D E F S A N D S T R U C T U R E S
63 *------------------------------------------------------------------------------
66 /*------------------------------------------------------------------------------
67 * 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
68 *------------------------------------------------------------------------------
71 /*------------------------------------------------------------------------------
72 * E X P O R T E D F U N C T I O N S
73 *------------------------------------------------------------------------------
76 /*------------------------------------------------------------------------------
77 * L O C A L F U N C T I O N S
78 *------------------------------------------------------------------------------
81 agesawrapper_amdinitcpuio (
89 AMD_CONFIG_PARAMS StdHeader;
91 /* Enable legacy video routing: D18F1xF4 VGA Enable */
92 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xF4);
94 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
96 /* The platform BIOS needs to ensure the memory ranges of SB800 legacy
97 * devices (TPM, HPET, BIOS RAM, Watchdog Timer, I/O APIC and ACPI) are
98 * set to non-posted regions.
100 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x84);
101 PciData = 0x00FEDF00; // last address before processor local APIC at FEE00000
102 PciData |= 1 << 7; // set NP (non-posted) bit
103 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
104 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x80);
105 PciData = (0xFED00000 >> 8) | 3; // lowest NP address is HPET at FED00000
106 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
108 /* Map the remaining PCI hole as posted MMIO */
109 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x8C);
110 PciData = 0x00FECF00; // last address before non-posted range
111 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
112 LibAmdMsrRead (0xC001001A, &MsrReg, &StdHeader);
113 MsrReg = (MsrReg >> 8) | 3;
114 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x88);
115 PciData = (UINT32)MsrReg;
116 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
118 /* Send all IO (0000-FFFF) to southbridge. */
119 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xC4);
120 PciData = 0x0000F000;
121 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
122 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xC0);
123 PciData = 0x00000003;
124 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
125 Status = AGESA_SUCCESS;
126 return (UINT32)Status;
130 agesawrapper_amdinitmmio (
138 AMD_CONFIG_PARAMS StdHeader;
140 UINT8 BusRangeVal = 0;
145 Set the MMIO Configuration Base Address and Bus Range onto MMIO configuration base
146 Address MSR register.
149 for (Index = 0; Index < 8; Index++) {
150 BusNum = CONFIG_MMCONF_BUS_NUMBER >> Index;
157 MsrReg = (CONFIG_MMCONF_BASE_ADDRESS | (UINT64)(BusRangeVal << 2) | MMCONF_ENABLE);
158 LibAmdMsrWrite (0xC0010058, &MsrReg, &StdHeader);
161 Set the NB_CFG MSR register. Enable CF8 extended configuration cycles.
163 LibAmdMsrRead (0xC001001F, &MsrReg, &StdHeader);
164 MsrReg = MsrReg | 0x0000400000000000ull;
165 LibAmdMsrWrite (0xC001001F, &MsrReg, &StdHeader);
167 /* Set Ontario Link Data */
168 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE0);
169 PciData = 0x01308002;
170 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
171 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE4);
172 PciData = (AMD_APU_SSID<<0x10)|AMD_APU_SVID;
173 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
175 Status = AGESA_SUCCESS;
176 return (UINT32)Status;
180 agesawrapper_amdinitreset (
185 AMD_INTERFACE_PARAMS AmdParamStruct;
186 AMD_RESET_PARAMS AmdResetParams;
188 LibAmdMemFill (&AmdParamStruct,
190 sizeof (AMD_INTERFACE_PARAMS),
191 &(AmdParamStruct.StdHeader));
194 LibAmdMemFill (&AmdResetParams,
196 sizeof (AMD_RESET_PARAMS),
197 &(AmdResetParams.StdHeader));
199 AmdParamStruct.AgesaFunctionName = AMD_INIT_RESET;
200 AmdParamStruct.AllocationMethod = ByHost;
201 AmdParamStruct.NewStructSize = sizeof(AMD_RESET_PARAMS);
202 AmdParamStruct.NewStructPtr = &AmdResetParams;
203 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
204 AmdParamStruct.StdHeader.CalloutPtr = NULL;
205 AmdParamStruct.StdHeader.Func = 0;
206 AmdParamStruct.StdHeader.ImageBasePtr = 0;
207 AmdCreateStruct (&AmdParamStruct);
208 AmdResetParams.HtConfig.Depth = 0;
210 status = AmdInitReset ((AMD_RESET_PARAMS *)AmdParamStruct.NewStructPtr);
211 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
212 AmdReleaseStruct (&AmdParamStruct);
213 return (UINT32)status;
217 agesawrapper_amdinitearly (
222 AMD_INTERFACE_PARAMS AmdParamStruct;
223 AMD_EARLY_PARAMS *AmdEarlyParamsPtr;
225 LibAmdMemFill (&AmdParamStruct,
227 sizeof (AMD_INTERFACE_PARAMS),
228 &(AmdParamStruct.StdHeader));
230 AmdParamStruct.AgesaFunctionName = AMD_INIT_EARLY;
231 AmdParamStruct.AllocationMethod = PreMemHeap;
232 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
233 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
234 AmdParamStruct.StdHeader.Func = 0;
235 AmdParamStruct.StdHeader.ImageBasePtr = 0;
236 AmdCreateStruct (&AmdParamStruct);
238 AmdEarlyParamsPtr = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
239 OemCustomizeInitEarly (AmdEarlyParamsPtr);
241 status = AmdInitEarly ((AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr);
242 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
243 AmdReleaseStruct (&AmdParamStruct);
245 return (UINT32)status;
249 agesawrapper_amdinitpost (
256 AMD_INTERFACE_PARAMS AmdParamStruct;
257 BIOS_HEAP_MANAGER *BiosManagerPtr;
259 LibAmdMemFill (&AmdParamStruct,
261 sizeof (AMD_INTERFACE_PARAMS),
262 &(AmdParamStruct.StdHeader));
264 AmdParamStruct.AgesaFunctionName = AMD_INIT_POST;
265 AmdParamStruct.AllocationMethod = PreMemHeap;
266 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
267 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
268 AmdParamStruct.StdHeader.Func = 0;
269 AmdParamStruct.StdHeader.ImageBasePtr = 0;
271 AmdCreateStruct (&AmdParamStruct);
272 status = AmdInitPost ((AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr);
273 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
274 AmdReleaseStruct (&AmdParamStruct);
276 /* Initialize heap space */
277 BiosManagerPtr = (BIOS_HEAP_MANAGER *)BIOS_HEAP_START_ADDRESS;
279 HeadPtr = (UINT32 *) ((UINT8 *) BiosManagerPtr + sizeof (BIOS_HEAP_MANAGER));
280 for (i = 0; i < ((BIOS_HEAP_SIZE/4) - (sizeof (BIOS_HEAP_MANAGER)/4)); i++) {
281 *HeadPtr = 0x00000000;
284 BiosManagerPtr->StartOfAllocatedNodes = 0;
285 BiosManagerPtr->StartOfFreedNodes = 0;
287 return (UINT32)status;
291 agesawrapper_amdinitenv (
296 AMD_INTERFACE_PARAMS AmdParamStruct;
300 LibAmdMemFill (&AmdParamStruct,
302 sizeof (AMD_INTERFACE_PARAMS),
303 &(AmdParamStruct.StdHeader));
305 AmdParamStruct.AgesaFunctionName = AMD_INIT_ENV;
306 AmdParamStruct.AllocationMethod = PostMemDram;
307 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
308 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
309 AmdParamStruct.StdHeader.Func = 0;
310 AmdParamStruct.StdHeader.ImageBasePtr = 0;
311 AmdCreateStruct (&AmdParamStruct);
312 status = AmdInitEnv ((AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr);
313 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
314 /* Initialize Subordinate Bus Number and Secondary Bus Number
315 * In platform BIOS this address is allocated by PCI enumeration code
318 PciAddress.Address.Bus = 0;
319 PciAddress.Address.Device = 1;
320 PciAddress.Address.Function = 0;
321 PciAddress.Address.Register = 0x18;
322 /* Write to D1F0x18 */
323 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
324 PciValue |= 0x00010100;
325 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
327 /* Initialize GMM Base Address for Legacy Bridge Mode
330 PciAddress.Address.Bus = 1;
331 PciAddress.Address.Device = 5;
332 PciAddress.Address.Function = 0;
333 PciAddress.Address.Register = 0x18;
335 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
336 PciValue |= 0x96000000;
337 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
339 /* Initialize FB Base Address for Legacy Bridge Mode
342 PciAddress.Address.Register = 0x10;
343 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
344 PciValue |= 0x80000000;
345 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
347 /* Initialize GMM Base Address for Pcie Mode
350 PciAddress.Address.Bus = 0;
351 PciAddress.Address.Device = 1;
352 PciAddress.Address.Function = 0;
353 PciAddress.Address.Register = 0x18;
355 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
356 PciValue |= 0x96000000;
357 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
359 /* Initialize FB Base Address for Pcie Mode
362 PciAddress.Address.Register = 0x10;
363 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
364 PciValue |= 0x80000000;
365 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
367 /* Initialize MMIO Base and Limit Address
370 PciAddress.Address.Bus = 0;
371 PciAddress.Address.Device = 1;
372 PciAddress.Address.Function = 0;
373 PciAddress.Address.Register = 0x20;
375 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
376 PciValue |= 0x96009600;
377 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
379 /* Initialize MMIO Prefetchable Memory Limit and Base
382 PciAddress.Address.Register = 0x24;
383 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
384 PciValue |= 0x8FF18001;
385 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
386 AmdReleaseStruct (&AmdParamStruct);
388 return (UINT32)status;
392 agesawrapper_getlateinitptr (
417 agesawrapper_amdinitmid (
422 AMD_INTERFACE_PARAMS AmdParamStruct;
424 /* Enable MMIO on AMD CPU Address Map Controller */
425 agesawrapper_amdinitcpuio ();
427 LibAmdMemFill (&AmdParamStruct,
429 sizeof (AMD_INTERFACE_PARAMS),
430 &(AmdParamStruct.StdHeader));
432 AmdParamStruct.AgesaFunctionName = AMD_INIT_MID;
433 AmdParamStruct.AllocationMethod = PostMemDram;
434 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
435 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
436 AmdParamStruct.StdHeader.Func = 0;
437 AmdParamStruct.StdHeader.ImageBasePtr = 0;
439 AmdCreateStruct (&AmdParamStruct);
441 status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
442 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
443 AmdReleaseStruct (&AmdParamStruct);
445 return (UINT32)status;
449 agesawrapper_amdinitlate (
454 AMD_INTERFACE_PARAMS AmdParamStruct;
455 AMD_LATE_PARAMS * AmdLateParamsPtr;
457 LibAmdMemFill (&AmdParamStruct,
459 sizeof (AMD_INTERFACE_PARAMS),
460 &(AmdParamStruct.StdHeader));
462 AmdParamStruct.AgesaFunctionName = AMD_INIT_LATE;
463 AmdParamStruct.AllocationMethod = PostMemDram;
464 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
465 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
466 AmdParamStruct.StdHeader.Func = 0;
467 AmdParamStruct.StdHeader.ImageBasePtr = 0;
469 AmdCreateStruct (&AmdParamStruct);
470 AmdLateParamsPtr = (AMD_LATE_PARAMS *) AmdParamStruct.NewStructPtr;
472 printk (BIOS_DEBUG, "agesawrapper_amdinitlate: AmdLateParamsPtr = %X\n", (u32)AmdLateParamsPtr);
474 Status = AmdInitLate (AmdLateParamsPtr);
475 if (Status != AGESA_SUCCESS) {
476 agesawrapper_amdreadeventlog();
477 ASSERT(Status == AGESA_SUCCESS);
480 DmiTable = AmdLateParamsPtr->DmiTable;
481 AcpiPstate = AmdLateParamsPtr->AcpiPState;
482 AcpiSrat = AmdLateParamsPtr->AcpiSrat;
483 AcpiSlit = AmdLateParamsPtr->AcpiSlit;
484 AcpiWheaMce = AmdLateParamsPtr->AcpiWheaMce;
485 AcpiWheaCmc = AmdLateParamsPtr->AcpiWheaCmc;
486 AcpiAlib = AmdLateParamsPtr->AcpiAlib;
488 /* Don't release the structure until coreboot has copied the ACPI tables.
489 * AmdReleaseStruct (&AmdLateParams);
492 return (UINT32)Status;
496 agesawrapper_amdlaterunaptask (
503 AP_EXE_PARAMS ApExeParams;
505 LibAmdMemFill (&ApExeParams,
507 sizeof (AP_EXE_PARAMS),
508 &(ApExeParams.StdHeader));
510 ApExeParams.StdHeader.AltImageBasePtr = 0;
511 ApExeParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
512 ApExeParams.StdHeader.Func = 0;
513 ApExeParams.StdHeader.ImageBasePtr = 0;
514 ApExeParams.FunctionNumber = Func;
515 ApExeParams.RelatedDataBlock = ConfigPtr;
517 Status = AmdLateRunApTask (&ApExeParams);
518 if (Status != AGESA_SUCCESS) {
519 agesawrapper_amdreadeventlog();
520 ASSERT(Status == AGESA_SUCCESS);
523 return (UINT32)Status;
527 agesawrapper_amdreadeventlog (
532 EVENT_PARAMS AmdEventParams;
534 LibAmdMemFill (&AmdEventParams,
536 sizeof (EVENT_PARAMS),
537 &(AmdEventParams.StdHeader));
539 AmdEventParams.StdHeader.AltImageBasePtr = 0;
540 AmdEventParams.StdHeader.CalloutPtr = NULL;
541 AmdEventParams.StdHeader.Func = 0;
542 AmdEventParams.StdHeader.ImageBasePtr = 0;
543 Status = AmdReadEventLog (&AmdEventParams);
544 while (AmdEventParams.EventClass != 0) {
545 printk(BIOS_DEBUG,"\nEventLog: EventClass = %lx, EventInfo = %lx.\n",AmdEventParams.EventClass,AmdEventParams.EventInfo);
546 printk(BIOS_DEBUG," Param1 = %lx, Param2 = %lx.\n",AmdEventParams.DataParam1,AmdEventParams.DataParam2);
547 printk(BIOS_DEBUG," Param3 = %lx, Param4 = %lx.\n",AmdEventParams.DataParam3,AmdEventParams.DataParam4);
548 Status = AmdReadEventLog (&AmdEventParams);
551 return (UINT32)Status;