assets: abstract away the firmware assets used for booting
As there can be more than one source of firmware assets this patch generalizes the notion of locating a particular asset. struct asset is added along with some helper functions for working on assets as a first class citizen. Change-Id: I2ce575d1e5259aed4c34c3dcfd438abe9db1d7b9 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/10264 Reviewed-by: Patrick Georgi <pgeorgi@google.com> Tested-by: build bot (Jenkins)
This commit is contained in:
committed by
Patrick Georgi
parent
6a452eff90
commit
ac12c66cf9
@@ -18,6 +18,7 @@
|
||||
#
|
||||
subdirs-y += loaders
|
||||
|
||||
bootblock-y += assets.c
|
||||
bootblock-y += prog_loaders.c
|
||||
bootblock-y += prog_ops.c
|
||||
bootblock-y += cbfs.c
|
||||
@@ -36,6 +37,7 @@ bootblock-y += region.c
|
||||
bootblock-y += boot_device.c
|
||||
bootblock-y += fmap.c
|
||||
|
||||
verstage-y += assets.c
|
||||
verstage-y += prog_loaders.c
|
||||
verstage-y += prog_ops.c
|
||||
verstage-y += delay.c
|
||||
@@ -60,6 +62,7 @@ verstage-$(CONFIG_GENERIC_UDELAY) += timer.c
|
||||
verstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
|
||||
verstage-y += mem_pool.c
|
||||
|
||||
romstage-y += assets.c
|
||||
romstage-y += prog_loaders.c
|
||||
romstage-y += prog_ops.c
|
||||
romstage-y += memchr.c
|
||||
@@ -92,6 +95,7 @@ endif
|
||||
|
||||
romstage-$(CONFIG_GENERIC_UDELAY) += timer.c
|
||||
|
||||
ramstage-y += assets.c
|
||||
ramstage-y += prog_loaders.c
|
||||
ramstage-y += prog_ops.c
|
||||
ramstage-y += hardwaremain.c
|
||||
|
93
src/lib/assets.c
Normal file
93
src/lib/assets.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 2015 Google 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <assets.h>
|
||||
#include <boot_device.h>
|
||||
#include <cbfs.h>
|
||||
#include <console/console.h>
|
||||
#include <rules.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEFAULT_CBFS_PROVIDER_PRESENT \
|
||||
(!ENV_VERSTAGE || (ENV_VERSTAGE && !CONFIG_RETURN_FROM_VERSTAGE))
|
||||
|
||||
#if DEFAULT_CBFS_PROVIDER_PRESENT
|
||||
static int cbfs_boot_asset_locate(struct asset *asset)
|
||||
{
|
||||
return cbfs_boot_locate(&asset->rdev, asset->name, NULL);
|
||||
}
|
||||
|
||||
static const struct asset_provider cbfs_default_provider = {
|
||||
.name = "CBFS",
|
||||
.locate = cbfs_boot_asset_locate,
|
||||
};
|
||||
#endif
|
||||
|
||||
extern const struct asset_provider vboot_provider;
|
||||
|
||||
static const struct asset_provider *providers[] = {
|
||||
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
||||
&vboot_provider,
|
||||
#endif
|
||||
#if DEFAULT_CBFS_PROVIDER_PRESENT
|
||||
&cbfs_default_provider,
|
||||
#endif
|
||||
};
|
||||
|
||||
int asset_locate(struct asset *asset)
|
||||
{
|
||||
int i;
|
||||
|
||||
boot_device_init();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(providers); i++) {
|
||||
/* Default provider state is active. */
|
||||
int ret = 1;
|
||||
const struct asset_provider *ops;
|
||||
|
||||
ops = providers[i];
|
||||
|
||||
if (ops->is_active != NULL)
|
||||
ret = ops->is_active(asset);
|
||||
|
||||
if (ret == 0) {
|
||||
printk(BIOS_DEBUG, "%s provider inactive.\n",
|
||||
ops->name);
|
||||
continue;
|
||||
} else if (ret < 0) {
|
||||
printk(BIOS_DEBUG, "%s provider failure.\n",
|
||||
ops->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "%s provider active.\n", ops->name);
|
||||
|
||||
if (ops->locate(asset))
|
||||
continue;
|
||||
|
||||
printk(BIOS_DEBUG, "'%s' located at offset: %zx size: %zx\n",
|
||||
asset->name, region_device_offset(&asset->rdev),
|
||||
region_device_sz(&asset->rdev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
@@ -188,12 +188,10 @@ void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device)
|
||||
|
||||
void *cbfs_boot_load_stage_by_name(const char *name)
|
||||
{
|
||||
struct prog stage = {
|
||||
.name = name,
|
||||
};
|
||||
struct prog stage = PROG_INIT(ASSET_UNKNOWN, name);
|
||||
uint32_t type = CBFS_TYPE_STAGE;
|
||||
|
||||
if (cbfs_boot_locate(&stage.rdev, name, &type))
|
||||
if (cbfs_boot_locate(&stage.asset.rdev, name, &type))
|
||||
return NULL;
|
||||
|
||||
if (cbfs_prog_stage_load(&stage))
|
||||
@@ -209,7 +207,7 @@ int cbfs_prog_stage_load(struct prog *pstage)
|
||||
void *entry;
|
||||
size_t fsize;
|
||||
size_t foffset;
|
||||
const struct region_device *fh = &pstage->rdev;
|
||||
const struct region_device *fh = &pstage->asset.rdev;
|
||||
|
||||
if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage))
|
||||
return 0;
|
||||
|
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <arch/stages.h>
|
||||
#include <boot_device.h>
|
||||
#include <cbfs.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
@@ -38,83 +37,10 @@
|
||||
/* Only can represent up to 1 byte less than size_t. */
|
||||
const struct mem_region_device addrspace_32bit = MEM_REGION_DEV_INIT(0, ~0UL);
|
||||
|
||||
#define DEFAULT_CBFS_LOADER_PRESENT \
|
||||
(!ENV_VERSTAGE || (ENV_VERSTAGE && !CONFIG_RETURN_FROM_VERSTAGE))
|
||||
|
||||
#if DEFAULT_CBFS_LOADER_PRESENT
|
||||
static int cbfs_boot_prog_locate(struct prog *prog)
|
||||
{
|
||||
return cbfs_boot_locate(&prog->rdev, prog->name, NULL);
|
||||
}
|
||||
|
||||
static const struct prog_loader_ops cbfs_default_loader = {
|
||||
.locate = cbfs_boot_prog_locate,
|
||||
};
|
||||
#endif
|
||||
|
||||
extern const struct prog_loader_ops vboot_loader;
|
||||
|
||||
static const struct prog_loader_ops *loaders[] = {
|
||||
#if CONFIG_VBOOT_VERIFY_FIRMWARE
|
||||
&vboot_loader,
|
||||
#endif
|
||||
#if DEFAULT_CBFS_LOADER_PRESENT
|
||||
&cbfs_default_loader,
|
||||
#endif
|
||||
};
|
||||
|
||||
int prog_locate(struct prog *prog)
|
||||
{
|
||||
int i;
|
||||
|
||||
boot_device_init();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(loaders); i++) {
|
||||
/* Default loader state is active. */
|
||||
int ret = 1;
|
||||
const struct prog_loader_ops *ops;
|
||||
|
||||
ops = loaders[i];
|
||||
|
||||
if (ops->is_loader_active != NULL)
|
||||
ret = ops->is_loader_active(prog);
|
||||
|
||||
if (ret == 0) {
|
||||
printk(BIOS_DEBUG, "%s loader inactive.\n",
|
||||
ops->name);
|
||||
continue;
|
||||
} else if (ret < 0) {
|
||||
printk(BIOS_DEBUG, "%s loader failure.\n",
|
||||
ops->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, "%s loader active.\n", ops->name);
|
||||
|
||||
if (ops->locate(prog))
|
||||
continue;
|
||||
|
||||
printk(BIOS_DEBUG, "'%s' located at offset: %zx size: %zx\n",
|
||||
prog->name, region_device_offset(&prog->rdev),
|
||||
region_device_sz(&prog->rdev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void run_romstage(void)
|
||||
{
|
||||
struct prog romstage = {
|
||||
.name = CONFIG_CBFS_PREFIX "/romstage",
|
||||
.type = PROG_ROMSTAGE,
|
||||
};
|
||||
|
||||
/* The only time the default CBFS loader isn't present is during
|
||||
* VERSTAGE in which it returns back to the calling stage. */
|
||||
if (!DEFAULT_CBFS_LOADER_PRESENT)
|
||||
return;
|
||||
struct prog romstage =
|
||||
PROG_INIT(ASSET_ROMSTAGE, CONFIG_CBFS_PREFIX "/romstage");
|
||||
|
||||
if (prog_locate(&romstage))
|
||||
goto fail;
|
||||
@@ -166,10 +92,8 @@ static int load_relocatable_ramstage(struct prog *ramstage)
|
||||
|
||||
void run_ramstage(void)
|
||||
{
|
||||
struct prog ramstage = {
|
||||
.name = CONFIG_CBFS_PREFIX "/ramstage",
|
||||
.type = PROG_RAMSTAGE,
|
||||
};
|
||||
struct prog ramstage =
|
||||
PROG_INIT(ASSET_RAMSTAGE, CONFIG_CBFS_PREFIX "/ramstage");
|
||||
|
||||
/* Only x86 systems currently take the same firmware path on resume. */
|
||||
if (IS_ENABLED(CONFIG_ARCH_X86) && IS_ENABLED(CONFIG_EARLY_CBMEM_INIT))
|
||||
@@ -197,10 +121,8 @@ fail:
|
||||
die("Ramstage was not loaded!\n");
|
||||
}
|
||||
|
||||
static struct prog global_payload = {
|
||||
.name = CONFIG_CBFS_PREFIX "/payload",
|
||||
.type = PROG_PAYLOAD,
|
||||
};
|
||||
static struct prog global_payload =
|
||||
PROG_INIT(ASSET_PAYLOAD, CONFIG_CBFS_PREFIX "/payload");
|
||||
|
||||
void __attribute__((weak)) mirror_payload(struct prog *payload)
|
||||
{
|
||||
|
@@ -264,10 +264,10 @@ int rmodule_stage_load(struct rmod_stage_load *rsl)
|
||||
void *rmod_loc;
|
||||
struct region_device *fh;
|
||||
|
||||
if (rsl->prog == NULL || rsl->prog->name == NULL)
|
||||
if (rsl->prog == NULL || prog_name(rsl->prog) == NULL)
|
||||
return -1;
|
||||
|
||||
fh = &rsl->prog->rdev;
|
||||
fh = prog_rdev(rsl->prog);
|
||||
|
||||
if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage))
|
||||
return -1;
|
||||
@@ -284,7 +284,7 @@ int rmodule_stage_load(struct rmod_stage_load *rsl)
|
||||
rmod_loc = &stage_region[rmodule_offset];
|
||||
|
||||
printk(BIOS_INFO, "Decompressing stage %s @ 0x%p (%d bytes)\n",
|
||||
rsl->prog->name, rmod_loc, stage.memlen);
|
||||
prog_name(rsl->prog), rmod_loc, stage.memlen);
|
||||
|
||||
if (stage.compression == CBFS_COMPRESS_NONE) {
|
||||
if (rdev_readat(fh, rmod_loc, sizeof(stage), stage.len) !=
|
||||
|
@@ -454,7 +454,7 @@ void *selfload(struct prog *payload)
|
||||
struct segment head;
|
||||
void *data;
|
||||
|
||||
data = rdev_mmap_full(&payload->rdev);
|
||||
data = rdev_mmap_full(prog_rdev(payload));
|
||||
|
||||
if (data == NULL)
|
||||
return NULL;
|
||||
@@ -469,7 +469,10 @@ void *selfload(struct prog *payload)
|
||||
|
||||
printk(BIOS_SPEW, "Loaded segments\n");
|
||||
|
||||
rdev_munmap(&payload->rdev, data);
|
||||
rdev_munmap(prog_rdev(payload), data);
|
||||
|
||||
/* Update the payload's area with the bounce buffer information. */
|
||||
prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size);
|
||||
|
||||
/* Update the payload's area with the bounce buffer information. */
|
||||
prog_set_area(payload, (void *)(uintptr_t)bounce_buffer, bounce_size);
|
||||
@@ -477,6 +480,6 @@ void *selfload(struct prog *payload)
|
||||
return (void *)entry;
|
||||
|
||||
out:
|
||||
rdev_munmap(&payload->rdev, data);
|
||||
rdev_munmap(prog_rdev(payload), data);
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user