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);
161 /* Set ROM cache onto WP to decrease post time */
162 MsrReg = (0x0100000000 - CONFIG_ROM_SIZE) | 5;
163 LibAmdMsrWrite (0x20C, &MsrReg, &StdHeader);
164 MsrReg = (0x1000000000 - CONFIG_ROM_SIZE) | 0x800;
165 LibAmdMsrWrite (0x20D, &MsrReg, &StdHeader);
167 Status = AGESA_SUCCESS;
168 return (UINT32)Status;
172 agesawrapper_amdinitreset (
177 AMD_INTERFACE_PARAMS AmdParamStruct;
178 AMD_RESET_PARAMS AmdResetParams;
180 LibAmdMemFill (&AmdParamStruct,
182 sizeof (AMD_INTERFACE_PARAMS),
183 &(AmdParamStruct.StdHeader));
186 LibAmdMemFill (&AmdResetParams,
188 sizeof (AMD_RESET_PARAMS),
189 &(AmdResetParams.StdHeader));
191 AmdParamStruct.AgesaFunctionName = AMD_INIT_RESET;
192 AmdParamStruct.AllocationMethod = ByHost;
193 AmdParamStruct.NewStructSize = sizeof(AMD_RESET_PARAMS);
194 AmdParamStruct.NewStructPtr = &AmdResetParams;
195 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
196 AmdParamStruct.StdHeader.CalloutPtr = NULL;
197 AmdParamStruct.StdHeader.Func = 0;
198 AmdParamStruct.StdHeader.ImageBasePtr = 0;
199 AmdCreateStruct (&AmdParamStruct);
200 AmdResetParams.HtConfig.Depth = 0;
202 status = AmdInitReset ((AMD_RESET_PARAMS *)AmdParamStruct.NewStructPtr);
203 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
204 AmdReleaseStruct (&AmdParamStruct);
205 return (UINT32)status;
209 agesawrapper_amdinitearly (
214 AMD_INTERFACE_PARAMS AmdParamStruct;
215 AMD_EARLY_PARAMS *AmdEarlyParamsPtr;
217 LibAmdMemFill (&AmdParamStruct,
219 sizeof (AMD_INTERFACE_PARAMS),
220 &(AmdParamStruct.StdHeader));
222 AmdParamStruct.AgesaFunctionName = AMD_INIT_EARLY;
223 AmdParamStruct.AllocationMethod = PreMemHeap;
224 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
225 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
226 AmdParamStruct.StdHeader.Func = 0;
227 AmdParamStruct.StdHeader.ImageBasePtr = 0;
228 AmdCreateStruct (&AmdParamStruct);
230 AmdEarlyParamsPtr = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
231 OemCustomizeInitEarly (AmdEarlyParamsPtr);
233 status = AmdInitEarly ((AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr);
234 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
235 AmdReleaseStruct (&AmdParamStruct);
237 return (UINT32)status;
241 agesawrapper_amdinitpost (
248 AMD_INTERFACE_PARAMS AmdParamStruct;
249 BIOS_HEAP_MANAGER *BiosManagerPtr;
251 LibAmdMemFill (&AmdParamStruct,
253 sizeof (AMD_INTERFACE_PARAMS),
254 &(AmdParamStruct.StdHeader));
256 AmdParamStruct.AgesaFunctionName = AMD_INIT_POST;
257 AmdParamStruct.AllocationMethod = PreMemHeap;
258 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
259 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
260 AmdParamStruct.StdHeader.Func = 0;
261 AmdParamStruct.StdHeader.ImageBasePtr = 0;
263 AmdCreateStruct (&AmdParamStruct);
264 status = AmdInitPost ((AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr);
265 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
266 AmdReleaseStruct (&AmdParamStruct);
267 /* Initialize heap space */
268 BiosManagerPtr = (BIOS_HEAP_MANAGER *)BIOS_HEAP_START_ADDRESS;
270 HeadPtr = (UINT32 *) ((UINT8 *) BiosManagerPtr + sizeof (BIOS_HEAP_MANAGER));
271 for (i = 0; i < ((BIOS_HEAP_SIZE/4) - (sizeof (BIOS_HEAP_MANAGER)/4)); i++)
273 *HeadPtr = 0x00000000;
276 BiosManagerPtr->StartOfAllocatedNodes = 0;
277 BiosManagerPtr->StartOfFreedNodes = 0;
279 return (UINT32)status;
283 agesawrapper_amdinitenv (
288 AMD_INTERFACE_PARAMS AmdParamStruct;
292 LibAmdMemFill (&AmdParamStruct,
294 sizeof (AMD_INTERFACE_PARAMS),
295 &(AmdParamStruct.StdHeader));
297 AmdParamStruct.AgesaFunctionName = AMD_INIT_ENV;
298 AmdParamStruct.AllocationMethod = PostMemDram;
299 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
300 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
301 AmdParamStruct.StdHeader.Func = 0;
302 AmdParamStruct.StdHeader.ImageBasePtr = 0;
303 AmdCreateStruct (&AmdParamStruct);
304 status = AmdInitEnv ((AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr);
305 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
306 /* Initialize Subordinate Bus Number and Secondary Bus Number
307 * In platform BIOS this address is allocated by PCI enumeration code
310 PciAddress.Address.Bus = 0;
311 PciAddress.Address.Device = 1;
312 PciAddress.Address.Function = 0;
313 PciAddress.Address.Register = 0x18;
314 /* Write to D1F0x18 */
315 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
316 PciValue |= 0x00010100;
317 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
319 /* Initialize GMM Base Address for Legacy Bridge Mode
322 PciAddress.Address.Bus = 1;
323 PciAddress.Address.Device = 5;
324 PciAddress.Address.Function = 0;
325 PciAddress.Address.Register = 0x18;
327 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
328 PciValue |= 0x96000000;
329 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
331 /* Initialize FB Base Address for Legacy Bridge Mode
334 PciAddress.Address.Register = 0x10;
335 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
336 PciValue |= 0x80000000;
337 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
339 /* Initialize GMM Base Address for Pcie Mode
342 PciAddress.Address.Bus = 0;
343 PciAddress.Address.Device = 1;
344 PciAddress.Address.Function = 0;
345 PciAddress.Address.Register = 0x18;
347 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
348 PciValue |= 0x96000000;
349 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
351 /* Initialize FB Base Address for Pcie Mode
354 PciAddress.Address.Register = 0x10;
355 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
356 PciValue |= 0x80000000;
357 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
360 /* Initialize MMIO Base and Limit Address
363 PciAddress.Address.Bus = 0;
364 PciAddress.Address.Device = 1;
365 PciAddress.Address.Function = 0;
366 PciAddress.Address.Register = 0x20;
368 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
369 PciValue |= 0x96009600;
370 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
372 /* Initialize MMIO Prefetchable Memory Limit and Base
375 PciAddress.Address.Register = 0x24;
376 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
377 PciValue |= 0x8FF18001;
378 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
379 AmdReleaseStruct (&AmdParamStruct);
381 return (UINT32)status;
385 agesawrapper_getlateinitptr (
410 agesawrapper_amdinitmid (
415 AMD_INTERFACE_PARAMS AmdParamStruct;
417 /* Enable MMIO on AMD CPU Address Map Controller */
418 agesawrapper_amdinitcpuio ();
420 LibAmdMemFill (&AmdParamStruct,
422 sizeof (AMD_INTERFACE_PARAMS),
423 &(AmdParamStruct.StdHeader));
425 AmdParamStruct.AgesaFunctionName = AMD_INIT_MID;
426 AmdParamStruct.AllocationMethod = PostMemDram;
427 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
428 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
429 AmdParamStruct.StdHeader.Func = 0;
430 AmdParamStruct.StdHeader.ImageBasePtr = 0;
432 AmdCreateStruct (&AmdParamStruct);
434 status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
435 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
436 AmdReleaseStruct (&AmdParamStruct);
438 return (UINT32)status;
442 agesawrapper_amdinitlate (
447 AMD_LATE_PARAMS AmdLateParams;
449 LibAmdMemFill (&AmdLateParams,
451 sizeof (AMD_LATE_PARAMS),
452 &(AmdLateParams.StdHeader));
454 AmdLateParams.StdHeader.AltImageBasePtr = 0;
455 AmdLateParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
456 AmdLateParams.StdHeader.Func = 0;
457 AmdLateParams.StdHeader.ImageBasePtr = 0;
459 Status = AmdInitLate (&AmdLateParams);
460 if (Status != AGESA_SUCCESS) {
461 agesawrapper_amdreadeventlog();
462 ASSERT(Status == AGESA_SUCCESS);
465 DmiTable = AmdLateParams.DmiTable;
466 AcpiPstate = AmdLateParams.AcpiPState;
467 AcpiSrat = AmdLateParams.AcpiSrat;
468 AcpiSlit = AmdLateParams.AcpiSlit;
470 AcpiWheaMce = AmdLateParams.AcpiWheaMce;
471 AcpiWheaCmc = AmdLateParams.AcpiWheaCmc;
472 AcpiAlib = AmdLateParams.AcpiAlib;
474 return (UINT32)Status;
478 agesawrapper_amdlaterunaptask (
484 AMD_LATE_PARAMS AmdLateParams;
486 LibAmdMemFill (&AmdLateParams,
488 sizeof (AMD_LATE_PARAMS),
489 &(AmdLateParams.StdHeader));
491 AmdLateParams.StdHeader.AltImageBasePtr = 0;
492 AmdLateParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
493 AmdLateParams.StdHeader.Func = 0;
494 AmdLateParams.StdHeader.ImageBasePtr = 0;
496 Status = AmdLateRunApTask (&AmdLateParams);
497 if (Status != AGESA_SUCCESS) {
498 agesawrapper_amdreadeventlog();
499 ASSERT(Status == AGESA_SUCCESS);
502 DmiTable = AmdLateParams.DmiTable;
503 AcpiPstate = AmdLateParams.AcpiPState;
504 AcpiSrat = AmdLateParams.AcpiSrat;
505 AcpiSlit = AmdLateParams.AcpiSlit;
507 AcpiWheaMce = AmdLateParams.AcpiWheaMce;
508 AcpiWheaCmc = AmdLateParams.AcpiWheaCmc;
509 AcpiAlib = AmdLateParams.AcpiAlib;
511 return (UINT32)Status;
515 agesawrapper_amdreadeventlog (
520 EVENT_PARAMS AmdEventParams;
522 LibAmdMemFill (&AmdEventParams,
524 sizeof (EVENT_PARAMS),
525 &(AmdEventParams.StdHeader));
527 AmdEventParams.StdHeader.AltImageBasePtr = 0;
528 AmdEventParams.StdHeader.CalloutPtr = NULL;
529 AmdEventParams.StdHeader.Func = 0;
530 AmdEventParams.StdHeader.ImageBasePtr = 0;
531 Status = AmdReadEventLog (&AmdEventParams);
532 while (AmdEventParams.EventClass != 0) {
533 printk(BIOS_DEBUG,"\nEventLog: EventClass = %x, EventInfo = %x.\n",AmdEventParams.EventClass,AmdEventParams.EventInfo);
534 printk(BIOS_DEBUG," Param1 = %x, Param2 = %x.\n",AmdEventParams.DataParam1,AmdEventParams.DataParam2);
535 printk(BIOS_DEBUG," Param3 = %x, Param4 = %x.\n",AmdEventParams.DataParam3,AmdEventParams.DataParam4);
536 Status = AmdReadEventLog (&AmdEventParams);
539 return (UINT32)Status;