1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <cbfs.h>
4 #include <cbmem.h>
5 #include <rmodule.h>
6 #include <stage_cache.h>
7 #include <amdblocks/agesawrapper.h>
8 #include <amdblocks/image.h>
9
agesa_map_raw_file(const char * name,size_t * size)10 static void *agesa_map_raw_file(const char *name, size_t *size)
11 {
12 enum cbfs_type type = CBFS_TYPE_RAW;
13 return cbfs_type_map(name, size, &type);
14 }
15
agesa_map_stage_file_early(const char * name,size_t * size)16 static void *agesa_map_stage_file_early(const char *name, size_t *size)
17 {
18 enum cbfs_type type = CBFS_TYPE_STAGE;
19 return cbfs_type_map(name, size, &type);
20 }
21
agesa_map_stage_file_ramstage(const char * name,size_t * size)22 static void *agesa_map_stage_file_ramstage(const char *name, size_t *size)
23 {
24 struct prog prog = PROG_INIT(PROG_REFCODE, name);
25 struct rmod_stage_load rmod_agesa = {
26 .cbmem_id = CBMEM_ID_REFCODE,
27 .prog = &prog,
28 };
29
30 if (resume_from_stage_cache()) {
31 stage_cache_load_stage(STAGE_REFCODE, &prog);
32 } else {
33 if (rmodule_stage_load(&rmod_agesa) < 0)
34 return NULL;
35
36 stage_cache_add(STAGE_REFCODE, &prog);
37 }
38
39 *size = prog_size(&prog);
40 return prog_start(&prog);
41 }
42
agesa_map_stage_file(const char * name,size_t * size)43 static void *agesa_map_stage_file(const char *name, size_t *size)
44 {
45 if (!ENV_RAMSTAGE || !CONFIG(AGESA_SPLIT_MEMORY_FILES))
46 return agesa_map_stage_file_early(name, size);
47 return agesa_map_stage_file_ramstage(name, size);
48 }
49
get_agesa_cbfs_name(void)50 static const char *get_agesa_cbfs_name(void)
51 {
52 if (!CONFIG(AGESA_SPLIT_MEMORY_FILES))
53 return CONFIG_AGESA_CBFS_NAME;
54 if (!ENV_RAMSTAGE)
55 return CONFIG_AGESA_PRE_MEMORY_CBFS_NAME;
56 return CONFIG_AGESA_POST_MEMORY_CBFS_NAME;
57 }
58
agesawrapper_locate_module(const char name[8])59 const void *agesawrapper_locate_module(const char name[8])
60 {
61 const void *agesa;
62 const AMD_IMAGE_HEADER *image;
63 size_t file_size;
64 const char *fname;
65
66 /* Assume boot device is memory mapped so the mapping can leak. */
67 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
68
69 fname = get_agesa_cbfs_name();
70
71 if (CONFIG(AGESA_BINARY_PI_AS_STAGE))
72 agesa = agesa_map_stage_file(fname, &file_size);
73 else
74 agesa = agesa_map_raw_file(fname, &file_size);
75
76 if (!agesa)
77 return NULL;
78
79 image = amd_find_image(agesa, agesa + file_size, 4096, name);
80
81 if (!image)
82 return NULL;
83
84 return (AMD_MODULE_HEADER *)image->ModuleInfoOffset;
85 }
86
87 static MODULE_ENTRY agesa_dispatcher;
88
agesa_get_dispatcher(void)89 MODULE_ENTRY agesa_get_dispatcher(void)
90 {
91 const AMD_MODULE_HEADER *module;
92 static const char id[8] = AGESA_ID;
93
94 if (agesa_dispatcher != NULL)
95 return agesa_dispatcher;
96
97 module = agesawrapper_locate_module(id);
98 if (!module)
99 return NULL;
100
101 agesa_dispatcher = module->ModuleDispatcher;
102 return agesa_dispatcher;
103 }
104