AGESA F15: AMD family15 AGESA code
[coreboot.git] / src / vendorcode / amd / agesa / f15 / Legacy / Proc / Dispatcher.c
1 /* $NoKeywords:$ */
2 /**
3  * @file
4  *
5  * AMD binary block interface
6  *
7  * Contains the block entry function dispatcher
8  *
9  * @xrefitem bom "File Content Label" "Release Content"
10  * @e project:      AGESA
11  * @e sub-project:  Legacy
12  * @e \$Revision: 56322 $   @e \$Date: 2011-07-11 16:51:42 -0600 (Mon, 11 Jul 2011) $
13  *
14  */
15 /*****************************************************************************
16  *
17  * Copyright (C) 2012 Advanced Micro Devices, Inc.
18  * All rights reserved.
19  *
20  * Redistribution and use in source and binary forms, with or without
21  * modification, are permitted provided that the following conditions are met:
22  *     * Redistributions of source code must retain the above copyright
23  *       notice, this list of conditions and the following disclaimer.
24  *     * Redistributions in binary form must reproduce the above copyright
25  *       notice, this list of conditions and the following disclaimer in the
26  *       documentation and/or other materials provided with the distribution.
27  *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
28  *       its contributors may be used to endorse or promote products derived
29  *       from this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34  * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  *
42  * ***************************************************************************
43  */
44
45 /*----------------------------------------------------------------------------------------
46  *                            M O D U L E S    U S E D
47  *----------------------------------------------------------------------------------------
48  */
49 #include "AGESA.h"
50 #include "amdlib.h"
51 #include "Dispatcher.h"
52 #include "Options.h"
53 #include "Filecode.h"
54 CODE_GROUP (G1_PEICC)
55 RDATA_GROUP (G2_PEI)
56
57 #define FILECODE LEGACY_PROC_DISPATCHER_FILECODE
58
59 /*----------------------------------------------------------------------------------------
60  *                   D E F I N I T I O N S    A N D    M A C R O S
61  *----------------------------------------------------------------------------------------
62  */
63 extern CONST DISPATCH_TABLE DispatchTable[];
64 extern AMD_MODULE_HEADER mCpuModuleID;
65
66 /*---------------------------------------------------------------------------------------*/
67 /**
68  * The Dispatcher is the entry point into the AGESA software. It takes a function
69  * number as entry parameter in order to invoke the published function
70  *
71  * @param[in,out]  ConfigPtr
72  *
73  * @return   AGESA Status.
74  *
75  */
76 AGESA_STATUS
77 CALLCONV
78 AmdAgesaDispatcher (
79   IN OUT   VOID *ConfigPtr
80   )
81 {
82   AGESA_STATUS Status;
83   IMAGE_ENTRY ImageEntry;
84   MODULE_ENTRY  ModuleEntry;
85   DISPATCH_TABLE *Entry;
86   UINT32 ImageStart;
87   UINT32 ImageEnd;
88   AMD_IMAGE_HEADER* AltImagePtr;
89
90   Status = AGESA_UNSUPPORTED;
91   ImageEntry = NULL;
92   ModuleEntry = NULL;
93   ImageStart = 0xFFF00000;
94   ImageEnd = 0xFFFFFFFF;
95   AltImagePtr = NULL;
96
97   Entry = (DISPATCH_TABLE *) DispatchTable;
98   while (Entry->FunctionId != 0) {
99     if ((((AMD_CONFIG_PARAMS *) ConfigPtr)->Func) == Entry->FunctionId) {
100       Status = Entry->EntryPoint (ConfigPtr);
101       break;
102     }
103     Entry++;
104   }
105
106   // 2. Try next dispatcher if possible, and we have not already got status back
107   if ((mCpuModuleID.NextBlock != NULL) && (Status == AGESA_UNSUPPORTED)) {
108     ModuleEntry = (MODULE_ENTRY) (UINT64) mCpuModuleID.NextBlock->ModuleDispatcher;
109     if (ModuleEntry != NULL) {
110       Status = (*ModuleEntry) (ConfigPtr);
111     }
112   }
113
114   // 3. If not this image specific function, see if we can find alternative image instead
115   if (Status == AGESA_UNSUPPORTED) {
116     if ((((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr != 0xFFFFFFFF  ) || (((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr != 0)) {
117       ImageStart = ((AMD_CONFIG_PARAMS *)ConfigPtr)->AltImageBasePtr;
118       ImageEnd = ImageStart + 4;
119       // Locate/test image base that matches this component
120       AltImagePtr = LibAmdLocateImage ((VOID *) (UINT64)ImageStart, (VOID *) (UINT64)ImageEnd, 4096, (CHAR8 *) AGESA_ID);
121       if (AltImagePtr != NULL) {
122         //Invoke alternative Image
123         ImageEntry = (IMAGE_ENTRY) ((UINT64) AltImagePtr + AltImagePtr->EntryPointAddress);
124         Status = (*ImageEntry) (ConfigPtr);
125       }
126     }
127   }
128
129   return (Status);
130 }
131
132 /*---------------------------------------------------------------------------------------*/
133 /**
134  * The host environment interface of callout.
135  *
136  * @param[in]      Func
137  * @param[in]      Data
138  * @param[in,out]  ConfigPtr
139  *
140  * @return   The AGESA Status returned from the callout.
141  *
142  */
143 AGESA_STATUS
144 CALLCONV
145 AmdAgesaCallout (
146   IN       UINT32  Func,
147   IN       UINT32  Data,
148   IN OUT   VOID    *ConfigPtr
149   )
150 {
151   UINT32 Result;
152   Result = AGESA_UNSUPPORTED;
153   if (((AMD_CONFIG_PARAMS *) ConfigPtr)->CalloutPtr == NULL) {
154     return Result;
155   }
156
157   Result = (((AMD_CONFIG_PARAMS *) ConfigPtr)->CalloutPtr) (Func, Data, ConfigPtr);
158   return (Result);
159 }