soc/intel/alderlake: Add ADL-P 4+4 with 28W TDP
[coreboot.git] / src / drivers / amd / agesa / state_machine.c
blob15cdeeae137b45f6729e888e22b9f20e63f181a8
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <stdint.h>
4 #include <string.h>
5 #include <acpi/acpi.h>
6 #include <bootstate.h>
7 #include <cbfs.h>
8 #include <timestamp.h>
10 #include <northbridge/amd/agesa/state_machine.h>
11 #include <northbridge/amd/agesa/agesa_helper.h>
12 #include <northbridge/amd/agesa/BiosCallOuts.h>
13 #include <amdlib.h>
15 #include <AMD.h>
17 #if ENV_RAMINIT
18 #include <PlatformMemoryConfiguration.h>
19 CONST PSO_ENTRY ROMDATA DefaultPlatformMemoryConfiguration[] = {PSO_END};
20 #endif
22 static void agesa_locate_image(AMD_CONFIG_PARAMS *StdHeader)
24 const char ModuleIdentifier[] = AGESA_ID;
25 const void *agesa, *image;
26 size_t file_size;
28 agesa = cbfs_map((const char *)CONFIG_AGESA_CBFS_NAME, &file_size);
29 if (agesa == NULL)
30 return;
32 image = LibAmdLocateImage(agesa, agesa + file_size, 4096,
33 ModuleIdentifier);
34 StdHeader->ImageBasePtr = (void *)image;
37 void agesa_set_interface(struct sysinfo *cb)
39 memset(&cb->StdHeader, 0, sizeof(AMD_CONFIG_PARAMS));
41 cb->StdHeader.CalloutPtr = GetBiosCallout;
43 agesa_locate_image(&cb->StdHeader);
44 AMD_IMAGE_HEADER *image =
45 (void *)(uintptr_t)cb->StdHeader.ImageBasePtr;
46 ASSERT(image);
47 AMD_MODULE_HEADER *module =
48 (void *)(uintptr_t)image->ModuleInfoOffset;
49 ASSERT(module && module->ModuleDispatcher);
52 AGESA_STATUS module_dispatch(AGESA_STRUCT_NAME func,
53 AMD_CONFIG_PARAMS *StdHeader)
55 MODULE_ENTRY dispatcher;
57 AMD_IMAGE_HEADER *image = (void *)(uintptr_t)StdHeader->ImageBasePtr;
58 AMD_MODULE_HEADER *module = (void *)(uintptr_t)image->ModuleInfoOffset;
59 dispatcher = module->ModuleDispatcher;
61 StdHeader->Func = func;
62 return dispatcher(StdHeader);
65 static AGESA_STATUS amd_create_struct(AMD_INTERFACE_PARAMS *aip,
66 AGESA_STRUCT_NAME func, void *buf, size_t len)
68 aip->AgesaFunctionName = func;
69 aip->AllocationMethod = 0;
70 aip->NewStructPtr = buf;
71 aip->NewStructSize = len;
72 if (buf != NULL && len != 0)
73 aip->AllocationMethod = ByHost;
75 return module_dispatch(AMD_CREATE_STRUCT, &aip->StdHeader);
78 static AGESA_STATUS amd_release_struct(AMD_INTERFACE_PARAMS *aip)
80 /* Cannot release AMD_LATE_PARAMS until ACPI tables are done. */
81 if (aip->AgesaFunctionName == AMD_INIT_LATE)
82 return AGESA_SUCCESS;
84 return module_dispatch(AMD_RELEASE_STRUCT, &aip->StdHeader);
87 /* By design, for each valid AGESA_STRUCT_NAME, AMD_CONFIG_PARAMS
88 * can be evaluated to apply correct typecast based on Func field.
91 static AGESA_STATUS romstage_dispatch(struct sysinfo *cb,
92 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
94 AGESA_STATUS status = AGESA_UNSUPPORTED;
96 switch (func)
98 case AMD_INIT_RESET:
100 AMD_RESET_PARAMS *param = (void *)StdHeader;
101 platform_BeforeInitReset(cb, param);
102 board_BeforeInitReset(cb, param);
103 status = module_dispatch(func, StdHeader);
104 break;
107 case AMD_INIT_EARLY:
109 AMD_EARLY_PARAMS *param = (void *)StdHeader;
110 platform_BeforeInitEarly(cb, param);
111 board_BeforeInitEarly(cb, param);
112 status = module_dispatch(func, StdHeader);
113 break;
116 case AMD_INIT_POST:
118 AMD_POST_PARAMS *param = (void *)StdHeader;
119 platform_BeforeInitPost(cb, param);
120 board_BeforeInitPost(cb, param);
121 status = module_dispatch(func, StdHeader);
123 /* FIXME: Detect if TSC frequency really
124 * changed during raminit? */
125 timestamp_rescale_table(1, 4);
127 platform_AfterInitPost(cb, param);
128 break;
131 case AMD_INIT_RESUME:
133 AMD_RESUME_PARAMS *param = (void *)StdHeader;
134 platform_BeforeInitResume(cb, param);
135 status = module_dispatch(func, StdHeader);
137 /* FIXME: Detect if TSC frequency really
138 * changed during raminit? */
139 timestamp_rescale_table(1, 4);
141 platform_AfterInitResume(cb, param);
142 break;
145 default:
147 break;
150 return status;
153 static AGESA_STATUS ramstage_dispatch(struct sysinfo *cb,
154 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
156 AGESA_STATUS status = AGESA_UNSUPPORTED;
158 switch (func)
160 case AMD_INIT_ENV:
162 AMD_ENV_PARAMS *param = (void *)StdHeader;
163 platform_BeforeInitEnv(cb, param);
164 board_BeforeInitEnv(cb, param);
165 status = module_dispatch(func, StdHeader);
166 platform_AfterInitEnv(cb, param);
167 break;
170 case AMD_S3LATE_RESTORE:
172 AMD_S3LATE_PARAMS *param = (void *)StdHeader;
173 platform_BeforeS3LateRestore(cb, param);
174 status = module_dispatch(func, StdHeader);
175 platform_AfterS3LateRestore(cb, param);
176 break;
179 case AMD_INIT_MID:
181 AMD_MID_PARAMS *param = (void *)StdHeader;
182 platform_BeforeInitMid(cb, param);
183 board_BeforeInitMid(cb, param);
184 status = module_dispatch(func, StdHeader);
185 break;
188 case AMD_S3_SAVE:
190 AMD_S3SAVE_PARAMS *param = (void *)StdHeader;
191 status = module_dispatch(func, StdHeader);
192 platform_AfterS3Save(cb, param);
193 break;
196 case AMD_INIT_LATE:
198 AMD_LATE_PARAMS *param = (void *)StdHeader;
199 platform_BeforeInitLate(cb, param);
200 board_BeforeInitLate(cb, param);
201 status = module_dispatch(func, StdHeader);
202 platform_AfterInitLate(cb, param);
203 completion_InitLate(cb, param);
204 break;
207 default:
209 break;
212 return status;
215 int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func)
217 AMD_INTERFACE_PARAMS aip;
218 union {
219 AMD_RESET_PARAMS reset;
220 AMD_S3LATE_PARAMS s3late;
221 } agesa_params;
222 void *buf = NULL;
223 size_t len = 0;
225 AGESA_STATUS status, final;
227 struct agesa_state task;
228 memset(&task, 0, sizeof(task));
229 agesa_state_on_entry(&task, func);
231 aip.StdHeader = cb->StdHeader;
233 /* For these calls, heap is not available. */
234 if (func == AMD_INIT_RESET || func == AMD_S3LATE_RESTORE) {
235 buf = (void *)&agesa_params;
236 len = sizeof(agesa_params);
237 memcpy(buf, &cb->StdHeader, sizeof(cb->StdHeader));
240 status = amd_create_struct(&aip, func, buf, len);
241 ASSERT(status == AGESA_SUCCESS);
243 /* Must call the function buffer was allocated for.*/
244 AMD_CONFIG_PARAMS *StdHeader = aip.NewStructPtr;
245 ASSERT(StdHeader != NULL && StdHeader->Func == func);
247 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_entry_id)
248 timestamp_add_now(task.ts_entry_id);
250 if (ENV_RAMINIT)
251 final = romstage_dispatch(cb, func, StdHeader);
253 if (ENV_RAMSTAGE)
254 final = ramstage_dispatch(cb, func, StdHeader);
256 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_exit_id)
257 timestamp_add_now(task.ts_exit_id);
259 agesawrapper_trace(final, StdHeader, task.function_name);
260 ASSERT(final < AGESA_FATAL);
262 status = amd_release_struct(&aip);
263 ASSERT(status == AGESA_SUCCESS);
265 agesa_state_on_exit(&task, &aip.StdHeader);
267 return (final < AGESA_FATAL) ? 0 : -1;
270 #if ENV_RAMSTAGE
272 static void amd_bs_ramstage_init(void *arg)
274 struct sysinfo *cb = arg;
276 agesa_set_interface(cb);
278 if (!acpi_is_wakeup_s3())
279 agesa_execute_state(cb, AMD_INIT_ENV);
280 else {
281 agesa_execute_state(cb, AMD_S3LATE_RESTORE);
282 fchs3earlyrestore(&cb->StdHeader);
286 void sb_After_Pci_Restore_Init(void);
288 static void amd_bs_dev_enable(void *arg)
290 struct sysinfo *cb = arg;
292 if (!acpi_is_wakeup_s3())
293 agesa_execute_state(cb, AMD_INIT_MID);
296 static void amd_bs_post_device(void *arg)
298 struct sysinfo *cb = arg;
300 if (acpi_is_wakeup_s3()) {
301 fchs3laterestore(&cb->StdHeader);
302 return;
305 agesa_execute_state(cb, AMD_INIT_LATE);
307 if (!acpi_s3_resume_allowed())
308 return;
310 agesa_execute_state(cb, AMD_S3_SAVE);
313 static struct sysinfo state_machine;
315 BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, amd_bs_ramstage_init,
316 &state_machine);
318 BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, amd_bs_dev_enable,
319 &state_machine);
321 BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, amd_bs_post_device,
322 &state_machine);
324 #endif /* ENV_RAMSTAGE */
326 /* Empty stubs for cases board does not need to override anything. */
327 void __weak
328 board_BeforeInitReset(struct sysinfo *cb, AMD_RESET_PARAMS *Reset) { }
329 void __weak
330 board_BeforeInitEarly(struct sysinfo *cb, AMD_EARLY_PARAMS *Early) { }
331 void __weak
332 board_BeforeInitPost(struct sysinfo *cb, AMD_POST_PARAMS *Post) { }
333 void __weak
334 board_BeforeInitEnv(struct sysinfo *cb, AMD_ENV_PARAMS *Env) { }
335 void __weak
336 board_BeforeInitMid(struct sysinfo *cb, AMD_MID_PARAMS *Mid) { }
337 void __weak
338 board_BeforeInitLate(struct sysinfo *cb, AMD_LATE_PARAMS *Late) { }
340 AGESA_STATUS __weak
341 fchs3earlyrestore(AMD_CONFIG_PARAMS *StdHeader)
343 return AGESA_SUCCESS;
346 AGESA_STATUS __weak
347 fchs3laterestore(AMD_CONFIG_PARAMS *StdHeader)
349 return AGESA_SUCCESS;