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++)
280 *HeadPtr = 0x00000000;
283 BiosManagerPtr->StartOfAllocatedNodes = 0;
284 BiosManagerPtr->StartOfFreedNodes = 0;
286 return (UINT32)status;
290 agesawrapper_amdinitenv (
295 AMD_INTERFACE_PARAMS AmdParamStruct;
299 LibAmdMemFill (&AmdParamStruct,
301 sizeof (AMD_INTERFACE_PARAMS),
302 &(AmdParamStruct.StdHeader));
304 AmdParamStruct.AgesaFunctionName = AMD_INIT_ENV;
305 AmdParamStruct.AllocationMethod = PostMemDram;
306 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
307 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
308 AmdParamStruct.StdHeader.Func = 0;
309 AmdParamStruct.StdHeader.ImageBasePtr = 0;
310 AmdCreateStruct (&AmdParamStruct);
311 status = AmdInitEnv ((AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr);
312 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
313 /* Initialize Subordinate Bus Number and Secondary Bus Number
314 * In platform BIOS this address is allocated by PCI enumeration code
317 PciAddress.Address.Bus = 0;
318 PciAddress.Address.Device = 1;
319 PciAddress.Address.Function = 0;
320 PciAddress.Address.Register = 0x18;
321 /* Write to D1F0x18 */
322 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
323 PciValue |= 0x00010100;
324 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
326 /* Initialize GMM Base Address for Legacy Bridge Mode
329 PciAddress.Address.Bus = 1;
330 PciAddress.Address.Device = 5;
331 PciAddress.Address.Function = 0;
332 PciAddress.Address.Register = 0x18;
334 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
335 PciValue |= 0x96000000;
336 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
338 /* Initialize FB Base Address for Legacy Bridge Mode
341 PciAddress.Address.Register = 0x10;
342 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
343 PciValue |= 0x80000000;
344 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
346 /* Initialize GMM Base Address for Pcie Mode
349 PciAddress.Address.Bus = 0;
350 PciAddress.Address.Device = 1;
351 PciAddress.Address.Function = 0;
352 PciAddress.Address.Register = 0x18;
354 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
355 PciValue |= 0x96000000;
356 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
358 /* Initialize FB Base Address for Pcie Mode
361 PciAddress.Address.Register = 0x10;
362 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
363 PciValue |= 0x80000000;
364 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
366 /* Initialize MMIO Base and Limit Address
369 PciAddress.Address.Bus = 0;
370 PciAddress.Address.Device = 1;
371 PciAddress.Address.Function = 0;
372 PciAddress.Address.Register = 0x20;
374 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
375 PciValue |= 0x96009600;
376 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
378 /* Initialize MMIO Prefetchable Memory Limit and Base
381 PciAddress.Address.Register = 0x24;
382 LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
383 PciValue |= 0x8FF18001;
384 LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
385 AmdReleaseStruct (&AmdParamStruct);
387 return (UINT32)status;
391 agesawrapper_getlateinitptr (
416 agesawrapper_amdinitmid (
421 AMD_INTERFACE_PARAMS AmdParamStruct;
423 /* Enable MMIO on AMD CPU Address Map Controller */
424 agesawrapper_amdinitcpuio ();
426 LibAmdMemFill (&AmdParamStruct,
428 sizeof (AMD_INTERFACE_PARAMS),
429 &(AmdParamStruct.StdHeader));
431 AmdParamStruct.AgesaFunctionName = AMD_INIT_MID;
432 AmdParamStruct.AllocationMethod = PostMemDram;
433 AmdParamStruct.StdHeader.AltImageBasePtr = 0;
434 AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
435 AmdParamStruct.StdHeader.Func = 0;
436 AmdParamStruct.StdHeader.ImageBasePtr = 0;
438 AmdCreateStruct (&AmdParamStruct);
440 status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
441 if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
442 AmdReleaseStruct (&AmdParamStruct);
444 return (UINT32)status;
448 agesawrapper_amdinitlate (
453 AMD_LATE_PARAMS AmdLateParams;
455 LibAmdMemFill (&AmdLateParams,
457 sizeof (AMD_LATE_PARAMS),
458 &(AmdLateParams.StdHeader));
460 AmdLateParams.StdHeader.AltImageBasePtr = 0;
461 AmdLateParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
462 AmdLateParams.StdHeader.Func = 0;
463 AmdLateParams.StdHeader.ImageBasePtr = 0;
465 Status = AmdInitLate (&AmdLateParams);
466 if (Status != AGESA_SUCCESS) {
467 agesawrapper_amdreadeventlog();
468 ASSERT(Status == AGESA_SUCCESS);
471 DmiTable = AmdLateParams.DmiTable;
472 AcpiPstate = AmdLateParams.AcpiPState;
473 AcpiSrat = AmdLateParams.AcpiSrat;
474 AcpiSlit = AmdLateParams.AcpiSlit;
476 AcpiWheaMce = AmdLateParams.AcpiWheaMce;
477 AcpiWheaCmc = AmdLateParams.AcpiWheaCmc;
478 AcpiAlib = AmdLateParams.AcpiAlib;
480 return (UINT32)Status;
484 agesawrapper_amdlaterunaptask (
491 AP_EXE_PARAMS ApExeParams;
493 LibAmdMemFill (&ApExeParams,
495 sizeof (AP_EXE_PARAMS),
496 &(ApExeParams.StdHeader));
498 ApExeParams.StdHeader.AltImageBasePtr = 0;
499 ApExeParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
500 ApExeParams.StdHeader.Func = 0;
501 ApExeParams.StdHeader.ImageBasePtr = 0;
502 ApExeParams.StdHeader.ImageBasePtr = 0;
503 ApExeParams.FunctionNumber = Func;
504 ApExeParams.RelatedDataBlock = ConfigPtr;
506 Status = AmdLateRunApTask (&ApExeParams);
507 if (Status != AGESA_SUCCESS) {
508 agesawrapper_amdreadeventlog();
509 ASSERT(Status == AGESA_SUCCESS);
512 return (UINT32)Status;
516 agesawrapper_amdreadeventlog (
521 EVENT_PARAMS AmdEventParams;
523 LibAmdMemFill (&AmdEventParams,
525 sizeof (EVENT_PARAMS),
526 &(AmdEventParams.StdHeader));
528 AmdEventParams.StdHeader.AltImageBasePtr = 0;
529 AmdEventParams.StdHeader.CalloutPtr = NULL;
530 AmdEventParams.StdHeader.Func = 0;
531 AmdEventParams.StdHeader.ImageBasePtr = 0;
532 Status = AmdReadEventLog (&AmdEventParams);
533 while (AmdEventParams.EventClass != 0) {
534 printk(BIOS_DEBUG,"\nEventLog: EventClass = %lx, EventInfo = %lx.\n",AmdEventParams.EventClass,AmdEventParams.EventInfo);
535 printk(BIOS_DEBUG," Param1 = %lx, Param2 = %lx.\n",AmdEventParams.DataParam1,AmdEventParams.DataParam2);
536 printk(BIOS_DEBUG," Param3 = %lx, Param4 = %lx.\n",AmdEventParams.DataParam3,AmdEventParams.DataParam4);
537 Status = AmdReadEventLog (&AmdEventParams);
540 return (UINT32)Status;