blob: 976412778ac80ffbbd28db199810528404d69ade [file] [log] [blame]
Marc Jones1587dc82017-05-15 18:55:11 -06001/*
2 * This file is part of the coreboot project.
3 *
Richard Spiegel67c2a7b2017-11-09 16:04:35 -07004 * Copyright (C) 2012 - 2017 Advanced Micro Devices, Inc.
Marc Jones1587dc82017-05-15 18:55:11 -06005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
Aaron Durbina78319b2017-12-08 15:38:59 -070016#include <arch/early_variables.h>
Marshall Dawson857a3872017-12-13 20:01:59 -070017#include <arch/acpi.h>
18#include <cpu/x86/mtrr.h>
Marc Jones1587dc82017-05-15 18:55:11 -060019#include <cbfs.h>
20#include <cbmem.h>
21#include <delay.h>
Justin TerAvest92261952017-12-22 15:15:02 -070022#include <rules.h>
Aaron Durbin931ed7f2017-12-22 17:13:17 -070023#include <rmodule.h>
Aaron Durbine3f7d442017-11-03 11:44:10 -060024#include <string.h>
Martin Rothbc5c3e72017-12-09 10:40:45 -070025#include <timestamp.h>
Marshall Dawson857a3872017-12-13 20:01:59 -070026#include <amdblocks/agesawrapper.h>
27#include <amdblocks/BiosCallOuts.h>
Marc Jones1587dc82017-05-15 18:55:11 -060028
Richard Spiegel67c2a7b2017-11-09 16:04:35 -070029void __attribute__((weak)) SetMemParams(AMD_POST_PARAMS *PostParams) {}
Marc Jones1587dc82017-05-15 18:55:11 -060030void __attribute__((weak)) OemPostParams(AMD_POST_PARAMS *PostParams) {}
31
Marc Jones1587dc82017-05-15 18:55:11 -060032/* ACPI table pointers returned by AmdInitLate */
Aaron Durbin8dd40062017-11-03 11:50:14 -060033static void *DmiTable;
34static void *AcpiPstate;
35static void *AcpiSrat;
36static void *AcpiSlit;
Marc Jones1587dc82017-05-15 18:55:11 -060037
Aaron Durbin8dd40062017-11-03 11:50:14 -060038static void *AcpiWheaMce;
39static void *AcpiWheaCmc;
40static void *AcpiAlib;
41static void *AcpiIvrs;
42static void *AcpiCrat;
Marc Jones1587dc82017-05-15 18:55:11 -060043
Marshall Dawson8f6cd222017-12-15 12:01:41 -070044static AGESA_STATUS agesawrapper_readeventlog(UINT8 HeapStatus)
45{
46 AGESA_STATUS Status;
47 EVENT_PARAMS AmdEventParams = {
48 .StdHeader.CalloutPtr = &GetBiosCallout,
49 .StdHeader.HeapStatus = HeapStatus,
50 };
51
52 Status = AmdReadEventLog(&AmdEventParams);
53 if (AmdEventParams.EventClass)
54 printk(BIOS_DEBUG, "AGESA Event Log:\n");
55
56 while (AmdEventParams.EventClass != 0) {
57 printk(BIOS_DEBUG, " Class = %x, Info = %x,"
58 " Param1 = 0x%x, Param2 = 0x%x"
59 " Param3 = 0x%x, Param4 = 0x%x\n",
60 (u32)AmdEventParams.EventClass,
61 (u32)AmdEventParams.EventInfo,
62 (u32)AmdEventParams.DataParam1,
63 (u32)AmdEventParams.DataParam2,
64 (u32)AmdEventParams.DataParam3,
65 (u32)AmdEventParams.DataParam4);
66 Status = AmdReadEventLog(&AmdEventParams);
67 }
68
69 return Status;
70}
71
Marc Jones1587dc82017-05-15 18:55:11 -060072AGESA_STATUS agesawrapper_amdinitreset(void)
73{
74 AGESA_STATUS status;
Marshall Dawson857a3872017-12-13 20:01:59 -070075 AMD_RESET_PARAMS ResetParams;
76 AMD_INTERFACE_PARAMS AmdParamStruct = {
77 .AgesaFunctionName = AMD_INIT_RESET,
78 .AllocationMethod = ByHost,
79 .NewStructSize = sizeof(AMD_RESET_PARAMS),
80 .NewStructPtr = &ResetParams,
81 .StdHeader.CalloutPtr = &GetBiosCallout
82 };
83 AmdCreateStruct(&AmdParamStruct);
84 SetFchResetParams(&ResetParams.FchInterface);
Marc Jones1587dc82017-05-15 18:55:11 -060085
Martin Rothbc5c3e72017-12-09 10:40:45 -070086 timestamp_add_now(TS_AGESA_INIT_RESET_START);
Marshall Dawson857a3872017-12-13 20:01:59 -070087 status = AmdInitReset(&ResetParams);
Martin Rothbc5c3e72017-12-09 10:40:45 -070088 timestamp_add_now(TS_AGESA_INIT_RESET_DONE);
89
Marshall Dawson3aed84a2017-12-13 20:59:23 -070090 if (status != AGESA_SUCCESS)
91 agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus);
Marshall Dawson857a3872017-12-13 20:01:59 -070092 AmdReleaseStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -060093 return status;
94}
95
96AGESA_STATUS agesawrapper_amdinitearly(void)
97{
98 AGESA_STATUS status;
Marshall Dawson857a3872017-12-13 20:01:59 -070099 AMD_EARLY_PARAMS *EarlyParams;
100 AMD_INTERFACE_PARAMS AmdParamStruct = {
101 .AgesaFunctionName = AMD_INIT_EARLY,
102 .AllocationMethod = PreMemHeap,
103 .StdHeader.CalloutPtr = &GetBiosCallout,
104 };
Marc Jones1587dc82017-05-15 18:55:11 -0600105
Marshall Dawson857a3872017-12-13 20:01:59 -0700106 AmdCreateStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -0600107
Marshall Dawson857a3872017-12-13 20:01:59 -0700108 EarlyParams = (AMD_EARLY_PARAMS *)AmdParamStruct.NewStructPtr;
109 OemCustomizeInitEarly(EarlyParams);
Marc Jones1587dc82017-05-15 18:55:11 -0600110
Marshall Dawson857a3872017-12-13 20:01:59 -0700111 EarlyParams->GnbConfig.PsppPolicy = PsppDisabled;
Martin Rothbc5c3e72017-12-09 10:40:45 -0700112
113 timestamp_add_now(TS_AGESA_INIT_EARLY_START);
Marshall Dawson857a3872017-12-13 20:01:59 -0700114 status = AmdInitEarly(EarlyParams);
Martin Rothbc5c3e72017-12-09 10:40:45 -0700115 timestamp_add_now(TS_AGESA_INIT_EARLY_DONE);
Marc Jones1587dc82017-05-15 18:55:11 -0600116
Marshall Dawson3aed84a2017-12-13 20:59:23 -0700117 if (status != AGESA_SUCCESS)
118 agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus);
Marshall Dawson857a3872017-12-13 20:01:59 -0700119 AmdReleaseStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -0600120
121 return status;
122}
123
Marshall Dawson972f8262017-12-14 09:08:02 -0700124static void print_init_post_settings(AMD_POST_PARAMS *parms)
125{
126 u64 syslimit, bottomio, uma_size, uma_start;
127 const char *mode;
128
129 switch (parms->MemConfig.UmaMode) {
130 case UMA_AUTO:
131 mode = "UMA_AUTO";
132 break;
133 case UMA_SPECIFIED:
134 mode = "UMA_SPECIFIED";
135 break;
136 case UMA_NONE:
137 mode = "UMA_NONE";
138 break;
139 default:
140 mode = "unknown!";
141 break;
142 }
143
144 syslimit = (u64)parms->MemConfig.SysLimit * 64 * KiB;
145 bottomio = (u64)parms->MemConfig.BottomIo * 64 * KiB;
146
147 uma_size = (u64)parms->MemConfig.UmaSize * 64 * KiB;
148 uma_start = (u64)parms->MemConfig.UmaBase * 64 * KiB;
149
150 printk(BIOS_SPEW, "AGESA set: umamode %s\n", mode);
151 printk(BIOS_SPEW, " : syslimit 0x%llx, bottomio 0x%08llx\n",
152 syslimit, bottomio);
153 printk(BIOS_SPEW, " : uma size %lluMB, uma start 0x%08llx\n",
154 uma_size / MiB, uma_start);
155}
156
Marc Jones1587dc82017-05-15 18:55:11 -0600157AGESA_STATUS agesawrapper_amdinitpost(void)
158{
159 AGESA_STATUS status;
Marshall Dawson857a3872017-12-13 20:01:59 -0700160 AMD_INTERFACE_PARAMS AmdParamStruct = {
161 .AgesaFunctionName = AMD_INIT_POST,
162 .AllocationMethod = PreMemHeap,
163 .StdHeader.CalloutPtr = &GetBiosCallout,
164 };
165 AMD_POST_PARAMS *PostParams;
Marc Jones1587dc82017-05-15 18:55:11 -0600166
Marshall Dawson857a3872017-12-13 20:01:59 -0700167 AmdCreateStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -0600168
Marc Jones1587dc82017-05-15 18:55:11 -0600169 PostParams = (AMD_POST_PARAMS *)AmdParamStruct.NewStructPtr;
Marc Jones1587dc82017-05-15 18:55:11 -0600170 PostParams->MemConfig.UmaMode = CONFIG_GFXUMA ? UMA_AUTO : UMA_NONE;
171 PostParams->MemConfig.UmaSize = 0;
172 PostParams->MemConfig.BottomIo = (UINT16)
173 (CONFIG_BOTTOMIO_POSITION >> 24);
174
Richard Spiegel67c2a7b2017-11-09 16:04:35 -0700175 SetMemParams(PostParams);
Marc Jones1587dc82017-05-15 18:55:11 -0600176 OemPostParams(PostParams);
Richard Spiegel67c2a7b2017-11-09 16:04:35 -0700177 printk(BIOS_SPEW, "DRAM clear on reset: %s\n",
178 (PostParams->MemConfig.EnableMemClr == FALSE) ? "Keep" :
179 (PostParams->MemConfig.EnableMemClr == TRUE) ? "Clear" :
180 "unknown"
181 );
Marc Jones1587dc82017-05-15 18:55:11 -0600182
Martin Rothbc5c3e72017-12-09 10:40:45 -0700183 timestamp_add_now(TS_AGESA_INIT_POST_START);
Marshall Dawson857a3872017-12-13 20:01:59 -0700184 status = AmdInitPost(PostParams);
Martin Rothbc5c3e72017-12-09 10:40:45 -0700185 timestamp_add_now(TS_AGESA_INIT_POST_DONE);
Marc Jones1587dc82017-05-15 18:55:11 -0600186
Marshall Dawson972f8262017-12-14 09:08:02 -0700187 /*
188 * If UMA is enabled we currently have it below TOP_MEM as well.
Marc Jones1587dc82017-05-15 18:55:11 -0600189 * UMA may or may not be cacheable, so Sub4GCacheTop could be
Marshall Dawson972f8262017-12-14 09:08:02 -0700190 * higher than UmaBase. With UMA_NONE we see UmaBase==0.
191 */
192 uintptr_t top;
Marc Jones1587dc82017-05-15 18:55:11 -0600193 if (PostParams->MemConfig.UmaBase)
Marshall Dawson972f8262017-12-14 09:08:02 -0700194 top = PostParams->MemConfig.UmaBase << 16;
Marc Jones1587dc82017-05-15 18:55:11 -0600195 else
Marshall Dawson972f8262017-12-14 09:08:02 -0700196 top = PostParams->MemConfig.Sub4GCacheTop;
197 backup_top_of_low_cacheable(top);
Marc Jones1587dc82017-05-15 18:55:11 -0600198
Marshall Dawson972f8262017-12-14 09:08:02 -0700199 print_init_post_settings(PostParams);
Marc Jones1587dc82017-05-15 18:55:11 -0600200
Marshall Dawson3aed84a2017-12-13 20:59:23 -0700201 if (status != AGESA_SUCCESS)
202 agesawrapper_readeventlog(PostParams->StdHeader.HeapStatus);
Marshall Dawson857a3872017-12-13 20:01:59 -0700203 AmdReleaseStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -0600204
205 return status;
206}
207
208AGESA_STATUS agesawrapper_amdinitenv(void)
209{
210 AGESA_STATUS status;
Marshall Dawson857a3872017-12-13 20:01:59 -0700211 AMD_INTERFACE_PARAMS AmdParamStruct = {
212 .AgesaFunctionName = AMD_INIT_ENV,
213 .AllocationMethod = PostMemDram,
214 .StdHeader.CalloutPtr = &GetBiosCallout,
215 };
216 AMD_ENV_PARAMS *EnvParams;
Marc Jones1587dc82017-05-15 18:55:11 -0600217
Marshall Dawson857a3872017-12-13 20:01:59 -0700218 status = AmdCreateStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -0600219
Marshall Dawson857a3872017-12-13 20:01:59 -0700220 EnvParams = (AMD_ENV_PARAMS *)AmdParamStruct.NewStructPtr;
221 SetFchEnvParams(&EnvParams->FchInterface);
222 SetNbEnvParams(&EnvParams->GnbEnvConfiguration);
Marc Jones1587dc82017-05-15 18:55:11 -0600223
Martin Rothbc5c3e72017-12-09 10:40:45 -0700224 timestamp_add_now(TS_AGESA_INIT_ENV_START);
Marshall Dawson857a3872017-12-13 20:01:59 -0700225 status = AmdInitEnv(EnvParams);
Martin Rothbc5c3e72017-12-09 10:40:45 -0700226 timestamp_add_now(TS_AGESA_INIT_ENV_DONE);
227
Marshall Dawson3aed84a2017-12-13 20:59:23 -0700228 if (status != AGESA_SUCCESS)
Marshall Dawson857a3872017-12-13 20:01:59 -0700229 agesawrapper_readeventlog(EnvParams->StdHeader.HeapStatus);
Marc Jones1587dc82017-05-15 18:55:11 -0600230
231 return status;
232}
233
Marshall Dawson857a3872017-12-13 20:01:59 -0700234VOID *agesawrapper_getlateinitptr(int pick)
Marc Jones1587dc82017-05-15 18:55:11 -0600235{
236 switch (pick) {
237 case PICK_DMI:
238 return DmiTable;
239 case PICK_PSTATE:
240 return AcpiPstate;
241 case PICK_SRAT:
242 return AcpiSrat;
243 case PICK_SLIT:
244 return AcpiSlit;
245 case PICK_WHEA_MCE:
246 return AcpiWheaMce;
247 case PICK_WHEA_CMC:
248 return AcpiWheaCmc;
249 case PICK_ALIB:
250 return AcpiAlib;
251 case PICK_IVRS:
252 return AcpiIvrs;
253 case PICK_CRAT:
254 return AcpiCrat;
255 default:
256 return NULL;
257 }
258}
Marc Jones1587dc82017-05-15 18:55:11 -0600259
260AGESA_STATUS agesawrapper_amdinitmid(void)
261{
262 AGESA_STATUS status;
Marshall Dawson857a3872017-12-13 20:01:59 -0700263 AMD_INTERFACE_PARAMS AmdParamStruct = {
264 .AgesaFunctionName = AMD_INIT_MID,
265 .AllocationMethod = PostMemDram,
266 .StdHeader.CalloutPtr = &GetBiosCallout,
267 };
268 AMD_MID_PARAMS *MidParams;
Marc Jones1587dc82017-05-15 18:55:11 -0600269
270 /* Enable MMIO on AMD CPU Address Map Controller */
Marshall Dawson857a3872017-12-13 20:01:59 -0700271 amd_initcpuio();
Marc Jones1587dc82017-05-15 18:55:11 -0600272
Marshall Dawson857a3872017-12-13 20:01:59 -0700273 AmdCreateStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -0600274
Marshall Dawson857a3872017-12-13 20:01:59 -0700275 MidParams = (AMD_MID_PARAMS *)AmdParamStruct.NewStructPtr;
276 SetFchMidParams(&MidParams->FchInterface);
277 SetNbMidParams(&MidParams->GnbMidConfiguration);
Marc Jones1587dc82017-05-15 18:55:11 -0600278
Martin Rothbc5c3e72017-12-09 10:40:45 -0700279 timestamp_add_now(TS_AGESA_INIT_MID_START);
Marshall Dawson857a3872017-12-13 20:01:59 -0700280 status = AmdInitMid(MidParams);
Martin Rothbc5c3e72017-12-09 10:40:45 -0700281 timestamp_add_now(TS_AGESA_INIT_MID_DONE);
282
Marshall Dawson3aed84a2017-12-13 20:59:23 -0700283 if (status != AGESA_SUCCESS)
284 agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus);
Marshall Dawson857a3872017-12-13 20:01:59 -0700285 AmdReleaseStruct(&AmdParamStruct);
Marc Jones1587dc82017-05-15 18:55:11 -0600286
287 return status;
288}
289
Marc Jones1587dc82017-05-15 18:55:11 -0600290AGESA_STATUS agesawrapper_amdinitlate(void)
291{
292 AGESA_STATUS Status;
Marshall Dawson857a3872017-12-13 20:01:59 -0700293 AMD_INTERFACE_PARAMS AmdParamStruct = {
294 .AgesaFunctionName = AMD_INIT_LATE,
295 .AllocationMethod = PostMemDram,
296 .StdHeader.CalloutPtr = &GetBiosCallout,
297 };
298 AMD_LATE_PARAMS *LateParams;
Marc Jones1587dc82017-05-15 18:55:11 -0600299
Richard Spiegelfc511272017-12-11 16:23:58 -0700300 /*
301 * NOTE: if not call amdcreatestruct, the initializer
302 * (AmdInitLateInitializer) would not be called.
303 */
Marc Jones1587dc82017-05-15 18:55:11 -0600304 AmdCreateStruct(&AmdParamStruct);
Marshall Dawson857a3872017-12-13 20:01:59 -0700305 LateParams = (AMD_LATE_PARAMS *)AmdParamStruct.NewStructPtr;
Martin Rothbc5c3e72017-12-09 10:40:45 -0700306
307 timestamp_add_now(TS_AGESA_INIT_LATE_START);
Marshall Dawson857a3872017-12-13 20:01:59 -0700308 Status = AmdInitLate(LateParams);
Martin Rothbc5c3e72017-12-09 10:40:45 -0700309 timestamp_add_now(TS_AGESA_INIT_LATE_DONE);
310
Marc Jones1587dc82017-05-15 18:55:11 -0600311 if (Status != AGESA_SUCCESS) {
Marshall Dawson857a3872017-12-13 20:01:59 -0700312 agesawrapper_readeventlog(LateParams->StdHeader.HeapStatus);
Marc Jones1587dc82017-05-15 18:55:11 -0600313 ASSERT(Status == AGESA_SUCCESS);
314 }
315
Marshall Dawson857a3872017-12-13 20:01:59 -0700316 DmiTable = LateParams->DmiTable;
317 AcpiPstate = LateParams->AcpiPState;
Marc Jones1587dc82017-05-15 18:55:11 -0600318
Marshall Dawson857a3872017-12-13 20:01:59 -0700319 AcpiWheaMce = LateParams->AcpiWheaMce;
320 AcpiWheaCmc = LateParams->AcpiWheaCmc;
321 AcpiAlib = LateParams->AcpiAlib;
322 AcpiIvrs = LateParams->AcpiIvrs;
323 AcpiCrat = LateParams->AcpiCrat;
Marc Jones1587dc82017-05-15 18:55:11 -0600324
Marshall Dawson857a3872017-12-13 20:01:59 -0700325 printk(BIOS_DEBUG, "DmiTable:%p, AcpiPstatein: %p, AcpiSrat:%p,"
326 "AcpiSlit:%p, Mce:%p, Cmc:%p,"
327 "Alib:%p, AcpiIvrs:%p in %s\n",
328 DmiTable, AcpiPstate, AcpiSrat,
329 AcpiSlit, AcpiWheaMce, AcpiWheaCmc,
330 AcpiAlib, AcpiIvrs, __func__);
Marc Jones1587dc82017-05-15 18:55:11 -0600331
332 /* AmdReleaseStruct (&AmdParamStruct); */
333 return Status;
334}
Marc Jones1587dc82017-05-15 18:55:11 -0600335
Marshall Dawson857a3872017-12-13 20:01:59 -0700336AGESA_STATUS agesawrapper_amdlaterunaptask(UINT32 Func, UINTN Data,
337 VOID *ConfigPtr)
Marc Jones1587dc82017-05-15 18:55:11 -0600338{
339 AGESA_STATUS Status;
340 AP_EXE_PARAMS ApExeParams;
341
Aaron Durbine3f7d442017-11-03 11:44:10 -0600342 memset(&ApExeParams, 0, sizeof(ApExeParams));
Marc Jones1587dc82017-05-15 18:55:11 -0600343
344 ApExeParams.StdHeader.AltImageBasePtr = 0;
345 ApExeParams.StdHeader.CalloutPtr = &GetBiosCallout;
346 ApExeParams.StdHeader.Func = 0;
347 ApExeParams.StdHeader.ImageBasePtr = 0;
348 ApExeParams.FunctionNumber = Func;
349 ApExeParams.RelatedDataBlock = ConfigPtr;
350
Marshall Dawson857a3872017-12-13 20:01:59 -0700351 Status = AmdLateRunApTask(&ApExeParams);
Marc Jones1587dc82017-05-15 18:55:11 -0600352 if (Status != AGESA_SUCCESS) {
Marshall Dawson3aed84a2017-12-13 20:59:23 -0700353 /* agesawrapper_readeventlog(); */
Marc Jones1587dc82017-05-15 18:55:11 -0600354 ASSERT(Status == AGESA_SUCCESS);
355 }
356
357 return Status;
358}
359
Aaron Durbin02b43aa2017-12-12 14:56:41 -0700360static int agesa_locate_file(const char *name, struct region_device *rdev,
361 uint32_t type)
362{
363 struct cbfsf fh;
364
365 if (cbfs_boot_locate(&fh, name, &type))
366 return -1;
367
368 cbfs_file_data(rdev, &fh);
369 return 0;
370}
371
372static int agesa_locate_raw_file(const char *name, struct region_device *rdev)
373{
374 return agesa_locate_file(name, rdev, CBFS_TYPE_RAW);
375}
376
Aaron Durbin931ed7f2017-12-22 17:13:17 -0700377static int agesa_locate_stage_file_early(const char *name,
378 struct region_device *rdev)
Aaron Durbin02b43aa2017-12-12 14:56:41 -0700379{
380 const size_t metadata_sz = sizeof(struct cbfs_stage);
381
382 if (agesa_locate_file(name, rdev, CBFS_TYPE_STAGE))
383 return -1;
384
385 /* Peel off the cbfs stage metadata. */
386 return rdev_chain(rdev, rdev, metadata_sz,
387 region_device_sz(rdev) - metadata_sz);
388}
389
Aaron Durbin931ed7f2017-12-22 17:13:17 -0700390static int agesa_locate_stage_file_ramstage(const char *name,
391 struct region_device *rdev)
392{
393 struct prog prog = PROG_INIT(PROG_REFCODE, name);
394 struct rmod_stage_load rmod_agesa = {
395 .cbmem_id = CBMEM_ID_REFCODE,
396 .prog = &prog,
397 };
398
399 if (prog_locate(&prog))
400 return -1;
401 if (rmodule_stage_load(&rmod_agesa) < 0)
402 return -1;
403
404 return rdev_chain(rdev, prog_rdev(&prog), 0,
405 region_device_sz(prog_rdev(&prog)));
406}
407
408static int agesa_locate_stage_file(const char *name, struct region_device *rdev)
409{
Daniel Kurtz462e4702018-01-05 15:40:52 -0700410 if (!ENV_RAMSTAGE || !IS_ENABLED(CONFIG_AGESA_SPLIT_MEMORY_FILES))
Aaron Durbin931ed7f2017-12-22 17:13:17 -0700411 return agesa_locate_stage_file_early(name, rdev);
412 return agesa_locate_stage_file_ramstage(name, rdev);
413}
414
Justin TerAvest92261952017-12-22 15:15:02 -0700415static const char *get_agesa_cbfs_name(void)
416{
417 if (!IS_ENABLED(CONFIG_AGESA_SPLIT_MEMORY_FILES))
418 return CONFIG_AGESA_CBFS_NAME;
419 if (!ENV_RAMSTAGE)
420 return CONFIG_AGESA_PRE_MEMORY_CBFS_NAME;
421 return CONFIG_AGESA_POST_MEMORY_CBFS_NAME;
422}
423
Marshall Dawson857a3872017-12-13 20:01:59 -0700424const void *agesawrapper_locate_module(const CHAR8 name[8])
Marc Jones1587dc82017-05-15 18:55:11 -0600425{
Richard Spiegelfc511272017-12-11 16:23:58 -0700426 const void *agesa;
427 const AMD_IMAGE_HEADER *image;
Aaron Durbin02b43aa2017-12-12 14:56:41 -0700428 struct region_device rdev;
Marc Jones1587dc82017-05-15 18:55:11 -0600429 size_t file_size;
Justin TerAvest92261952017-12-22 15:15:02 -0700430 const char *fname;
Aaron Durbin02b43aa2017-12-12 14:56:41 -0700431 int ret;
Marc Jones1587dc82017-05-15 18:55:11 -0600432
Justin TerAvest92261952017-12-22 15:15:02 -0700433 fname = get_agesa_cbfs_name();
434
Aaron Durbin02b43aa2017-12-12 14:56:41 -0700435 if (IS_ENABLED(CONFIG_AGESA_BINARY_PI_AS_STAGE))
436 ret = agesa_locate_stage_file(fname, &rdev);
437 else
438 ret = agesa_locate_raw_file(fname, &rdev);
439
440 if (ret)
441 return NULL;
442
443 file_size = region_device_sz(&rdev);
444
445 /* Assume boot device is memory mapped so the mapping can leak. */
446 assert(IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED));
447
448 agesa = rdev_mmap_full(&rdev);
Marc Jones1587dc82017-05-15 18:55:11 -0600449
450 if (!agesa)
451 return NULL;
Marc Jones1587dc82017-05-15 18:55:11 -0600452
Aaron Durbin02b43aa2017-12-12 14:56:41 -0700453 image = LibAmdLocateImage(agesa, agesa + file_size, 4096, name);
454
455 if (!image)
456 return NULL;
457
458 return (AMD_MODULE_HEADER *)image->ModuleInfoOffset;
Marc Jones1587dc82017-05-15 18:55:11 -0600459}
Aaron Durbina78319b2017-12-08 15:38:59 -0700460
461static MODULE_ENTRY agesa_dispatcher CAR_GLOBAL;
462
463MODULE_ENTRY agesa_get_dispatcher(void)
464{
465 const AMD_MODULE_HEADER *module;
466 static const CHAR8 id[8] = AGESA_ID;
467 MODULE_ENTRY val = car_get_var(agesa_dispatcher);
468
469 if (val != NULL)
470 return val;
471
472 module = agesawrapper_locate_module(id);
473 if (!module)
474 return NULL;
475
476 val = module->ModuleDispatcher;
477 car_set_var(agesa_dispatcher, val);
478
479 return val;
480}