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:
Kyösti Mälkki 2018-06-28 17:33:25 +03:00
parent 7340a499fb
commit e90b632e97
3 changed files with 155 additions and 136 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}