1 /* SPDX-License-Identifier: GPL-2.0-only */
10 #include <northbridge/amd/agesa/state_machine.h>
11 #include <northbridge/amd/agesa/agesa_helper.h>
12 #include <northbridge/amd/agesa/BiosCallOuts.h>
18 #include <PlatformMemoryConfiguration.h>
19 CONST PSO_ENTRY ROMDATA DefaultPlatformMemoryConfiguration
[] = {PSO_END
};
22 static void agesa_locate_image(AMD_CONFIG_PARAMS
*StdHeader
)
24 const char ModuleIdentifier
[] = AGESA_ID
;
25 const void *agesa
, *image
;
28 agesa
= cbfs_map((const char *)CONFIG_AGESA_CBFS_NAME
, &file_size
);
32 image
= LibAmdLocateImage(agesa
, agesa
+ file_size
, 4096,
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
;
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
)
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
;
100 AMD_RESET_PARAMS
*param
= (void *)StdHeader
;
101 platform_BeforeInitReset(cb
, param
);
102 board_BeforeInitReset(cb
, param
);
103 status
= module_dispatch(func
, StdHeader
);
109 AMD_EARLY_PARAMS
*param
= (void *)StdHeader
;
110 platform_BeforeInitEarly(cb
, param
);
111 board_BeforeInitEarly(cb
, param
);
112 status
= module_dispatch(func
, StdHeader
);
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
);
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
);
153 static AGESA_STATUS
ramstage_dispatch(struct sysinfo
*cb
,
154 AGESA_STRUCT_NAME func
, AMD_CONFIG_PARAMS
*StdHeader
)
156 AGESA_STATUS status
= AGESA_UNSUPPORTED
;
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
);
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
);
181 AMD_MID_PARAMS
*param
= (void *)StdHeader
;
182 platform_BeforeInitMid(cb
, param
);
183 board_BeforeInitMid(cb
, param
);
184 status
= module_dispatch(func
, StdHeader
);
190 AMD_S3SAVE_PARAMS
*param
= (void *)StdHeader
;
191 status
= module_dispatch(func
, StdHeader
);
192 platform_AfterS3Save(cb
, param
);
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
);
215 int agesa_execute_state(struct sysinfo
*cb
, AGESA_STRUCT_NAME func
)
217 AMD_INTERFACE_PARAMS aip
;
219 AMD_RESET_PARAMS reset
;
220 AMD_S3LATE_PARAMS s3late
;
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
);
251 final
= romstage_dispatch(cb
, func
, StdHeader
);
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;
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
);
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
);
305 agesa_execute_state(cb
, AMD_INIT_LATE
);
307 if (!acpi_s3_resume_allowed())
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
,
318 BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE
, BS_ON_ENTRY
, amd_bs_dev_enable
,
321 BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE
, BS_ON_EXIT
, amd_bs_post_device
,
324 #endif /* ENV_RAMSTAGE */
326 /* Empty stubs for cases board does not need to override anything. */
328 board_BeforeInitReset(struct sysinfo
*cb
, AMD_RESET_PARAMS
*Reset
) { }
330 board_BeforeInitEarly(struct sysinfo
*cb
, AMD_EARLY_PARAMS
*Early
) { }
332 board_BeforeInitPost(struct sysinfo
*cb
, AMD_POST_PARAMS
*Post
) { }
334 board_BeforeInitEnv(struct sysinfo
*cb
, AMD_ENV_PARAMS
*Env
) { }
336 board_BeforeInitMid(struct sysinfo
*cb
, AMD_MID_PARAMS
*Mid
) { }
338 board_BeforeInitLate(struct sysinfo
*cb
, AMD_LATE_PARAMS
*Late
) { }
341 fchs3earlyrestore(AMD_CONFIG_PARAMS
*StdHeader
)
343 return AGESA_SUCCESS
;
347 fchs3laterestore(AMD_CONFIG_PARAMS
*StdHeader
)
349 return AGESA_SUCCESS
;