diff --git a/src/soc/amd/common/block/pi/Makefile.inc b/src/soc/amd/common/block/pi/Makefile.inc index ba0812343b..5afbb3ebdb 100644 --- a/src/soc/amd/common/block/pi/Makefile.inc +++ b/src/soc/amd/common/block/pi/Makefile.inc @@ -4,6 +4,7 @@ romstage-y += agesawrapper.c romstage-y += def_callouts.c romstage-y += heapmanager.c romstage-y += image.c +romstage-y += refcode_loader.c ramstage-y += agesawrapper.c ramstage-y += amd_late_init.c @@ -11,5 +12,6 @@ ramstage-$(CONFIG_HAVE_ACPI_RESUME) += amd_resume_final.c ramstage-y += def_callouts.c ramstage-y += heapmanager.c ramstage-y += image.c +ramstage-y += refcode_loader.c endif diff --git a/src/soc/amd/common/block/pi/agesawrapper.c b/src/soc/amd/common/block/pi/agesawrapper.c index 89cb9bec76..92153eee7d 100644 --- a/src/soc/amd/common/block/pi/agesawrapper.c +++ b/src/soc/amd/common/block/pi/agesawrapper.c @@ -15,17 +15,12 @@ */ #include -#include -#include #include #include -#include -#include #include #include #include #include -#include #include #include #include @@ -498,134 +493,3 @@ AGESA_STATUS agesawrapper_amds3finalrestore(void) return Status; } - -static int agesa_locate_file(const char *name, struct region_device *rdev, - uint32_t type) -{ - struct cbfsf fh; - - if (cbfs_boot_locate(&fh, name, &type)) - return -1; - - cbfs_file_data(rdev, &fh); - return 0; -} - -static int agesa_locate_raw_file(const char *name, struct region_device *rdev) -{ - return agesa_locate_file(name, rdev, CBFS_TYPE_RAW); -} - -static int agesa_locate_stage_file_early(const char *name, - struct region_device *rdev) -{ - const size_t metadata_sz = sizeof(struct cbfs_stage); - - if (agesa_locate_file(name, rdev, CBFS_TYPE_STAGE)) - return -1; - - /* Peel off the cbfs stage metadata. */ - return rdev_chain(rdev, rdev, metadata_sz, - region_device_sz(rdev) - metadata_sz); -} - -static int agesa_locate_stage_file_ramstage(const char *name, - struct region_device *rdev) -{ - struct prog prog = PROG_INIT(PROG_REFCODE, name); - struct rmod_stage_load rmod_agesa = { - .cbmem_id = CBMEM_ID_REFCODE, - .prog = &prog, - }; - - if (acpi_is_wakeup_s3() && !IS_ENABLED(CONFIG_NO_STAGE_CACHE)) { - printk(BIOS_INFO, "AGESA: Loading stage from cache\n"); - // There is no way to tell if this succeeded. - stage_cache_load_stage(STAGE_REFCODE, &prog); - } else { - if (prog_locate(&prog)) - return -1; - - if (rmodule_stage_load(&rmod_agesa) < 0) - return -1; - - if (!IS_ENABLED(CONFIG_NO_STAGE_CACHE)) { - printk(BIOS_INFO, "AGESA: Saving stage to cache\n"); - stage_cache_add(STAGE_REFCODE, &prog); - } - } - - return rdev_chain(rdev, prog_rdev(&prog), 0, - region_device_sz(prog_rdev(&prog))); -} - -static int agesa_locate_stage_file(const char *name, struct region_device *rdev) -{ - if (!ENV_RAMSTAGE || !IS_ENABLED(CONFIG_AGESA_SPLIT_MEMORY_FILES)) - return agesa_locate_stage_file_early(name, rdev); - return agesa_locate_stage_file_ramstage(name, rdev); -} - -static const char *get_agesa_cbfs_name(void) -{ - if (!IS_ENABLED(CONFIG_AGESA_SPLIT_MEMORY_FILES)) - return CONFIG_AGESA_CBFS_NAME; - if (!ENV_RAMSTAGE) - return CONFIG_AGESA_PRE_MEMORY_CBFS_NAME; - return CONFIG_AGESA_POST_MEMORY_CBFS_NAME; -} - -const void *agesawrapper_locate_module(const char name[8]) -{ - const void *agesa; - const AMD_IMAGE_HEADER *image; - struct region_device rdev; - size_t file_size; - const char *fname; - int ret; - - fname = get_agesa_cbfs_name(); - - if (IS_ENABLED(CONFIG_AGESA_BINARY_PI_AS_STAGE)) - ret = agesa_locate_stage_file(fname, &rdev); - else - ret = agesa_locate_raw_file(fname, &rdev); - - if (ret) - return NULL; - - file_size = region_device_sz(&rdev); - - /* Assume boot device is memory mapped so the mapping can leak. */ - assert(IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED)); - - agesa = rdev_mmap_full(&rdev); - - if (!agesa) - return NULL; - - image = amd_find_image(agesa, agesa + file_size, 4096, name); - - if (!image) - return NULL; - - return (AMD_MODULE_HEADER *)image->ModuleInfoOffset; -} - -static MODULE_ENTRY agesa_dispatcher; - -MODULE_ENTRY agesa_get_dispatcher(void) -{ - const AMD_MODULE_HEADER *module; - static const char id[8] = AGESA_ID; - - if (agesa_dispatcher != NULL) - return agesa_dispatcher; - - module = agesawrapper_locate_module(id); - if (!module) - return NULL; - - agesa_dispatcher = module->ModuleDispatcher; - return agesa_dispatcher; -} diff --git a/src/soc/amd/common/block/pi/refcode_loader.c b/src/soc/amd/common/block/pi/refcode_loader.c new file mode 100644 index 0000000000..7937817316 --- /dev/null +++ b/src/soc/amd/common/block/pi/refcode_loader.c @@ -0,0 +1,153 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 - 2017 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int agesa_locate_file(const char *name, struct region_device *rdev, + uint32_t type) +{ + struct cbfsf fh; + + if (cbfs_boot_locate(&fh, name, &type)) + return -1; + + cbfs_file_data(rdev, &fh); + return 0; +} + +static int agesa_locate_raw_file(const char *name, struct region_device *rdev) +{ + return agesa_locate_file(name, rdev, CBFS_TYPE_RAW); +} + +static int agesa_locate_stage_file_early(const char *name, + struct region_device *rdev) +{ + const size_t metadata_sz = sizeof(struct cbfs_stage); + + if (agesa_locate_file(name, rdev, CBFS_TYPE_STAGE)) + return -1; + + /* Peel off the cbfs stage metadata. */ + return rdev_chain(rdev, rdev, metadata_sz, + region_device_sz(rdev) - metadata_sz); +} + +static int agesa_locate_stage_file_ramstage(const char *name, + struct region_device *rdev) +{ + struct prog prog = PROG_INIT(PROG_REFCODE, name); + struct rmod_stage_load rmod_agesa = { + .cbmem_id = CBMEM_ID_REFCODE, + .prog = &prog, + }; + + if (acpi_is_wakeup_s3() && !IS_ENABLED(CONFIG_NO_STAGE_CACHE)) { + printk(BIOS_INFO, "AGESA: Loading stage from cache\n"); + // There is no way to tell if this succeeded. + stage_cache_load_stage(STAGE_REFCODE, &prog); + } else { + if (prog_locate(&prog)) + return -1; + + if (rmodule_stage_load(&rmod_agesa) < 0) + return -1; + + if (!IS_ENABLED(CONFIG_NO_STAGE_CACHE)) { + printk(BIOS_INFO, "AGESA: Saving stage to cache\n"); + stage_cache_add(STAGE_REFCODE, &prog); + } + } + + return rdev_chain(rdev, prog_rdev(&prog), 0, + region_device_sz(prog_rdev(&prog))); +} + +static int agesa_locate_stage_file(const char *name, struct region_device *rdev) +{ + if (!ENV_RAMSTAGE || !IS_ENABLED(CONFIG_AGESA_SPLIT_MEMORY_FILES)) + return agesa_locate_stage_file_early(name, rdev); + return agesa_locate_stage_file_ramstage(name, rdev); +} + +static const char *get_agesa_cbfs_name(void) +{ + if (!IS_ENABLED(CONFIG_AGESA_SPLIT_MEMORY_FILES)) + return CONFIG_AGESA_CBFS_NAME; + if (!ENV_RAMSTAGE) + return CONFIG_AGESA_PRE_MEMORY_CBFS_NAME; + return CONFIG_AGESA_POST_MEMORY_CBFS_NAME; +} + +const void *agesawrapper_locate_module(const char name[8]) +{ + const void *agesa; + const AMD_IMAGE_HEADER *image; + struct region_device rdev; + size_t file_size; + const char *fname; + int ret; + + fname = get_agesa_cbfs_name(); + + if (IS_ENABLED(CONFIG_AGESA_BINARY_PI_AS_STAGE)) + ret = agesa_locate_stage_file(fname, &rdev); + else + ret = agesa_locate_raw_file(fname, &rdev); + + if (ret) + return NULL; + + file_size = region_device_sz(&rdev); + + /* Assume boot device is memory mapped so the mapping can leak. */ + assert(IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED)); + + agesa = rdev_mmap_full(&rdev); + + if (!agesa) + return NULL; + + image = amd_find_image(agesa, agesa + file_size, 4096, name); + + if (!image) + return NULL; + + return (AMD_MODULE_HEADER *)image->ModuleInfoOffset; +} + +static MODULE_ENTRY agesa_dispatcher; + +MODULE_ENTRY agesa_get_dispatcher(void) +{ + const AMD_MODULE_HEADER *module; + static const char id[8] = AGESA_ID; + + if (agesa_dispatcher != NULL) + return agesa_dispatcher; + + module = agesawrapper_locate_module(id); + if (!module) + return NULL; + + agesa_dispatcher = module->ModuleDispatcher; + return agesa_dispatcher; +}