1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/console.h>
5 #include <cpu/x86/lapic.h>
6 #include <cpu/x86/mp.h>
8 #include <amdblocks/BiosCallOuts.h>
9 #include <amdblocks/agesawrapper.h>
10 #include <amdblocks/agesawrapper_call.h>
11 #include <amdblocks/reset.h>
12 #include <soc/southbridge.h>
16 const BIOS_CALLOUT_STRUCT BiosCallouts
[] = {
17 { AGESA_DO_RESET
, agesa_Reset
},
18 { AGESA_FCH_OEM_CALLOUT
, agesa_fch_initreset
},
19 { AGESA_HALT_THIS_AP
, agesa_HaltThisAp
},
20 { AGESA_HEAP_REBASE
, agesa_HeapRebase
},
21 { AGESA_GNB_PCIE_SLOT_RESET
, agesa_PcieSlotResetControl
}
24 const BIOS_CALLOUT_STRUCT BiosCallouts
[] = {
25 /* Required callouts */
27 { AGESA_HALT_THIS_AP
, agesa_HaltThisAp
},
29 { AGESA_ALLOCATE_BUFFER
, agesa_AllocateBuffer
},
30 { AGESA_DEALLOCATE_BUFFER
, agesa_DeallocateBuffer
},
31 { AGESA_DO_RESET
, agesa_Reset
},
32 { AGESA_LOCATE_BUFFER
, agesa_LocateBuffer
},
33 { AGESA_READ_SPD
, agesa_ReadSpd
},
34 { AGESA_GNB_PCIE_SLOT_RESET
, agesa_PcieSlotResetControl
},
35 { AGESA_GET_TEMP_HEAP_BASE
, agesa_GetTempHeapBase
},
36 { AGESA_HEAP_REBASE
, agesa_HeapRebase
},
38 { AGESA_RUNFUNC_ONAP
, agesa_RunFuncOnAp
},
39 { AGESA_RUNFUNC_ON_ALL_APS
, agesa_RunFcnOnAllAps
},
40 { AGESA_WAIT_FOR_ALL_APS
, agesa_WaitForAllApsFinished
},
41 { AGESA_IDLE_AN_AP
, agesa_IdleAnAp
},
42 #endif /* ENV_RAMSTAGE */
44 /* Optional callouts */
45 { AGESA_GET_IDS_INIT_DATA
, agesa_EmptyIdsInitData
},
46 //AgesaHeapRebase - Hook ID?
47 { AGESA_HOOKBEFORE_DRAM_INIT
, agesa_NoopUnsupported
},
48 { AGESA_HOOKBEFORE_DQS_TRAINING
, agesa_NoopUnsupported
},
49 { AGESA_EXTERNAL_2D_TRAIN_VREF_CHANGE
, agesa_NoopUnsupported
},
50 { AGESA_HOOKBEFORE_EXIT_SELF_REF
, agesa_NoopUnsupported
},
51 { AGESA_GNB_GFX_GET_VBIOS_IMAGE
, agesa_GfxGetVbiosImage
},
52 { AGESA_FCH_OEM_CALLOUT
, agesa_fch_initenv
},
53 { AGESA_EXTERNAL_VOLTAGE_ADJUST
, agesa_NoopUnsupported
},
54 { AGESA_GNB_PCIE_CLK_REQ
, agesa_NoopUnsupported
},
57 { AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY
, agesa_NoopUnsupported
},
58 { AGESA_READ_SPD_RECOVERY
, agesa_NoopUnsupported
},
63 const int BiosCalloutsLen
= ARRAY_SIZE(BiosCallouts
);
65 AGESA_STATUS
GetBiosCallout(uint32_t Func
, uintptr_t Data
, void *ConfigPtr
)
69 for (i
= 0 ; i
< BiosCalloutsLen
; i
++) {
70 if (BiosCallouts
[i
].CalloutName
== Func
)
74 if (i
>= BiosCalloutsLen
) {
75 printk(BIOS_ERR
, "AGESA Callout Not Supported: 0x%x\n",
77 return AGESA_UNSUPPORTED
;
80 return BiosCallouts
[i
].CalloutPtr(Func
, Data
, ConfigPtr
);
83 AGESA_STATUS
agesa_NoopUnsupported(uint32_t Func
, uintptr_t Data
,
86 return AGESA_UNSUPPORTED
;
89 AGESA_STATUS
agesa_NoopSuccess(uint32_t Func
, uintptr_t Data
, void *ConfigPtr
)
94 AGESA_STATUS
agesa_EmptyIdsInitData(uint32_t Func
, uintptr_t Data
,
97 IDS_NV_ITEM
*IdsPtr
= ((IDS_CALLOUT_STRUCT
*) ConfigPtr
)->IdsNvPtr
;
98 if (Data
== IDS_CALLOUT_INIT
)
99 IdsPtr
[0].IdsNvValue
= IdsPtr
[0].IdsNvId
= 0xffff;
100 return AGESA_SUCCESS
;
103 AGESA_STATUS
agesa_Reset(uint32_t Func
, uintptr_t Data
, void *ConfigPtr
)
111 * This should perform the RESET based upon the ResetType, but coreboot
112 * doesn't have a reset manager to handle a WHENEVER case. Do all
113 * resets immediately.
116 case WARM_RESET_WHENEVER
:
117 case WARM_RESET_IMMEDIATELY
:
121 case COLD_RESET_WHENEVER
:
122 case COLD_RESET_IMMEDIATELY
:
134 AGESA_STATUS
agesa_GfxGetVbiosImage(uint32_t Func
, uintptr_t FchData
,
137 GFX_VBIOS_IMAGE_INFO
*pVbiosImageInfo
;
139 pVbiosImageInfo
= (GFX_VBIOS_IMAGE_INFO
*)ConfigPrt
;
140 pVbiosImageInfo
->ImagePtr
= cbfs_map(
141 "pci"CONFIG_VGA_BIOS_ID
".rom", NULL
);
142 printk(BIOS_DEBUG
, "%s: IMGptr=%p\n", __func__
,
143 pVbiosImageInfo
->ImagePtr
);
144 return pVbiosImageInfo
->ImagePtr
? AGESA_SUCCESS
: AGESA_WARNING
;
147 AGESA_STATUS __weak
platform_PcieSlotResetControl(uint32_t Func
,
148 uintptr_t Data
, void *ConfigPtr
)
150 printk(BIOS_WARNING
, "AGESA callout: %s not supported\n",
152 return AGESA_UNSUPPORTED
;
155 AGESA_STATUS
agesa_PcieSlotResetControl(uint32_t Func
, uintptr_t Data
,
158 return platform_PcieSlotResetControl(Func
, Data
, ConfigPtr
);
162 * Application Processor callouts:
163 * agesa_RunFuncOnAp() and agesa_RunFcnOnAllAps() are called after main memory
164 * has been initialized and coreboot has taken control of AP task dispatching.
165 * These functions execute callout_ap_entry() on each AP, which calls the
166 * AmdLateRunApTask() entry point if it is a targeted AP.
170 * Global data for APs.
171 * Passed from the AGESA_Callout for the agesawrapper_amdlaterunaptask.
173 static struct agesa_data
{
176 AP_EXE_PARAMS
*ConfigPtr
;
180 * BSP deploys APs to callout_ap_entry(), which calls
181 * agesawrapper_amdlaterunaptask with the agesadata.
183 static void callout_ap_entry(void *unused
)
185 AGESA_STATUS Status
= AGESA_UNSUPPORTED
;
187 printk(BIOS_DEBUG
, "%s Func: 0x%x, Data: 0x%lx, Ptr: %p\n",
188 __func__
, agesadata
.Func
, agesadata
.Data
, agesadata
.ConfigPtr
);
190 /* Check if this AP should run the function */
191 if (!((agesadata
.Func
== AGESA_RUNFUNC_ONAP
) &&
192 (agesadata
.Data
== lapicid())))
195 Status
= amd_late_run_ap_task(agesadata
.ConfigPtr
);
198 printk(BIOS_DEBUG
, "There was a problem with %x returned %s\n",
199 lapicid(), decodeAGESA_STATUS(Status
));
202 AGESA_STATUS
agesa_RunFuncOnAp(uint32_t Func
, uintptr_t Data
, void *ConfigPtr
)
204 printk(BIOS_DEBUG
, "%s\n", __func__
);
206 agesadata
.Func
= Func
;
207 agesadata
.Data
= Data
;
208 agesadata
.ConfigPtr
= ConfigPtr
;
209 if (mp_run_on_aps(callout_ap_entry
, NULL
, MP_RUN_ON_ALL_CPUS
, 100 * USECS_PER_MSEC
) !=
213 return AGESA_SUCCESS
;
216 AGESA_STATUS
agesa_RunFcnOnAllAps(uint32_t Func
, uintptr_t Data
,
219 printk(BIOS_DEBUG
, "%s\n", __func__
);
221 agesadata
.Func
= Func
;
222 agesadata
.Data
= Data
;
223 agesadata
.ConfigPtr
= ConfigPtr
;
224 if (mp_run_on_aps(callout_ap_entry
, NULL
, MP_RUN_ON_ALL_CPUS
, 100 * USECS_PER_MSEC
) !=
228 return AGESA_SUCCESS
;
231 AGESA_STATUS
agesa_WaitForAllApsFinished(uint32_t Func
, uintptr_t Data
,
234 printk(BIOS_WARNING
, "AGESA callout: %s not supported\n",
236 AGESA_STATUS Status
= AGESA_UNSUPPORTED
;
241 AGESA_STATUS
agesa_IdleAnAp(uint32_t Func
, uintptr_t Data
, void *ConfigPtr
)
243 printk(BIOS_WARNING
, "AGESA callout: %s not supported\n",
245 AGESA_STATUS Status
= AGESA_UNSUPPORTED
;