blob: a0d775295c2fec1e6ba681e86f537afb2adb7763 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +02003
4#include <stdint.h>
5#include <string.h>
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +02006#include <arch/acpi.h>
7#include <bootstate.h>
Kyösti Mälkkidbd64952017-07-16 16:08:58 +03008#include <cbfs.h>
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +02009#include <cbmem.h>
10#include <timestamp.h>
11
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020012#include <northbridge/amd/agesa/state_machine.h>
13#include <northbridge/amd/agesa/agesa_helper.h>
14#include <northbridge/amd/agesa/BiosCallOuts.h>
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +020015#include <amdlib.h>
Kyösti Mälkkic6918f92018-06-11 08:52:22 +030016
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +020017#include <AMD.h>
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020018
Julius Wernercd49cce2019-03-05 16:53:33 -080019#if CONFIG(CPU_AMD_AGESA_OPENSOURCE)
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030020#include "Dispatcher.h"
21#endif
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020022
23#if ENV_ROMSTAGE
24#include <PlatformMemoryConfiguration.h>
25CONST PSO_ENTRY ROMDATA DefaultPlatformMemoryConfiguration[] = {PSO_END};
26#endif
27
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030028static void agesa_locate_image(AMD_CONFIG_PARAMS *StdHeader)
29{
Julius Wernercd49cce2019-03-05 16:53:33 -080030#if CONFIG(CPU_AMD_AGESA_BINARY_PI)
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030031 const char ModuleIdentifier[] = AGESA_ID;
32 const void *agesa, *image;
33 size_t file_size;
34
35 agesa = cbfs_boot_map_with_leak((const char *)CONFIG_AGESA_CBFS_NAME,
36 CBFS_TYPE_RAW, &file_size);
37 if (agesa == NULL)
38 return;
39
40 image = LibAmdLocateImage(agesa, agesa + file_size, 4096,
41 ModuleIdentifier);
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020042 StdHeader->ImageBasePtr = (void *) image;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030043#endif
44}
45
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020046void agesa_set_interface(struct sysinfo *cb)
47{
48 memset(&cb->StdHeader, 0, sizeof(AMD_CONFIG_PARAMS));
49
50 cb->StdHeader.CalloutPtr = GetBiosCallout;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030051
Julius Wernercd49cce2019-03-05 16:53:33 -080052 if (CONFIG(CPU_AMD_AGESA_BINARY_PI)) {
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030053 agesa_locate_image(&cb->StdHeader);
54 AMD_IMAGE_HEADER *image =
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020055 (void *)(uintptr_t)cb->StdHeader.ImageBasePtr;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030056 ASSERT(image);
57 AMD_MODULE_HEADER *module =
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020058 (void *)(uintptr_t)image->ModuleInfoOffset;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030059 ASSERT(module && module->ModuleDispatcher);
60 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020061}
62
63AGESA_STATUS module_dispatch(AGESA_STRUCT_NAME func,
64 AMD_CONFIG_PARAMS *StdHeader)
65{
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030066 MODULE_ENTRY dispatcher;
67
Julius Wernercd49cce2019-03-05 16:53:33 -080068#if CONFIG(CPU_AMD_AGESA_OPENSOURCE)
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030069 dispatcher = AmdAgesaDispatcher;
70#endif
Julius Wernercd49cce2019-03-05 16:53:33 -080071#if CONFIG(CPU_AMD_AGESA_BINARY_PI)
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020072 AMD_IMAGE_HEADER *image = (void *)(uintptr_t)StdHeader->ImageBasePtr;
73 AMD_MODULE_HEADER *module = (void *)(uintptr_t)image->ModuleInfoOffset;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030074 dispatcher = module->ModuleDispatcher;
75#endif
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020076
77 StdHeader->Func = func;
78 return dispatcher(StdHeader);
79}
80
81static AGESA_STATUS amd_create_struct(AMD_INTERFACE_PARAMS *aip,
82 AGESA_STRUCT_NAME func, void *buf, size_t len)
83{
84 aip->AgesaFunctionName = func;
85 aip->AllocationMethod = 0;
86 aip->NewStructPtr = buf;
87 aip->NewStructSize = len;
88 if (buf != NULL && len != 0)
89 aip->AllocationMethod = ByHost;
90
91 return module_dispatch(AMD_CREATE_STRUCT, &aip->StdHeader);
92}
93
94static AGESA_STATUS amd_release_struct(AMD_INTERFACE_PARAMS *aip)
95{
96 /* Cannot release AMD_LATE_PARAMS until ACPI tables are done. */
97 if (aip->AgesaFunctionName == AMD_INIT_LATE)
98 return AGESA_SUCCESS;
99
100 return module_dispatch(AMD_RELEASE_STRUCT, &aip->StdHeader);
101}
102
103/* By design, for each valid AGESA_STRUCT_NAME, AMD_CONFIG_PARAMS
104 * can be evaluated to apply correct typecast based on Func field.
105 */
106
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300107static AGESA_STATUS romstage_dispatch(struct sysinfo *cb,
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200108 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
109{
110 AGESA_STATUS status = AGESA_UNSUPPORTED;
111
112 switch (func)
113 {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200114 case AMD_INIT_RESET:
115 {
116 AMD_RESET_PARAMS *param = (void *)StdHeader;
117 platform_BeforeInitReset(cb, param);
118 board_BeforeInitReset(cb, param);
119 status = module_dispatch(func, StdHeader);
120 break;
121 }
122
123 case AMD_INIT_EARLY:
124 {
125 AMD_EARLY_PARAMS *param = (void *)StdHeader;
126 platform_BeforeInitEarly(cb, param);
127 board_BeforeInitEarly(cb, param);
128 status = module_dispatch(func, StdHeader);
129 break;
130 }
131
132 case AMD_INIT_POST:
133 {
134 AMD_POST_PARAMS *param = (void *)StdHeader;
135 platform_BeforeInitPost(cb, param);
136 board_BeforeInitPost(cb, param);
137 status = module_dispatch(func, StdHeader);
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200138
139 /* FIXME: Detect if TSC frequency really
140 * changed during raminit? */
141 timestamp_rescale_table(1, 4);
142
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200143 platform_AfterInitPost(cb, param);
144 break;
145 }
146
147 case AMD_INIT_RESUME:
148 {
149 AMD_RESUME_PARAMS *param = (void *)StdHeader;
150 platform_BeforeInitResume(cb, param);
151 status = module_dispatch(func, StdHeader);
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200152
153 /* FIXME: Detect if TSC frequency really
154 * changed during raminit? */
155 timestamp_rescale_table(1, 4);
156
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200157 platform_AfterInitResume(cb, param);
158 break;
159 }
160
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300161 default:
162 {
163 break;
164 }
165
166 }
167 return status;
168}
169
170static AGESA_STATUS ramstage_dispatch(struct sysinfo *cb,
171 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
172{
173 AGESA_STATUS status = AGESA_UNSUPPORTED;
174
175 switch (func)
176 {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200177 case AMD_INIT_ENV:
178 {
179 AMD_ENV_PARAMS *param = (void *)StdHeader;
180 platform_BeforeInitEnv(cb, param);
181 board_BeforeInitEnv(cb, param);
182 status = module_dispatch(func, StdHeader);
183 platform_AfterInitEnv(cb, param);
184 break;
185 }
186
187 case AMD_S3LATE_RESTORE:
188 {
189 AMD_S3LATE_PARAMS *param = (void *)StdHeader;
190 platform_BeforeS3LateRestore(cb, param);
191 status = module_dispatch(func, StdHeader);
192 platform_AfterS3LateRestore(cb, param);
193 break;
194 }
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200195
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200196 case AMD_INIT_MID:
197 {
198 AMD_MID_PARAMS *param = (void *)StdHeader;
199 platform_BeforeInitMid(cb, param);
200 board_BeforeInitMid(cb, param);
201 status = module_dispatch(func, StdHeader);
202 break;
203 }
204
205 case AMD_S3_SAVE:
206 {
207 AMD_S3SAVE_PARAMS *param = (void *)StdHeader;
208 status = module_dispatch(func, StdHeader);
209 platform_AfterS3Save(cb, param);
210 break;
211 }
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300212
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200213 case AMD_INIT_LATE:
214 {
215 AMD_LATE_PARAMS *param = (void *)StdHeader;
Michał Żygowski506b9c12019-12-20 16:57:13 +0100216 platform_BeforeInitLate(cb, param);
217 board_BeforeInitLate(cb, param);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200218 status = module_dispatch(func, StdHeader);
219 platform_AfterInitLate(cb, param);
220 completion_InitLate(cb, param);
221 break;
222 }
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300223
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200224 default:
225 {
226 break;
227 }
228
229 }
230 return status;
231}
232
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200233int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func)
234{
235 AMD_INTERFACE_PARAMS aip;
236 union {
237 AMD_RESET_PARAMS reset;
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200238 AMD_S3LATE_PARAMS s3late;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200239 } agesa_params;
240 void *buf = NULL;
241 size_t len = 0;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200242
243 AGESA_STATUS status, final;
244
245 struct agesa_state task;
246 memset(&task, 0, sizeof(task));
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300247 agesa_state_on_entry(&task, func);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200248
249 aip.StdHeader = cb->StdHeader;
250
251 /* For these calls, heap is not available. */
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200252 if (func == AMD_INIT_RESET || func == AMD_S3LATE_RESTORE) {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200253 buf = (void *) &agesa_params;
254 len = sizeof(agesa_params);
255 memcpy(buf, &cb->StdHeader, sizeof(cb->StdHeader));
256 }
257
258 status = amd_create_struct(&aip, func, buf, len);
259 ASSERT(status == AGESA_SUCCESS);
260
261 /* Must call the function buffer was allocated for.*/
262 AMD_CONFIG_PARAMS *StdHeader = aip.NewStructPtr;
Jacob Garber176670e2019-06-04 15:13:46 -0600263 ASSERT(StdHeader != NULL && StdHeader->Func == func);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200264
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200265 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_entry_id)
266 timestamp_add_now(task.ts_entry_id);
267
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300268 if (ENV_ROMSTAGE)
269 final = romstage_dispatch(cb, func, StdHeader);
270
271 if (ENV_RAMSTAGE)
272 final = ramstage_dispatch(cb, func, StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200273
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200274 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_exit_id)
275 timestamp_add_now(task.ts_exit_id);
276
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300277 agesawrapper_trace(final, StdHeader, task.function_name);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200278 ASSERT(final < AGESA_FATAL);
279
280 status = amd_release_struct(&aip);
281 ASSERT(status == AGESA_SUCCESS);
282
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300283 agesa_state_on_exit(&task, &aip.StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200284
285 return (final < AGESA_FATAL) ? 0 : -1;
286}
287
288#if ENV_RAMSTAGE
289
290static void amd_bs_ramstage_init(void *arg)
291{
292 struct sysinfo *cb = arg;
293
294 agesa_set_interface(cb);
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200295
296 if (!acpi_is_wakeup_s3())
297 agesa_execute_state(cb, AMD_INIT_ENV);
298 else {
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200299 agesa_execute_state(cb, AMD_S3LATE_RESTORE);
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300300 fchs3earlyrestore(&cb->StdHeader);
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200301 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200302}
303
304void sb_After_Pci_Restore_Init(void);
305
306static void amd_bs_dev_enable(void *arg)
307{
308 struct sysinfo *cb = arg;
309
310 if (!acpi_is_wakeup_s3())
311 agesa_execute_state(cb, AMD_INIT_MID);
312
313 /* FIXME */
Julius Wernercd49cce2019-03-05 16:53:33 -0800314 if (CONFIG(AMD_SB_CIMX) && acpi_is_wakeup_s3())
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200315 sb_After_Pci_Restore_Init();
316}
317
318static void amd_bs_post_device(void *arg)
319{
320 struct sysinfo *cb = arg;
321
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300322 if (acpi_is_wakeup_s3()) {
323 fchs3laterestore(&cb->StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200324 return;
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300325 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200326
327 agesa_execute_state(cb, AMD_INIT_LATE);
328
329 if (!acpi_s3_resume_allowed())
330 return;
331
332 agesa_execute_state(cb, AMD_S3_SAVE);
333}
334
335static struct sysinfo state_machine;
336
337BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, amd_bs_ramstage_init,
338 &state_machine);
339
340BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, amd_bs_dev_enable,
341 &state_machine);
342
343BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, amd_bs_post_device,
344 &state_machine);
345
346#endif /* ENV_RAMSTAGE */
347
348/* Empty stubs for cases board does not need to override anything. */
Aaron Durbin64031672018-04-21 14:45:32 -0600349void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200350board_BeforeInitReset(struct sysinfo *cb, AMD_RESET_PARAMS *Reset) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600351void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200352board_BeforeInitEarly(struct sysinfo *cb, AMD_EARLY_PARAMS *Early) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600353void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200354board_BeforeInitPost(struct sysinfo *cb, AMD_POST_PARAMS *Post) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600355void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200356board_BeforeInitEnv(struct sysinfo *cb, AMD_ENV_PARAMS *Env) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600357void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200358board_BeforeInitMid(struct sysinfo *cb, AMD_MID_PARAMS *Mid) { }
Michał Żygowski506b9c12019-12-20 16:57:13 +0100359void __weak
360board_BeforeInitLate(struct sysinfo *cb, AMD_LATE_PARAMS *Late) { }
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300361
Aaron Durbin64031672018-04-21 14:45:32 -0600362AGESA_STATUS __weak
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300363fchs3earlyrestore(AMD_CONFIG_PARAMS *StdHeader)
364{
365 return AGESA_SUCCESS;
366}
367
Aaron Durbin64031672018-04-21 14:45:32 -0600368AGESA_STATUS __weak
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300369fchs3laterestore(AMD_CONFIG_PARAMS *StdHeader)
370{
371 return AGESA_SUCCESS;
372}