55e848867733bf0ce7c1c04168afb693f47e1210
[coreboot.git] / src / mainboard / amd / persimmon / agesawrapper.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2011 Advanced Micro Devices, Inc.
5  *
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.
9  *
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.
14  *
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
18  */
19
20 /*-----------------------------------------------------------------------------
21  *                                              M O D U L E S           U S E D
22  *-----------------------------------------------------------------------------
23  */
24
25 #include <stdint.h>
26 #include <string.h>
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"
36 #include "amdlib.h"
37 #include "PlatformGnbPcieComplex.h"
38 #include "Filecode.h"
39 #include <arch/io.h>
40
41 #define FILECODE UNASSIGNED_FILE_FILECODE
42
43 /*------------------------------------------------------------------------------
44  *                                      D E F I N I T I O N S           A N D           M A C R O S
45  *------------------------------------------------------------------------------
46  */
47
48 #define MMCONF_ENABLE 1
49
50 /* ACPI table pointers returned by AmdInitLate */
51 VOID *DmiTable          = NULL;
52 VOID *AcpiPstate        = NULL;
53 VOID *AcpiSrat          = NULL;
54 VOID *AcpiSlit          = NULL;
55
56 VOID *AcpiWheaMce       = NULL;
57 VOID *AcpiWheaCmc       = NULL;
58 VOID *AcpiAlib          = NULL;
59
60 /*------------------------------------------------------------------------------
61  *                              T Y P E D E F S          A N D           S T R U C T U R E S
62  *------------------------------------------------------------------------------
63  */
64
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  *------------------------------------------------------------------------------
68  */
69
70 /*------------------------------------------------------------------------------
71  *                                              E X P O R T E D         F U N C T I O N S
72  *------------------------------------------------------------------------------
73  */
74
75 /*------------------------------------------------------------------------------
76  *                                              L O C A L               F U N C T I O N S
77  *------------------------------------------------------------------------------
78  */
79 UINT32
80 agesawrapper_amdinitcpuio (
81         VOID
82         )
83 {
84         AGESA_STATUS            Status;
85         UINT64                          MsrReg;
86         UINT32                          PciData;
87         PCI_ADDR                        PciAddress;
88         AMD_CONFIG_PARAMS       StdHeader;
89
90         /* Enable legacy video routing: D18F1xF4 VGA Enable */
91         PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xF4);
92         PciData = 1;
93         LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader);
94
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.
98          */
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);
106
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);
116
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;
126 }
127
128 UINT32
129 agesawrapper_amdinitmmio (
130         VOID
131         )
132 {
133         AGESA_STATUS            Status;
134         UINT64                          MsrReg;
135         UINT32                          PciData;
136         PCI_ADDR                        PciAddress;
137         AMD_CONFIG_PARAMS       StdHeader;
138
139         UINT8                           BusRangeVal = 0;
140         UINT8                           BusNum;
141         UINT8                           Index;
142
143         /*
144          Set the MMIO Configuration Base Address and Bus Range onto MMIO configuration base
145          Address MSR register.
146         */
147
148         for (Index = 0; Index < 8; Index++) {
149                 BusNum = CONFIG_MMCONF_BUS_NUMBER >> Index;
150                 if (BusNum == 1) {
151                         BusRangeVal = Index;
152                         break;
153                 }
154         }
155
156         MsrReg = (CONFIG_MMCONF_BASE_ADDRESS | (UINT64)(BusRangeVal << 2) | MMCONF_ENABLE);
157         LibAmdMsrWrite (0xC0010058, &MsrReg, &StdHeader);
158
159         /*
160          Set the NB_CFG MSR register. Enable CF8 extended configuration cycles.
161         */
162         LibAmdMsrRead (0xC001001F, &MsrReg, &StdHeader);
163         MsrReg = MsrReg | 0x0000400000000000ull;
164         LibAmdMsrWrite (0xC001001F, &MsrReg, &StdHeader);
165
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);
173
174         Status = AGESA_SUCCESS;
175         return (UINT32)Status;
176 }
177
178 UINT32
179 agesawrapper_amdinitreset (
180         VOID
181         )
182 {
183         AGESA_STATUS status;
184         AMD_INTERFACE_PARAMS AmdParamStruct;
185         AMD_RESET_PARAMS AmdResetParams;
186
187         LibAmdMemFill (&AmdParamStruct,
188                                         0,
189                                         sizeof (AMD_INTERFACE_PARAMS),
190                                         &(AmdParamStruct.StdHeader));
191
192         LibAmdMemFill (&AmdResetParams,
193                                         0,
194                                         sizeof (AMD_RESET_PARAMS),
195                                         &(AmdResetParams.StdHeader));
196
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;
207
208         status = AmdInitReset ((AMD_RESET_PARAMS *)AmdParamStruct.NewStructPtr);
209         if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
210         AmdReleaseStruct (&AmdParamStruct);
211         return (UINT32)status;
212  }
213
214 UINT32
215 agesawrapper_amdinitearly (
216         VOID
217         )
218 {
219         AGESA_STATUS status;
220         AMD_INTERFACE_PARAMS AmdParamStruct;
221         AMD_EARLY_PARAMS                 *AmdEarlyParamsPtr;
222
223         LibAmdMemFill (&AmdParamStruct,
224                                         0,
225                                         sizeof (AMD_INTERFACE_PARAMS),
226                                         &(AmdParamStruct.StdHeader));
227
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);
235
236         AmdEarlyParamsPtr = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
237         OemCustomizeInitEarly (AmdEarlyParamsPtr);
238
239         status = AmdInitEarly ((AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr);
240         if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
241         AmdReleaseStruct (&AmdParamStruct);
242
243         return (UINT32)status;
244 }
245
246 UINT32
247 agesawrapper_amdinitpost (
248         VOID
249         )
250 {
251         AGESA_STATUS status;
252         UINT16                                  i;
253         UINT32                                  *HeadPtr;
254         AMD_INTERFACE_PARAMS    AmdParamStruct;
255         BIOS_HEAP_MANAGER               *BiosManagerPtr;
256
257         LibAmdMemFill (&AmdParamStruct,
258                                         0,
259                                         sizeof (AMD_INTERFACE_PARAMS),
260                                         &(AmdParamStruct.StdHeader));
261
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;
268
269         AmdCreateStruct (&AmdParamStruct);
270         status = AmdInitPost ((AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr);
271         if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
272         AmdReleaseStruct (&AmdParamStruct);
273
274         /* Initialize heap space */
275         BiosManagerPtr = (BIOS_HEAP_MANAGER *)BIOS_HEAP_START_ADDRESS;
276
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         {
280                 *HeadPtr = 0x00000000;
281                 HeadPtr++;
282         }
283         BiosManagerPtr->StartOfAllocatedNodes = 0;
284         BiosManagerPtr->StartOfFreedNodes = 0;
285
286         return (UINT32)status;
287 }
288
289 UINT32
290 agesawrapper_amdinitenv (
291         VOID
292         )
293 {
294         AGESA_STATUS status;
295         AMD_INTERFACE_PARAMS AmdParamStruct;
296         PCI_ADDR                         PciAddress;
297         UINT32                           PciValue;
298
299         LibAmdMemFill (&AmdParamStruct,
300                                         0,
301                                         sizeof (AMD_INTERFACE_PARAMS),
302                                         &(AmdParamStruct.StdHeader));
303
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
315                  Modify D1F0x18
316          */
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);
325
326         /* Initialize GMM Base Address for Legacy Bridge Mode
327         *       Modify B1D5F0x18
328         */
329         PciAddress.Address.Bus = 1;
330         PciAddress.Address.Device = 5;
331         PciAddress.Address.Function = 0;
332         PciAddress.Address.Register = 0x18;
333
334         LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
335         PciValue |= 0x96000000;
336         LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
337
338         /* Initialize FB Base Address for Legacy Bridge Mode
339         * Modify B1D5F0x10
340         */
341         PciAddress.Address.Register = 0x10;
342         LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
343         PciValue |= 0x80000000;
344         LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
345
346         /* Initialize GMM Base Address for Pcie Mode
347         *       Modify B0D1F0x18
348         */
349         PciAddress.Address.Bus = 0;
350         PciAddress.Address.Device = 1;
351         PciAddress.Address.Function = 0;
352         PciAddress.Address.Register = 0x18;
353
354         LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
355         PciValue |= 0x96000000;
356         LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
357
358         /* Initialize FB Base Address for Pcie Mode
359         *       Modify B0D1F0x10
360         */
361         PciAddress.Address.Register = 0x10;
362         LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
363         PciValue |= 0x80000000;
364         LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
365
366         /* Initialize MMIO Base and Limit Address
367         *       Modify B0D1F0x20
368         */
369         PciAddress.Address.Bus = 0;
370         PciAddress.Address.Device = 1;
371         PciAddress.Address.Function = 0;
372         PciAddress.Address.Register = 0x20;
373
374         LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
375         PciValue |= 0x96009600;
376         LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
377
378         /* Initialize MMIO Prefetchable Memory Limit and Base
379         *       Modify B0D1F0x24
380         */
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);
386
387         return (UINT32)status;
388 }
389
390 VOID *
391 agesawrapper_getlateinitptr (
392         int pick
393         )
394 {
395         switch (pick) {
396                 case PICK_DMI:
397                         return DmiTable;
398                 case PICK_PSTATE:
399                         return AcpiPstate;
400                 case PICK_SRAT:
401                         return AcpiSrat;
402                 case PICK_SLIT:
403                         return AcpiSlit;
404                 case PICK_WHEA_MCE:
405                         return AcpiWheaMce;
406                 case PICK_WHEA_CMC:
407                         return AcpiWheaCmc;
408                 case PICK_ALIB:
409                         return AcpiAlib;
410                 default:
411                         return NULL;
412         }
413 }
414
415 UINT32
416 agesawrapper_amdinitmid (
417         VOID
418         )
419 {
420         AGESA_STATUS status;
421         AMD_INTERFACE_PARAMS AmdParamStruct;
422
423         /* Enable MMIO on AMD CPU Address Map Controller */
424         agesawrapper_amdinitcpuio ();
425
426         LibAmdMemFill (&AmdParamStruct,
427                                         0,
428                                         sizeof (AMD_INTERFACE_PARAMS),
429                                         &(AmdParamStruct.StdHeader));
430
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;
437
438         AmdCreateStruct (&AmdParamStruct);
439
440         status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
441         if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
442         AmdReleaseStruct (&AmdParamStruct);
443
444         return (UINT32)status;
445 }
446
447 UINT32
448 agesawrapper_amdinitlate (
449         VOID
450         )
451 {
452         AGESA_STATUS Status;
453         AMD_LATE_PARAMS AmdLateParams;
454
455         LibAmdMemFill (&AmdLateParams,
456                                         0,
457                                         sizeof (AMD_LATE_PARAMS),
458                                         &(AmdLateParams.StdHeader));
459
460         AmdLateParams.StdHeader.AltImageBasePtr = 0;
461         AmdLateParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
462         AmdLateParams.StdHeader.Func = 0;
463         AmdLateParams.StdHeader.ImageBasePtr = 0;
464
465         Status = AmdInitLate (&AmdLateParams);
466         if (Status != AGESA_SUCCESS) {
467                 agesawrapper_amdreadeventlog();
468                 ASSERT(Status == AGESA_SUCCESS);
469         }
470
471         DmiTable                = AmdLateParams.DmiTable;
472         AcpiPstate              = AmdLateParams.AcpiPState;
473         AcpiSrat                = AmdLateParams.AcpiSrat;
474         AcpiSlit                = AmdLateParams.AcpiSlit;
475
476         AcpiWheaMce             = AmdLateParams.AcpiWheaMce;
477         AcpiWheaCmc             = AmdLateParams.AcpiWheaCmc;
478         AcpiAlib                = AmdLateParams.AcpiAlib;
479
480         return (UINT32)Status;
481 }
482
483 UINT32
484 agesawrapper_amdlaterunaptask (
485         UINT32 Func,
486         UINT32 Data,
487         VOID *ConfigPtr
488         )
489 {
490         AGESA_STATUS Status;
491         AP_EXE_PARAMS ApExeParams;
492
493         LibAmdMemFill (&ApExeParams,
494                                         0,
495                                         sizeof (AP_EXE_PARAMS),
496                                         &(ApExeParams.StdHeader));
497
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;
505
506         Status = AmdLateRunApTask (&ApExeParams);
507         if (Status != AGESA_SUCCESS) {
508                 agesawrapper_amdreadeventlog();
509                 ASSERT(Status == AGESA_SUCCESS);
510         }
511
512         return (UINT32)Status;
513 }
514
515 UINT32
516 agesawrapper_amdreadeventlog (
517         VOID
518         )
519 {
520         AGESA_STATUS Status;
521         EVENT_PARAMS AmdEventParams;
522
523         LibAmdMemFill (&AmdEventParams,
524                                         0,
525                                         sizeof (EVENT_PARAMS),
526                                         &(AmdEventParams.StdHeader));
527
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);
538         }
539
540         return (UINT32)Status;
541 }