blob: 31db0b6b4c9ce6cb3ce8578b74274f62d7b5a701 [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
Julius Wernercd49cce2019-03-05 16:53:33 -080017#if CONFIG(CPU_AMD_AGESA_OPENSOURCE)
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030018#include "Dispatcher.h"
19#endif
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020020
21#if ENV_ROMSTAGE
22#include <PlatformMemoryConfiguration.h>
23CONST PSO_ENTRY ROMDATA DefaultPlatformMemoryConfiguration[] = {PSO_END};
24#endif
25
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030026static void agesa_locate_image(AMD_CONFIG_PARAMS *StdHeader)
27{
Julius Wernercd49cce2019-03-05 16:53:33 -080028#if CONFIG(CPU_AMD_AGESA_BINARY_PI)
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030029 const char ModuleIdentifier[] = AGESA_ID;
30 const void *agesa, *image;
31 size_t file_size;
32
Julius Werner834b3ec2020-03-04 16:52:08 -080033 agesa = cbfs_map((const char *)CONFIG_AGESA_CBFS_NAME, &file_size);
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030034 if (agesa == NULL)
35 return;
36
37 image = LibAmdLocateImage(agesa, agesa + file_size, 4096,
38 ModuleIdentifier);
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020039 StdHeader->ImageBasePtr = (void *) image;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030040#endif
41}
42
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020043void agesa_set_interface(struct sysinfo *cb)
44{
45 memset(&cb->StdHeader, 0, sizeof(AMD_CONFIG_PARAMS));
46
47 cb->StdHeader.CalloutPtr = GetBiosCallout;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030048
Julius Wernercd49cce2019-03-05 16:53:33 -080049 if (CONFIG(CPU_AMD_AGESA_BINARY_PI)) {
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030050 agesa_locate_image(&cb->StdHeader);
51 AMD_IMAGE_HEADER *image =
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020052 (void *)(uintptr_t)cb->StdHeader.ImageBasePtr;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030053 ASSERT(image);
54 AMD_MODULE_HEADER *module =
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020055 (void *)(uintptr_t)image->ModuleInfoOffset;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030056 ASSERT(module && module->ModuleDispatcher);
57 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020058}
59
60AGESA_STATUS module_dispatch(AGESA_STRUCT_NAME func,
61 AMD_CONFIG_PARAMS *StdHeader)
62{
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030063 MODULE_ENTRY dispatcher;
64
Julius Wernercd49cce2019-03-05 16:53:33 -080065#if CONFIG(CPU_AMD_AGESA_OPENSOURCE)
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030066 dispatcher = AmdAgesaDispatcher;
67#endif
Julius Wernercd49cce2019-03-05 16:53:33 -080068#if CONFIG(CPU_AMD_AGESA_BINARY_PI)
Elyes HAOUASb0b0c8c2018-07-08 12:33:47 +020069 AMD_IMAGE_HEADER *image = (void *)(uintptr_t)StdHeader->ImageBasePtr;
70 AMD_MODULE_HEADER *module = (void *)(uintptr_t)image->ModuleInfoOffset;
Kyösti Mälkkidbd64952017-07-16 16:08:58 +030071 dispatcher = module->ModuleDispatcher;
72#endif
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +020073
74 StdHeader->Func = func;
75 return dispatcher(StdHeader);
76}
77
78static AGESA_STATUS amd_create_struct(AMD_INTERFACE_PARAMS *aip,
79 AGESA_STRUCT_NAME func, void *buf, size_t len)
80{
81 aip->AgesaFunctionName = func;
82 aip->AllocationMethod = 0;
83 aip->NewStructPtr = buf;
84 aip->NewStructSize = len;
85 if (buf != NULL && len != 0)
86 aip->AllocationMethod = ByHost;
87
88 return module_dispatch(AMD_CREATE_STRUCT, &aip->StdHeader);
89}
90
91static AGESA_STATUS amd_release_struct(AMD_INTERFACE_PARAMS *aip)
92{
93 /* Cannot release AMD_LATE_PARAMS until ACPI tables are done. */
94 if (aip->AgesaFunctionName == AMD_INIT_LATE)
95 return AGESA_SUCCESS;
96
97 return module_dispatch(AMD_RELEASE_STRUCT, &aip->StdHeader);
98}
99
100/* By design, for each valid AGESA_STRUCT_NAME, AMD_CONFIG_PARAMS
101 * can be evaluated to apply correct typecast based on Func field.
102 */
103
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300104static AGESA_STATUS romstage_dispatch(struct sysinfo *cb,
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200105 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
106{
107 AGESA_STATUS status = AGESA_UNSUPPORTED;
108
109 switch (func)
110 {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200111 case AMD_INIT_RESET:
112 {
113 AMD_RESET_PARAMS *param = (void *)StdHeader;
114 platform_BeforeInitReset(cb, param);
115 board_BeforeInitReset(cb, param);
116 status = module_dispatch(func, StdHeader);
117 break;
118 }
119
120 case AMD_INIT_EARLY:
121 {
122 AMD_EARLY_PARAMS *param = (void *)StdHeader;
123 platform_BeforeInitEarly(cb, param);
124 board_BeforeInitEarly(cb, param);
125 status = module_dispatch(func, StdHeader);
126 break;
127 }
128
129 case AMD_INIT_POST:
130 {
131 AMD_POST_PARAMS *param = (void *)StdHeader;
132 platform_BeforeInitPost(cb, param);
133 board_BeforeInitPost(cb, param);
134 status = module_dispatch(func, StdHeader);
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200135
136 /* FIXME: Detect if TSC frequency really
137 * changed during raminit? */
138 timestamp_rescale_table(1, 4);
139
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200140 platform_AfterInitPost(cb, param);
141 break;
142 }
143
144 case AMD_INIT_RESUME:
145 {
146 AMD_RESUME_PARAMS *param = (void *)StdHeader;
147 platform_BeforeInitResume(cb, param);
148 status = module_dispatch(func, StdHeader);
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200149
150 /* FIXME: Detect if TSC frequency really
151 * changed during raminit? */
152 timestamp_rescale_table(1, 4);
153
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200154 platform_AfterInitResume(cb, param);
155 break;
156 }
157
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300158 default:
159 {
160 break;
161 }
162
163 }
164 return status;
165}
166
167static AGESA_STATUS ramstage_dispatch(struct sysinfo *cb,
168 AGESA_STRUCT_NAME func, AMD_CONFIG_PARAMS *StdHeader)
169{
170 AGESA_STATUS status = AGESA_UNSUPPORTED;
171
172 switch (func)
173 {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200174 case AMD_INIT_ENV:
175 {
176 AMD_ENV_PARAMS *param = (void *)StdHeader;
177 platform_BeforeInitEnv(cb, param);
178 board_BeforeInitEnv(cb, param);
179 status = module_dispatch(func, StdHeader);
180 platform_AfterInitEnv(cb, param);
181 break;
182 }
183
184 case AMD_S3LATE_RESTORE:
185 {
186 AMD_S3LATE_PARAMS *param = (void *)StdHeader;
187 platform_BeforeS3LateRestore(cb, param);
188 status = module_dispatch(func, StdHeader);
189 platform_AfterS3LateRestore(cb, param);
190 break;
191 }
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200192
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200193 case AMD_INIT_MID:
194 {
195 AMD_MID_PARAMS *param = (void *)StdHeader;
196 platform_BeforeInitMid(cb, param);
197 board_BeforeInitMid(cb, param);
198 status = module_dispatch(func, StdHeader);
199 break;
200 }
201
202 case AMD_S3_SAVE:
203 {
204 AMD_S3SAVE_PARAMS *param = (void *)StdHeader;
205 status = module_dispatch(func, StdHeader);
206 platform_AfterS3Save(cb, param);
207 break;
208 }
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300209
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200210 case AMD_INIT_LATE:
211 {
212 AMD_LATE_PARAMS *param = (void *)StdHeader;
Michał Żygowski506b9c12019-12-20 16:57:13 +0100213 platform_BeforeInitLate(cb, param);
214 board_BeforeInitLate(cb, param);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200215 status = module_dispatch(func, StdHeader);
216 platform_AfterInitLate(cb, param);
217 completion_InitLate(cb, param);
218 break;
219 }
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300220
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200221 default:
222 {
223 break;
224 }
225
226 }
227 return status;
228}
229
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200230int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func)
231{
232 AMD_INTERFACE_PARAMS aip;
233 union {
234 AMD_RESET_PARAMS reset;
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200235 AMD_S3LATE_PARAMS s3late;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200236 } agesa_params;
237 void *buf = NULL;
238 size_t len = 0;
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200239
240 AGESA_STATUS status, final;
241
242 struct agesa_state task;
243 memset(&task, 0, sizeof(task));
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300244 agesa_state_on_entry(&task, func);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200245
246 aip.StdHeader = cb->StdHeader;
247
248 /* For these calls, heap is not available. */
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200249 if (func == AMD_INIT_RESET || func == AMD_S3LATE_RESTORE) {
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200250 buf = (void *) &agesa_params;
251 len = sizeof(agesa_params);
252 memcpy(buf, &cb->StdHeader, sizeof(cb->StdHeader));
253 }
254
255 status = amd_create_struct(&aip, func, buf, len);
256 ASSERT(status == AGESA_SUCCESS);
257
258 /* Must call the function buffer was allocated for.*/
259 AMD_CONFIG_PARAMS *StdHeader = aip.NewStructPtr;
Jacob Garber176670e2019-06-04 15:13:46 -0600260 ASSERT(StdHeader != NULL && StdHeader->Func == func);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200261
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200262 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_entry_id)
263 timestamp_add_now(task.ts_entry_id);
264
Kyösti Mälkkia18f58b2017-07-25 11:34:43 +0300265 if (ENV_ROMSTAGE)
266 final = romstage_dispatch(cb, func, StdHeader);
267
268 if (ENV_RAMSTAGE)
269 final = ramstage_dispatch(cb, func, StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200270
Kyösti Mälkki43f6d9d2019-03-14 14:59:31 +0200271 if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_exit_id)
272 timestamp_add_now(task.ts_exit_id);
273
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300274 agesawrapper_trace(final, StdHeader, task.function_name);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200275 ASSERT(final < AGESA_FATAL);
276
277 status = amd_release_struct(&aip);
278 ASSERT(status == AGESA_SUCCESS);
279
Kyösti Mälkkid1d4f932017-09-24 08:21:00 +0300280 agesa_state_on_exit(&task, &aip.StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200281
282 return (final < AGESA_FATAL) ? 0 : -1;
283}
284
285#if ENV_RAMSTAGE
286
287static void amd_bs_ramstage_init(void *arg)
288{
289 struct sysinfo *cb = arg;
290
291 agesa_set_interface(cb);
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200292
293 if (!acpi_is_wakeup_s3())
294 agesa_execute_state(cb, AMD_INIT_ENV);
295 else {
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200296 agesa_execute_state(cb, AMD_S3LATE_RESTORE);
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300297 fchs3earlyrestore(&cb->StdHeader);
Kyösti Mälkki21e609c2017-03-09 20:08:15 +0200298 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200299}
300
301void sb_After_Pci_Restore_Init(void);
302
303static void amd_bs_dev_enable(void *arg)
304{
305 struct sysinfo *cb = arg;
306
307 if (!acpi_is_wakeup_s3())
308 agesa_execute_state(cb, AMD_INIT_MID);
309
310 /* FIXME */
Julius Wernercd49cce2019-03-05 16:53:33 -0800311 if (CONFIG(AMD_SB_CIMX) && acpi_is_wakeup_s3())
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200312 sb_After_Pci_Restore_Init();
313}
314
315static void amd_bs_post_device(void *arg)
316{
317 struct sysinfo *cb = arg;
318
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300319 if (acpi_is_wakeup_s3()) {
320 fchs3laterestore(&cb->StdHeader);
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200321 return;
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300322 }
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200323
324 agesa_execute_state(cb, AMD_INIT_LATE);
325
326 if (!acpi_s3_resume_allowed())
327 return;
328
329 agesa_execute_state(cb, AMD_S3_SAVE);
330}
331
332static struct sysinfo state_machine;
333
334BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, amd_bs_ramstage_init,
335 &state_machine);
336
337BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, amd_bs_dev_enable,
338 &state_machine);
339
340BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, amd_bs_post_device,
341 &state_machine);
342
343#endif /* ENV_RAMSTAGE */
344
345/* Empty stubs for cases board does not need to override anything. */
Aaron Durbin64031672018-04-21 14:45:32 -0600346void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200347board_BeforeInitReset(struct sysinfo *cb, AMD_RESET_PARAMS *Reset) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600348void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200349board_BeforeInitEarly(struct sysinfo *cb, AMD_EARLY_PARAMS *Early) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600350void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200351board_BeforeInitPost(struct sysinfo *cb, AMD_POST_PARAMS *Post) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600352void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200353board_BeforeInitEnv(struct sysinfo *cb, AMD_ENV_PARAMS *Env) { }
Aaron Durbin64031672018-04-21 14:45:32 -0600354void __weak
Kyösti Mälkki28c4d2f2016-11-25 11:21:02 +0200355board_BeforeInitMid(struct sysinfo *cb, AMD_MID_PARAMS *Mid) { }
Michał Żygowski506b9c12019-12-20 16:57:13 +0100356void __weak
357board_BeforeInitLate(struct sysinfo *cb, AMD_LATE_PARAMS *Late) { }
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300358
Aaron Durbin64031672018-04-21 14:45:32 -0600359AGESA_STATUS __weak
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300360fchs3earlyrestore(AMD_CONFIG_PARAMS *StdHeader)
361{
362 return AGESA_SUCCESS;
363}
364
Aaron Durbin64031672018-04-21 14:45:32 -0600365AGESA_STATUS __weak
Kyösti Mälkki38aff1a2017-07-26 00:57:30 +0300366fchs3laterestore(AMD_CONFIG_PARAMS *StdHeader)
367{
368 return AGESA_SUCCESS;
369}