74aa73d49fe0e334deaccfa7b691be7901d65585
[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 }