soc/amd/common: Move PI refcode loader
The moved functions are only about locating and loading the refcode blobs. Separate them from the actual calls into the blob. Eventually previous binaryPI blobs should be unified to share same loader code. Change-Id: I68885e7f855b195c178e746c8f3f0f49166d0def Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/31318 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Richard Spiegel <richard.spiegel@silverbackltd.com> Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com>
This commit is contained in:
parent
7340a499fb
commit
e90b632e97
|
@ -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
|
||||
|
|
|
@ -15,17 +15,12 @@
|
|||
*/
|
||||
|
||||
#include <arch/acpi.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <delay.h>
|
||||
#include <rmodule.h>
|
||||
#include <stage_cache.h>
|
||||
#include <string.h>
|
||||
#include <timestamp.h>
|
||||
#include <amdblocks/s3_resume.h>
|
||||
#include <amdblocks/agesawrapper.h>
|
||||
#include <amdblocks/image.h>
|
||||
#include <amdblocks/BiosCallOuts.h>
|
||||
#include <soc/pci_devs.h>
|
||||
#include <soc/southbridge.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <arch/acpi.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <rmodule.h>
|
||||
#include <stage_cache.h>
|
||||
#include <amdblocks/agesawrapper.h>
|
||||
#include <amdblocks/image.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue