Port persimmon r6573 to e350m1: VGA, PCI MMIO and SB800 legacy
[coreboot.git] / src / mainboard / asrock / e350m1 / 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
40 #define FILECODE UNASSIGNED_FILE_FILECODE
41
42 /*----------------------------------------------------------------------------------------
43  *                   D E F I N I T I O N S    A N D    M A C R O S
44  *----------------------------------------------------------------------------------------
45  */
46
47 /* ACPI table pointers returned by AmdInitLate */
48 VOID *DmiTable    = NULL;
49 VOID *AcpiPstate  = NULL;
50 VOID *AcpiSrat    = NULL;
51 VOID *AcpiSlit    = NULL;
52
53 VOID *AcpiWheaMce = NULL;
54 VOID *AcpiWheaCmc = NULL;
55 VOID *AcpiAlib    = NULL; 
56  
57
58 /*----------------------------------------------------------------------------------------
59  *                  T Y P E D E F S     A N D     S T R U C T U  R E S
60  *----------------------------------------------------------------------------------------
61  */
62
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  *----------------------------------------------------------------------------------------
66  */
67  
68 /*----------------------------------------------------------------------------------------
69  *                          E X P O R T E D    F U N C T I O N S
70  *----------------------------------------------------------------------------------------
71  */
72  
73 /*---------------------------------------------------------------------------------------
74  *                          L O C A L    F U N C T I O N S
75  *---------------------------------------------------------------------------------------
76  */
77 UINT32 
78 agesawrapper_amdinitcpuio (
79   VOID
80   )
81 {
82   AGESA_STATUS                  Status;
83   UINT64                        MsrReg;
84   UINT32                        PciData;
85   PCI_ADDR                      PciAddress;
86   AMD_CONFIG_PARAMS             StdHeader;
87   
88   /* Enable legacy video routing: D18F1xF4 VGA Enable */
89   PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 1, 0xF4);
90   PciData = 1;
91   LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader); 
92
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.
96    */
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); 
104    
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); 
114    
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;
124 }
125  
126 UINT32 
127 agesawrapper_amdinitmmio (
128   VOID
129   )
130 {
131   AGESA_STATUS                  Status;
132   UINT64                        MsrReg;
133   UINT32                        PciData;
134   PCI_ADDR                      PciAddress;
135   AMD_CONFIG_PARAMS             StdHeader;
136   
137   /*
138    Set the MMIO Configuration Base Address and Bus Range onto MMIO configuration base
139    Address MSR register.
140   */
141   MsrReg = CONFIG_MMCONF_BASE_ADDRESS | (8 << 2) | 1;
142   LibAmdMsrWrite (0xC0010058, &MsrReg, &StdHeader);
143   
144   /*
145    Set the NB_CFG MSR register. Enable CF8 extended configuration cycles.
146   */
147   LibAmdMsrRead (0xC001001F, &MsrReg, &StdHeader);
148   MsrReg = MsrReg | 0x0000400000000000;
149   LibAmdMsrWrite (0xC001001F, &MsrReg, &StdHeader);
150   
151   /* Set Ontario Link Data */
152   PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE0);
153   PciData = 0x01308002;
154   LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader); 
155   PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0xE4);
156   PciData = (AMD_APU_SSID<<0x10)|AMD_APU_SVID;
157   LibAmdPciWrite(AccessWidth32, PciAddress, &PciData, &StdHeader); 
158   
159
160   /* Set ROM cache onto WP to decrease post time */
161   MsrReg = (0x0100000000 - CONFIG_ROM_SIZE) | 5;
162   LibAmdMsrWrite (0x20C, &MsrReg, &StdHeader);
163   MsrReg = (0x1000000000 - CONFIG_ROM_SIZE) | 0x800;
164   LibAmdMsrWrite (0x20D, &MsrReg, &StdHeader);
165
166   Status = AGESA_SUCCESS;
167   return (UINT32)Status;
168 }
169
170 UINT32 
171 agesawrapper_amdinitreset (
172   VOID
173   )
174 {
175   AGESA_STATUS status;
176   AMD_INTERFACE_PARAMS AmdParamStruct;
177   AMD_RESET_PARAMS AmdResetParams;
178   
179   LibAmdMemFill (&AmdParamStruct,
180                  0,
181                  sizeof (AMD_INTERFACE_PARAMS),
182                  &(AmdParamStruct.StdHeader));
183
184
185   LibAmdMemFill (&AmdResetParams,
186                  0,
187                  sizeof (AMD_RESET_PARAMS),
188                  &(AmdResetParams.StdHeader));
189
190   AmdParamStruct.AgesaFunctionName = AMD_INIT_RESET;
191   AmdParamStruct.AllocationMethod = ByHost;
192   AmdParamStruct.NewStructSize = sizeof(AMD_RESET_PARAMS);
193   AmdParamStruct.NewStructPtr = &AmdResetParams;
194   AmdParamStruct.StdHeader.AltImageBasePtr = 0;
195   AmdParamStruct.StdHeader.CalloutPtr = NULL;
196   AmdParamStruct.StdHeader.Func = 0;
197   AmdParamStruct.StdHeader.ImageBasePtr = 0;
198   AmdCreateStruct (&AmdParamStruct);
199   AmdResetParams.HtConfig.Depth = 0;
200   
201   status = AmdInitReset ((AMD_RESET_PARAMS *)AmdParamStruct.NewStructPtr);
202   if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
203   AmdReleaseStruct (&AmdParamStruct);
204   return (UINT32)status;
205  }  
206   
207 UINT32 
208 agesawrapper_amdinitearly (
209   VOID
210   )
211 {
212   AGESA_STATUS status;
213   AMD_INTERFACE_PARAMS AmdParamStruct;
214   AMD_EARLY_PARAMS     *AmdEarlyParamsPtr;
215   
216   LibAmdMemFill (&AmdParamStruct,
217                  0,
218                  sizeof (AMD_INTERFACE_PARAMS),
219                  &(AmdParamStruct.StdHeader));
220
221   AmdParamStruct.AgesaFunctionName = AMD_INIT_EARLY;
222   AmdParamStruct.AllocationMethod = PreMemHeap;
223   AmdParamStruct.StdHeader.AltImageBasePtr = 0;
224   AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
225   AmdParamStruct.StdHeader.Func = 0;
226   AmdParamStruct.StdHeader.ImageBasePtr = 0;
227   AmdCreateStruct (&AmdParamStruct);
228   
229   AmdEarlyParamsPtr = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
230   OemCustomizeInitEarly (AmdEarlyParamsPtr);
231   
232   status = AmdInitEarly ((AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr);
233   if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
234   AmdReleaseStruct (&AmdParamStruct);
235
236   return (UINT32)status;
237 }
238
239 UINT32 
240 agesawrapper_amdinitpost (
241   VOID
242   )
243 {
244   AGESA_STATUS status;
245   UINT16                  i;
246   UINT32          *HeadPtr;
247   AMD_INTERFACE_PARAMS  AmdParamStruct;
248   BIOS_HEAP_MANAGER    *BiosManagerPtr;
249
250   LibAmdMemFill (&AmdParamStruct,
251                  0,
252                  sizeof (AMD_INTERFACE_PARAMS),
253                  &(AmdParamStruct.StdHeader));
254
255   AmdParamStruct.AgesaFunctionName = AMD_INIT_POST;
256   AmdParamStruct.AllocationMethod = PreMemHeap;
257   AmdParamStruct.StdHeader.AltImageBasePtr = 0;
258   AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
259   AmdParamStruct.StdHeader.Func = 0;
260   AmdParamStruct.StdHeader.ImageBasePtr = 0;
261
262   AmdCreateStruct (&AmdParamStruct);
263   status = AmdInitPost ((AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr);
264   if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
265   AmdReleaseStruct (&AmdParamStruct);
266   /* Initialize heap space */
267   BiosManagerPtr = (BIOS_HEAP_MANAGER *)BIOS_HEAP_START_ADDRESS;
268
269   HeadPtr = (UINT32 *) ((UINT8 *) BiosManagerPtr + sizeof (BIOS_HEAP_MANAGER));
270   for (i = 0; i < ((BIOS_HEAP_SIZE/4) - (sizeof (BIOS_HEAP_MANAGER)/4)); i++)
271   {
272     *HeadPtr = 0x00000000;
273     HeadPtr++;
274   }
275   BiosManagerPtr->StartOfAllocatedNodes = 0;
276   BiosManagerPtr->StartOfFreedNodes = 0;
277
278   return (UINT32)status;
279 }
280
281 UINT32 
282 agesawrapper_amdinitenv (
283   VOID
284   )
285 {
286   AGESA_STATUS status;
287   AMD_INTERFACE_PARAMS AmdParamStruct;
288   PCI_ADDR             PciAddress;
289   UINT32               PciValue;
290
291   LibAmdMemFill (&AmdParamStruct,
292                  0,
293                  sizeof (AMD_INTERFACE_PARAMS),
294                  &(AmdParamStruct.StdHeader));
295
296   AmdParamStruct.AgesaFunctionName = AMD_INIT_ENV;
297   AmdParamStruct.AllocationMethod = PostMemDram;
298   AmdParamStruct.StdHeader.AltImageBasePtr = 0;
299   AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
300   AmdParamStruct.StdHeader.Func = 0;
301   AmdParamStruct.StdHeader.ImageBasePtr = 0;
302   AmdCreateStruct (&AmdParamStruct);
303   status = AmdInitEnv ((AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr);
304   if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
305   /* Initialize Subordinate Bus Number and Secondary Bus Number
306    * In platform BIOS this address is allocated by PCI enumeration code
307      Modify D1F0x18
308    */  
309   PciAddress.Address.Bus = 0;
310   PciAddress.Address.Device = 1;
311   PciAddress.Address.Function = 0;
312   PciAddress.Address.Register = 0x18;
313   /* Write to D1F0x18 */
314   LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
315   PciValue |= 0x00010100;
316   LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
317
318   /* Initialize GMM Base Address for Legacy Bridge Mode
319   *  Modify B1D5F0x18
320   */
321   PciAddress.Address.Bus = 1;
322   PciAddress.Address.Device = 5;
323   PciAddress.Address.Function = 0;
324   PciAddress.Address.Register = 0x18;
325
326   LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
327   PciValue |= 0x96000000;
328   LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
329
330   /* Initialize FB Base Address for Legacy Bridge Mode
331   * Modify B1D5F0x10
332   */
333   PciAddress.Address.Register = 0x10;
334   LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
335   PciValue |= 0x80000000;
336   LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
337
338   /* Initialize GMM Base Address for Pcie Mode
339   *  Modify B0D1F0x18
340   */
341   PciAddress.Address.Bus = 0;
342   PciAddress.Address.Device = 1;
343   PciAddress.Address.Function = 0;
344   PciAddress.Address.Register = 0x18;
345
346   LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
347   PciValue |= 0x96000000;
348   LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
349
350   /* Initialize FB Base Address for Pcie Mode
351   *  Modify B0D1F0x10
352   */
353   PciAddress.Address.Register = 0x10;
354   LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
355   PciValue |= 0x80000000;
356   LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
357
358
359   /* Initialize MMIO Base and Limit Address
360   *  Modify B0D1F0x20
361   */
362   PciAddress.Address.Bus = 0;
363   PciAddress.Address.Device = 1;
364   PciAddress.Address.Function = 0;
365   PciAddress.Address.Register = 0x20;
366
367   LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
368   PciValue |= 0x96009600;
369   LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
370
371   /* Initialize MMIO Prefetchable Memory Limit and Base
372   *  Modify B0D1F0x24
373   */
374   PciAddress.Address.Register = 0x24;
375   LibAmdPciRead (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
376   PciValue |= 0x8FF18001;
377   LibAmdPciWrite (AccessWidth32, PciAddress, &PciValue, &AmdParamStruct.StdHeader);
378   AmdReleaseStruct (&AmdParamStruct);
379
380   return (UINT32)status;
381 }
382
383 VOID *
384 agesawrapper_getlateinitptr (
385   int pick
386   )
387 {
388   switch (pick) {
389     case PICK_DMI:
390       return DmiTable;
391     case PICK_PSTATE:
392       return AcpiPstate;
393     case PICK_SRAT:
394       return AcpiSrat;
395     case PICK_SLIT:
396       return AcpiSlit;
397     case PICK_WHEA_MCE:
398       return AcpiWheaMce;
399     case PICK_WHEA_CMC:
400       return AcpiWheaCmc;
401     case PICK_ALIB:
402       return AcpiAlib;
403     default:
404       return NULL;
405   }
406 }
407
408 UINT32 
409 agesawrapper_amdinitmid (
410   VOID
411   )
412 {
413   AGESA_STATUS status;
414   AMD_INTERFACE_PARAMS AmdParamStruct;
415   
416   /* Enable MMIO on AMD CPU Address Map Controller */
417   agesawrapper_amdinitcpuio ();
418   
419   LibAmdMemFill (&AmdParamStruct,
420                  0,
421                  sizeof (AMD_INTERFACE_PARAMS),
422                  &(AmdParamStruct.StdHeader));
423
424   AmdParamStruct.AgesaFunctionName = AMD_INIT_MID;
425   AmdParamStruct.AllocationMethod = PostMemDram;
426   AmdParamStruct.StdHeader.AltImageBasePtr = 0;
427   AmdParamStruct.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
428   AmdParamStruct.StdHeader.Func = 0;
429   AmdParamStruct.StdHeader.ImageBasePtr = 0;
430
431   AmdCreateStruct (&AmdParamStruct);
432
433   status = AmdInitMid ((AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr);
434   if (status != AGESA_SUCCESS) agesawrapper_amdreadeventlog();
435   AmdReleaseStruct (&AmdParamStruct);
436
437   return (UINT32)status;
438 }
439
440 UINT32 
441 agesawrapper_amdinitlate (
442   VOID
443   )
444 {
445   AGESA_STATUS Status;
446   AMD_LATE_PARAMS AmdLateParams;
447
448   LibAmdMemFill (&AmdLateParams,
449                  0,
450                  sizeof (AMD_LATE_PARAMS),
451                  &(AmdLateParams.StdHeader));
452
453   AmdLateParams.StdHeader.AltImageBasePtr = 0;
454   AmdLateParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
455   AmdLateParams.StdHeader.Func = 0;
456   AmdLateParams.StdHeader.ImageBasePtr = 0;
457
458   Status = AmdInitLate (&AmdLateParams);
459   if (Status != AGESA_SUCCESS) {
460     agesawrapper_amdreadeventlog();
461     ASSERT(Status == AGESA_SUCCESS);
462   }
463
464   DmiTable       = AmdLateParams.DmiTable;
465   AcpiPstate     = AmdLateParams.AcpiPState;
466   AcpiSrat       = AmdLateParams.AcpiSrat;
467   AcpiSlit       = AmdLateParams.AcpiSlit;
468
469   AcpiWheaMce    = AmdLateParams.AcpiWheaMce;
470   AcpiWheaCmc    = AmdLateParams.AcpiWheaCmc;
471   AcpiAlib       = AmdLateParams.AcpiAlib;
472
473   return (UINT32)Status;
474 }
475
476 UINT32 
477 agesawrapper_amdlaterunaptask (
478   UINT32 Data, 
479   VOID *ConfigPtr
480   )
481 {
482   AGESA_STATUS Status;
483   AMD_LATE_PARAMS AmdLateParams;
484
485   LibAmdMemFill (&AmdLateParams,
486                  0,
487                  sizeof (AMD_LATE_PARAMS),
488                  &(AmdLateParams.StdHeader));
489
490   AmdLateParams.StdHeader.AltImageBasePtr = 0;
491   AmdLateParams.StdHeader.CalloutPtr = (CALLOUT_ENTRY) &GetBiosCallout;
492   AmdLateParams.StdHeader.Func = 0;
493   AmdLateParams.StdHeader.ImageBasePtr = 0;
494
495   Status = AmdLateRunApTask (&AmdLateParams);
496   if (Status != AGESA_SUCCESS) {
497     agesawrapper_amdreadeventlog();
498     ASSERT(Status == AGESA_SUCCESS);
499   }
500
501   DmiTable       = AmdLateParams.DmiTable;
502   AcpiPstate     = AmdLateParams.AcpiPState;
503   AcpiSrat       = AmdLateParams.AcpiSrat;
504   AcpiSlit       = AmdLateParams.AcpiSlit;
505
506   AcpiWheaMce    = AmdLateParams.AcpiWheaMce;
507   AcpiWheaCmc    = AmdLateParams.AcpiWheaCmc;
508   AcpiAlib       = AmdLateParams.AcpiAlib;
509
510   return (UINT32)Status;
511 }
512
513 UINT32 
514 agesawrapper_amdreadeventlog (
515   VOID
516   )
517 {
518   AGESA_STATUS Status;
519   EVENT_PARAMS AmdEventParams;
520
521   LibAmdMemFill (&AmdEventParams,
522                  0,
523                  sizeof (EVENT_PARAMS),
524                  &(AmdEventParams.StdHeader));
525
526   AmdEventParams.StdHeader.AltImageBasePtr = 0;
527   AmdEventParams.StdHeader.CalloutPtr = NULL;
528   AmdEventParams.StdHeader.Func = 0;
529   AmdEventParams.StdHeader.ImageBasePtr = 0;
530   Status = AmdReadEventLog (&AmdEventParams);
531   while (AmdEventParams.EventClass != 0) {
532     printk(BIOS_DEBUG,"\nEventLog:  EventClass = %x, EventInfo = %x.\n",AmdEventParams.EventClass,AmdEventParams.EventInfo);
533     printk(BIOS_DEBUG,"  Param1 = %x, Param2 = %x.\n",AmdEventParams.DataParam1,AmdEventParams.DataParam2);
534     printk(BIOS_DEBUG,"  Param3 = %x, Param4 = %x.\n",AmdEventParams.DataParam3,AmdEventParams.DataParam4);
535     Status = AmdReadEventLog (&AmdEventParams);
536   }
537
538   return (UINT32)Status;
539 }