1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
5 #include <amdblocks/biosram.h>
6 #include <amdblocks/s3_resume.h>
7 #include <amdblocks/agesawrapper.h>
8 #include <amdblocks/BiosCallOuts.h>
9 #include <amdblocks/ioapic.h>
10 #include <soc/pci_devs.h>
11 #include <soc/northbridge.h>
16 void __weak
SetMemParams(AMD_POST_PARAMS
*PostParams
) {}
17 void __weak
OemPostParams(AMD_POST_PARAMS
*PostParams
) {}
19 /* ACPI table pointers returned by AmdInitLate */
20 static void *DmiTable
;
21 static void *AcpiPstate
;
22 static void *AcpiSrat
;
23 static void *AcpiSlit
;
25 static void *AcpiWheaMce
;
26 static void *AcpiWheaCmc
;
27 static void *AcpiAlib
;
28 static void *AcpiIvrs
;
29 static void *AcpiCrat
;
31 static AGESA_STATUS
module_dispatch(AGESA_STRUCT_NAME func
,
32 AMD_CONFIG_PARAMS
*StdHeader
)
34 MODULE_ENTRY dispatcher
= agesa_get_dispatcher();
37 return AGESA_UNSUPPORTED
;
39 StdHeader
->Func
= func
;
40 return dispatcher(StdHeader
);
43 static AGESA_STATUS
amd_dispatch(void *Params
)
45 AMD_CONFIG_PARAMS
*StdHeader
= Params
;
46 return module_dispatch(StdHeader
->Func
, StdHeader
);
49 AGESA_STATUS
amd_late_run_ap_task(AP_EXE_PARAMS
*ApExeParams
)
51 AMD_CONFIG_PARAMS
*StdHeader
= (void *)ApExeParams
;
52 return module_dispatch(AMD_LATE_RUN_AP_TASK
, StdHeader
);
55 static AGESA_STATUS
amd_create_struct(AMD_INTERFACE_PARAMS
*aip
,
56 AGESA_STRUCT_NAME func
, void *buf
, size_t len
)
60 /* Should clone entire StdHeader here. */
61 memset(aip
, 0, sizeof(*aip
));
62 aip
->StdHeader
.CalloutPtr
= &GetBiosCallout
;
64 /* If we provide the buffer, API expects it to have
65 StdHeader already filled. */
66 if (buf
!= NULL
&& len
>= sizeof(aip
->StdHeader
)) {
67 memcpy(buf
, &aip
->StdHeader
, sizeof(aip
->StdHeader
));
68 aip
->AllocationMethod
= ByHost
;
69 aip
->NewStructPtr
= buf
;
70 aip
->NewStructSize
= len
;
73 aip
->AllocationMethod
= PreMemHeap
;
75 aip
->AllocationMethod
= PostMemDram
;
78 aip
->AgesaFunctionName
= func
;
79 status
= module_dispatch(AMD_CREATE_STRUCT
, &aip
->StdHeader
);
81 if (status
!= AGESA_SUCCESS
) {
82 printk(BIOS_ERR
, "AmdCreateStruct() for 0x%x returned 0x%x. "
83 "Proper system initialization may not be possible.\n",
84 aip
->AgesaFunctionName
, status
);
87 if (!aip
->NewStructPtr
)
88 die("No AGESA structure created");
93 static AGESA_STATUS
amd_release_struct(AMD_INTERFACE_PARAMS
*aip
)
95 return module_dispatch(AMD_RELEASE_STRUCT
, &aip
->StdHeader
);
98 static AGESA_STATUS
amd_init_reset(AMD_RESET_PARAMS
*ResetParams
)
102 SetFchResetParams(&ResetParams
->FchInterface
);
104 timestamp_add_now(TS_AGESA_INIT_RESET_START
);
105 status
= amd_dispatch(ResetParams
);
106 timestamp_add_now(TS_AGESA_INIT_RESET_END
);
111 static AGESA_STATUS
amd_init_early(AMD_EARLY_PARAMS
*EarlyParams
)
115 soc_customize_init_early(EarlyParams
);
116 OemCustomizeInitEarly(EarlyParams
);
118 timestamp_add_now(TS_AGESA_INIT_EARLY_START
);
119 status
= amd_dispatch(EarlyParams
);
120 timestamp_add_now(TS_AGESA_INIT_EARLY_END
);
125 static void print_init_post_settings(AMD_POST_PARAMS
*parms
)
127 u64 syslimit
, bottomio
, uma_size
, uma_start
;
130 switch (parms
->MemConfig
.UmaMode
) {
135 mode
= "UMA_SPECIFIED";
145 syslimit
= (u64
)(parms
->MemConfig
.SysLimit
+ 1) * 64 * KiB
- 1;
146 bottomio
= (u64
)parms
->MemConfig
.BottomIo
* 64 * KiB
;
148 uma_size
= (u64
)parms
->MemConfig
.UmaSize
* 64 * KiB
;
149 uma_start
= (u64
)parms
->MemConfig
.UmaBase
* 64 * KiB
;
151 printk(BIOS_SPEW
, "AGESA set: umamode %s\n", mode
);
152 printk(BIOS_SPEW
, " : syslimit 0x%llx, bottomio 0x%08llx\n",
154 printk(BIOS_SPEW
, " : uma size %lluMB, uma start 0x%08llx\n",
155 uma_size
/ MiB
, uma_start
);
158 static AGESA_STATUS
amd_init_post(AMD_POST_PARAMS
*PostParams
)
162 PostParams
->MemConfig
.UmaMode
= CONFIG(GFXUMA
) ? UMA_AUTO
: UMA_NONE
;
163 PostParams
->MemConfig
.UmaSize
= 0;
164 PostParams
->MemConfig
.BottomIo
= (uint16_t)
165 (CONFIG_BOTTOMIO_POSITION
>> 24);
167 SetMemParams(PostParams
);
168 OemPostParams(PostParams
);
169 printk(BIOS_SPEW
, "DRAM clear on reset: %s\n",
170 (PostParams
->MemConfig
.EnableMemClr
== FALSE
) ? "Keep" :
171 (PostParams
->MemConfig
.EnableMemClr
== TRUE
) ? "Clear" :
175 timestamp_add_now(TS_AGESA_INIT_POST_START
);
176 status
= amd_dispatch(PostParams
);
177 timestamp_add_now(TS_AGESA_INIT_POST_END
);
180 * AGESA passes back the base and size of UMA. This is the only
181 * opportunity to get and save these settings to be used in resource
182 * allocation. We also need to allocate the top of low memory.
183 * If UMA is below 4GiB, UMA base is the top of low memory, otherwise
184 * Sub4GCachetop is the top of low memory.
185 * With UMA_NONE we see UmaBase==0.
188 if (PostParams
->MemConfig
.UmaBase
&&
189 (PostParams
->MemConfig
.UmaBase
< ((4ull * GiB
) >> 16)))
190 top
= PostParams
->MemConfig
.UmaBase
<< 16;
192 top
= PostParams
->MemConfig
.Sub4GCacheTop
;
193 backup_top_of_low_cacheable(top
);
195 save_uma_size(PostParams
->MemConfig
.UmaSize
* 64 * KiB
);
196 save_uma_base((u64
)PostParams
->MemConfig
.UmaBase
* 64 * KiB
);
198 print_init_post_settings(PostParams
);
203 static AGESA_STATUS
amd_init_env(AMD_ENV_PARAMS
*EnvParams
)
207 SetFchEnvParams(&EnvParams
->FchInterface
);
208 SetNbEnvParams(&EnvParams
->GnbEnvConfiguration
);
210 timestamp_add_now(TS_AGESA_INIT_ENV_START
);
211 status
= amd_dispatch(EnvParams
);
212 timestamp_add_now(TS_AGESA_INIT_ENV_END
);
217 void *agesawrapper_getlateinitptr(int pick
)
243 static AGESA_STATUS
amd_init_mid(AMD_MID_PARAMS
*MidParams
)
247 /* Enable MMIO on AMD CPU Address Map Controller */
250 SetFchMidParams(&MidParams
->FchInterface
);
251 SetNbMidParams(&MidParams
->GnbMidConfiguration
);
253 timestamp_add_now(TS_AGESA_INIT_MID_START
);
254 status
= amd_dispatch(MidParams
);
255 timestamp_add_now(TS_AGESA_INIT_MID_END
);
260 static AGESA_STATUS
amd_init_late(AMD_LATE_PARAMS
*LateParams
)
264 if (is_dev_enabled(DEV_PTR(iommu
))) {
265 LateParams
->GnbLateConfiguration
.GnbIoapicId
= GNB_IOAPIC_ID
;
266 LateParams
->GnbLateConfiguration
.FchIoapicId
= FCH_IOAPIC_ID
;
269 /* Make binaryPI use \_SB_ as processor object scope in PSTATE SSDT */
270 LateParams
->PlatformConfig
.ProcessorScopeInSb
= true;
272 timestamp_add_now(TS_AGESA_INIT_LATE_START
);
273 Status
= amd_dispatch(LateParams
);
274 timestamp_add_now(TS_AGESA_INIT_LATE_END
);
276 DmiTable
= LateParams
->DmiTable
;
277 AcpiPstate
= LateParams
->AcpiPState
;
279 AcpiWheaMce
= LateParams
->AcpiWheaMce
;
280 AcpiWheaCmc
= LateParams
->AcpiWheaCmc
;
281 AcpiAlib
= LateParams
->AcpiAlib
;
282 AcpiIvrs
= LateParams
->AcpiIvrs
;
283 AcpiCrat
= LateParams
->AcpiCrat
;
285 printk(BIOS_DEBUG
, "DmiTable:%p, AcpiPstatein: %p, AcpiSrat:%p,"
286 "AcpiSlit:%p, Mce:%p, Cmc:%p,"
287 "Alib:%p, AcpiIvrs:%p in %s\n",
288 DmiTable
, AcpiPstate
, AcpiSrat
,
289 AcpiSlit
, AcpiWheaMce
, AcpiWheaCmc
,
290 AcpiAlib
, AcpiIvrs
, __func__
);
295 static AGESA_STATUS
amd_init_rtb(AMD_RTB_PARAMS
*RtbParams
)
299 timestamp_add_now(TS_AGESA_INIT_RTB_START
);
300 Status
= amd_dispatch(RtbParams
);
301 timestamp_add_now(TS_AGESA_INIT_RTB_END
);
303 if (Status
!= AGESA_SUCCESS
)
306 if (OemS3Save(&RtbParams
->S3DataBlock
) != AGESA_SUCCESS
)
307 printk(BIOS_ERR
, "S3 data not saved, resuming impossible\n");
312 static AGESA_STATUS
amd_init_resume(AMD_RESUME_PARAMS
*InitResumeParams
)
316 OemInitResume(&InitResumeParams
->S3DataBlock
);
318 timestamp_add_now(TS_AGESA_INIT_RESUME_START
);
319 status
= amd_dispatch(InitResumeParams
);
320 timestamp_add_now(TS_AGESA_INIT_RESUME_END
);
325 static AGESA_STATUS
amd_s3late_restore(AMD_S3LATE_PARAMS
*S3LateParams
)
331 OemS3LateRestore(&S3LateParams
->S3DataBlock
);
333 timestamp_add_now(TS_AGESA_S3_LATE_START
);
334 Status
= amd_dispatch(S3LateParams
);
335 timestamp_add_now(TS_AGESA_S3_LATE_END
);
340 static AGESA_STATUS
amd_s3final_restore(AMD_S3FINAL_PARAMS
*S3FinalParams
)
344 OemS3LateRestore(&S3FinalParams
->S3DataBlock
);
346 timestamp_add_now(TS_AGESA_S3_FINAL_START
);
347 Status
= amd_dispatch(S3FinalParams
);
348 timestamp_add_now(TS_AGESA_S3_FINAL_END
);
353 static AGESA_STATUS
romstage_dispatch(AMD_CONFIG_PARAMS
*StdHeader
)
355 void *Params
= StdHeader
;
357 switch (StdHeader
->Func
) {
359 return amd_init_reset(Params
);
361 return amd_init_early(Params
);
363 return amd_init_post(Params
);
364 case AMD_INIT_RESUME
:
365 return amd_init_resume(Params
);
367 return AGESA_UNSUPPORTED
;
371 static AGESA_STATUS
ramstage_dispatch(AMD_CONFIG_PARAMS
*StdHeader
)
373 void *Params
= StdHeader
;
375 switch (StdHeader
->Func
) {
377 return amd_init_env(Params
);
379 return amd_init_mid(Params
);
381 return amd_init_late(Params
);
383 return amd_init_rtb(Params
);
384 case AMD_S3LATE_RESTORE
:
385 return amd_s3late_restore(Params
);
386 case AMD_S3FINAL_RESTORE
:
387 return amd_s3final_restore(Params
);
389 return AGESA_UNSUPPORTED
;
393 AGESA_STATUS
agesa_execute_state(AGESA_STRUCT_NAME func
)
395 AGESA_STATUS status
= AGESA_UNSUPPORTED
;
396 AMD_CONFIG_PARAMS
template = {};
397 AMD_CONFIG_PARAMS
*StdHeader
= &template;
398 AMD_INTERFACE_PARAMS AmdParamStruct
;
399 AMD_INTERFACE_PARAMS
*aip
= &AmdParamStruct
;
401 AMD_RESET_PARAMS ResetParams
;
402 AMD_S3LATE_PARAMS S3LateParams
;
403 AMD_S3FINAL_PARAMS S3FinalParams
;
406 if ((func
== AMD_INIT_RESET
) || (func
== AMD_S3LATE_RESTORE
) ||
407 (func
== AMD_S3FINAL_RESTORE
)) {
408 memset(&sp
, 0, sizeof(sp
));
409 amd_create_struct(aip
, func
, &sp
, sizeof(sp
));
411 amd_create_struct(aip
, func
, NULL
, 0);
414 StdHeader
= aip
->NewStructPtr
;
415 StdHeader
->Func
= func
;
418 status
= romstage_dispatch(StdHeader
);
420 status
= ramstage_dispatch(StdHeader
);
422 amd_release_struct(aip
);