xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/pi/refcode_loader.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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