blob: 414de6f8ce29f984c8532a725b4e687df133aed9 [file] [log] [blame]
Angel Ponsae593872020-04-04 18:50:57 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Marc Jones1587dc82017-05-15 18:55:11 -06002
3#include <cbfs.h>
Elyes HAOUAS20eaef02019-03-29 17:45:28 +01004#include <console/console.h>
Marc Jones33eef132017-10-26 16:50:42 -06005#include <cpu/x86/lapic.h>
6#include <cpu/x86/mp.h>
7#include <timer.h>
Richard Spiegel0ad74ac2017-12-08 16:53:29 -07008#include <amdblocks/BiosCallOuts.h>
9#include <amdblocks/agesawrapper.h>
10#include <amdblocks/agesawrapper_call.h>
Nico Huber73c11192018-10-06 18:20:47 +020011#include <amdblocks/reset.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060012#include <soc/southbridge.h>
Felix Held82faefb2021-10-20 20:50:58 +020013#include <types.h>
Marc Jones1587dc82017-05-15 18:55:11 -060014
Martin Rothc450fbe2017-10-02 13:46:50 -060015#if ENV_BOOTBLOCK
16const BIOS_CALLOUT_STRUCT BiosCallouts[] = {
17 { AGESA_DO_RESET, agesa_Reset },
18 { AGESA_FCH_OEM_CALLOUT, agesa_fch_initreset },
Richard Spiegela9f49362018-03-05 08:11:50 -070019 { AGESA_HALT_THIS_AP, agesa_HaltThisAp },
Marshall Dawsonc150a572018-04-30 17:59:27 -060020 { AGESA_HEAP_REBASE, agesa_HeapRebase },
Martin Rothc450fbe2017-10-02 13:46:50 -060021 { AGESA_GNB_PCIE_SLOT_RESET, agesa_PcieSlotResetControl }
22};
23#else
24const BIOS_CALLOUT_STRUCT BiosCallouts[] = {
25 /* Required callouts */
Richard Spiegel09a16e62018-04-04 12:40:20 -070026#if ENV_ROMSTAGE
27 { AGESA_HALT_THIS_AP, agesa_HaltThisAp },
28#endif
Martin Rothc450fbe2017-10-02 13:46:50 -060029 { 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 },
Marc Jones33eef132017-10-26 16:50:42 -060034 { AGESA_GNB_PCIE_SLOT_RESET, agesa_PcieSlotResetControl },
Marshall Dawson10b52e02018-05-07 08:51:04 -060035 { AGESA_GET_TEMP_HEAP_BASE, agesa_GetTempHeapBase },
Marshall Dawsonc150a572018-04-30 17:59:27 -060036 { AGESA_HEAP_REBASE, agesa_HeapRebase },
Marc Jones33eef132017-10-26 16:50:42 -060037#if ENV_RAMSTAGE
Martin Rothc450fbe2017-10-02 13:46:50 -060038 { AGESA_RUNFUNC_ONAP, agesa_RunFuncOnAp },
39 { AGESA_RUNFUNC_ON_ALL_APS, agesa_RunFcnOnAllAps },
Martin Rothc450fbe2017-10-02 13:46:50 -060040 { AGESA_WAIT_FOR_ALL_APS, agesa_WaitForAllApsFinished },
41 { AGESA_IDLE_AN_AP, agesa_IdleAnAp },
Marc Jones33eef132017-10-26 16:50:42 -060042#endif /* ENV_RAMSTAGE */
Martin Rothc450fbe2017-10-02 13:46:50 -060043
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 },
55
56 /* Deprecated */
57 { AGESA_HOOKBEFORE_DRAM_INIT_RECOVERY, agesa_NoopUnsupported},
58 { AGESA_READ_SPD_RECOVERY, agesa_NoopUnsupported },
59
60};
61#endif
62
63const int BiosCalloutsLen = ARRAY_SIZE(BiosCallouts);
64
Richard Spiegel271b8a52018-11-06 16:32:28 -070065AGESA_STATUS GetBiosCallout(uint32_t Func, uintptr_t Data, void *ConfigPtr)
Marc Jones1587dc82017-05-15 18:55:11 -060066{
Richard Spiegel271b8a52018-11-06 16:32:28 -070067 uintptr_t i;
Marc Jones1587dc82017-05-15 18:55:11 -060068
Marshall Dawsonf3dc71e2017-06-14 16:22:07 -060069 for (i = 0 ; i < BiosCalloutsLen ; i++) {
Marc Jones1587dc82017-05-15 18:55:11 -060070 if (BiosCallouts[i].CalloutName == Func)
71 break;
72 }
Marc Jones7e710e02017-10-12 15:19:51 -060073
74 if (i >= BiosCalloutsLen) {
Julius Wernere9665952022-01-21 17:06:20 -080075 printk(BIOS_ERR, "AGESA Callout Not Supported: 0x%x\n",
Marc Jones7e710e02017-10-12 15:19:51 -060076 (u32)Func);
Marc Jones1587dc82017-05-15 18:55:11 -060077 return AGESA_UNSUPPORTED;
Marc Jones7e710e02017-10-12 15:19:51 -060078 }
Marc Jones1587dc82017-05-15 18:55:11 -060079
Marshall Dawsonf3dc71e2017-06-14 16:22:07 -060080 return BiosCallouts[i].CalloutPtr(Func, Data, ConfigPtr);
Marc Jones1587dc82017-05-15 18:55:11 -060081}
82
Richard Spiegel271b8a52018-11-06 16:32:28 -070083AGESA_STATUS agesa_NoopUnsupported(uint32_t Func, uintptr_t Data,
84 void *ConfigPtr)
Marc Jones1587dc82017-05-15 18:55:11 -060085{
86 return AGESA_UNSUPPORTED;
87}
88
Richard Spiegel271b8a52018-11-06 16:32:28 -070089AGESA_STATUS agesa_NoopSuccess(uint32_t Func, uintptr_t Data, void *ConfigPtr)
Marc Jones1587dc82017-05-15 18:55:11 -060090{
91 return AGESA_SUCCESS;
92}
93
Richard Spiegel271b8a52018-11-06 16:32:28 -070094AGESA_STATUS agesa_EmptyIdsInitData(uint32_t Func, uintptr_t Data,
95 void *ConfigPtr)
Marc Jones1587dc82017-05-15 18:55:11 -060096{
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;
101}
102
Richard Spiegel271b8a52018-11-06 16:32:28 -0700103AGESA_STATUS agesa_Reset(uint32_t Func, uintptr_t Data, void *ConfigPtr)
Marc Jones1587dc82017-05-15 18:55:11 -0600104{
Marshall Dawsonf3dc71e2017-06-14 16:22:07 -0600105 AGESA_STATUS Status;
Richard Spiegel271b8a52018-11-06 16:32:28 -0700106 uintptr_t ResetType;
Marc Jones1587dc82017-05-15 18:55:11 -0600107
108 ResetType = Data;
Marc Jones1587dc82017-05-15 18:55:11 -0600109
Marc Jones4f886cc2017-10-11 20:20:49 -0600110 /*
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.
Marshall Dawsonf3dc71e2017-06-14 16:22:07 -0600114 */
Marc Jones1587dc82017-05-15 18:55:11 -0600115 switch (ResetType) {
116 case WARM_RESET_WHENEVER:
Marc Jones1587dc82017-05-15 18:55:11 -0600117 case WARM_RESET_IMMEDIATELY:
Nico Huber73c11192018-10-06 18:20:47 +0200118 warm_reset();
Martin Roth4f92b152017-11-12 10:56:43 -0700119 break;
120
121 case COLD_RESET_WHENEVER:
Marc Jones1587dc82017-05-15 18:55:11 -0600122 case COLD_RESET_IMMEDIATELY:
Nico Huber73c11192018-10-06 18:20:47 +0200123 cold_reset();
Marc Jones1587dc82017-05-15 18:55:11 -0600124 break;
125
126 default:
127 break;
128 }
129
130 Status = 0;
131 return Status;
132}
133
Richard Spiegel271b8a52018-11-06 16:32:28 -0700134AGESA_STATUS agesa_GfxGetVbiosImage(uint32_t Func, uintptr_t FchData,
135 void *ConfigPrt)
Marc Jones1587dc82017-05-15 18:55:11 -0600136{
Marshall Dawsonf3dc71e2017-06-14 16:22:07 -0600137 GFX_VBIOS_IMAGE_INFO *pVbiosImageInfo;
138
139 pVbiosImageInfo = (GFX_VBIOS_IMAGE_INFO *)ConfigPrt;
Julius Werner834b3ec2020-03-04 16:52:08 -0800140 pVbiosImageInfo->ImagePtr = cbfs_map(
141 "pci"CONFIG_VGA_BIOS_ID".rom", NULL);
Richard Spiegelde332f32018-10-23 14:34:12 -0700142 printk(BIOS_DEBUG, "%s: IMGptr=%p\n", __func__,
143 pVbiosImageInfo->ImagePtr);
Marshall Dawsonf3dc71e2017-06-14 16:22:07 -0600144 return pVbiosImageInfo->ImagePtr ? AGESA_SUCCESS : AGESA_WARNING;
Marc Jones1587dc82017-05-15 18:55:11 -0600145}
146
Richard Spiegel271b8a52018-11-06 16:32:28 -0700147AGESA_STATUS __weak platform_PcieSlotResetControl(uint32_t Func,
148 uintptr_t Data, void *ConfigPtr)
Marc Jones6e70d672017-10-26 16:42:03 -0600149{
150 printk(BIOS_WARNING, "Warning - AGESA callout: %s not supported\n",
151 __func__);
152 return AGESA_UNSUPPORTED;
153}
154
Richard Spiegel271b8a52018-11-06 16:32:28 -0700155AGESA_STATUS agesa_PcieSlotResetControl(uint32_t Func, uintptr_t Data,
156 void *ConfigPtr)
Martin Rothf80a4312017-09-26 14:45:16 -0600157{
Marc Jones6e70d672017-10-26 16:42:03 -0600158 return platform_PcieSlotResetControl(Func, Data, ConfigPtr);
Martin Rothf80a4312017-09-26 14:45:16 -0600159}
160
Marc Jones33eef132017-10-26 16:50:42 -0600161/*
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.
167 */
168
169/*
170 * Global data for APs.
171 * Passed from the AGESA_Callout for the agesawrapper_amdlaterunaptask.
172 */
173static struct agesa_data {
Richard Spiegel271b8a52018-11-06 16:32:28 -0700174 uint32_t Func;
175 uintptr_t Data;
Kyösti Mälkki423d03c2018-06-28 21:18:12 +0300176 AP_EXE_PARAMS *ConfigPtr;
Marc Jones33eef132017-10-26 16:50:42 -0600177} agesadata;
178
179/*
180 * BSP deploys APs to callout_ap_entry(), which calls
181 * agesawrapper_amdlaterunaptask with the agesadata.
182 */
Subrata Banik33374972018-04-24 13:45:30 +0530183static void callout_ap_entry(void *unused)
Marc Jones33eef132017-10-26 16:50:42 -0600184{
185 AGESA_STATUS Status = AGESA_UNSUPPORTED;
186
Julius Werner540a9802019-12-09 13:03:29 -0800187 printk(BIOS_DEBUG, "%s Func: 0x%x, Data: 0x%lx, Ptr: %p\n",
Marc Jones33eef132017-10-26 16:50:42 -0600188 __func__, agesadata.Func, agesadata.Data, agesadata.ConfigPtr);
189
190 /* Check if this AP should run the function */
191 if (!((agesadata.Func == AGESA_RUNFUNC_ONAP) &&
192 (agesadata.Data == lapicid())))
193 return;
194
Kyösti Mälkki423d03c2018-06-28 21:18:12 +0300195 Status = amd_late_run_ap_task(agesadata.ConfigPtr);
Marc Jones33eef132017-10-26 16:50:42 -0600196
197 if (Status)
Patrick Rudolphfc57d6c2019-11-12 16:30:14 +0100198 printk(BIOS_DEBUG, "There was a problem with %x returned %s\n",
Marc Jones33eef132017-10-26 16:50:42 -0600199 lapicid(), decodeAGESA_STATUS(Status));
200}
201
Richard Spiegel271b8a52018-11-06 16:32:28 -0700202AGESA_STATUS agesa_RunFuncOnAp(uint32_t Func, uintptr_t Data, void *ConfigPtr)
Marc Jones33eef132017-10-26 16:50:42 -0600203{
204 printk(BIOS_DEBUG, "%s\n", __func__);
205
206 agesadata.Func = Func;
207 agesadata.Data = Data;
208 agesadata.ConfigPtr = ConfigPtr;
Felix Held82faefb2021-10-20 20:50:58 +0200209 if (mp_run_on_aps(callout_ap_entry, NULL, MP_RUN_ON_ALL_CPUS, 100 * USECS_PER_MSEC) !=
210 CB_SUCCESS)
Patrick Rudolphbe207b12019-07-26 14:22:09 +0200211 return AGESA_ERROR;
Marc Jones33eef132017-10-26 16:50:42 -0600212
213 return AGESA_SUCCESS;
214}
215
Richard Spiegel271b8a52018-11-06 16:32:28 -0700216AGESA_STATUS agesa_RunFcnOnAllAps(uint32_t Func, uintptr_t Data,
217 void *ConfigPtr)
Marc Jones33eef132017-10-26 16:50:42 -0600218{
219 printk(BIOS_DEBUG, "%s\n", __func__);
220
221 agesadata.Func = Func;
222 agesadata.Data = Data;
223 agesadata.ConfigPtr = ConfigPtr;
Felix Held82faefb2021-10-20 20:50:58 +0200224 if (mp_run_on_aps(callout_ap_entry, NULL, MP_RUN_ON_ALL_CPUS, 100 * USECS_PER_MSEC) !=
225 CB_SUCCESS)
Patrick Rudolphbe207b12019-07-26 14:22:09 +0200226 return AGESA_ERROR;
Marc Jones33eef132017-10-26 16:50:42 -0600227
228 return AGESA_SUCCESS;
229}
230
Richard Spiegel271b8a52018-11-06 16:32:28 -0700231AGESA_STATUS agesa_WaitForAllApsFinished(uint32_t Func, uintptr_t Data,
232 void *ConfigPtr)
Martin Rothf80a4312017-09-26 14:45:16 -0600233{
Marc Jones33eef132017-10-26 16:50:42 -0600234 printk(BIOS_WARNING, "Warning - AGESA callout: %s not supported\n",
235 __func__);
Martin Rothf80a4312017-09-26 14:45:16 -0600236 AGESA_STATUS Status = AGESA_UNSUPPORTED;
237
238 return Status;
239}
240
Richard Spiegel271b8a52018-11-06 16:32:28 -0700241AGESA_STATUS agesa_IdleAnAp(uint32_t Func, uintptr_t Data, void *ConfigPtr)
Martin Rothf80a4312017-09-26 14:45:16 -0600242{
Marc Jones33eef132017-10-26 16:50:42 -0600243 printk(BIOS_WARNING, "Warning - AGESA callout: %s no supported\n",
244 __func__);
Martin Rothf80a4312017-09-26 14:45:16 -0600245 AGESA_STATUS Status = AGESA_UNSUPPORTED;
246
247 return Status;
248}