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;
60 /*------------------------------------------------------------------------------
61 * T Y P E D E F S A N D S T R U C T U R E S
62 *------------------------------------------------------------------------------
65 /*------------------------------------------------------------------------------
66 * 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
67 *------------------------------------------------------------------------------
70 /*------------------------------------------------------------------------------
71 * E X P O R T E D F U N C T I O N S
72 *------------------------------------------------------------------------------
75 /*------------------------------------------------------------------------------
76 * L O C A L F U N C T I O N S
77 *------------------------------------------------------------------------------
80 agesawrapper_amdinitcpuio (
88 AMD_CONFIG_PARAMS StdHeader;
90 /* Enable legacy video routing: D18F1xF4 VGA Enable */
91 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xF4);
93 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
95 /* The platform BIOS needs to ensure the memory ranges of SB800 legacy
96 * devices (TPM, HPET, BIOS RAM, Watchdog Timer, I/O APIC and ACPI) are
97 * set to non-posted regions.
99 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x84);
100 PciData = 0x00FEDF00; // last address before processor local APIC at FEE00000
101 PciData |= 1 << 7; // set NP (non-posted) bit
102 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
103 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x80);
104 PciData = (0xFED00000 >> 8) | 3; // lowest NP address is HPET at FED00000
105 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
107 /* Map the remaining PCI hole as posted MMIO */
108 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x8C);
109 PciData = 0x00FECF00; // last address before non-posted range
110 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
111 LibAmdMsrRead (0xC001001A, &MsrReg, &StdHeader);
112 MsrReg = (MsrReg >> 8) | 3;
113 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0x88);
114 PciData = (UINT32)MsrReg;
115 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
117 /* Send all IO (0000-FFFF) to southbridge. */
118 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xC4);
119 PciData = 0x0000F000;
120 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
121 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xC0);
122 PciData = 0x00000003;
123 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
124 Status = AGESA_SUCCESS;
125 return (UINT32)Status;
129 agesawrapper_amdinitmmio (
137 AMD_CONFIG_PARAMS StdHeader;
139 UINT8 BusRangeVal = 0;
144 Set the MMIO Configuration Base Address and Bus Range onto MMIO configuration base
145 Address MSR register.
148 for (Index = 0; Index < 8; Index++) {
149 BusNum = CONFIG_MMCONF_BUS_NUMBER >> Index;
156 MsrReg = (CONFIG_MMCONF_BASE_ADDRESS | (UINT64)(BusRangeVal << 2) | MMCONF_ENABLE);
157 LibAmdMsrWrite (0xC0010058, &MsrReg, &StdHeader);
160 Set the NB_CFG MSR register. Enable CF8 extended configuration cycles.
162 LibAmdMsrRead (0xC001001F, &MsrReg, &StdHeader);
163 MsrReg = MsrReg | 0x0000400000000000ull;
164 LibAmdMsrWrite (0xC001001F, &MsrReg, &StdHeader);
166 /* Set Ontario Link Data */
167 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE0);
168 PciData = 0x01308002;
169 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
170 PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE4);
171 PciData = (AMD_APU_SSID<<0x10)|AMD_APU_SVID;
172 LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
174 Status = AGESA_SUCCESS;
175 return (UINT32)Status;
179 agesawrapper_amdinitreset (
184 AMD_INTERFACE_PARAMS AmdParamStruct;
185 AMD_RESET_PARAMS AmdResetParams;
187 LibAmdMemFill (&AmdParamStruct,
189 sizeof (AMD_INTERFACE_PARAMS),
190 &(AmdParamStruct.StdHeader));
192 LibAmdMemFill (&AmdResetParams,
194 sizeof (AMD_RESET_PARAMS),
195 &(AmdResetParams.StdHeader));
197 AmdParamStruct.AgesaFunctionName = AMD_INIT_RESET;
198 AmdParamStruct.AllocationMethod = ByHost;
199 AmdParamStruct.NewStructSize = sizeof(AMD_RESET_PARAMS);
200 AmdParamStruct.NewStructPtr = &AmdResetParams;
201 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
202 AmdParamStruct.StdHeader.CalloutPtr = NULL;
203 AmdParamStruct.StdHeader.Func = 0;
204 AmdParamStruct.StdHeader.ImageBasePtr = 0;
205 AmdCreateStruct (&AmdParamStruct);
206 AmdResetParams.HtConfig.Depth = 0;
208 status = AmdInitReset ((AMD_RESET_PARAMS *)AmdParamStruct.NewStructPtr);
209 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
210 AmdReleaseStruct (&AmdParamStruct);
211 return (UINT32)status;
215 agesawrapper_amdinitearly (
220 AMD_INTERFACE_PARAMS AmdParamStruct;
221 AMD_EARLY_PARAMS *AmdEarlyParamsPtr;
223 LibAmdMemFill (&AmdParamStruct,
225 sizeof (AMD_INTERFACE_PARAMS),
226 &(AmdParamStruct.StdHeader));
228 AmdParamStruct.AgesaFunctionName = AMD_INIT_EARLY;
229 AmdParamStruct.AllocationMethod = PreMemHeap;
230 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
231 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
232 AmdParamStruct.StdHeader.Func = 0;
233 AmdParamStruct.StdHeader.ImageBasePtr = 0;
234 AmdCreateStruct (&AmdParamStruct);
236 AmdEarlyParamsPtr = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
237 OemCustomizeInitEarly (AmdEarlyParamsPtr);
239 status = AmdInitEarly ((AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr);
240 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
241 AmdReleaseStruct (&AmdParamStruct);
243 return (UINT32)status;
247 agesawrapper_amdinitpost (
254 AMD_INTERFACE_PARAMS AmdParamStruct;
255 BIOS_HEAP_MANAGER *BiosManagerPtr;
257 LibAmdMemFill (&AmdParamStruct,
259 sizeof (AMD_INTERFACE_PARAMS),
260 &(AmdParamStruct.StdHeader));
262 AmdParamStruct.AgesaFunctionName = AMD_INIT_POST;
263 AmdParamStruct.AllocationMethod = PreMemHeap;
264 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
265 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
266 AmdParamStruct.StdHeader.Func = 0;
267 AmdParamStruct.StdHeader.ImageBasePtr = 0;
269 AmdCreateStruct (&AmdParamStruct);
270 status = AmdInitPost ((AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr);
271 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
272 AmdReleaseStruct (&AmdParamStruct);
274 /* Initialize heap space */
275 BiosManagerPtr = (BIOS_HEAP_MANAGER *)BIOS_HEAP_START_ADDRESS;
277 HeadPtr = (UINT32 *) ((UINT8 *) BiosManagerPtr + sizeof (BIOS_HEAP_MANAGER));
278 for (i = 0; i < ((BIOS_HEAP_SIZE/4) - (sizeof (BIOS_HEAP_MANAGER)/4)); i++) {
279 *HeadPtr = 0x00000000;
282 BiosManagerPtr->StartOfAllocatedNodes = 0;
283 BiosManagerPtr->StartOfFreedNodes = 0;
285 return (UINT32)status;
289 agesawrapper_amdinitenv (
294 AMD_INTERFACE_PARAMS AmdParamStruct;
298 LibAmdMemFill (&AmdParamStruct,
300 sizeof (AMD_INTERFACE_PARAMS),
301 &(AmdParamStruct.StdHeader));
303 AmdParamStruct.AgesaFunctionName = AMD_INIT_ENV;
304 AmdParamStruct.AllocationMethod = PostMemDram;
305 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
306 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
307 AmdParamStruct.StdHeader.Func = 0;
308 AmdParamStruct.StdHeader.ImageBasePtr = 0;
309 AmdCreateStruct (&AmdParamStruct);
310 status = AmdInitEnv ((AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr);
311 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
312 /* Initialize Subordinate Bus Number and Secondary Bus Number
313 * In platform BIOS this address is allocated by PCI enumeration code
316 PciAddress.Address.Bus = 0;
317 PciAddress.Address.Device = 1;
318 PciAddress.Address.Function = 0;
319 PciAddress.Address.Register = 0x18;
320 /* Write to D1F0x18 */
321 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
322 PciValue |= 0x00010100;
323 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
325 /* Initialize GMM Base Address for Legacy Bridge Mode
328 PciAddress.Address.Bus = 1;
329 PciAddress.Address.Device = 5;
330 PciAddress.Address.Function = 0;
331 PciAddress.Address.Register = 0x18;
333 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
334 PciValue |= 0x96000000;
335 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
337 /* Initialize FB Base Address for Legacy Bridge Mode
340 PciAddress.Address.Register = 0x10;
341 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
342 PciValue |= 0x80000000;
343 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
345 /* Initialize GMM Base Address for Pcie Mode
348 PciAddress.Address.Bus = 0;
349 PciAddress.Address.Device = 1;
350 PciAddress.Address.Function = 0;
351 PciAddress.Address.Register = 0x18;
353 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
354 PciValue |= 0x96000000;
355 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
357 /* Initialize FB Base Address for Pcie Mode
360 PciAddress.Address.Register = 0x10;
361 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
362 PciValue |= 0x80000000;
363 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
365 /* Initialize MMIO Base and Limit Address
368 PciAddress.Address.Bus = 0;
369 PciAddress.Address.Device = 1;
370 PciAddress.Address.Function = 0;
371 PciAddress.Address.Register = 0x20;
373 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
374 PciValue |= 0x96009600;
375 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
377 /* Initialize MMIO Prefetchable Memory Limit and Base
380 PciAddress.Address.Register = 0x24;
381 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
382 PciValue |= 0x8FF18001;
383 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
384 AmdReleaseStruct (&AmdParamStruct);
386 return (UINT32)status;
390 agesawrapper_getlateinitptr (
415 agesawrapper_amdinitmid (
420 AMD_INTERFACE_PARAMS AmdParamStruct;
422 /* Enable MMIO on AMD CPU Address Map Controller */
423 agesawrapper_amdinitcpuio ();
425 LibAmdMemFill (&AmdParamStruct,
427 sizeof (AMD_INTERFACE_PARAMS),
428 &(AmdParamStruct.StdHeader));
430 AmdParamStruct.AgesaFunctionName = AMD_INIT_MID;
431 AmdParamStruct.AllocationMethod = PostMemDram;
432 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
433 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
434 AmdParamStruct.StdHeader.Func = 0;
435 AmdParamStruct.StdHeader.ImageBasePtr = 0;
437 AmdCreateStruct (&AmdParamStruct);
439 status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
440 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
441 AmdReleaseStruct (&AmdParamStruct);
443 return (UINT32)status;
447 agesawrapper_amdinitlate (
452 AMD_INTERFACE_PARAMS AmdParamStruct;
453 AMD_LATE_PARAMS * AmdLateParamsPtr;
455 LibAmdMemFill (&AmdParamStruct,
457 sizeof (AMD_INTERFACE_PARAMS),
458 &(AmdParamStruct.StdHeader));
460 AmdParamStruct.AgesaFunctionName = AMD_INIT_LATE;
461 AmdParamStruct.AllocationMethod = PostMemDram;
462 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
463 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
464 AmdParamStruct.StdHeader.Func = 0;
465 AmdParamStruct.StdHeader.ImageBasePtr = 0;
467 AmdCreateStruct (&AmdParamStruct);
468 AmdLateParamsPtr = (AMD_LATE_PARAMS *) AmdParamStruct.NewStructPtr;
470 printk (BIOS_DEBUG, "agesawrapper_amdinitlate: AmdLateParamsPtr = %X\n", (u32)AmdLateParamsPtr);
472 Status = AmdInitLate (AmdLateParamsPtr);
473 if (Status != AGESA_SUCCESS) {
474 agesawrapper_amdreadeventlog();
475 ASSERT(Status == AGESA_SUCCESS);
478 DmiTable = AmdLateParamsPtr->DmiTable;
479 AcpiPstate = AmdLateParamsPtr->AcpiPState;
480 AcpiSrat = AmdLateParamsPtr->AcpiSrat;
481 AcpiSlit = AmdLateParamsPtr->AcpiSlit;
482 AcpiWheaMce = AmdLateParamsPtr->AcpiWheaMce;
483 AcpiWheaCmc = AmdLateParamsPtr->AcpiWheaCmc;
484 AcpiAlib = AmdLateParamsPtr->AcpiAlib;
486 printk(BIOS_DEBUG, "In %s, AGESA generated ACPI tables:\n"
487 " DmiTable:%p\n AcpiPstate: %p\n AcpiSrat:%p\n AcpiSlit:%p\n"
488 " Mce:%p\n Cmc:%p\n Alib:%p\n",
489 __func__, DmiTable, AcpiPstate, AcpiSrat, AcpiSlit,
490 AcpiWheaMce, AcpiWheaCmc, AcpiAlib);
492 /* Don't release the structure until coreboot has copied the ACPI tables.
493 * AmdReleaseStruct (&AmdLateParams);
496 return (UINT32)Status;
500 agesawrapper_amdlaterunaptask (
507 AP_EXE_PARAMS ApExeParams;
509 LibAmdMemFill (&ApExeParams,
511 sizeof (AP_EXE_PARAMS),
512 &(ApExeParams.StdHeader));
514 ApExeParams.StdHeader.AltImageBasePtr = 0;
515 ApExeParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
516 ApExeParams.StdHeader.Func = 0;
517 ApExeParams.StdHeader.ImageBasePtr = 0;
518 ApExeParams.FunctionNumber = Func;
519 ApExeParams.RelatedDataBlock = ConfigPtr;
521 Status = AmdLateRunApTask (&ApExeParams);
522 if (Status != AGESA_SUCCESS) {
523 agesawrapper_amdreadeventlog();
524 ASSERT(Status == AGESA_SUCCESS);
527 return (UINT32)Status;
531 agesawrapper_amdreadeventlog (
536 EVENT_PARAMS AmdEventParams;
538 LibAmdMemFill (&AmdEventParams,
540 sizeof (EVENT_PARAMS),
541 &(AmdEventParams.StdHeader));
543 AmdEventParams.StdHeader.AltImageBasePtr = 0;
544 AmdEventParams.StdHeader.CalloutPtr = NULL;
545 AmdEventParams.StdHeader.Func = 0;
546 AmdEventParams.StdHeader.ImageBasePtr = 0;
547 Status = AmdReadEventLog (&AmdEventParams);
548 while (AmdEventParams.EventClass != 0) {
549 printk(BIOS_DEBUG,"\nEventLog: EventClass = %lx, EventInfo = %lx.\n",AmdEventParams.EventClass,AmdEventParams.EventInfo);
550 printk(BIOS_DEBUG," Param1 = %lx, Param2 = %lx.\n",AmdEventParams.DataParam1,AmdEventParams.DataParam2);
551 printk(BIOS_DEBUG," Param3 = %lx, Param4 = %lx.\n",AmdEventParams.DataParam3,AmdEventParams.DataParam4);
552 Status = AmdReadEventLog (&AmdEventParams);
555 return (UINT32)Status;