blob: 15cdeeae137b45f6729e888e22b9f20e63f181a8 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +02002
3#include <stdint.h>
4#include <string.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07005#include <acpi/acpi.h>
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +02006#include <bootstate.h>
Kyösti Mälkkidbd64952017-07-16 16:08:58 +03007#include <cbfs.h>
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +02008#include <timestamp.h>
9
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020010#include <northbridge/amd/agesa/state_machine.h>
11#include <northbridge/amd/agesa/agesa_helper.h>
12#include <northbridge/amd/agesa/BiosCallOuts.h>
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +020013#include <amdlib.h>
Kyösti Mälkkic6918f92018-06-11 08:52:22 +030014
Elyes HAOUAS19f5ba82018-10-14 14:52:06 +020015#include <AMD.h>
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020016
Kyösti Mälkki11cac782022-04-07 07:16:48 +030017#if ENV_RAMINIT
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020018#include <PlatformMemoryConfiguration.h>
19CONST PSO_ENTRY ROMDATA DefaultPlatformMemoryConfiguration[] = {PSO_END};
20#endif
21
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030022static void agesa_locate_image(AMD_CONFIG_PARAMS *StdHeader)
23{
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030024 const char ModuleIdentifier[] = AGESA_ID;
25 const void *agesa, *image;
26 size_t file_size;
27
Julius Werner834b3ec2020-03-04 16:52:08 -080028 agesa = cbfs_map((const char *)CONFIG_AGESA_CBFS_NAME, &file_size);
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030029 if (agesa == NULL)
30 return;
31
32 image = LibAmdLocateImage(agesa, agesa + file_size, 4096,
33 ModuleIdentifier);
Elyes Haouas76c63232022-07-16 09:47:00 +020034 StdHeader->ImageBasePtr = (void *)image;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030035}
36
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020037void agesa_set_interface(struct sysinfo *cb)
38{
39 memset(&cb->StdHeader, 0, sizeof(AMD_CONFIG_PARAMS));
40
41 cb->StdHeader.CalloutPtr = GetBiosCallout;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030042
Arthur Heymans81a4fef2022-11-01 23:33:45 +010043 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);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020050}
51
52AGESA_STATUS module_dispatch(AGESA_STRUCT_NAME func,
53 AMD_CONFIG_PARAMS *StdHeader)
54{
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030055 MODULE_ENTRY dispatcher;
56
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020057 AMD_IMAGE_HEADER *image = (void *)(uintptr_t)StdHeader->ImageBasePtr;
58 AMD_MODULE_HEADER *module = (void *)(uintptr_t)image->ModuleInfoOffset;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030059 dispatcher = module->ModuleDispatcher;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020060
61 StdHeader->Func = func;
62 return dispatcher(StdHeader);
63}
64
65static AGESA_STATUS amd_create_struct(AMD_INTERFACE_PARAMS *aip,
66 AGESA_STRUCT_NAME func, void *buf, size_t len)
67{
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;
74
75 return module_dispatch(AMD_CREATE_STRUCT, &aip->StdHeader);
76}
77
78static AGESA_STATUS amd_release_struct(AMD_INTERFACE_PARAMS *aip)
79{
80 /* Cannot release AMD_LATE_PARAMS until ACPI tables are done. */
81 if (aip->AgesaFunctionName == AMD_INIT_LATE)
82 return AGESA_SUCCESS;
83
84 return module_dispatch(AMD_RELEASE_STRUCT, &aip->StdHeader);
85}
86
87/* By design, for each valid AGESA_STRUCT_NAME, AMD_CONFIG_PARAMS
88 * can be evaluated to apply correct typecast based on Func field.
89 */
90
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +030091static AGESA_STATUS romstage_dispatch(struct sysinfo *cb,
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020092 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
93{
94 AGESA_STATUS status = AGESA_UNSUPPORTED;
95
96 switch (func)
97 {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020098 case AMD_INIT_RESET:
99 {
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;
105 }
106
107 case AMD_INIT_EARLY:
108 {
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;
114 }
115
116 case AMD_INIT_POST:
117 {
118 AMD_POST_PARAMS *param = (void *)StdHeader;
119 platform_BeforeInitPost(cb, param);
120 board_BeforeInitPost(cb, param);
121 status = module_dispatch(func, StdHeader);
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200122
123 /* FIXME: Detect if TSC frequency really
124 * changed during raminit? */
125 timestamp_rescale_table(1, 4);
126
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200127 platform_AfterInitPost(cb, param);
128 break;
129 }
130
131 case AMD_INIT_RESUME:
132 {
133 AMD_RESUME_PARAMS *param = (void *)StdHeader;
134 platform_BeforeInitResume(cb, param);
135 status = module_dispatch(func, StdHeader);
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200136
137 /* FIXME: Detect if TSC frequency really
138 * changed during raminit? */
139 timestamp_rescale_table(1, 4);
140
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200141 platform_AfterInitResume(cb, param);
142 break;
143 }
144
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300145 default:
146 {
147 break;
148 }
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300149 }
150 return status;
151}
152
153static AGESA_STATUS ramstage_dispatch(struct sysinfo *cb,
154 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
155{
156 AGESA_STATUS status = AGESA_UNSUPPORTED;
157
158 switch (func)
159 {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200160 case AMD_INIT_ENV:
161 {
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;
168 }
169
170 case AMD_S3LATE_RESTORE:
171 {
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;
177 }
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200178
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200179 case AMD_INIT_MID:
180 {
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;
186 }
187
188 case AMD_S3_SAVE:
189 {
190 AMD_S3SAVE_PARAMS *param = (void *)StdHeader;
191 status = module_dispatch(func, StdHeader);
192 platform_AfterS3Save(cb, param);
193 break;
194 }
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300195
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200196 case AMD_INIT_LATE:
197 {
198 AMD_LATE_PARAMS *param = (void *)StdHeader;
Michał Żygowski506b9c12019-12-20 16:57:13 +0100199 platform_BeforeInitLate(cb, param);
200 board_BeforeInitLate(cb, param);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200201 status = module_dispatch(func, StdHeader);
202 platform_AfterInitLate(cb, param);
203 completion_InitLate(cb, param);
204 break;
205 }
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300206
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200207 default:
208 {
209 break;
210 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200211 }
212 return status;
213}
214
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200215int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func)
216{
217 AMD_INTERFACE_PARAMS aip;
218 union {
219 AMD_RESET_PARAMS reset;
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200220 AMD_S3LATE_PARAMS s3late;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200221 } agesa_params;
222 void *buf = NULL;
223 size_t len = 0;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200224
225 AGESA_STATUS status, final;
226
227 struct agesa_state task;
228 memset(&task, 0, sizeof(task));
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300229 agesa_state_on_entry(&task, func);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200230
231 aip.StdHeader = cb->StdHeader;
232
233 /* For these calls, heap is not available. */
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200234 if (func == AMD_INIT_RESET || func == AMD_S3LATE_RESTORE) {
Elyes Haouas76c63232022-07-16 09:47:00 +0200235 buf = (void *)&agesa_params;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200236 len = sizeof(agesa_params);
237 memcpy(buf, &cb->StdHeader, sizeof(cb->StdHeader));
238 }
239
240 status = amd_create_struct(&aip, func, buf, len);
241 ASSERT(status == AGESA_SUCCESS);
242
243 /* Must call the function buffer was allocated for.*/
244 AMD_CONFIG_PARAMS *StdHeader = aip.NewStructPtr;
Jacob Garber176670e2019-06-04 15:13:46 -0600245 ASSERT(StdHeader != NULL && StdHeader->Func == func);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200246
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200247 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_entry_id)
248 timestamp_add_now(task.ts_entry_id);
249
Kyösti Mälkki11cac782022-04-07 07:16:48 +0300250 if (ENV_RAMINIT)
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300251 final = romstage_dispatch(cb, func, StdHeader);
252
253 if (ENV_RAMSTAGE)
254 final = ramstage_dispatch(cb, func, StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200255
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200256 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_exit_id)
257 timestamp_add_now(task.ts_exit_id);
258
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300259 agesawrapper_trace(final, StdHeader, task.function_name);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200260 ASSERT(final < AGESA_FATAL);
261
262 status = amd_release_struct(&aip);
263 ASSERT(status == AGESA_SUCCESS);
264
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300265 agesa_state_on_exit(&task, &aip.StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200266
267 return (final < AGESA_FATAL) ? 0 : -1;
268}
269
270#if ENV_RAMSTAGE
271
272static void amd_bs_ramstage_init(void *arg)
273{
274 struct sysinfo *cb = arg;
275
276 agesa_set_interface(cb);
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200277
278 if (!acpi_is_wakeup_s3())
279 agesa_execute_state(cb, AMD_INIT_ENV);
280 else {
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200281 agesa_execute_state(cb, AMD_S3LATE_RESTORE);
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300282 fchs3earlyrestore(&cb->StdHeader);
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200283 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200284}
285
286void sb_After_Pci_Restore_Init(void);
287
288static void amd_bs_dev_enable(void *arg)
289{
290 struct sysinfo *cb = arg;
291
292 if (!acpi_is_wakeup_s3())
293 agesa_execute_state(cb, AMD_INIT_MID);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200294}
295
296static void amd_bs_post_device(void *arg)
297{
298 struct sysinfo *cb = arg;
299
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300300 if (acpi_is_wakeup_s3()) {
301 fchs3laterestore(&cb->StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200302 return;
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300303 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200304
305 agesa_execute_state(cb, AMD_INIT_LATE);
306
307 if (!acpi_s3_resume_allowed())
308 return;
309
310 agesa_execute_state(cb, AMD_S3_SAVE);
311}
312
313static struct sysinfo state_machine;
314
315BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, amd_bs_ramstage_init,
316 &state_machine);
317
318BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, amd_bs_dev_enable,
319 &state_machine);
320
321BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, amd_bs_post_device,
322 &state_machine);
323
324#endif /* ENV_RAMSTAGE */
325
326/* Empty stubs for cases board does not need to override anything. */
Aaron Durbin64031672018-04-21 14:45:32 -0600327void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200328board_BeforeInitReset(struct sysinfo *cb, AMD_RESET_PARAMS *Reset) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600329void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200330board_BeforeInitEarly(struct sysinfo *cb, AMD_EARLY_PARAMS *Early) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600331void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200332board_BeforeInitPost(struct sysinfo *cb, AMD_POST_PARAMS *Post) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600333void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200334board_BeforeInitEnv(struct sysinfo *cb, AMD_ENV_PARAMS *Env) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600335void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200336board_BeforeInitMid(struct sysinfo *cb, AMD_MID_PARAMS *Mid) { }
Michał Żygowski506b9c12019-12-20 16:57:13 +0100337void __weak
338board_BeforeInitLate(struct sysinfo *cb, AMD_LATE_PARAMS *Late) { }
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300339
Aaron Durbin64031672018-04-21 14:45:32 -0600340AGESA_STATUS __weak
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300341fchs3earlyrestore(AMD_CONFIG_PARAMS *StdHeader)
342{
343 return AGESA_SUCCESS;
344}
345
Aaron Durbin64031672018-04-21 14:45:32 -0600346AGESA_STATUS __weak
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300347fchs3laterestore(AMD_CONFIG_PARAMS *StdHeader)
348{
349 return AGESA_SUCCESS;
350}